mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
Merge m-i to m-c
This commit is contained in:
commit
691bab3d66
@ -31,7 +31,6 @@ CPPSRCS = \
|
||||
nsAccessibilityService.cpp \
|
||||
nsAccessiblePivot.cpp \
|
||||
nsAccTreeWalker.cpp \
|
||||
nsBaseWidgetAccessible.cpp \
|
||||
nsEventShell.cpp \
|
||||
nsCaretAccessible.cpp \
|
||||
nsTextEquivUtils.cpp \
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "DocAccessible-inl.h"
|
||||
#include "FocusManager.h"
|
||||
#include "HTMLElementAccessibles.h"
|
||||
#include "HTMLImageMapAccessible.h"
|
||||
#include "HTMLLinkAccessible.h"
|
||||
#include "HTMLListAccessible.h"
|
||||
#include "HyperTextAccessibleWrap.h"
|
||||
#include "nsAccessiblePivot.h"
|
||||
@ -22,8 +24,6 @@
|
||||
#include "nsARIAMap.h"
|
||||
#include "nsIAccessibleProvider.h"
|
||||
#include "nsHTMLCanvasAccessible.h"
|
||||
#include "nsHTMLImageMapAccessible.h"
|
||||
#include "nsHTMLLinkAccessible.h"
|
||||
#include "nsHTMLSelectAccessible.h"
|
||||
#include "nsHTMLTableAccessibleWrap.h"
|
||||
#include "nsXFormsFormControlsAccessible.h"
|
||||
@ -170,7 +170,7 @@ nsAccessibilityService::GetRootDocumentAccessible(nsIPresShell* aPresShell,
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
||||
already_AddRefed<Accessible>
|
||||
nsAccessibilityService::CreateOuterDocAccessible(nsIContent* aContent,
|
||||
nsIPresShell* aPresShell)
|
||||
@ -266,7 +266,7 @@ nsAccessibilityService::CreateHTMLImageMapAccessible(nsIContent* aContent,
|
||||
nsIPresShell* aPresShell)
|
||||
{
|
||||
Accessible* accessible =
|
||||
new nsHTMLImageMapAccessible(aContent, GetDocAccessible(aPresShell));
|
||||
new HTMLImageMapAccessible(aContent, GetDocAccessible(aPresShell));
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
@ -296,8 +296,8 @@ nsAccessibilityService::CreateHTMLMediaAccessible(nsIContent* aContent,
|
||||
nsIPresShell* aPresShell)
|
||||
{
|
||||
Accessible* accessible =
|
||||
new nsEnumRoleAccessible(aContent, GetDocAccessible(aPresShell),
|
||||
roles::GROUPING);
|
||||
new EnumRoleAccessible(aContent, GetDocAccessible(aPresShell),
|
||||
roles::GROUPING);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
@ -405,7 +405,7 @@ nsAccessibilityService::CreateHTMLTableRowAccessible(nsIContent* aContent,
|
||||
nsIPresShell* aPresShell)
|
||||
{
|
||||
Accessible* accessible =
|
||||
new nsEnumRoleAccessible(aContent, GetDocAccessible(aPresShell), roles::ROW);
|
||||
new EnumRoleAccessible(aContent, GetDocAccessible(aPresShell), roles::ROW);
|
||||
NS_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
@ -562,7 +562,7 @@ nsAccessibilityService::UpdateImageMap(nsImageFrame* aImageFrame)
|
||||
Accessible* accessible =
|
||||
document->GetAccessible(aImageFrame->GetContent());
|
||||
if (accessible) {
|
||||
nsHTMLImageMapAccessible* imageMap = accessible->AsImageMap();
|
||||
HTMLImageMapAccessible* imageMap = accessible->AsImageMap();
|
||||
if (imageMap) {
|
||||
imageMap->UpdateChildAreas();
|
||||
return;
|
||||
@ -1015,7 +1015,7 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
||||
// map rect is empty then it is used for links grouping. Otherwise it should
|
||||
// be used in conjunction with HTML image element and in this case we don't
|
||||
// create any accessible for it and don't walk into it. The accessibles for
|
||||
// HTML area (nsHTMLAreaAccessible) the map contains are attached as
|
||||
// HTML area (HTMLAreaAccessible) the map contains are attached as
|
||||
// children of the appropriate accessible for HTML image
|
||||
// (ImageAccessible).
|
||||
if (nsLayoutUtils::GetAllInFlowRectsUnion(weakFrame,
|
||||
@ -1173,12 +1173,10 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
||||
if (!newAcc) {
|
||||
// Create generic accessibles for SVG and MathML nodes.
|
||||
if (content->IsSVG(nsGkAtoms::svg)) {
|
||||
newAcc = new nsEnumRoleAccessible(content, docAcc,
|
||||
roles::DIAGRAM);
|
||||
newAcc = new EnumRoleAccessible(content, docAcc, roles::DIAGRAM);
|
||||
}
|
||||
else if (content->IsMathML(nsGkAtoms::math)) {
|
||||
newAcc = new nsEnumRoleAccessible(content, docAcc,
|
||||
roles::EQUATION);
|
||||
newAcc = new EnumRoleAccessible(content, docAcc, roles::EQUATION);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1189,9 +1187,9 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
||||
|
||||
// If no accessible, see if we need to create a generic accessible because
|
||||
// of some property that makes this object interesting
|
||||
// We don't do this for <body>, <html>, <window>, <dialog> etc. which
|
||||
// We don't do this for <body>, <html>, <window>, <dialog> etc. which
|
||||
// correspond to the doc accessible and will be created in any case
|
||||
if (!newAcc && content->Tag() != nsGkAtoms::body && content->GetParent() &&
|
||||
if (!newAcc && content->Tag() != nsGkAtoms::body && content->GetParent() &&
|
||||
((weakFrame.GetFrame() && weakFrame.GetFrame()->IsFocusable()) ||
|
||||
(isHTML && nsCoreUtils::HasClickListener(content)) ||
|
||||
HasUniversalAriaProperty(content) || roleMapEntry ||
|
||||
@ -1419,8 +1417,7 @@ nsAccessibilityService::CreateAccessibleByType(nsIContent* aContent,
|
||||
break;
|
||||
|
||||
case nsIAccessibleProvider::XULPane:
|
||||
accessible = new nsEnumRoleAccessible(aContent, aDoc,
|
||||
roles::PANE);
|
||||
accessible = new EnumRoleAccessible(aContent, aDoc, roles::PANE);
|
||||
break;
|
||||
|
||||
case nsIAccessibleProvider::XULProgressMeter:
|
||||
@ -1626,7 +1623,7 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame* aFrame,
|
||||
}
|
||||
|
||||
if (tag == nsGkAtoms::a) {
|
||||
// Only some roles truly enjoy life as nsHTMLLinkAccessibles, for details
|
||||
// Only some roles truly enjoy life as HTMLLinkAccessibles, for details
|
||||
// see closed bug 494807.
|
||||
nsRoleMapEntry* roleMapEntry = aria::GetRoleMap(aContent);
|
||||
if (roleMapEntry && roleMapEntry->role != roles::NOTHING &&
|
||||
@ -1636,7 +1633,7 @@ nsAccessibilityService::CreateHTMLAccessibleByMarkup(nsIFrame* aFrame,
|
||||
return accessible;
|
||||
}
|
||||
|
||||
Accessible* accessible = new nsHTMLLinkAccessible(aContent, aDoc);
|
||||
Accessible* accessible = new HTMLLinkAccessible(aContent, aDoc);
|
||||
NS_IF_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
@ -1786,8 +1783,8 @@ nsAccessibilityService::CreateAccessibleForDeckChild(nsIFrame* aFrame,
|
||||
return accessible;
|
||||
}
|
||||
#endif
|
||||
Accessible* accessible = new nsEnumRoleAccessible(aContent, aDoc,
|
||||
roles::PROPERTYPAGE);
|
||||
Accessible* accessible = new EnumRoleAccessible(aContent, aDoc,
|
||||
roles::PROPERTYPAGE);
|
||||
NS_IF_ADDREF(accessible);
|
||||
return accessible;
|
||||
}
|
||||
|
@ -27,13 +27,13 @@ class EmbeddedObjCollector;
|
||||
class KeyBinding;
|
||||
class Accessible;
|
||||
class HyperTextAccessible;
|
||||
class nsHTMLImageMapAccessible;
|
||||
struct nsRoleMapEntry;
|
||||
class Relation;
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class HTMLImageMapAccessible;
|
||||
class HTMLLIAccessible;
|
||||
class ImageAccessible;
|
||||
class TableAccessible;
|
||||
@ -504,7 +504,7 @@ public:
|
||||
mozilla::a11y::ImageAccessible* AsImage();
|
||||
|
||||
bool IsImageMapAccessible() const { return mFlags & eImageMapAccessible; }
|
||||
nsHTMLImageMapAccessible* AsImageMap();
|
||||
mozilla::a11y::HTMLImageMapAccessible* AsImageMap();
|
||||
|
||||
inline bool IsXULTree() const { return mFlags & eXULTreeAccessible; }
|
||||
nsXULTreeAccessible* AsXULTree();
|
||||
@ -879,7 +879,7 @@ protected:
|
||||
|
||||
nsAutoPtr<AccGroupInfo> mGroupInfo;
|
||||
friend class AccGroupInfo;
|
||||
|
||||
|
||||
/**
|
||||
* Non-null indicates author-supplied role; possibly state & value as well
|
||||
*/
|
||||
|
@ -3,7 +3,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "BaseAccessibles.h"
|
||||
|
||||
#include "Accessible-inl.h"
|
||||
#include "HyperTextAccessibleWrap.h"
|
||||
@ -22,44 +22,44 @@
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLeafAccessible
|
||||
// LeafAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsLeafAccessible::
|
||||
nsLeafAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
LeafAccessible::
|
||||
LeafAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
AccessibleWrap(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsLeafAccessible, Accessible)
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(LeafAccessible, Accessible)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLeafAccessible: Accessible public
|
||||
// LeafAccessible: Accessible public
|
||||
|
||||
Accessible*
|
||||
nsLeafAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
EWhichChildAtPoint aWhichChild)
|
||||
LeafAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
EWhichChildAtPoint aWhichChild)
|
||||
{
|
||||
// Don't walk into leaf accessibles.
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLeafAccessible: Accessible private
|
||||
// LeafAccessible: Accessible private
|
||||
|
||||
void
|
||||
nsLeafAccessible::CacheChildren()
|
||||
LeafAccessible::CacheChildren()
|
||||
{
|
||||
// No children for leaf accessible.
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible
|
||||
// LinkableAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsLinkableAccessible::
|
||||
nsLinkableAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
LinkableAccessible::
|
||||
LinkableAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
AccessibleWrap(aContent, aDoc),
|
||||
mActionAcc(nsnull),
|
||||
mIsLink(false),
|
||||
@ -67,19 +67,19 @@ nsLinkableAccessible::
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsLinkableAccessible, AccessibleWrap)
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(LinkableAccessible, AccessibleWrap)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible. nsIAccessible
|
||||
// LinkableAccessible. nsIAccessible
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::TakeFocus()
|
||||
LinkableAccessible::TakeFocus()
|
||||
{
|
||||
return mActionAcc ? mActionAcc->TakeFocus() : AccessibleWrap::TakeFocus();
|
||||
}
|
||||
|
||||
PRUint64
|
||||
nsLinkableAccessible::NativeLinkState() const
|
||||
LinkableAccessible::NativeLinkState() const
|
||||
{
|
||||
if (mIsLink)
|
||||
return states::LINKED | (mActionAcc->LinkState() & states::TRAVERSED);
|
||||
@ -88,7 +88,7 @@ nsLinkableAccessible::NativeLinkState() const
|
||||
}
|
||||
|
||||
void
|
||||
nsLinkableAccessible::Value(nsString& aValue)
|
||||
LinkableAccessible::Value(nsString& aValue)
|
||||
{
|
||||
aValue.Truncate();
|
||||
|
||||
@ -102,18 +102,18 @@ nsLinkableAccessible::Value(nsString& aValue)
|
||||
|
||||
|
||||
PRUint8
|
||||
nsLinkableAccessible::ActionCount()
|
||||
LinkableAccessible::ActionCount()
|
||||
{
|
||||
return (mIsOnclick || mIsLink) ? 1 : 0;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
LinkableAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
// Action 0 (default action): Jump to link
|
||||
if (aIndex == eAction_Jump) {
|
||||
if (aIndex == eAction_Jump) {
|
||||
if (mIsLink) {
|
||||
aName.AssignLiteral("jump");
|
||||
return NS_OK;
|
||||
@ -128,7 +128,7 @@ nsLinkableAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::DoAction(PRUint8 aIndex)
|
||||
LinkableAccessible::DoAction(PRUint8 aIndex)
|
||||
{
|
||||
if (aIndex != eAction_Jump)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
@ -138,17 +138,17 @@ nsLinkableAccessible::DoAction(PRUint8 aIndex)
|
||||
}
|
||||
|
||||
KeyBinding
|
||||
nsLinkableAccessible::AccessKey() const
|
||||
LinkableAccessible::AccessKey() const
|
||||
{
|
||||
return mActionAcc ?
|
||||
mActionAcc->AccessKey() : Accessible::AccessKey();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible. nsAccessNode
|
||||
// LinkableAccessible. nsAccessNode
|
||||
|
||||
void
|
||||
nsLinkableAccessible::Shutdown()
|
||||
LinkableAccessible::Shutdown()
|
||||
{
|
||||
mIsLink = false;
|
||||
mIsOnclick = false;
|
||||
@ -157,10 +157,10 @@ nsLinkableAccessible::Shutdown()
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible: HyperLinkAccessible
|
||||
// LinkableAccessible: HyperLinkAccessible
|
||||
|
||||
already_AddRefed<nsIURI>
|
||||
nsLinkableAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
|
||||
LinkableAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
|
||||
{
|
||||
if (mIsLink) {
|
||||
NS_ASSERTION(mActionAcc->IsLink(),
|
||||
@ -174,11 +174,11 @@ nsLinkableAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible: Accessible protected
|
||||
// LinkableAccessible: Accessible protected
|
||||
|
||||
void
|
||||
nsLinkableAccessible::BindToParent(Accessible* aParent,
|
||||
PRUint32 aIndexInParent)
|
||||
LinkableAccessible::BindToParent(Accessible* aParent,
|
||||
PRUint32 aIndexInParent)
|
||||
{
|
||||
AccessibleWrap::BindToParent(aParent, aIndexInParent);
|
||||
|
||||
@ -212,7 +212,7 @@ nsLinkableAccessible::BindToParent(Accessible* aParent,
|
||||
}
|
||||
|
||||
void
|
||||
nsLinkableAccessible::UnbindFromParent()
|
||||
LinkableAccessible::UnbindFromParent()
|
||||
{
|
||||
mActionAcc = nsnull;
|
||||
mIsLink = false;
|
||||
@ -222,20 +222,19 @@ nsLinkableAccessible::UnbindFromParent()
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsEnumRoleAccessible
|
||||
// EnumRoleAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsEnumRoleAccessible::
|
||||
nsEnumRoleAccessible(nsIContent* aNode, DocAccessible* aDoc,
|
||||
roles::Role aRole) :
|
||||
EnumRoleAccessible::
|
||||
EnumRoleAccessible(nsIContent* aNode, DocAccessible* aDoc, roles::Role aRole) :
|
||||
AccessibleWrap(aNode, aDoc), mRole(aRole)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsEnumRoleAccessible, Accessible)
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(EnumRoleAccessible, Accessible)
|
||||
|
||||
role
|
||||
nsEnumRoleAccessible::NativeRole()
|
||||
EnumRoleAccessible::NativeRole()
|
||||
{
|
||||
return mRole;
|
||||
}
|
@ -3,8 +3,8 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _nsBaseWidgetAccessible_H_
|
||||
#define _nsBaseWidgetAccessible_H_
|
||||
#ifndef mozilla_a11y_BaseAccessibles_h__
|
||||
#define mozilla_a11y_BaseAccessibles_h__
|
||||
|
||||
#include "AccessibleWrap.h"
|
||||
#include "HyperTextAccessibleWrap.h"
|
||||
@ -16,14 +16,17 @@
|
||||
* the HTML and XUL widget sets. --jgaunt
|
||||
*/
|
||||
|
||||
/**
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
/**
|
||||
* Leaf version of DOM Accessible -- has no children
|
||||
*/
|
||||
class nsLeafAccessible : public AccessibleWrap
|
||||
class LeafAccessible : public AccessibleWrap
|
||||
{
|
||||
public:
|
||||
|
||||
nsLeafAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
LeafAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
@ -44,12 +47,12 @@ protected:
|
||||
* report the state of the host link (traveled or not) and can activate (click)
|
||||
* the host accessible programmatically.
|
||||
*/
|
||||
class nsLinkableAccessible : public AccessibleWrap
|
||||
class LinkableAccessible : public AccessibleWrap
|
||||
{
|
||||
public:
|
||||
enum { eAction_Jump = 0 };
|
||||
|
||||
nsLinkableAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
LinkableAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
@ -87,21 +90,24 @@ protected:
|
||||
|
||||
/**
|
||||
* A simple accessible that gets its enumerated role passed into constructor.
|
||||
*/
|
||||
class nsEnumRoleAccessible : public AccessibleWrap
|
||||
*/
|
||||
class EnumRoleAccessible : public AccessibleWrap
|
||||
{
|
||||
public:
|
||||
nsEnumRoleAccessible(nsIContent* aContent, DocAccessible* aDoc,
|
||||
mozilla::a11y::role aRole);
|
||||
virtual ~nsEnumRoleAccessible() { }
|
||||
EnumRoleAccessible(nsIContent* aContent, DocAccessible* aDoc,
|
||||
a11y::role aRole);
|
||||
virtual ~EnumRoleAccessible() { }
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// Accessible
|
||||
virtual mozilla::a11y::role NativeRole();
|
||||
virtual a11y::role NativeRole();
|
||||
|
||||
protected:
|
||||
mozilla::a11y::role mRole;
|
||||
a11y::role mRole;
|
||||
};
|
||||
|
||||
#endif
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -26,14 +26,14 @@ template class mozilla::a11y::ProgressMeterAccessible<100>;
|
||||
// nsISupports
|
||||
|
||||
template<int Max>
|
||||
NS_IMPL_ADDREF_INHERITED(ProgressMeterAccessible<Max>, nsLeafAccessible)
|
||||
NS_IMPL_ADDREF_INHERITED(ProgressMeterAccessible<Max>, LeafAccessible)
|
||||
|
||||
template<int Max>
|
||||
NS_IMPL_RELEASE_INHERITED(ProgressMeterAccessible<Max>, nsLeafAccessible)
|
||||
NS_IMPL_RELEASE_INHERITED(ProgressMeterAccessible<Max>, LeafAccessible)
|
||||
|
||||
template<int Max>
|
||||
NS_IMPL_QUERY_INTERFACE_INHERITED1(ProgressMeterAccessible<Max>,
|
||||
nsLeafAccessible,
|
||||
LeafAccessible,
|
||||
nsIAccessibleValue)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -50,7 +50,7 @@ template<int Max>
|
||||
PRUint64
|
||||
ProgressMeterAccessible<Max>::NativeState()
|
||||
{
|
||||
PRUint64 state = nsLeafAccessible::NativeState();
|
||||
PRUint64 state = LeafAccessible::NativeState();
|
||||
|
||||
// An undetermined progressbar (i.e. without a value) has a mixed state.
|
||||
nsAutoString attrValue;
|
||||
@ -79,7 +79,7 @@ template<int Max>
|
||||
void
|
||||
ProgressMeterAccessible<Max>::Value(nsString& aValue)
|
||||
{
|
||||
nsLeafAccessible::Value(aValue);
|
||||
LeafAccessible::Value(aValue);
|
||||
if (!aValue.IsEmpty())
|
||||
return;
|
||||
|
||||
@ -105,7 +105,7 @@ template<int Max>
|
||||
NS_IMETHODIMP
|
||||
ProgressMeterAccessible<Max>::GetMaximumValue(double* aMaximumValue)
|
||||
{
|
||||
nsresult rv = nsLeafAccessible::GetMaximumValue(aMaximumValue);
|
||||
nsresult rv = LeafAccessible::GetMaximumValue(aMaximumValue);
|
||||
if (rv != NS_OK_NO_ARIA_VALUE)
|
||||
return rv;
|
||||
|
||||
@ -124,7 +124,7 @@ template<int Max>
|
||||
NS_IMETHODIMP
|
||||
ProgressMeterAccessible<Max>::GetMinimumValue(double* aMinimumValue)
|
||||
{
|
||||
nsresult rv = nsLeafAccessible::GetMinimumValue(aMinimumValue);
|
||||
nsresult rv = LeafAccessible::GetMinimumValue(aMinimumValue);
|
||||
if (rv != NS_OK_NO_ARIA_VALUE)
|
||||
return rv;
|
||||
|
||||
@ -136,7 +136,7 @@ template<int Max>
|
||||
NS_IMETHODIMP
|
||||
ProgressMeterAccessible<Max>::GetMinimumIncrement(double* aMinimumIncrement)
|
||||
{
|
||||
nsresult rv = nsLeafAccessible::GetMinimumIncrement(aMinimumIncrement);
|
||||
nsresult rv = LeafAccessible::GetMinimumIncrement(aMinimumIncrement);
|
||||
if (rv != NS_OK_NO_ARIA_VALUE)
|
||||
return rv;
|
||||
|
||||
@ -148,7 +148,7 @@ template<int Max>
|
||||
NS_IMETHODIMP
|
||||
ProgressMeterAccessible<Max>::GetCurrentValue(double* aCurrentValue)
|
||||
{
|
||||
nsresult rv = nsLeafAccessible::GetCurrentValue(aCurrentValue);
|
||||
nsresult rv = LeafAccessible::GetCurrentValue(aCurrentValue);
|
||||
if (rv != NS_OK_NO_ARIA_VALUE)
|
||||
return rv;
|
||||
|
||||
@ -181,7 +181,7 @@ ProgressMeterAccessible<Max>::SetCurrentValue(double aValue)
|
||||
|
||||
RadioButtonAccessible::
|
||||
RadioButtonAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsLeafAccessible(aContent, aDoc)
|
||||
LeafAccessible(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#ifndef MOZILLA_A11Y_FormControlAccessible_H_
|
||||
#define MOZILLA_A11Y_FormControlAccessible_H_
|
||||
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "BaseAccessibles.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
@ -15,11 +15,11 @@ namespace a11y {
|
||||
* Generic class used for progress meters.
|
||||
*/
|
||||
template<int Max>
|
||||
class ProgressMeterAccessible : public nsLeafAccessible
|
||||
class ProgressMeterAccessible : public LeafAccessible
|
||||
{
|
||||
public:
|
||||
ProgressMeterAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsLeafAccessible(aContent, aDoc)
|
||||
LeafAccessible(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ public:
|
||||
/**
|
||||
* Generic class used for radio buttons.
|
||||
*/
|
||||
class RadioButtonAccessible : public nsLeafAccessible
|
||||
class RadioButtonAccessible : public LeafAccessible
|
||||
{
|
||||
|
||||
public:
|
||||
|
@ -30,7 +30,7 @@ using namespace mozilla::a11y;
|
||||
|
||||
ImageAccessible::
|
||||
ImageAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsLinkableAccessible(aContent, aDoc)
|
||||
LinkableAccessible(aContent, aDoc)
|
||||
{
|
||||
mFlags |= eImageAccessible;
|
||||
}
|
||||
@ -47,7 +47,7 @@ ImageAccessible::NativeState()
|
||||
// The state is a bitfield, get our inherited state, then logically OR it with
|
||||
// states::ANIMATED if this is an animated image.
|
||||
|
||||
PRUint64 state = nsLinkableAccessible::NativeState();
|
||||
PRUint64 state = LinkableAccessible::NativeState();
|
||||
|
||||
nsCOMPtr<nsIImageLoadingContent> content(do_QueryInterface(mContent));
|
||||
nsCOMPtr<imgIRequest> imageRequest;
|
||||
@ -104,7 +104,7 @@ ImageAccessible::NativeRole()
|
||||
PRUint8
|
||||
ImageAccessible::ActionCount()
|
||||
{
|
||||
PRUint8 actionCount = nsLinkableAccessible::ActionCount();
|
||||
PRUint8 actionCount = LinkableAccessible::ActionCount();
|
||||
return HasLongDesc() ? actionCount + 1 : actionCount;
|
||||
}
|
||||
|
||||
@ -120,7 +120,7 @@ ImageAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
aName.AssignLiteral("showlongdesc");
|
||||
return NS_OK;
|
||||
}
|
||||
return nsLinkableAccessible::GetActionName(aIndex, aName);
|
||||
return LinkableAccessible::GetActionName(aIndex, aName);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -131,7 +131,7 @@ ImageAccessible::DoAction(PRUint8 aIndex)
|
||||
|
||||
// Get the long description uri and open in a new window.
|
||||
if (!IsLongDescIndex(aIndex))
|
||||
return nsLinkableAccessible::DoAction(aIndex);
|
||||
return LinkableAccessible::DoAction(aIndex);
|
||||
|
||||
nsCOMPtr<nsIURI> uri = GetLongDescURI();
|
||||
if (!uri)
|
||||
@ -179,7 +179,7 @@ ImageAccessible::GetAttributesInternal(nsIPersistentProperties* aAttributes)
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv = nsLinkableAccessible::GetAttributesInternal(aAttributes);
|
||||
nsresult rv = LinkableAccessible::GetAttributesInternal(aAttributes);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString src;
|
||||
@ -228,6 +228,6 @@ ImageAccessible::GetLongDescURI() const
|
||||
bool
|
||||
ImageAccessible::IsLongDescIndex(PRUint8 aIndex)
|
||||
{
|
||||
return aIndex == nsLinkableAccessible::ActionCount();
|
||||
return aIndex == LinkableAccessible::ActionCount();
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#ifndef mozilla_a11y_ImageAccessible_h__
|
||||
#define mozilla_a11y_ImageAccessible_h__
|
||||
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "BaseAccessibles.h"
|
||||
#include "nsIAccessibleImage.h"
|
||||
|
||||
class nsGenericHTMLElement;
|
||||
@ -19,7 +19,7 @@ namespace a11y {
|
||||
* - gets name, role
|
||||
* - support basic state
|
||||
*/
|
||||
class ImageAccessible : public nsLinkableAccessible,
|
||||
class ImageAccessible : public LinkableAccessible,
|
||||
public nsIAccessibleImage
|
||||
{
|
||||
public:
|
||||
|
@ -18,6 +18,7 @@ CPPSRCS = \
|
||||
Accessible.cpp \
|
||||
ApplicationAccessible.cpp \
|
||||
ARIAGridAccessible.cpp \
|
||||
BaseAccessibles.cpp \
|
||||
DocAccessible.cpp \
|
||||
FormControlAccessible.cpp \
|
||||
HyperTextAccessible.cpp \
|
||||
|
@ -17,7 +17,7 @@ using namespace mozilla::a11y;
|
||||
|
||||
TextLeafAccessible::
|
||||
TextLeafAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsLinkableAccessible(aContent, aDoc)
|
||||
LinkableAccessible(aContent, aDoc)
|
||||
{
|
||||
mFlags |= eTextLeafAccessible;
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
#ifndef mozilla_a11y_TextLeafAccessible_h__
|
||||
#define mozilla_a11y_TextLeafAccessible_h__
|
||||
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "BaseAccessibles.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
@ -14,7 +14,7 @@ namespace a11y {
|
||||
/**
|
||||
* Generic class used for text nodes.
|
||||
*/
|
||||
class TextLeafAccessible : public nsLinkableAccessible
|
||||
class TextLeafAccessible : public LinkableAccessible
|
||||
{
|
||||
public:
|
||||
TextLeafAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
|
@ -6,8 +6,8 @@
|
||||
#ifndef mozilla_a11y_HTMLElementAccessibles_h__
|
||||
#define mozilla_a11y_HTMLElementAccessibles_h__
|
||||
|
||||
#include "BaseAccessibles.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
@ -15,12 +15,12 @@ namespace a11y {
|
||||
/**
|
||||
* Used for HTML hr element.
|
||||
*/
|
||||
class HTMLHRAccessible : public nsLeafAccessible
|
||||
class HTMLHRAccessible : public LeafAccessible
|
||||
{
|
||||
public:
|
||||
|
||||
HTMLHRAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsLeafAccessible(aContent, aDoc) {};
|
||||
LeafAccessible(aContent, aDoc) {};
|
||||
|
||||
// Accessible
|
||||
virtual a11y::role NativeRole();
|
||||
@ -29,12 +29,12 @@ public:
|
||||
/**
|
||||
* Used for HTML br element.
|
||||
*/
|
||||
class HTMLBRAccessible : public nsLeafAccessible
|
||||
class HTMLBRAccessible : public LeafAccessible
|
||||
{
|
||||
public:
|
||||
|
||||
HTMLBRAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsLeafAccessible(aContent, aDoc) {};
|
||||
LeafAccessible(aContent, aDoc) {};
|
||||
|
||||
// Accessible
|
||||
virtual nsresult GetNameInternal(nsAString& aName);
|
||||
|
@ -43,7 +43,7 @@ using namespace mozilla::a11y;
|
||||
|
||||
HTMLCheckboxAccessible::
|
||||
HTMLCheckboxAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsLeafAccessible(aContent, aDoc)
|
||||
LeafAccessible(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ HTMLCheckboxAccessible::DoAction(PRUint8 aIndex)
|
||||
PRUint64
|
||||
HTMLCheckboxAccessible::NativeState()
|
||||
{
|
||||
PRUint64 state = nsLeafAccessible::NativeState();
|
||||
PRUint64 state = LeafAccessible::NativeState();
|
||||
|
||||
state |= states::CHECKABLE;
|
||||
bool checkState = false; // Radio buttons and check boxes can be checked or mixed
|
||||
|
@ -20,7 +20,7 @@ typedef ProgressMeterAccessible<1> HTMLProgressMeterAccessible;
|
||||
/**
|
||||
* Accessible for HTML input@type="checkbox".
|
||||
*/
|
||||
class HTMLCheckboxAccessible : public nsLeafAccessible
|
||||
class HTMLCheckboxAccessible : public LeafAccessible
|
||||
{
|
||||
|
||||
public:
|
||||
|
@ -3,7 +3,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsHTMLImageMapAccessible.h"
|
||||
#include "HTMLImageMapAccessible.h"
|
||||
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsARIAMap.h"
|
||||
@ -21,47 +21,47 @@
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageMapAccessible
|
||||
// HTMLImageMapAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsHTMLImageMapAccessible::
|
||||
nsHTMLImageMapAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
HTMLImageMapAccessible::
|
||||
HTMLImageMapAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
ImageAccessibleWrap(aContent, aDoc)
|
||||
{
|
||||
mFlags |= eImageMapAccessible;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageMapAccessible: nsISupports
|
||||
// HTMLImageMapAccessible: nsISupports
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLImageMapAccessible, ImageAccessible)
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(HTMLImageMapAccessible, ImageAccessible)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageMapAccessible: Accessible public
|
||||
// HTMLImageMapAccessible: Accessible public
|
||||
|
||||
role
|
||||
nsHTMLImageMapAccessible::NativeRole()
|
||||
HTMLImageMapAccessible::NativeRole()
|
||||
{
|
||||
return roles::IMAGE_MAP;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageMapAccessible: HyperLinkAccessible
|
||||
// HTMLImageMapAccessible: HyperLinkAccessible
|
||||
|
||||
PRUint32
|
||||
nsHTMLImageMapAccessible::AnchorCount()
|
||||
HTMLImageMapAccessible::AnchorCount()
|
||||
{
|
||||
return ChildCount();
|
||||
}
|
||||
|
||||
Accessible*
|
||||
nsHTMLImageMapAccessible::AnchorAt(PRUint32 aAnchorIndex)
|
||||
HTMLImageMapAccessible::AnchorAt(PRUint32 aAnchorIndex)
|
||||
{
|
||||
return GetChildAt(aAnchorIndex);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIURI>
|
||||
nsHTMLImageMapAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
|
||||
HTMLImageMapAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
|
||||
{
|
||||
Accessible* area = GetChildAt(aAnchorIndex);
|
||||
if (!area)
|
||||
@ -72,10 +72,10 @@ nsHTMLImageMapAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageMapAccessible: public
|
||||
// HTMLImageMapAccessible: public
|
||||
|
||||
void
|
||||
nsHTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
|
||||
HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
|
||||
{
|
||||
nsImageFrame* imageFrame = do_QueryFrame(mContent->GetPrimaryFrame());
|
||||
|
||||
@ -108,7 +108,7 @@ nsHTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
|
||||
|
||||
Accessible* area = mChildren.SafeElementAt(idx);
|
||||
if (!area || area->GetContent() != areaContent) {
|
||||
nsRefPtr<Accessible> area = new nsHTMLAreaAccessible(areaContent, mDoc);
|
||||
nsRefPtr<Accessible> area = new HTMLAreaAccessible(areaContent, mDoc);
|
||||
if (!mDoc->BindToDocument(area, aria::GetRoleMap(areaContent)))
|
||||
break;
|
||||
|
||||
@ -135,30 +135,30 @@ nsHTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageMapAccessible: Accessible protected
|
||||
// HTMLImageMapAccessible: Accessible protected
|
||||
|
||||
void
|
||||
nsHTMLImageMapAccessible::CacheChildren()
|
||||
HTMLImageMapAccessible::CacheChildren()
|
||||
{
|
||||
UpdateChildAreas(false);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLAreaAccessible
|
||||
// HTMLAreaAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsHTMLAreaAccessible::
|
||||
nsHTMLAreaAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsHTMLLinkAccessible(aContent, aDoc)
|
||||
HTMLAreaAccessible::
|
||||
HTMLAreaAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
HTMLLinkAccessible(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLAreaAccessible: nsIAccessible
|
||||
// HTMLAreaAccessible: nsIAccessible
|
||||
|
||||
nsresult
|
||||
nsHTMLAreaAccessible::GetNameInternal(nsAString & aName)
|
||||
HTMLAreaAccessible::GetNameInternal(nsAString& aName)
|
||||
{
|
||||
nsresult rv = Accessible::GetNameInternal(aName);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -173,7 +173,7 @@ nsHTMLAreaAccessible::GetNameInternal(nsAString & aName)
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLAreaAccessible::Description(nsString& aDescription)
|
||||
HTMLAreaAccessible::Description(nsString& aDescription)
|
||||
{
|
||||
aDescription.Truncate();
|
||||
|
||||
@ -184,10 +184,10 @@ nsHTMLAreaAccessible::Description(nsString& aDescription)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLAreaAccessible: nsAccessNode public
|
||||
// HTMLAreaAccessible: nsAccessNode public
|
||||
|
||||
bool
|
||||
nsHTMLAreaAccessible::IsPrimaryForNode() const
|
||||
HTMLAreaAccessible::IsPrimaryForNode() const
|
||||
{
|
||||
// Make HTML area DOM element not accessible. HTML image map accessible
|
||||
// manages its tree itself.
|
||||
@ -195,21 +195,21 @@ nsHTMLAreaAccessible::IsPrimaryForNode() const
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLAreaAccessible: Accessible public
|
||||
// HTMLAreaAccessible: Accessible public
|
||||
|
||||
Accessible*
|
||||
nsHTMLAreaAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
EWhichChildAtPoint aWhichChild)
|
||||
HTMLAreaAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||
EWhichChildAtPoint aWhichChild)
|
||||
{
|
||||
// Don't walk into area accessibles.
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageMapAccessible: HyperLinkAccessible
|
||||
// HTMLImageMapAccessible: HyperLinkAccessible
|
||||
|
||||
PRUint32
|
||||
nsHTMLAreaAccessible::StartOffset()
|
||||
HTMLAreaAccessible::StartOffset()
|
||||
{
|
||||
// Image map accessible is not hypertext accessible therefore
|
||||
// StartOffset/EndOffset implementations of Accessible doesn't work here.
|
||||
@ -220,22 +220,22 @@ nsHTMLAreaAccessible::StartOffset()
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsHTMLAreaAccessible::EndOffset()
|
||||
HTMLAreaAccessible::EndOffset()
|
||||
{
|
||||
return IndexInParent() + 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLAreaAccessible: Accessible protected
|
||||
// HTMLAreaAccessible: Accessible protected
|
||||
|
||||
void
|
||||
nsHTMLAreaAccessible::CacheChildren()
|
||||
HTMLAreaAccessible::CacheChildren()
|
||||
{
|
||||
// No children for aria accessible.
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLAreaAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame)
|
||||
HTMLAreaAccessible::GetBoundsRect(nsRect& aBounds, nsIFrame** aBoundingFrame)
|
||||
{
|
||||
nsIFrame* frame = GetFrame();
|
||||
if (!frame)
|
@ -3,28 +3,30 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _nsHTMLAreaAccessible_H_
|
||||
#define _nsHTMLAreaAccessible_H_
|
||||
#ifndef mozilla_a11y_HTMLImageMapAccessible_h__
|
||||
#define mozilla_a11y_HTMLImageMapAccessible_h__
|
||||
|
||||
#include "HTMLLinkAccessible.h"
|
||||
#include "ImageAccessibleWrap.h"
|
||||
#include "nsHTMLLinkAccessible.h"
|
||||
|
||||
#include "nsIDOMHTMLMapElement.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
/**
|
||||
* Used for HTML image maps.
|
||||
*/
|
||||
class nsHTMLImageMapAccessible : public mozilla::a11y::ImageAccessibleWrap
|
||||
class HTMLImageMapAccessible : public ImageAccessibleWrap
|
||||
{
|
||||
public:
|
||||
nsHTMLImageMapAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
virtual ~nsHTMLImageMapAccessible() { }
|
||||
HTMLImageMapAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
virtual ~HTMLImageMapAccessible() { }
|
||||
|
||||
// nsISupports and cycle collector
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// Accessible
|
||||
virtual mozilla::a11y::role NativeRole();
|
||||
virtual a11y::role NativeRole();
|
||||
|
||||
// HyperLinkAccessible
|
||||
virtual PRUint32 AnchorCount();
|
||||
@ -42,25 +44,14 @@ protected:
|
||||
virtual void CacheChildren();
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Accessible downcasting method
|
||||
|
||||
inline nsHTMLImageMapAccessible*
|
||||
Accessible::AsImageMap()
|
||||
{
|
||||
return IsImageMapAccessible() ?
|
||||
static_cast<nsHTMLImageMapAccessible*>(this) : nsnull;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Accessible for image map areas - must be child of image.
|
||||
*/
|
||||
class nsHTMLAreaAccessible : public nsHTMLLinkAccessible
|
||||
class HTMLAreaAccessible : public HTMLLinkAccessible
|
||||
{
|
||||
public:
|
||||
|
||||
nsHTMLAreaAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
HTMLAreaAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
|
||||
// nsAccessNode
|
||||
virtual bool IsPrimaryForNode() const;
|
||||
@ -82,4 +73,17 @@ protected:
|
||||
virtual void CacheChildren();
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Accessible downcasting method
|
||||
|
||||
inline mozilla::a11y::HTMLImageMapAccessible*
|
||||
Accessible::AsImageMap()
|
||||
{
|
||||
return IsImageMapAccessible() ?
|
||||
static_cast<mozilla::a11y::HTMLImageMapAccessible*>(this) : nsnull;
|
||||
}
|
||||
|
||||
#endif
|
@ -3,7 +3,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsHTMLLinkAccessible.h"
|
||||
#include "HTMLLinkAccessible.h"
|
||||
|
||||
#include "nsCoreUtils.h"
|
||||
#include "DocAccessible.h"
|
||||
@ -17,36 +17,36 @@
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLLinkAccessible
|
||||
// HTMLLinkAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsHTMLLinkAccessible::
|
||||
nsHTMLLinkAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
HTMLLinkAccessible::
|
||||
HTMLLinkAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
HyperTextAccessibleWrap(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
// Expose nsIAccessibleHyperLink unconditionally
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLLinkAccessible, HyperTextAccessibleWrap,
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(HTMLLinkAccessible, HyperTextAccessibleWrap,
|
||||
nsIAccessibleHyperLink)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessible
|
||||
|
||||
role
|
||||
nsHTMLLinkAccessible::NativeRole()
|
||||
HTMLLinkAccessible::NativeRole()
|
||||
{
|
||||
return roles::LINK;
|
||||
}
|
||||
|
||||
PRUint64
|
||||
nsHTMLLinkAccessible::NativeState()
|
||||
HTMLLinkAccessible::NativeState()
|
||||
{
|
||||
return HyperTextAccessibleWrap::NativeState() & ~states::READONLY;
|
||||
}
|
||||
|
||||
PRUint64
|
||||
nsHTMLLinkAccessible::NativeLinkState() const
|
||||
HTMLLinkAccessible::NativeLinkState() const
|
||||
{
|
||||
nsEventStates eventState = mContent->AsElement()->State();
|
||||
if (eventState.HasState(NS_EVENT_STATE_UNVISITED))
|
||||
@ -62,7 +62,7 @@ nsHTMLLinkAccessible::NativeLinkState() const
|
||||
}
|
||||
|
||||
PRUint64
|
||||
nsHTMLLinkAccessible::NativeInteractiveState() const
|
||||
HTMLLinkAccessible::NativeInteractiveState() const
|
||||
{
|
||||
PRUint64 state = HyperTextAccessibleWrap::NativeInteractiveState();
|
||||
|
||||
@ -76,7 +76,7 @@ nsHTMLLinkAccessible::NativeInteractiveState() const
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLLinkAccessible::Value(nsString& aValue)
|
||||
HTMLLinkAccessible::Value(nsString& aValue)
|
||||
{
|
||||
aValue.Truncate();
|
||||
|
||||
@ -86,13 +86,13 @@ nsHTMLLinkAccessible::Value(nsString& aValue)
|
||||
}
|
||||
|
||||
PRUint8
|
||||
nsHTMLLinkAccessible::ActionCount()
|
||||
HTMLLinkAccessible::ActionCount()
|
||||
{
|
||||
return IsLinked() ? 1 : HyperTextAccessible::ActionCount();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
HTMLLinkAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
@ -108,7 +108,7 @@ nsHTMLLinkAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLLinkAccessible::DoAction(PRUint8 aIndex)
|
||||
HTMLLinkAccessible::DoAction(PRUint8 aIndex)
|
||||
{
|
||||
if (!IsLinked())
|
||||
return HyperTextAccessible::DoAction(aIndex);
|
||||
@ -128,14 +128,14 @@ nsHTMLLinkAccessible::DoAction(PRUint8 aIndex)
|
||||
// HyperLinkAccessible
|
||||
|
||||
bool
|
||||
nsHTMLLinkAccessible::IsLink()
|
||||
HTMLLinkAccessible::IsLink()
|
||||
{
|
||||
// Expose HyperLinkAccessible unconditionally.
|
||||
return true;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIURI>
|
||||
nsHTMLLinkAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
|
||||
HTMLLinkAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
|
||||
{
|
||||
return aAnchorIndex == 0 ? mContent->GetHrefURI() : nsnull;
|
||||
}
|
||||
@ -144,7 +144,7 @@ nsHTMLLinkAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
|
||||
// Protected members
|
||||
|
||||
bool
|
||||
nsHTMLLinkAccessible::IsLinked()
|
||||
HTMLLinkAccessible::IsLinked()
|
||||
{
|
||||
if (IsDefunct())
|
||||
return false;
|
@ -3,15 +3,18 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _nsHTMLLinkAccessible_H_
|
||||
#define _nsHTMLLinkAccessible_H_
|
||||
#ifndef mozilla_a11y_HTMLLinkAccessible_h__
|
||||
#define mozilla_a11y_HTMLLinkAccessible_h__
|
||||
|
||||
#include "HyperTextAccessibleWrap.h"
|
||||
|
||||
class nsHTMLLinkAccessible : public HyperTextAccessibleWrap
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class HTMLLinkAccessible : public HyperTextAccessibleWrap
|
||||
{
|
||||
public:
|
||||
nsHTMLLinkAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
HTMLLinkAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
@ -21,7 +24,7 @@ public:
|
||||
|
||||
// Accessible
|
||||
virtual void Value(nsString& aValue);
|
||||
virtual mozilla::a11y::role NativeRole();
|
||||
virtual a11y::role NativeRole();
|
||||
virtual PRUint64 NativeState();
|
||||
virtual PRUint64 NativeLinkState() const;
|
||||
virtual PRUint64 NativeInteractiveState() const;
|
||||
@ -42,4 +45,7 @@ protected:
|
||||
bool IsLinked();
|
||||
};
|
||||
|
||||
#endif
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
@ -188,7 +188,7 @@ HTMLListBulletAccessible::NativeRole()
|
||||
PRUint64
|
||||
HTMLListBulletAccessible::NativeState()
|
||||
{
|
||||
return nsLeafAccessible::NativeState() | states::READONLY;
|
||||
return LeafAccessible::NativeState() | states::READONLY;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -7,8 +7,8 @@
|
||||
#ifndef mozilla_a11y_HTMLListAccessible_h__
|
||||
#define mozilla_a11y_HTMLListAccessible_h__
|
||||
|
||||
#include "BaseAccessibles.h"
|
||||
#include "HyperTextAccessibleWrap.h"
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
@ -72,11 +72,11 @@ private:
|
||||
/**
|
||||
* Used for bullet of HTML list item element (for example, HTML li).
|
||||
*/
|
||||
class HTMLListBulletAccessible : public nsLeafAccessible
|
||||
class HTMLListBulletAccessible : public LeafAccessible
|
||||
{
|
||||
public:
|
||||
HTMLListBulletAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsLeafAccessible(aContent, aDoc) { }
|
||||
LeafAccessible(aContent, aDoc) { }
|
||||
virtual ~HTMLListBulletAccessible() { }
|
||||
|
||||
// nsAccessNode
|
||||
|
@ -19,10 +19,10 @@ LIBXUL_LIBRARY = 1
|
||||
CPPSRCS = \
|
||||
HTMLElementAccessibles.cpp \
|
||||
HTMLFormControlAccessible.cpp \
|
||||
HTMLImageMapAccessible.cpp \
|
||||
HTMLLinkAccessible.cpp \
|
||||
HTMLListAccessible.cpp \
|
||||
nsHTMLCanvasAccessible.cpp \
|
||||
nsHTMLImageMapAccessible.cpp \
|
||||
nsHTMLLinkAccessible.cpp \
|
||||
nsHTMLSelectAccessible.cpp \
|
||||
nsHTMLTableAccessible.cpp \
|
||||
$(NULL)
|
||||
|
@ -65,8 +65,8 @@ nsHTMLWin32ObjectOwnerAccessible::CacheChildren()
|
||||
// nsHTMLWin32ObjectAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsHTMLWin32ObjectAccessible::nsHTMLWin32ObjectAccessible(void* aHwnd):
|
||||
nsLeafAccessible(nsnull, nsnull)
|
||||
nsHTMLWin32ObjectAccessible::nsHTMLWin32ObjectAccessible(void* aHwnd) :
|
||||
LeafAccessible(nsnull, nsnull)
|
||||
{
|
||||
// XXX: Mark it as defunct to make sure no single Accessible method is
|
||||
// running on it. We need to allow accessible without DOM nodes.
|
||||
|
@ -6,7 +6,7 @@
|
||||
#ifndef _nsHTMLWin32ObjectAccessible_H_
|
||||
#define _nsHTMLWin32ObjectAccessible_H_
|
||||
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "BaseAccessibles.h"
|
||||
|
||||
struct IAccessible;
|
||||
|
||||
@ -48,11 +48,11 @@ protected:
|
||||
* object returned by us in Accessible::NewAccessible() that gets the IAccessible
|
||||
* from the windows system from the window handle.
|
||||
*/
|
||||
class nsHTMLWin32ObjectAccessible : public nsLeafAccessible
|
||||
class nsHTMLWin32ObjectAccessible : public mozilla::a11y::LeafAccessible
|
||||
{
|
||||
public:
|
||||
|
||||
nsHTMLWin32ObjectAccessible(void *aHwnd);
|
||||
nsHTMLWin32ObjectAccessible(void* aHwnd);
|
||||
virtual ~nsHTMLWin32ObjectAccessible() {}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
@ -17,7 +17,7 @@ using namespace mozilla::a11y;
|
||||
nsXFormsDropmarkerWidgetAccessible::
|
||||
nsXFormsDropmarkerWidgetAccessible(nsIContent* aContent,
|
||||
DocAccessible* aDoc) :
|
||||
nsLeafAccessible(aContent, aDoc)
|
||||
LeafAccessible(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -6,15 +6,15 @@
|
||||
#ifndef _nsXFormsWidgetsAccessible_H_
|
||||
#define _nsXFormsWidgetsAccessible_H_
|
||||
|
||||
#include "BaseAccessibles.h"
|
||||
#include "nsXFormsAccessible.h"
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
|
||||
/**
|
||||
* Accessible object for dropmarker widget that is used inside xforms elements
|
||||
* of combobox representation. For example, these are xforms:select1,
|
||||
* xforms:input[type="xsd:date"].
|
||||
*/
|
||||
class nsXFormsDropmarkerWidgetAccessible : public nsLeafAccessible,
|
||||
class nsXFormsDropmarkerWidgetAccessible : public mozilla::a11y::LeafAccessible,
|
||||
public nsXFormsAccessibleBase
|
||||
{
|
||||
public:
|
||||
|
@ -239,7 +239,7 @@ XULButtonAccessible::ContainsMenu()
|
||||
|
||||
XULDropmarkerAccessible::
|
||||
XULDropmarkerAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsLeafAccessible(aContent, aDoc)
|
||||
LeafAccessible(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
@ -323,7 +323,7 @@ XULDropmarkerAccessible::NativeState()
|
||||
|
||||
XULCheckboxAccessible::
|
||||
XULCheckboxAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsLeafAccessible(aContent, aDoc)
|
||||
LeafAccessible(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
@ -376,7 +376,7 @@ XULCheckboxAccessible::NativeState()
|
||||
{
|
||||
// Possible states: focused, focusable, unavailable(disabled), checked
|
||||
// Get focus and disable status from base class
|
||||
PRUint64 state = nsLeafAccessible::NativeState();
|
||||
PRUint64 state = LeafAccessible::NativeState();
|
||||
|
||||
state |= states::CHECKABLE;
|
||||
|
||||
@ -468,7 +468,7 @@ XULRadioButtonAccessible::
|
||||
PRUint64
|
||||
XULRadioButtonAccessible::NativeState()
|
||||
{
|
||||
PRUint64 state = nsLeafAccessible::NativeState();
|
||||
PRUint64 state = LeafAccessible::NativeState();
|
||||
state |= states::CHECKABLE;
|
||||
|
||||
nsCOMPtr<nsIDOMXULSelectControlItemElement> radioButton =
|
||||
@ -659,7 +659,7 @@ XULToolbarAccessible::GetNameInternal(nsAString& aName)
|
||||
|
||||
XULToolbarSeparatorAccessible::
|
||||
XULToolbarSeparatorAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsLeafAccessible(aContent, aDoc)
|
||||
LeafAccessible(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ typedef ProgressMeterAccessible<100> XULProgressMeterAccessible;
|
||||
/**
|
||||
* Used for XUL button.
|
||||
*
|
||||
* @note Don't inherit from nsLeafAccessible - it doesn't allow children
|
||||
* @note Don't inherit from LeafAccessible - it doesn't allow children
|
||||
* and a button can have a dropmarker child.
|
||||
*/
|
||||
class XULButtonAccessible : public AccessibleWrap
|
||||
@ -65,7 +65,7 @@ protected:
|
||||
/**
|
||||
* Used for XUL checkbox element.
|
||||
*/
|
||||
class XULCheckboxAccessible : public nsLeafAccessible
|
||||
class XULCheckboxAccessible : public LeafAccessible
|
||||
{
|
||||
public:
|
||||
enum { eAction_Click = 0 };
|
||||
@ -86,7 +86,7 @@ public:
|
||||
/**
|
||||
* Used for XUL dropmarker element.
|
||||
*/
|
||||
class XULDropmarkerAccessible : public nsLeafAccessible
|
||||
class XULDropmarkerAccessible : public LeafAccessible
|
||||
{
|
||||
public:
|
||||
enum { eAction_Click = 0 };
|
||||
@ -200,7 +200,7 @@ public:
|
||||
/**
|
||||
* Used for XUL toolbarseparator element.
|
||||
*/
|
||||
class XULToolbarSeparatorAccessible : public nsLeafAccessible
|
||||
class XULToolbarSeparatorAccessible : public LeafAccessible
|
||||
{
|
||||
public:
|
||||
XULToolbarSeparatorAccessible(nsIContent* aContent,
|
||||
|
@ -52,7 +52,7 @@ nsXULColumAccessible::NativeState()
|
||||
|
||||
nsXULColumnItemAccessible::
|
||||
nsXULColumnItemAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsLeafAccessible(aContent, aDoc)
|
||||
LeafAccessible(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,8 @@
|
||||
#ifndef __nsXULListboxAccessible_h__
|
||||
#define __nsXULListboxAccessible_h__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "BaseAccessibles.h"
|
||||
#include "nsXULMenuAccessible.h"
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "nsIAccessibleTable.h"
|
||||
#include "TableAccessible.h"
|
||||
#include "xpcAccessibleTable.h"
|
||||
@ -33,7 +32,7 @@ public:
|
||||
* nsXULColumnAccessible are accessibles for list and tree column elements
|
||||
* (xul:listcol and xul:treecol).
|
||||
*/
|
||||
class nsXULColumnItemAccessible : public nsLeafAccessible
|
||||
class nsXULColumnItemAccessible : public mozilla::a11y::LeafAccessible
|
||||
{
|
||||
public:
|
||||
nsXULColumnItemAccessible(nsIContent* aContent, DocAccessible* aDoc);
|
||||
|
@ -7,7 +7,6 @@
|
||||
#define _nsXULTabAccessible_H_
|
||||
|
||||
// NOTE: alphabetically ordered
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "nsXULMenuAccessible.h"
|
||||
#include "XULSelectControlAccessible.h"
|
||||
|
||||
|
@ -7,8 +7,8 @@
|
||||
#include "nsXULTextAccessible.h"
|
||||
|
||||
#include "Accessible-inl.h"
|
||||
#include "BaseAccessibles.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
#include "nsCoreUtils.h"
|
||||
#include "nsTextEquivUtils.h"
|
||||
#include "Relation.h"
|
||||
@ -80,14 +80,14 @@ nsXULTextAccessible::RelationByType(PRUint32 aType)
|
||||
|
||||
nsXULTooltipAccessible::
|
||||
nsXULTooltipAccessible(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
nsLeafAccessible(aContent, aDoc)
|
||||
LeafAccessible(aContent, aDoc)
|
||||
{
|
||||
}
|
||||
|
||||
PRUint64
|
||||
nsXULTooltipAccessible::NativeState()
|
||||
{
|
||||
return nsLeafAccessible::NativeState() | states::READONLY;
|
||||
return LeafAccessible::NativeState() | states::READONLY;
|
||||
}
|
||||
|
||||
role
|
||||
|
@ -6,8 +6,8 @@
|
||||
#ifndef _nsXULTextAccessible_H_
|
||||
#define _nsXULTextAccessible_H_
|
||||
|
||||
#include "BaseAccessibles.h"
|
||||
#include "HyperTextAccessibleWrap.h"
|
||||
#include "nsBaseWidgetAccessible.h"
|
||||
|
||||
/**
|
||||
* Used for XUL description and label elements.
|
||||
@ -27,7 +27,7 @@ public:
|
||||
/**
|
||||
* Used for XUL tooltip element.
|
||||
*/
|
||||
class nsXULTooltipAccessible : public nsLeafAccessible
|
||||
class nsXULTooltipAccessible : public mozilla::a11y::LeafAccessible
|
||||
{
|
||||
|
||||
public:
|
||||
|
@ -719,7 +719,7 @@ nsXULTreeGridCellAccessible::
|
||||
nsXULTreeGridRowAccessible* aRowAcc,
|
||||
nsITreeBoxObject* aTree, nsITreeView* aTreeView,
|
||||
PRInt32 aRow, nsITreeColumn* aColumn) :
|
||||
nsLeafAccessible(aContent, aDoc), mTree(aTree),
|
||||
LeafAccessible(aContent, aDoc), mTree(aTree),
|
||||
mTreeView(aTreeView), mRow(aRow), mColumn(aColumn)
|
||||
{
|
||||
mParent = aRowAcc;
|
||||
@ -731,13 +731,13 @@ nsXULTreeGridCellAccessible::
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULTreeGridCellAccessible)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULTreeGridCellAccessible,
|
||||
nsLeafAccessible)
|
||||
LeafAccessible)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTree)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mColumn)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXULTreeGridCellAccessible,
|
||||
nsLeafAccessible)
|
||||
LeafAccessible)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTree)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mColumn)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
@ -746,9 +746,9 @@ NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsXULTreeGridCellAccessible)
|
||||
NS_INTERFACE_TABLE_INHERITED2(nsXULTreeGridCellAccessible,
|
||||
nsIAccessibleTableCell,
|
||||
nsXULTreeGridCellAccessible)
|
||||
NS_INTERFACE_TABLE_TAIL_INHERITING(nsLeafAccessible)
|
||||
NS_IMPL_ADDREF_INHERITED(nsXULTreeGridCellAccessible, nsLeafAccessible)
|
||||
NS_IMPL_RELEASE_INHERITED(nsXULTreeGridCellAccessible, nsLeafAccessible)
|
||||
NS_INTERFACE_TABLE_TAIL_INHERITING(LeafAccessible)
|
||||
NS_IMPL_ADDREF_INHERITED(nsXULTreeGridCellAccessible, LeafAccessible)
|
||||
NS_IMPL_RELEASE_INHERITED(nsXULTreeGridCellAccessible, LeafAccessible)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULTreeGridCellAccessible: nsIAccessible implementation
|
||||
@ -1029,7 +1029,7 @@ nsXULTreeGridCellAccessible::IsSelected(bool *aIsSelected)
|
||||
bool
|
||||
nsXULTreeGridCellAccessible::Init()
|
||||
{
|
||||
if (!nsLeafAccessible::Init() || !mTreeView)
|
||||
if (!LeafAccessible::Init() || !mTreeView)
|
||||
return false;
|
||||
|
||||
PRInt16 type;
|
||||
|
@ -104,7 +104,7 @@ protected:
|
||||
{ 0xa9, 0x32, 0x4c, 0x5c, 0xa5, 0xde, 0x5d, 0xff } \
|
||||
}
|
||||
|
||||
class nsXULTreeGridCellAccessible : public nsLeafAccessible,
|
||||
class nsXULTreeGridCellAccessible : public mozilla::a11y::LeafAccessible,
|
||||
public nsIAccessibleTableCell
|
||||
{
|
||||
public:
|
||||
@ -117,12 +117,12 @@ public:
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXULTreeGridCellAccessible,
|
||||
nsLeafAccessible)
|
||||
LeafAccessible)
|
||||
|
||||
// nsIAccessible
|
||||
|
||||
NS_IMETHOD GetBounds(PRInt32 *aX, PRInt32 *aY,
|
||||
PRInt32 *aWidth, PRInt32 *aHeight);
|
||||
NS_IMETHOD GetBounds(PRInt32* aX, PRInt32* aY,
|
||||
PRInt32* aWidth, PRInt32* aHeight);
|
||||
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 aIndex);
|
||||
@ -137,7 +137,7 @@ public:
|
||||
// Accessible
|
||||
virtual mozilla::a11y::ENameValueFlag Name(nsString& aName);
|
||||
virtual Accessible* FocusedChild();
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties* aAttributes);
|
||||
virtual PRInt32 IndexInParent() const;
|
||||
virtual Relation RelationByType(PRUint32 aType);
|
||||
virtual mozilla::a11y::role NativeRole();
|
||||
@ -164,8 +164,8 @@ public:
|
||||
protected:
|
||||
// Accessible
|
||||
virtual Accessible* GetSiblingAtOffset(PRInt32 aOffset,
|
||||
nsresult *aError = nsnull) const;
|
||||
virtual void DispatchClickEvent(nsIContent *aContent, PRUint32 aActionIndex);
|
||||
nsresult* aError = nsnull) const;
|
||||
virtual void DispatchClickEvent(nsIContent* aContent, PRUint32 aActionIndex);
|
||||
|
||||
// nsXULTreeGridCellAccessible
|
||||
|
||||
|
@ -130,7 +130,7 @@
|
||||
|
||||
//
|
||||
// This section tests aria roles on links/anchors for underlying
|
||||
// nsHTMLLinkAccessible creation. (see closed bug 494807)
|
||||
// HTMLLinkAccessible creation. (see closed bug 494807)
|
||||
//
|
||||
|
||||
// strong roles
|
||||
|
@ -39,13 +39,13 @@
|
||||
var rootDir = getRootDirectory(window.location.href);
|
||||
var href = getRootDirectory(window.location.href) + "foo";
|
||||
|
||||
// roles that can't live as nsHTMLLinkAccessibles
|
||||
// roles that can't live as HTMLLinkAccessibles
|
||||
testValue("aria_menuitem_link", "");
|
||||
testValue("aria_button_link", "");
|
||||
testValue("aria_checkbox_link", "");
|
||||
testValue("aria_application_link", "");
|
||||
|
||||
// roles that can live as nsHTMLLinkAccessibles
|
||||
// roles that can live as HTMLLinkAccessibles
|
||||
testValue("aria_link_link", href);
|
||||
testValue("aria_main_link", href);
|
||||
testValue("aria_navigation_link", href);
|
||||
|
@ -12,6 +12,7 @@ const Cr = Components.results;
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://gre/modules/ContactService.jsm');
|
||||
Cu.import('resource://gre/modules/SettingsChangeNotifier.jsm');
|
||||
Cu.import('resource://gre/modules/Webapps.jsm');
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(Services, 'env',
|
||||
|
@ -1160,6 +1160,18 @@ pref("full-screen-api.approval-required", true);
|
||||
// (this pref has no effect if more than 6 hours have passed since the last crash)
|
||||
pref("toolkit.startup.max_resumed_crashes", 3);
|
||||
|
||||
// Completely disable pdf.js as an option to preview pdfs within firefox.
|
||||
// Note: if this is not disabled it does not necessarily mean pdf.js is the pdf
|
||||
// handler just that it is an option.
|
||||
pref("pdfjs.disabled", false);
|
||||
// Used by pdf.js to know the first time firefox is run with it installed so it
|
||||
// can become the default pdf viewer.
|
||||
pref("pdfjs.firstRun", true);
|
||||
// The values of preferredAction and alwaysAskBeforeHandling before pdf.js
|
||||
// became the default.
|
||||
pref("pdfjs.previousHandler.preferredAction", 0);
|
||||
pref("pdfjs.previousHandler.alwaysAskBeforeHandling", false);
|
||||
|
||||
// The maximum amount of decoded image data we'll willingly keep around (we
|
||||
// might keep around more than this, but we'll try to get down to this value).
|
||||
// (This is intentionally on the high side; see bug 746055.)
|
||||
|
@ -31,6 +31,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "webappsUI",
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PageThumbs",
|
||||
"resource:///modules/PageThumbs.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "PdfJs",
|
||||
"resource://pdf.js/PdfJs.jsm");
|
||||
|
||||
const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
|
||||
const PREF_PLUGINS_UPDATEURL = "plugins.update.url";
|
||||
|
||||
@ -329,6 +332,8 @@ BrowserGlue.prototype = {
|
||||
|
||||
PageThumbs.init();
|
||||
|
||||
PdfJs.init();
|
||||
|
||||
Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
|
||||
},
|
||||
|
||||
|
@ -17,10 +17,15 @@ var Cr = Components.results;
|
||||
/*
|
||||
#endif
|
||||
*/
|
||||
Components.utils.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
|
||||
const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
|
||||
const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
|
||||
const TYPE_PDF = "application/pdf";
|
||||
|
||||
const PREF_PDFJS_DISABLED = "pdfjs.disabled";
|
||||
const TOPIC_PDFJS_HANDLER_CHANGED = "pdfjs:handlerChanged";
|
||||
|
||||
const PREF_DISABLED_PLUGIN_TYPES = "plugin.disable_full_page_plugin_for_types";
|
||||
|
||||
@ -810,6 +815,46 @@ var audioFeedHandlerInfo = {
|
||||
_appPrefLabel: "audioPodcastFeed"
|
||||
}
|
||||
|
||||
/**
|
||||
* InternalHandlerInfoWrapper provides a basic mechanism to create an internal
|
||||
* mime type handler that can be enabled/disabled in the applications preference
|
||||
* menu.
|
||||
*/
|
||||
function InternalHandlerInfoWrapper(aMIMEType) {
|
||||
var mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
|
||||
var handlerInfo = mimeSvc.getFromTypeAndExtension(aMIMEType, null);
|
||||
|
||||
HandlerInfoWrapper.call(this, aMIMEType, handlerInfo);
|
||||
}
|
||||
|
||||
InternalHandlerInfoWrapper.prototype = {
|
||||
__proto__: HandlerInfoWrapper.prototype,
|
||||
|
||||
// Override store so we so we can notify any code listening for registration
|
||||
// or unregistration of this handler.
|
||||
store: function() {
|
||||
HandlerInfoWrapper.prototype.store.call(this);
|
||||
Services.obs.notifyObservers(null, this._handlerChanged, null);
|
||||
},
|
||||
|
||||
get enabled() {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
get description() {
|
||||
return this.element("bundlePreferences").getString(this._appPrefLabel);
|
||||
}
|
||||
};
|
||||
|
||||
var pdfHandlerInfo = {
|
||||
__proto__: new InternalHandlerInfoWrapper(TYPE_PDF),
|
||||
_handlerChanged: TOPIC_PDFJS_HANDLER_CHANGED,
|
||||
_appPrefLabel: "portableDocumentFormat",
|
||||
get enabled() {
|
||||
return !Services.prefs.getBoolPref(PREF_PDFJS_DISABLED);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
//****************************************************************************//
|
||||
// Prefpane Controller
|
||||
@ -999,6 +1044,7 @@ var gApplicationsPane = {
|
||||
|
||||
_loadData: function() {
|
||||
this._loadFeedHandler();
|
||||
this._loadInternalHandlers();
|
||||
this._loadPluginHandlers();
|
||||
this._loadApplicationHandlers();
|
||||
},
|
||||
@ -1014,6 +1060,19 @@ var gApplicationsPane = {
|
||||
audioFeedHandlerInfo.handledOnlyByPlugin = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Load higher level internal handlers so they can be turned on/off in the
|
||||
* applications menu.
|
||||
*/
|
||||
_loadInternalHandlers: function() {
|
||||
var internalHandlers = [pdfHandlerInfo];
|
||||
for (let internalHandler of internalHandlers) {
|
||||
if (internalHandler.enabled) {
|
||||
this._handledTypes[internalHandler.type] = internalHandler;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load the set of handlers defined by plugins.
|
||||
*
|
||||
@ -1216,9 +1275,15 @@ var gApplicationsPane = {
|
||||
|
||||
case Ci.nsIHandlerInfo.handleInternally:
|
||||
// For the feed type, handleInternally means live bookmarks.
|
||||
if (isFeedType(aHandlerInfo.type))
|
||||
if (isFeedType(aHandlerInfo.type)) {
|
||||
return this._prefsBundle.getFormattedString("addLiveBookmarksInApp",
|
||||
[this._brandShortName]);
|
||||
}
|
||||
|
||||
if (aHandlerInfo instanceof InternalHandlerInfoWrapper) {
|
||||
return this._prefsBundle.getFormattedString("previewInApp",
|
||||
[this._brandShortName]);
|
||||
}
|
||||
|
||||
// For other types, handleInternally looks like either useHelperApp
|
||||
// or useSystemDefault depending on whether or not there's a preferred
|
||||
@ -1319,6 +1384,18 @@ var gApplicationsPane = {
|
||||
while (menuPopup.hasChildNodes())
|
||||
menuPopup.removeChild(menuPopup.lastChild);
|
||||
|
||||
// Add the "Preview in Firefox" option for optional internal handlers.
|
||||
if (handlerInfo instanceof InternalHandlerInfoWrapper) {
|
||||
var internalMenuItem = document.createElement("menuitem");
|
||||
internalMenuItem.setAttribute("action", Ci.nsIHandlerInfo.handleInternally);
|
||||
let label = this._prefsBundle.getFormattedString("previewInApp",
|
||||
[this._brandShortName]);
|
||||
internalMenuItem.setAttribute("label", label);
|
||||
internalMenuItem.setAttribute("tooltiptext", label);
|
||||
internalMenuItem.setAttribute(APP_ICON_ATTR_NAME, "ask");
|
||||
menuPopup.appendChild(internalMenuItem);
|
||||
}
|
||||
|
||||
{
|
||||
var askMenuItem = document.createElement("menuitem");
|
||||
askMenuItem.setAttribute("alwaysAsk", "true");
|
||||
@ -1739,6 +1816,9 @@ var gApplicationsPane = {
|
||||
if (isFeedType(aHandlerInfo.type)) {
|
||||
aElement.setAttribute(APP_ICON_ATTR_NAME, "feed");
|
||||
return true;
|
||||
} else if (aHandlerInfo instanceof InternalHandlerInfoWrapper) {
|
||||
aElement.setAttribute(APP_ICON_ATTR_NAME, "ask");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
|
82
browser/components/preferences/in-content/applications.js
Normal file → Executable file
82
browser/components/preferences/in-content/applications.js
Normal file → Executable file
@ -5,9 +5,14 @@
|
||||
//****************************************************************************//
|
||||
// Constants & Enumeration Values
|
||||
|
||||
Components.utils.import('resource://gre/modules/Services.jsm');
|
||||
const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
|
||||
const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
|
||||
const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
|
||||
const TYPE_PDF = "application/pdf";
|
||||
|
||||
const PREF_PDFJS_DISABLED = "pdfjs.disabled";
|
||||
const TOPIC_PDFJS_HANDLER_CHANGED = "pdfjs:handlerChanged";
|
||||
|
||||
const PREF_DISABLED_PLUGIN_TYPES = "plugin.disable_full_page_plugin_for_types";
|
||||
|
||||
@ -797,6 +802,46 @@ var audioFeedHandlerInfo = {
|
||||
_appPrefLabel: "audioPodcastFeed"
|
||||
}
|
||||
|
||||
/**
|
||||
* InternalHandlerInfoWrapper provides a basic mechanism to create an internal
|
||||
* mime type handler that can be enabled/disabled in the applications preference
|
||||
* menu.
|
||||
*/
|
||||
function InternalHandlerInfoWrapper(aMIMEType) {
|
||||
var mimeSvc = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
|
||||
var handlerInfo = mimeSvc.getFromTypeAndExtension(aMIMEType, null);
|
||||
|
||||
HandlerInfoWrapper.call(this, aMIMEType, handlerInfo);
|
||||
}
|
||||
|
||||
InternalHandlerInfoWrapper.prototype = {
|
||||
__proto__: HandlerInfoWrapper.prototype,
|
||||
|
||||
// Override store so we so we can notify any code listening for registration
|
||||
// or unregistration of this handler.
|
||||
store: function() {
|
||||
HandlerInfoWrapper.prototype.store.call(this);
|
||||
Services.obs.notifyObservers(null, this._handlerChanged, null);
|
||||
},
|
||||
|
||||
get enabled() {
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
get description() {
|
||||
return this.element("bundlePreferences").getString(this._appPrefLabel);
|
||||
}
|
||||
};
|
||||
|
||||
var pdfHandlerInfo = {
|
||||
__proto__: new InternalHandlerInfoWrapper(TYPE_PDF),
|
||||
_handlerChanged: TOPIC_PDFJS_HANDLER_CHANGED,
|
||||
_appPrefLabel: "portableDocumentFormat",
|
||||
get enabled() {
|
||||
return !Services.prefs.getBoolPref(PREF_PDFJS_DISABLED);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
//****************************************************************************//
|
||||
// Prefpane Controller
|
||||
@ -986,6 +1031,7 @@ var gApplicationsPane = {
|
||||
|
||||
_loadData: function() {
|
||||
this._loadFeedHandler();
|
||||
this._loadInternalHandlers();
|
||||
this._loadPluginHandlers();
|
||||
this._loadApplicationHandlers();
|
||||
},
|
||||
@ -1001,6 +1047,19 @@ var gApplicationsPane = {
|
||||
audioFeedHandlerInfo.handledOnlyByPlugin = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Load higher level internal handlers so they can be turned on/off in the
|
||||
* applications menu.
|
||||
*/
|
||||
_loadInternalHandlers: function() {
|
||||
var internalHandlers = [pdfHandlerInfo];
|
||||
for (let internalHandler of internalHandlers) {
|
||||
if (internalHandler.enabled) {
|
||||
this._handledTypes[internalHandler.type] = internalHandler;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load the set of handlers defined by plugins.
|
||||
*
|
||||
@ -1203,9 +1262,15 @@ var gApplicationsPane = {
|
||||
|
||||
case Ci.nsIHandlerInfo.handleInternally:
|
||||
// For the feed type, handleInternally means live bookmarks.
|
||||
if (isFeedType(aHandlerInfo.type))
|
||||
if (isFeedType(aHandlerInfo.type)) {
|
||||
return this._prefsBundle.getFormattedString("addLiveBookmarksInApp",
|
||||
[this._brandShortName]);
|
||||
}
|
||||
|
||||
if (aHandlerInfo instanceof InternalHandlerInfoWrapper) {
|
||||
return this._prefsBundle.getFormattedString("previewInApp",
|
||||
[this._brandShortName]);
|
||||
}
|
||||
|
||||
// For other types, handleInternally looks like either useHelperApp
|
||||
// or useSystemDefault depending on whether or not there's a preferred
|
||||
@ -1306,6 +1371,18 @@ var gApplicationsPane = {
|
||||
while (menuPopup.hasChildNodes())
|
||||
menuPopup.removeChild(menuPopup.lastChild);
|
||||
|
||||
// Add the "Preview in Firefox" option for optional internal handlers.
|
||||
if (handlerInfo instanceof InternalHandlerInfoWrapper) {
|
||||
var internalMenuItem = document.createElement("menuitem");
|
||||
internalMenuItem.setAttribute("action", Ci.nsIHandlerInfo.handleInternally);
|
||||
let label = this._prefsBundle.getFormattedString("previewInApp",
|
||||
[this._brandShortName]);
|
||||
internalMenuItem.setAttribute("label", label);
|
||||
internalMenuItem.setAttribute("tooltiptext", label);
|
||||
internalMenuItem.setAttribute(APP_ICON_ATTR_NAME, "ask");
|
||||
menuPopup.appendChild(internalMenuItem);
|
||||
}
|
||||
|
||||
{
|
||||
var askMenuItem = document.createElement("menuitem");
|
||||
askMenuItem.setAttribute("alwaysAsk", "true");
|
||||
@ -1726,6 +1803,9 @@ var gApplicationsPane = {
|
||||
if (isFeedType(aHandlerInfo.type)) {
|
||||
aElement.setAttribute(APP_ICON_ATTR_NAME, "feed");
|
||||
return true;
|
||||
} else if (aHandlerInfo instanceof InternalHandlerInfoWrapper) {
|
||||
aElement.setAttribute(APP_ICON_ATTR_NAME, "ask");
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
This is the pdf.js project output, https://github.com/mozilla/pdf.js
|
||||
|
||||
Current extension version is: 0.3.266
|
||||
Current extension version is: 0.3.345
|
||||
|
||||
|
@ -1,8 +1,2 @@
|
||||
resource pdf.js content/
|
||||
component {6457a96b-2d68-439a-bcfa-44465fbcdbb1} components/PdfStreamConverter.js
|
||||
contract @mozilla.org/streamconv;1?from=application/pdf&to=*/* {6457a96b-2d68-439a-bcfa-44465fbcdbb1}
|
||||
|
||||
# Additional resources for pdf.js
|
||||
|
||||
# PDFJS_SUPPORTED_LOCALES
|
||||
|
||||
resource pdf.js.components components/
|
||||
|
@ -9,9 +9,11 @@ const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
// True only if this is the version of pdf.js that is included with firefox.
|
||||
const MOZ_CENTRAL = true;
|
||||
const PDFJS_EVENT_ID = 'pdf.js.message';
|
||||
const PDF_CONTENT_TYPE = 'application/pdf';
|
||||
const EXT_PREFIX = 'extensions.uriloader@pdf.js';
|
||||
const PREF_PREFIX = 'pdfjs';
|
||||
const MAX_DATABASE_LENGTH = 4096;
|
||||
const FIREFOX_ID = '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}';
|
||||
const SEAMONKEY_ID = '{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}';
|
||||
@ -20,9 +22,14 @@ Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://gre/modules/NetUtil.jsm');
|
||||
|
||||
|
||||
let appInfo = Cc['@mozilla.org/xre/app-info;1']
|
||||
.getService(Ci.nsIXULAppInfo);
|
||||
let privateBrowsing, inPrivateBrowsing;
|
||||
let Svc = {};
|
||||
XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
|
||||
'@mozilla.org/mime;1',
|
||||
'nsIMIMEService');
|
||||
|
||||
if (appInfo.ID === FIREFOX_ID) {
|
||||
privateBrowsing = Cc['@mozilla.org/privatebrowsing;1']
|
||||
@ -57,7 +64,7 @@ function getStringPref(pref, def) {
|
||||
}
|
||||
|
||||
function log(aMsg) {
|
||||
if (!getBoolPref(EXT_PREFIX + '.pdfBugEnabled', false))
|
||||
if (!getBoolPref(PREF_PREFIX + '.pdfBugEnabled', false))
|
||||
return;
|
||||
let msg = 'PdfStreamConverter.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
|
||||
Services.console.logStringMessage(msg);
|
||||
@ -70,6 +77,23 @@ function getDOMWindow(aChannel) {
|
||||
return win;
|
||||
}
|
||||
|
||||
function isEnabled() {
|
||||
if (MOZ_CENTRAL) {
|
||||
var disabled = getBoolPref(PREF_PREFIX + '.disabled', false);
|
||||
if (disabled)
|
||||
return false;
|
||||
// To also be considered enabled the "Preview in Firefox" option must be
|
||||
// selected in the Application preferences.
|
||||
var handlerInfo = Svc.mime
|
||||
.getFromTypeAndExtension('application/pdf', 'pdf');
|
||||
return handlerInfo.alwaysAskBeforeHandling == false &&
|
||||
handlerInfo.preferredAction == Ci.nsIHandlerInfo.handleInternally;
|
||||
}
|
||||
// Always returns true for the extension since enabling/disabling is handled
|
||||
// by the add-on manager.
|
||||
return true;
|
||||
}
|
||||
|
||||
function getLocalizedStrings(path) {
|
||||
var stringBundle = Cc['@mozilla.org/intl/stringbundle;1'].
|
||||
getService(Ci.nsIStringBundleService).
|
||||
@ -91,16 +115,22 @@ function getLocalizedStrings(path) {
|
||||
}
|
||||
return map;
|
||||
}
|
||||
function getLocalizedString(strings, id, property) {
|
||||
property = property || 'textContent';
|
||||
if (id in strings)
|
||||
return strings[id][property];
|
||||
return id;
|
||||
}
|
||||
|
||||
// All the priviledged actions.
|
||||
function ChromeActions() {
|
||||
function ChromeActions(domWindow) {
|
||||
this.domWindow = domWindow;
|
||||
}
|
||||
|
||||
ChromeActions.prototype = {
|
||||
download: function(data) {
|
||||
let mimeService = Cc['@mozilla.org/mime;1'].getService(Ci.nsIMIMEService);
|
||||
var handlerInfo = mimeService.
|
||||
getFromTypeAndExtension('application/pdf', 'pdf');
|
||||
var handlerInfo = Svc.mime
|
||||
.getFromTypeAndExtension('application/pdf', 'pdf');
|
||||
var uri = NetUtil.newURI(data);
|
||||
|
||||
var extHelperAppSvc =
|
||||
@ -136,12 +166,12 @@ ChromeActions.prototype = {
|
||||
// Protect against something sending tons of data to setDatabase.
|
||||
if (data.length > MAX_DATABASE_LENGTH)
|
||||
return;
|
||||
setStringPref(EXT_PREFIX + '.database', data);
|
||||
setStringPref(PREF_PREFIX + '.database', data);
|
||||
},
|
||||
getDatabase: function() {
|
||||
if (inPrivateBrowsing)
|
||||
return '{}';
|
||||
return getStringPref(EXT_PREFIX + '.database', '{}');
|
||||
return getStringPref(PREF_PREFIX + '.database', '{}');
|
||||
},
|
||||
getLocale: function() {
|
||||
return getStringPref('general.useragent.locale', 'en-US');
|
||||
@ -160,11 +190,34 @@ ChromeActions.prototype = {
|
||||
}
|
||||
},
|
||||
pdfBugEnabled: function() {
|
||||
return getBoolPref(EXT_PREFIX + '.pdfBugEnabled', false);
|
||||
return getBoolPref(PREF_PREFIX + '.pdfBugEnabled', false);
|
||||
},
|
||||
searchEnabled: function() {
|
||||
return getBoolPref(PREF_PREFIX + '.searchEnabled', false);
|
||||
},
|
||||
fallback: function(url) {
|
||||
var self = this;
|
||||
var domWindow = this.domWindow;
|
||||
var strings = getLocalizedStrings('chrome.properties');
|
||||
var message = getLocalizedString(strings, 'unsupported_feature');
|
||||
|
||||
var win = Services.wm.getMostRecentWindow('navigator:browser');
|
||||
var browser = win.gBrowser.getBrowserForDocument(domWindow.top.document);
|
||||
var notificationBox = win.gBrowser.getNotificationBox(browser);
|
||||
var buttons = [{
|
||||
label: getLocalizedString(strings, 'open_with_different_viewer'),
|
||||
accessKey: getLocalizedString(strings, 'open_with_different_viewer',
|
||||
'accessKey'),
|
||||
callback: function() {
|
||||
self.download(url);
|
||||
}
|
||||
}];
|
||||
notificationBox.appendNotification(message, 'pdfjs-fallback', null,
|
||||
notificationBox.PRIORITY_WARNING_LOW,
|
||||
buttons);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Event listener to trigger chrome privedged code.
|
||||
function RequestListener(actions) {
|
||||
this.actions = actions;
|
||||
@ -190,7 +243,7 @@ function PdfStreamConverter() {
|
||||
PdfStreamConverter.prototype = {
|
||||
|
||||
// properties required for XPCOM registration:
|
||||
classID: Components.ID('{6457a96b-2d68-439a-bcfa-44465fbcdbb1}'),
|
||||
classID: Components.ID('{d0c5195d-e798-49d4-b1d3-9324328b2291}'),
|
||||
classDescription: 'pdf.js Component',
|
||||
contractID: '@mozilla.org/streamconv;1?from=application/pdf&to=*/*',
|
||||
|
||||
@ -218,6 +271,8 @@ PdfStreamConverter.prototype = {
|
||||
|
||||
// nsIStreamConverter::asyncConvertData
|
||||
asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
|
||||
if (!isEnabled())
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
// Ignoring HTTP POST requests -- pdf.js has to repeat the request.
|
||||
var skipConversion = false;
|
||||
try {
|
||||
@ -267,7 +322,8 @@ PdfStreamConverter.prototype = {
|
||||
var domWindow = getDOMWindow(channel);
|
||||
// Double check the url is still the correct one.
|
||||
if (domWindow.document.documentURIObject.equals(aRequest.URI)) {
|
||||
let requestListener = new RequestListener(new ChromeActions);
|
||||
let requestListener = new RequestListener(
|
||||
new ChromeActions(domWindow));
|
||||
domWindow.addEventListener(PDFJS_EVENT_ID, function(event) {
|
||||
requestListener.receive(event);
|
||||
}, false, true);
|
||||
|
142
browser/extensions/pdfjs/content/PdfJs.jsm
Normal file
142
browser/extensions/pdfjs/content/PdfJs.jsm
Normal file
@ -0,0 +1,142 @@
|
||||
var EXPORTED_SYMBOLS = ["PdfJs"];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cm = Components.manager;
|
||||
const Cu = Components.utils;
|
||||
|
||||
const PREF_PREFIX = 'pdfjs';
|
||||
const PREF_DISABLED = PREF_PREFIX + '.disabled';
|
||||
const PREF_FIRST_RUN = PREF_PREFIX + '.firstRun';
|
||||
const PREF_PREVIOUS_ACTION = PREF_PREFIX + '.previousHandler.preferredAction';
|
||||
const PREF_PREVIOUS_ASK = PREF_PREFIX + '.previousHandler.alwaysAskBeforeHandling';
|
||||
const TOPIC_PDFJS_HANDLER_CHANGED = 'pdfjs:handlerChanged';
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://pdf.js.components/PdfStreamConverter.js');
|
||||
|
||||
let Svc = {};
|
||||
XPCOMUtils.defineLazyServiceGetter(Svc, 'mime',
|
||||
'@mozilla.org/mime;1',
|
||||
'nsIMIMEService');
|
||||
|
||||
function getBoolPref(aPref, aDefaultValue) {
|
||||
try {
|
||||
return Services.prefs.getBoolPref(aPref);
|
||||
} catch (ex) {
|
||||
return aDefaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
// Register/unregister a constructor as a component.
|
||||
let Factory = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory]),
|
||||
_targetConstructor: null,
|
||||
|
||||
register: function register(targetConstructor) {
|
||||
this._targetConstructor = targetConstructor;
|
||||
var proto = targetConstructor.prototype;
|
||||
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
registrar.registerFactory(proto.classID, proto.classDescription,
|
||||
proto.contractID, this);
|
||||
},
|
||||
|
||||
unregister: function unregister() {
|
||||
var proto = this._targetConstructor.prototype;
|
||||
var registrar = Cm.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
registrar.unregisterFactory(proto.classID, this);
|
||||
this._targetConstructor = null;
|
||||
},
|
||||
|
||||
// nsIFactory
|
||||
createInstance: function createInstance(aOuter, iid) {
|
||||
if (aOuter !== null)
|
||||
throw Cr.NS_ERROR_NO_AGGREGATION;
|
||||
return (new (this._targetConstructor)).QueryInterface(iid);
|
||||
},
|
||||
|
||||
// nsIFactory
|
||||
lockFactory: function lockFactory(lock) {
|
||||
// No longer used as of gecko 1.7.
|
||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
};
|
||||
|
||||
let PdfJs = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
|
||||
_registered: false,
|
||||
|
||||
init: function init() {
|
||||
// On first run make pdf.js the default handler.
|
||||
if (!getBoolPref(PREF_DISABLED, true) && getBoolPref(PREF_FIRST_RUN, false)) {
|
||||
Services.prefs.setBoolPref(PREF_FIRST_RUN, false);
|
||||
|
||||
let handlerInfo = Svc.mime.getFromTypeAndExtension('application/pdf', 'pdf');
|
||||
// Store the previous settings of preferredAction and
|
||||
// alwaysAskBeforeHandling in case we need to revert them in a hotfix that
|
||||
// would turn pdf.js off.
|
||||
Services.prefs.setIntPref(PREF_PREVIOUS_ACTION, handlerInfo.preferredAction);
|
||||
Services.prefs.setBoolPref(PREF_PREVIOUS_ASK, handlerInfo.alwaysAskBeforeHandling);
|
||||
|
||||
let handlerService = Cc['@mozilla.org/uriloader/handler-service;1'].
|
||||
getService(Ci.nsIHandlerService);
|
||||
|
||||
// Change and save mime handler settings.
|
||||
handlerInfo.alwaysAskBeforeHandling = false;
|
||||
handlerInfo.preferredAction = Ci.nsIHandlerInfo.handleInternally;
|
||||
handlerService.store(handlerInfo);
|
||||
}
|
||||
|
||||
if (this.enabled)
|
||||
this._ensureRegistered();
|
||||
else
|
||||
this._ensureUnregistered();
|
||||
|
||||
// Listen for when pdf.js is completely disabled or a different pdf handler
|
||||
// is chosen.
|
||||
Services.prefs.addObserver(PREF_DISABLED, this, false);
|
||||
Services.obs.addObserver(this, TOPIC_PDFJS_HANDLER_CHANGED, false);
|
||||
},
|
||||
|
||||
// nsIObserver
|
||||
observe: function observe(aSubject, aTopic, aData) {
|
||||
if (this.enabled)
|
||||
this._ensureRegistered();
|
||||
else
|
||||
this._ensureUnregistered();
|
||||
},
|
||||
|
||||
/**
|
||||
* pdf.js is only enabled if it is both selected as the pdf viewer and if the
|
||||
* global switch enabling it is true.
|
||||
* @return {boolean} Wether or not it's enabled.
|
||||
*/
|
||||
get enabled() {
|
||||
var disabled = getBoolPref(PREF_DISABLED, true);
|
||||
if (disabled)
|
||||
return false;
|
||||
|
||||
var handlerInfo = Svc.mime.
|
||||
getFromTypeAndExtension('application/pdf', 'pdf');
|
||||
return handlerInfo.alwaysAskBeforeHandling == false &&
|
||||
handlerInfo.preferredAction == Ci.nsIHandlerInfo.handleInternally;
|
||||
},
|
||||
|
||||
_ensureRegistered: function _ensureRegistered() {
|
||||
if (this._registered)
|
||||
return;
|
||||
|
||||
Factory.register(PdfStreamConverter);
|
||||
this._registered = true;
|
||||
},
|
||||
|
||||
_ensureUnregistered: function _ensureUnregistered() {
|
||||
if (!this._registered)
|
||||
return;
|
||||
|
||||
Factory.unregister();
|
||||
this._registered = false;
|
||||
}
|
||||
};
|
@ -238,6 +238,10 @@ html[dir='rtl'] .splitToolbarButton > .toolbarButton {
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
.toolbarButton.group {
|
||||
margin-right:0;
|
||||
}
|
||||
|
||||
.splitToolbarButton:hover > .toolbarButton,
|
||||
.splitToolbarButton:focus > .toolbarButton,
|
||||
.splitToolbarButton.toggled > .toolbarButton {
|
||||
@ -533,6 +537,12 @@ html[dir='rtl'] .toolbarButton.pageDown::before {
|
||||
content: url(images/toolbarButton-viewOutline.png);
|
||||
}
|
||||
|
||||
#viewSearch.toolbarButton::before {
|
||||
display: inline-block;
|
||||
content: url(images/toolbarButton-search.png);
|
||||
}
|
||||
|
||||
|
||||
.toolbarField {
|
||||
min-width: 16px;
|
||||
width: 32px;
|
||||
@ -697,6 +707,53 @@ a:focus > .thumbnail > .thumbnailSelectionRing,
|
||||
color: hsla(0,0%,100%,.9);
|
||||
}
|
||||
|
||||
#searchScrollView {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
#searchToolbar {
|
||||
padding-left: 0px;
|
||||
right: 0px;
|
||||
padding-top: 0px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
#searchToolbar > input {
|
||||
margin-left: 8px;
|
||||
width: 130px;
|
||||
}
|
||||
|
||||
#searchResults {
|
||||
overflow: auto;
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
right: 0;
|
||||
font-size: smaller;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
#searchResults a {
|
||||
display: block;
|
||||
white-space: pre;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
|
||||
#sidebarControls {
|
||||
position:absolute;
|
||||
width: 180px;
|
||||
height: 32px;
|
||||
left: 15px;
|
||||
bottom: 35px;
|
||||
}
|
||||
|
||||
.outlineItem.selected {
|
||||
background-color: hsla(0,0%,100%,.08);
|
||||
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
|
||||
@ -937,6 +994,30 @@ canvas {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
@media print {
|
||||
#sidebarContainer, .toolbar, #loadingBox, #errorWrapper, .textLayer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mainContainer, #viewerContainer, .page, .page canvas {
|
||||
position: static;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.page {
|
||||
float: left;
|
||||
display: none;
|
||||
box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
}
|
||||
|
||||
.page[data-loaded] {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 950px) {
|
||||
html[dir='ltr'] #outerContainer.sidebarMoving .outerCenter,
|
||||
html[dir='ltr'] #outerContainer.sidebarOpen .outerCenter {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -219,8 +219,11 @@ var PDFView = {
|
||||
currentScale: kUnknownScale,
|
||||
currentScaleValue: null,
|
||||
initialBookmark: document.location.hash.substring(1),
|
||||
startedTextExtraction: false,
|
||||
pageText: [],
|
||||
container: null,
|
||||
initialized: false,
|
||||
fellback: false,
|
||||
// called once when the document is loaded
|
||||
initialize: function pdfViewInitialize() {
|
||||
this.container = document.getElementById('viewerContainer');
|
||||
@ -390,6 +393,18 @@ var PDFView = {
|
||||
}
|
||||
},
|
||||
|
||||
fallback: function pdfViewFallback() {
|
||||
if (!PDFJS.isFirefoxExtension)
|
||||
return;
|
||||
// Only trigger the fallback once so we don't spam the user with messages
|
||||
// for one PDF.
|
||||
if (this.fellback)
|
||||
return;
|
||||
this.fellback = true;
|
||||
var url = this.url.split('#')[0];
|
||||
FirefoxCom.request('fallback', url);
|
||||
},
|
||||
|
||||
navigateTo: function pdfViewNavigateTo(dest) {
|
||||
if (typeof dest === 'string')
|
||||
dest = this.destinations[dest];
|
||||
@ -452,6 +467,34 @@ var PDFView = {
|
||||
* and optionally a 'stack' property.
|
||||
*/
|
||||
error: function pdfViewError(message, moreInfo) {
|
||||
var moreInfoText = mozL10n.get('error_build', {build: PDFJS.build},
|
||||
'PDF.JS Build: {{build}}') + '\n';
|
||||
if (moreInfo) {
|
||||
moreInfoText +=
|
||||
mozL10n.get('error_message', {message: moreInfo.message},
|
||||
'Message: {{message}}');
|
||||
if (moreInfo.stack) {
|
||||
moreInfoText += '\n' +
|
||||
mozL10n.get('error_stack', {stack: moreInfo.stack},
|
||||
'Stack: {{stack}}');
|
||||
} else {
|
||||
if (moreInfo.filename) {
|
||||
moreInfoText += '\n' +
|
||||
mozL10n.get('error_file', {file: moreInfo.filename},
|
||||
'File: {{file}}');
|
||||
}
|
||||
if (moreInfo.lineNumber) {
|
||||
moreInfoText += '\n' +
|
||||
mozL10n.get('error_line', {line: moreInfo.lineNumber},
|
||||
'Line: {{line}}');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (PDFJS.isFirefoxExtension) {
|
||||
console.error(message + '\n' + moreInfoText);
|
||||
this.fallback();
|
||||
return;
|
||||
}
|
||||
var errorWrapper = document.getElementById('errorWrapper');
|
||||
errorWrapper.removeAttribute('hidden');
|
||||
|
||||
@ -478,32 +521,9 @@ var PDFView = {
|
||||
};
|
||||
moreInfoButton.removeAttribute('hidden');
|
||||
lessInfoButton.setAttribute('hidden', 'true');
|
||||
errorMoreInfo.value =
|
||||
mozL10n.get('error_build', {build: PDFJS.build},
|
||||
'PDF.JS Build: {{build}}') + '\n';
|
||||
errorMoreInfo.value = moreInfoText;
|
||||
|
||||
if (moreInfo) {
|
||||
errorMoreInfo.value +=
|
||||
mozL10n.get('error_message', {message: moreInfo.message},
|
||||
'Message: {{message}}');
|
||||
if (moreInfo.stack) {
|
||||
errorMoreInfo.value += '\n' +
|
||||
mozL10n.get('error_stack', {stack: moreInfo.stack},
|
||||
'Stack: {{stack}}');
|
||||
} else {
|
||||
if (moreInfo.filename) {
|
||||
errorMoreInfo.value += '\n' +
|
||||
mozL10n.get('error_file', {file: moreInfo.filename},
|
||||
'File: {{file}}');
|
||||
}
|
||||
if (moreInfo.lineNumber) {
|
||||
errorMoreInfo.value += '\n' +
|
||||
mozL10n.get('error_line', {line: moreInfo.lineNumber},
|
||||
'Line: {{line}}');
|
||||
}
|
||||
}
|
||||
}
|
||||
errorMoreInfo.rows = errorMoreInfo.value.split('\n').length - 1;
|
||||
errorMoreInfo.rows = moreInfoText.split('\n').length - 1;
|
||||
},
|
||||
|
||||
progress: function pdfViewProgress(level) {
|
||||
@ -561,6 +581,8 @@ var PDFView = {
|
||||
}
|
||||
|
||||
var pages = this.pages = [];
|
||||
this.pageText = [];
|
||||
this.startedTextExtraction = false;
|
||||
var pagesRefMap = {};
|
||||
var thumbnails = this.thumbnails = [];
|
||||
var pagePromises = [];
|
||||
@ -641,6 +663,67 @@ var PDFView = {
|
||||
}
|
||||
},
|
||||
|
||||
search: function pdfViewStartSearch() {
|
||||
// Limit this function to run every <SEARCH_TIMEOUT>ms.
|
||||
var SEARCH_TIMEOUT = 250;
|
||||
var lastSeach = this.lastSearch;
|
||||
var now = Date.now();
|
||||
if (lastSeach && (now - lastSeach) < SEARCH_TIMEOUT) {
|
||||
if (!this.searchTimer) {
|
||||
this.searchTimer = setTimeout(function resumeSearch() {
|
||||
PDFView.search();
|
||||
},
|
||||
SEARCH_TIMEOUT - (now - lastSeach)
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.searchTimer = null;
|
||||
this.lastSearch = now;
|
||||
|
||||
function bindLink(link, pageNumber) {
|
||||
link.href = '#' + pageNumber;
|
||||
link.onclick = function searchBindLink() {
|
||||
PDFView.page = pageNumber;
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
var searchResults = document.getElementById('searchResults');
|
||||
|
||||
var searchTermsInput = document.getElementById('searchTermsInput');
|
||||
searchResults.removeAttribute('hidden');
|
||||
searchResults.textContent = '';
|
||||
|
||||
var terms = searchTermsInput.value;
|
||||
|
||||
if (!terms)
|
||||
return;
|
||||
|
||||
// simple search: removing spaces and hyphens, then scanning every
|
||||
terms = terms.replace(/\s-/g, '').toLowerCase();
|
||||
var index = PDFView.pageText;
|
||||
var pageFound = false;
|
||||
for (var i = 0, ii = index.length; i < ii; i++) {
|
||||
var pageText = index[i].replace(/\s-/g, '').toLowerCase();
|
||||
var j = pageText.indexOf(terms);
|
||||
if (j < 0)
|
||||
continue;
|
||||
|
||||
var pageNumber = i + 1;
|
||||
var textSample = index[i].substr(j, 50);
|
||||
var link = document.createElement('a');
|
||||
bindLink(link, pageNumber);
|
||||
link.textContent = 'Page ' + pageNumber + ': ' + textSample;
|
||||
searchResults.appendChild(link);
|
||||
|
||||
pageFound = true;
|
||||
}
|
||||
if (!pageFound) {
|
||||
searchResults.textContent = '(Not found)';
|
||||
}
|
||||
},
|
||||
|
||||
setHash: function pdfViewSetHash(hash) {
|
||||
if (!hash)
|
||||
return;
|
||||
@ -683,26 +766,70 @@ var PDFView = {
|
||||
switchSidebarView: function pdfViewSwitchSidebarView(view) {
|
||||
var thumbsView = document.getElementById('thumbnailView');
|
||||
var outlineView = document.getElementById('outlineView');
|
||||
var thumbsSwitchButton = document.getElementById('viewThumbnail');
|
||||
var outlineSwitchButton = document.getElementById('viewOutline');
|
||||
var searchView = document.getElementById('searchView');
|
||||
|
||||
if (outlineSwitchButton.getAttribute('disabled'))
|
||||
return;
|
||||
|
||||
thumbsView.classList.toggle('hidden');
|
||||
outlineView.classList.toggle('hidden');
|
||||
document.getElementById('viewThumbnail').classList.toggle('toggled');
|
||||
document.getElementById('viewOutline').classList.toggle('toggled');
|
||||
var thumbsButton = document.getElementById('viewThumbnail');
|
||||
var outlineButton = document.getElementById('viewOutline');
|
||||
var searchButton = document.getElementById('viewSearch');
|
||||
|
||||
switch (view) {
|
||||
case 'thumbs':
|
||||
thumbsButton.classList.add('toggled');
|
||||
outlineButton.classList.remove('toggled');
|
||||
searchButton.classList.remove('toggled');
|
||||
thumbsView.classList.remove('hidden');
|
||||
outlineView.classList.add('hidden');
|
||||
searchView.classList.add('hidden');
|
||||
|
||||
updateThumbViewArea();
|
||||
break;
|
||||
|
||||
case 'outline':
|
||||
thumbsButton.classList.remove('toggled');
|
||||
outlineButton.classList.add('toggled');
|
||||
searchButton.classList.remove('toggled');
|
||||
thumbsView.classList.add('hidden');
|
||||
outlineView.classList.remove('hidden');
|
||||
searchView.classList.add('hidden');
|
||||
|
||||
if (outlineButton.getAttribute('disabled'))
|
||||
return;
|
||||
break;
|
||||
|
||||
case 'search':
|
||||
thumbsButton.classList.remove('toggled');
|
||||
outlineButton.classList.remove('toggled');
|
||||
searchButton.classList.add('toggled');
|
||||
thumbsView.classList.add('hidden');
|
||||
outlineView.classList.add('hidden');
|
||||
searchView.classList.remove('hidden');
|
||||
|
||||
var searchTermsInput = document.getElementById('searchTermsInput');
|
||||
searchTermsInput.focus();
|
||||
// Start text extraction as soon as the search gets displayed.
|
||||
this.extractText();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
extractText: function() {
|
||||
if (this.startedTextExtraction)
|
||||
return;
|
||||
this.startedTextExtraction = true;
|
||||
var self = this;
|
||||
function extractPageText(pageIndex) {
|
||||
self.pages[pageIndex].pdfPage.getTextContent().then(
|
||||
function textContentResolved(textContent) {
|
||||
self.pageText[pageIndex] = textContent;
|
||||
self.search();
|
||||
if ((pageIndex + 1) < self.pages.length)
|
||||
extractPageText(pageIndex + 1);
|
||||
}
|
||||
);
|
||||
};
|
||||
extractPageText(0);
|
||||
},
|
||||
|
||||
getVisiblePages: function pdfViewGetVisiblePages() {
|
||||
var pages = this.pages;
|
||||
var kBottomMargin = 10;
|
||||
@ -916,6 +1043,10 @@ var PageView = function pageView(container, pdfPage, id, scale,
|
||||
if (comment)
|
||||
div.appendChild(comment);
|
||||
break;
|
||||
case 'Widget':
|
||||
// TODO: support forms
|
||||
PDFView.fallback();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1397,6 +1528,19 @@ window.addEventListener('load', function webViewerLoad(evt) {
|
||||
PDFBug.init();
|
||||
}
|
||||
|
||||
if (!PDFJS.isFirefoxExtension ||
|
||||
(PDFJS.isFirefoxExtension && FirefoxCom.request('searchEnabled'))) {
|
||||
document.querySelector('#viewSearch').classList.remove('hidden');
|
||||
}
|
||||
|
||||
// Listen for warnings to trigger the fallback UI. Errors should be caught
|
||||
// and call PDFView.error() so we don't need to listen for those.
|
||||
PDFJS.LogManager.addLogger({
|
||||
warn: function() {
|
||||
PDFView.fallback();
|
||||
}
|
||||
});
|
||||
|
||||
var thumbsView = document.getElementById('thumbnailView');
|
||||
thumbsView.addEventListener('scroll', updateThumbViewArea, true);
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
bootstrap.js
|
||||
icon.png
|
||||
icon64.png
|
||||
chrome.manifest
|
||||
components/PdfStreamConverter.js
|
||||
content/PdfJs.jsm
|
||||
content/web/debugger.js
|
||||
content/web/images/annotation-check.svg
|
||||
content/web/images/annotation-comment.svg
|
||||
@ -18,6 +16,7 @@ content/web/images/toolbarButton-pageDown.png
|
||||
content/web/images/toolbarButton-pageUp-rtl.png
|
||||
content/web/images/toolbarButton-pageUp.png
|
||||
content/web/images/toolbarButton-print.png
|
||||
content/web/images/toolbarButton-search.png
|
||||
content/web/images/toolbarButton-sidebarToggle.png
|
||||
content/web/images/toolbarButton-viewOutline.png
|
||||
content/web/images/toolbarButton-viewThumbnail.png
|
||||
|
@ -13,6 +13,7 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_BROWSER_TEST_FILES = \
|
||||
browser_pdfjs_main.js \
|
||||
browser_pdfjs_savedialog.js \
|
||||
file_pdfjs_test.pdf \
|
||||
$(NULL)
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const RELATIVE_DIR = "browser/extensions/pdfjs/test/";
|
||||
const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
|
||||
@ -8,6 +7,16 @@ const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
|
||||
function test() {
|
||||
var tab;
|
||||
|
||||
let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
|
||||
let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
|
||||
let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
|
||||
|
||||
// Make sure pdf.js is the default handler.
|
||||
is(handlerInfo.alwaysAskBeforeHandling, false, 'pdf handler defaults to always-ask is false');
|
||||
is(handlerInfo.preferredAction, Ci.nsIHandlerInfo.handleInternally, 'pdf handler defaults to internal');
|
||||
|
||||
info('Pref action: ' + handlerInfo.preferredAction);
|
||||
|
||||
waitForExplicitFinish();
|
||||
registerCleanupFunction(function() {
|
||||
gBrowser.removeTab(tab);
|
||||
@ -23,13 +32,14 @@ function test() {
|
||||
|
||||
// Runs tests after all 'load' event handlers have fired off
|
||||
setTimeout(function() {
|
||||
runTests(document, window);
|
||||
runTests(document, window, finish);
|
||||
}, 0);
|
||||
}, true);
|
||||
}
|
||||
|
||||
|
||||
function runTests(document, window) {
|
||||
function runTests(document, window, callback) {
|
||||
|
||||
//
|
||||
// Overall sanity tests
|
||||
//
|
||||
@ -67,5 +77,5 @@ function runTests(document, window) {
|
||||
viewBookmark.click();
|
||||
ok(viewBookmark.href.length > 0, 'viewBookmark button has href');
|
||||
|
||||
finish();
|
||||
callback();
|
||||
}
|
||||
|
65
browser/extensions/pdfjs/test/browser_pdfjs_savedialog.js
Normal file
65
browser/extensions/pdfjs/test/browser_pdfjs_savedialog.js
Normal file
@ -0,0 +1,65 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const RELATIVE_DIR = "browser/extensions/pdfjs/test/";
|
||||
const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
|
||||
|
||||
function test() {
|
||||
var oldAction = changeMimeHandler(Ci.nsIHandlerInfo.useSystemDefault, true);
|
||||
var tab = gBrowser.addTab(TESTROOT + "file_pdfjs_test.pdf");
|
||||
//
|
||||
// Test: "Open with" dialog comes up when pdf.js is not selected as the default
|
||||
// handler.
|
||||
//
|
||||
addWindowListener('chrome://mozapps/content/downloads/unknownContentType.xul', finish);
|
||||
|
||||
waitForExplicitFinish();
|
||||
registerCleanupFunction(function() {
|
||||
changeMimeHandler(oldAction[0], oldAction[1]);
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
}
|
||||
|
||||
function changeMimeHandler(preferredAction, alwaysAskBeforeHandling) {
|
||||
let handlerService = Cc["@mozilla.org/uriloader/handler-service;1"].getService(Ci.nsIHandlerService);
|
||||
let mimeService = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService);
|
||||
let handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
|
||||
var oldAction = [handlerInfo.preferredAction, handlerInfo.alwaysAskBeforeHandling];
|
||||
|
||||
// Change and save mime handler settings
|
||||
handlerInfo.alwaysAskBeforeHandling = alwaysAskBeforeHandling;
|
||||
handlerInfo.preferredAction = preferredAction;
|
||||
handlerService.store(handlerInfo);
|
||||
|
||||
Services.obs.notifyObservers(null, 'pdfjs:handlerChanged', null);
|
||||
|
||||
// Refresh data
|
||||
handlerInfo = mimeService.getFromTypeAndExtension('application/pdf', 'pdf');
|
||||
|
||||
//
|
||||
// Test: Mime handler was updated
|
||||
//
|
||||
is(handlerInfo.alwaysAskBeforeHandling, alwaysAskBeforeHandling, 'always-ask prompt change successful');
|
||||
is(handlerInfo.preferredAction, preferredAction, 'mime handler change successful');
|
||||
|
||||
return oldAction;
|
||||
}
|
||||
|
||||
function addWindowListener(aURL, aCallback) {
|
||||
Services.wm.addListener({
|
||||
onOpenWindow: function(aXULWindow) {
|
||||
info("window opened, waiting for focus");
|
||||
Services.wm.removeListener(this);
|
||||
|
||||
var domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindow);
|
||||
waitForFocus(function() {
|
||||
is(domwindow.document.location.href, aURL, "should have seen the right window open");
|
||||
domwindow.close();
|
||||
aCallback();
|
||||
}, domwindow);
|
||||
},
|
||||
onCloseWindow: function(aXULWindow) { },
|
||||
onWindowTitleChange: function(aXULWindow, aNewTitle) { }
|
||||
});
|
||||
}
|
@ -63,6 +63,7 @@ webFeed=Web Feed
|
||||
videoPodcastFeed=Video Podcast
|
||||
audioPodcastFeed=Podcast
|
||||
alwaysAsk=Always ask
|
||||
portableDocumentFormat=Portable Document Format (PDF)
|
||||
|
||||
# LOCALIZATION NOTE (usePluginIn):
|
||||
# %1$S = plugin name (for example "QuickTime Plugin-in 7.2")
|
||||
|
3
browser/locales/en-US/pdfviewer/chrome.properties
Normal file
3
browser/locales/en-US/pdfviewer/chrome.properties
Normal file
@ -0,0 +1,3 @@
|
||||
# Chrome notification bar messages and buttons
|
||||
unsupported_feature=This PDF document might not be displayed correctly.
|
||||
open_with_different_viewer=Open With Different Viewer
|
@ -1,46 +1,91 @@
|
||||
bookmark.title=Current view (copy or open in new window)
|
||||
# Main toolbar buttons (tooltips and alt text for images)
|
||||
previous.title=Previous Page
|
||||
previous_label=Previous
|
||||
next.title=Next Page
|
||||
print.title=Print
|
||||
download.title=Download
|
||||
next_label=Next
|
||||
|
||||
# LOCALIZATION NOTE (page_label, page_of):
|
||||
# These strings are concatenated to form the "Page: X of Y" string.
|
||||
# Do not translate "{{pageCount}}", it will be substituted with a number
|
||||
# representing the total number of pages.
|
||||
page_label=Page:
|
||||
page_of=of {{pageCount}}
|
||||
|
||||
zoom_out.title=Zoom Out
|
||||
zoom_out_label=Zoom Out
|
||||
zoom_in.title=Zoom In
|
||||
zoom_in_label=Zoom In
|
||||
zoom.title=Zoom
|
||||
print.title=Print
|
||||
print_label=Print
|
||||
open_file.title=Open File
|
||||
open_file_label=Open
|
||||
download.title=Download
|
||||
download_label=Download
|
||||
bookmark.title=Current view (copy or open in new window)
|
||||
bookmark_label=Current View
|
||||
|
||||
# Tooltips and alt text for side panel toolbar buttons
|
||||
# (the _label strings are alt text for the buttons, the .title strings are
|
||||
# tooltips)
|
||||
toggle_slider.title=Toggle Slider
|
||||
toggle_slider_label=Toggle Slider
|
||||
outline.title=Show Document Outline
|
||||
outline_label=Document Outline
|
||||
thumbs.title=Show Thumbnails
|
||||
thumbs_label=Thumbnails
|
||||
search_panel.title=Search Document
|
||||
search_panel_label=Search
|
||||
|
||||
# Document outline messages
|
||||
no_outline=No Outline Available
|
||||
|
||||
# Thumbnails panel item (tooltip and alt text for images)
|
||||
# LOCALIZATION NOTE (thumb_page_title): "{{page}}" will be replaced by the page
|
||||
# number.
|
||||
thumb_page_title=Page {{page}}
|
||||
# LOCALIZATION NOTE (thumb_page_canvas): "{{page}}" will be replaced by the page
|
||||
# number.
|
||||
thumb_page_canvas=Thumbnail of Page {{page}}
|
||||
|
||||
# Search panel button title and messages
|
||||
search=Find
|
||||
search_terms_not_found=(Not found)
|
||||
|
||||
# Error panel labels
|
||||
error_more_info=More Information
|
||||
error_less_info=Less Information
|
||||
error_close=Close
|
||||
# LOCALIZATION NOTE (error_build): "{{build}}" will be replaced by the PDF.JS
|
||||
# build ID.
|
||||
error_build=PDF.JS Build: {{build}}
|
||||
# LOCALIZATION NOTE (error_message): "{{message}}" will be replaced by an
|
||||
# english string describing the error.
|
||||
error_message=Message: {{message}}
|
||||
# LOCALIZATION NOTE (error_stack): "{{stack}}" will be replaced with a stack
|
||||
# trace.
|
||||
error_stack=Stack: {{stack}}
|
||||
# LOCALIZATION NOTE (error_file): "{{file}}" will be replaced with a filename
|
||||
error_file=File: {{file}}
|
||||
# LOCALIZATION NOTE (error_line): "{{line}}" will be replaced with a line number
|
||||
error_line=Line: {{line}}
|
||||
rendering_error=An error occurred while rendering the page.
|
||||
|
||||
# Predefined zoom values
|
||||
page_scale_width=Page Width
|
||||
page_scale_fit=Page Fit
|
||||
page_scale_auto=Automatic Zoom
|
||||
page_scale_actual=Actual Size
|
||||
toggle_slider.title=Toggle Slider
|
||||
thumbs.title=Show Thumbnails
|
||||
outline.title=Show Document Outline
|
||||
loading=Loading... {{percent}}%
|
||||
|
||||
# Loading indicator messages
|
||||
# LOCALIZATION NOTE (error_line): "{{[percent}}" will be replaced with a percentage
|
||||
loading=Loading… {{percent}}%
|
||||
loading_error_indicator=Error
|
||||
loading_error=An error occurred while loading the PDF.
|
||||
rendering_error=An error occurred while rendering the page.
|
||||
page_label=Page:
|
||||
page_of=of {{pageCount}}
|
||||
no_outline=No Outline Available
|
||||
open_file.title=Open File
|
||||
|
||||
# LOCALIZATION NOTE (text_annotation_type): This is used as a tooltip.
|
||||
# "{{[type}}" will be replaced with an annotation type from a list defined in
|
||||
# the PDF spec (32000-1:2008 Table 169 – Annotation types).
|
||||
# Some common types are e.g.: "Check", "Text", "Comment", "Note"
|
||||
text_annotation_type=[{{type}} Annotation]
|
||||
toggle_slider_label=Toggle Slider
|
||||
thumbs_label=Thumbnails
|
||||
outline_label=Document Outline
|
||||
bookmark_label=Current View
|
||||
previous_label=Previous
|
||||
next_label=Next
|
||||
print_label=Print
|
||||
download_label=Download
|
||||
zoom_out_label=Zoom Out
|
||||
zoom_in_label=Zoom In
|
||||
zoom.title=Zoom
|
||||
thumb_page_title=Page {{page}}
|
||||
thumb_page_canvas=Thumbnail of Page {{page}}
|
||||
request_password=PDF is protected by a password:
|
||||
open_file_label=Open
|
||||
|
@ -116,6 +116,9 @@
|
||||
% locale testpilot @AB_CD@ %locale/feedback/
|
||||
locale/feedback/main.dtd (%feedback/main.dtd)
|
||||
locale/feedback/main.properties (%feedback/main.properties)
|
||||
% locale pdf.js @AB_CD@ %locale/pdfviewer/
|
||||
locale/pdfviewer/viewer.properties (%pdfviewer/viewer.properties)
|
||||
locale/pdfviewer/chrome.properties (%pdfviewer/chrome.properties)
|
||||
#ifdef MOZ_WEBAPP_RUNTIME
|
||||
% locale webapprt @AB_CD@ %locale/webapprt/
|
||||
locale/webapprt/webapp.dtd (%webapprt/webapp.dtd)
|
||||
|
13
configure.in
13
configure.in
@ -4593,7 +4593,15 @@ MOZ_USE_NATIVE_POPUP_WINDOWS=
|
||||
MOZ_ANDROID_HISTORY=
|
||||
MOZ_WEBSMS_BACKEND=
|
||||
MOZ_GRAPHITE=1
|
||||
ACCESSIBILITY=1
|
||||
|
||||
case "${target}" in
|
||||
*darwin*)
|
||||
ACCESSIBILITY=
|
||||
;;
|
||||
*)
|
||||
ACCESSIBILITY=1
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$target_os" in
|
||||
mingw*)
|
||||
@ -5526,9 +5534,10 @@ AC_DEFINE(IBMBIDI)
|
||||
|
||||
dnl ========================================================
|
||||
dnl accessibility support on by default on all platforms
|
||||
dnl except OS X.
|
||||
dnl ========================================================
|
||||
MOZ_ARG_DISABLE_BOOL(accessibility,
|
||||
[ --disable-accessibility Disable accessibility support],
|
||||
[ --disable-accessibility Disable accessibility support (off by default on OS X)],
|
||||
ACCESSIBILITY=,
|
||||
ACCESSIBILITY=1 )
|
||||
if test "$ACCESSIBILITY"; then
|
||||
|
@ -48,3 +48,4 @@ DEPRECATED_OPERATION(DOMExceptionCode)
|
||||
DEPRECATED_OPERATION(NoExposedProps)
|
||||
DEPRECATED_OPERATION(MutationEvent)
|
||||
DEPRECATED_OPERATION(MozSlice)
|
||||
DEPRECATED_OPERATION(Onuploadprogress)
|
||||
|
@ -626,6 +626,11 @@ CSPSourceList.prototype = {
|
||||
*/
|
||||
equals:
|
||||
function(that) {
|
||||
// special case to default-src * and 'none' to look different
|
||||
// (both have a ._sources.length of 0).
|
||||
if (that._permitAllSources != this._permitAllSources) {
|
||||
return false;
|
||||
}
|
||||
if (that._sources.length != this._sources.length) {
|
||||
return false;
|
||||
}
|
||||
|
@ -28,6 +28,11 @@ public:
|
||||
return mNames.AppendElement(aName) != nsnull;
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
mNames.Clear();
|
||||
}
|
||||
|
||||
private:
|
||||
nsTArray<nsString> mNames;
|
||||
};
|
||||
|
@ -16,6 +16,8 @@
|
||||
class nsGenericElement;
|
||||
class nsIAtom;
|
||||
|
||||
// nsISupports must be on the primary inheritance chain
|
||||
// because nsDOMSettableTokenList is traversed by nsGenericElement.
|
||||
class nsDOMSettableTokenList : public nsDOMTokenList,
|
||||
public nsIDOMDOMSettableTokenList
|
||||
{
|
||||
@ -30,7 +32,6 @@ public:
|
||||
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap);
|
||||
|
||||
protected:
|
||||
virtual ~nsDOMSettableTokenList();
|
||||
};
|
||||
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
class nsAttrValue;
|
||||
|
||||
// nsISupports must be on the primary inheritance chain
|
||||
// because nsDOMSettableTokenList is traversed by nsGenericElement.
|
||||
class nsDOMTokenList : public nsIDOMDOMTokenList,
|
||||
public nsWrapperCache
|
||||
{
|
||||
@ -34,9 +36,6 @@ public:
|
||||
return mElement;
|
||||
}
|
||||
|
||||
protected:
|
||||
~nsDOMTokenList();
|
||||
|
||||
const nsAttrValue* GetParsedAttr() {
|
||||
if (!mElement) {
|
||||
return nsnull;
|
||||
@ -44,6 +43,9 @@ protected:
|
||||
return mElement->GetAttrInfo(kNameSpaceID_None, mAttrAtom).mValue;
|
||||
}
|
||||
|
||||
protected:
|
||||
~nsDOMTokenList();
|
||||
|
||||
nsresult CheckToken(const nsAString& aStr);
|
||||
void AddInternal(const nsAttrValue* aAttr, const nsAString& aToken);
|
||||
void RemoveInternal(const nsAttrValue* aAttr, const nsAString& aToken);
|
||||
|
@ -4487,9 +4487,16 @@ ContentUnbinder* ContentUnbinder::sContentUnbinder = nsnull;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsGenericElement)
|
||||
nsINode::Unlink(tmp);
|
||||
|
||||
if (tmp->HasProperties() && tmp->IsXUL()) {
|
||||
tmp->DeleteProperty(nsGkAtoms::contextmenulistener);
|
||||
tmp->DeleteProperty(nsGkAtoms::popuplistener);
|
||||
if (tmp->HasProperties()) {
|
||||
if (tmp->IsHTML()) {
|
||||
tmp->DeleteProperty(nsGkAtoms::microdataProperties);
|
||||
tmp->DeleteProperty(nsGkAtoms::itemtype);
|
||||
tmp->DeleteProperty(nsGkAtoms::itemref);
|
||||
tmp->DeleteProperty(nsGkAtoms::itemprop);
|
||||
} else if (tmp->IsXUL()) {
|
||||
tmp->DeleteProperty(nsGkAtoms::contextmenulistener);
|
||||
tmp->DeleteProperty(nsGkAtoms::popuplistener);
|
||||
}
|
||||
}
|
||||
|
||||
// Unlink child content (and unbind our subtree).
|
||||
@ -4987,14 +4994,25 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsGenericElement)
|
||||
|
||||
tmp->OwnerDoc()->BindingManager()->Traverse(tmp, cb);
|
||||
|
||||
if (tmp->HasProperties() && tmp->IsXUL()) {
|
||||
nsISupports* property =
|
||||
static_cast<nsISupports*>
|
||||
(tmp->GetProperty(nsGkAtoms::contextmenulistener));
|
||||
cb.NoteXPCOMChild(property);
|
||||
property = static_cast<nsISupports*>
|
||||
(tmp->GetProperty(nsGkAtoms::popuplistener));
|
||||
cb.NoteXPCOMChild(property);
|
||||
if (tmp->HasProperties()) {
|
||||
if (tmp->IsHTML()) {
|
||||
nsISupports* property = static_cast<nsISupports*>
|
||||
(tmp->GetProperty(nsGkAtoms::microdataProperties));
|
||||
cb.NoteXPCOMChild(property);
|
||||
property = static_cast<nsISupports*>(tmp->GetProperty(nsGkAtoms::itemref));
|
||||
cb.NoteXPCOMChild(property);
|
||||
property = static_cast<nsISupports*>(tmp->GetProperty(nsGkAtoms::itemprop));
|
||||
cb.NoteXPCOMChild(property);
|
||||
property = static_cast<nsISupports*>(tmp->GetProperty(nsGkAtoms::itemtype));
|
||||
cb.NoteXPCOMChild(property);
|
||||
} else if (tmp->IsXUL()) {
|
||||
nsISupports* property = static_cast<nsISupports*>
|
||||
(tmp->GetProperty(nsGkAtoms::contextmenulistener));
|
||||
cb.NoteXPCOMChild(property);
|
||||
property = static_cast<nsISupports*>
|
||||
(tmp->GetProperty(nsGkAtoms::popuplistener));
|
||||
cb.NoteXPCOMChild(property);
|
||||
}
|
||||
}
|
||||
|
||||
// Traverse attribute names and child content.
|
||||
|
@ -95,9 +95,7 @@ GK_ATOM(_auto, "auto")
|
||||
GK_ATOM(autocheck, "autocheck")
|
||||
GK_ATOM(autocomplete, "autocomplete")
|
||||
GK_ATOM(autofocus, "autofocus")
|
||||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(autoplay, "autoplay")
|
||||
#endif
|
||||
GK_ATOM(autorepeatbutton, "autorepeatbutton")
|
||||
GK_ATOM(axis, "axis")
|
||||
GK_ATOM(b, "b")
|
||||
@ -220,9 +218,7 @@ GK_ATOM(context, "context")
|
||||
GK_ATOM(contextmenu, "contextmenu")
|
||||
GK_ATOM(contextmenulistener, "contextmenulistener")
|
||||
GK_ATOM(control, "control")
|
||||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(controls, "controls")
|
||||
#endif
|
||||
GK_ATOM(coords, "coords")
|
||||
GK_ATOM(copy, "copy")
|
||||
GK_ATOM(copyOf, "copy-of")
|
||||
@ -253,9 +249,7 @@ GK_ATOM(defaultchecked, "defaultchecked")
|
||||
GK_ATOM(defaultLabel, "defaultLabel")
|
||||
GK_ATOM(defaultselected, "defaultselected")
|
||||
GK_ATOM(defaultvalue, "defaultvalue")
|
||||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(defaultplaybackrate, "defaultplaybackrate")
|
||||
#endif
|
||||
GK_ATOM(defer, "defer")
|
||||
GK_ATOM(del, "del")
|
||||
GK_ATOM(descendant, "descendant")
|
||||
@ -505,9 +499,7 @@ GK_ATOM(load, "load")
|
||||
GK_ATOM(localedir, "localedir")
|
||||
GK_ATOM(localName, "local-name")
|
||||
GK_ATOM(longdesc, "longdesc")
|
||||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(loop, "loop")
|
||||
#endif
|
||||
GK_ATOM(low, "low")
|
||||
GK_ATOM(lowerFirst, "lower-first")
|
||||
GK_ATOM(lowest, "lowest")
|
||||
@ -544,6 +536,7 @@ GK_ATOM(message, "message")
|
||||
GK_ATOM(meta, "meta")
|
||||
GK_ATOM(meter, "meter")
|
||||
GK_ATOM(method, "method")
|
||||
GK_ATOM(microdataProperties, "microdataProperties")
|
||||
GK_ATOM(middle, "middle")
|
||||
GK_ATOM(min, "min")
|
||||
GK_ATOM(minheight, "minheight")
|
||||
@ -571,9 +564,7 @@ GK_ATOM(x_moz_errormessage, "x-moz-errormessage")
|
||||
GK_ATOM(msthemecompatible, "msthemecompatible")
|
||||
GK_ATOM(multicol, "multicol")
|
||||
GK_ATOM(multiple, "multiple")
|
||||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(muted, "muted")
|
||||
#endif
|
||||
GK_ATOM(name, "name")
|
||||
GK_ATOM(_namespace, "namespace")
|
||||
GK_ATOM(namespaceAlias, "namespace-alias")
|
||||
@ -761,9 +752,7 @@ GK_ATOM(phase, "phase")
|
||||
GK_ATOM(ping, "ping")
|
||||
GK_ATOM(placeholder, "placeholder")
|
||||
GK_ATOM(plaintext, "plaintext")
|
||||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(playbackrate, "playbackrate")
|
||||
#endif
|
||||
GK_ATOM(pointSize, "point-size")
|
||||
GK_ATOM(poly, "poly")
|
||||
GK_ATOM(polygon, "polygon")
|
||||
@ -779,17 +768,13 @@ GK_ATOM(popupshowing, "popupshowing")
|
||||
GK_ATOM(popupshown, "popupshown")
|
||||
GK_ATOM(popupsinherittooltip, "popupsinherittooltip")
|
||||
GK_ATOM(position, "position")
|
||||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(poster, "poster")
|
||||
#endif
|
||||
GK_ATOM(pre, "pre")
|
||||
GK_ATOM(preceding, "preceding")
|
||||
GK_ATOM(precedingSibling, "preceding-sibling")
|
||||
GK_ATOM(predicate, "predicate")
|
||||
GK_ATOM(prefix, "prefix")
|
||||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(preload, "preload")
|
||||
#endif
|
||||
GK_ATOM(preserve, "preserve")
|
||||
GK_ATOM(preserveSpace, "preserve-space")
|
||||
GK_ATOM(preventdefault, "preventdefault")
|
||||
@ -910,9 +895,7 @@ GK_ATOM(sortResource, "sortResource")
|
||||
GK_ATOM(sortResource2, "sortResource2")
|
||||
GK_ATOM(sortSeparators, "sortSeparators")
|
||||
GK_ATOM(sortStaticsLast, "sortStaticsLast")
|
||||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(source, "source")
|
||||
#endif
|
||||
GK_ATOM(space, "space")
|
||||
GK_ATOM(spacer, "spacer")
|
||||
GK_ATOM(span, "span")
|
||||
@ -1048,11 +1031,9 @@ GK_ATOM(vendorUrl, "vendor-url")
|
||||
GK_ATOM(version, "version")
|
||||
GK_ATOM(vert, "vert")
|
||||
GK_ATOM(vertical, "vertical")
|
||||
#ifdef MOZ_MEDIA
|
||||
GK_ATOM(audio, "audio")
|
||||
GK_ATOM(video, "video")
|
||||
GK_ATOM(videocontrols, "videocontrols")
|
||||
#endif
|
||||
GK_ATOM(viewport, "viewport")
|
||||
GK_ATOM(viewport_height, "viewport-height")
|
||||
GK_ATOM(viewport_initial_scale, "viewport-initial-scale")
|
||||
@ -1701,6 +1682,7 @@ GK_ATOM(comboboxControlFrame, "ComboboxControlFrame")
|
||||
GK_ATOM(comboboxDisplayFrame, "ComboboxDisplayFrame")
|
||||
GK_ATOM(deckFrame, "DeckFrame")
|
||||
GK_ATOM(fieldSetFrame, "FieldSetFrame")
|
||||
GK_ATOM(formControlFrame, "FormControlFrame") // radio or checkbox
|
||||
GK_ATOM(frameSetFrame, "FrameSetFrame")
|
||||
GK_ATOM(gfxButtonControlFrame, "gfxButtonControlFrame")
|
||||
GK_ATOM(HTMLButtonControlFrame, "HTMLButtonControlFrame")
|
||||
|
@ -74,6 +74,27 @@ using namespace mozilla;
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
class CallDispatchConnectionCloseEvents: public nsRunnable
|
||||
{
|
||||
public:
|
||||
CallDispatchConnectionCloseEvents(nsWebSocket *aWebSocket)
|
||||
: mWebSocket(aWebSocket)
|
||||
{}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
mWebSocket->DispatchConnectionCloseEvents();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<nsWebSocket> mWebSocket;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsWebSocket
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
nsWebSocket::PrintErrorOnConsole(const char *aBundleURI,
|
||||
const PRUnichar *aError,
|
||||
@ -124,37 +145,43 @@ nsWebSocket::PrintErrorOnConsole(const char *aBundleURI,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// when this is called the browser side wants no more part of it
|
||||
nsresult
|
||||
nsWebSocket::CloseConnection(PRUint16 aReasonCode,
|
||||
const nsACString& aReasonString)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
if (mDisconnected)
|
||||
return NS_OK;
|
||||
|
||||
// Disconnect() can release this object, so we keep a
|
||||
// reference until the end of the method
|
||||
nsRefPtr<nsWebSocket> kungfuDeathGrip = this;
|
||||
|
||||
if (mReadyState == nsIWebSocket::CONNECTING) {
|
||||
SetReadyState(nsIWebSocket::CLOSED);
|
||||
if (mChannel) {
|
||||
mChannel->Close(aReasonCode, aReasonString);
|
||||
}
|
||||
Disconnect();
|
||||
if (mReadyState == nsIWebSocket::CLOSING ||
|
||||
mReadyState == nsIWebSocket::CLOSED) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
SetReadyState(nsIWebSocket::CLOSING);
|
||||
|
||||
if (mDisconnected) {
|
||||
SetReadyState(nsIWebSocket::CLOSED);
|
||||
Disconnect();
|
||||
return NS_OK;
|
||||
// The common case...
|
||||
if (mChannel) {
|
||||
mReadyState = nsIWebSocket::CLOSING;
|
||||
return mChannel->Close(aReasonCode, aReasonString);
|
||||
}
|
||||
|
||||
return mChannel->Close(aReasonCode, aReasonString);
|
||||
// No channel, but not disconnected: canceled or failed early
|
||||
//
|
||||
MOZ_ASSERT(mReadyState == nsIWebSocket::CONNECTING,
|
||||
"Should only get here for early websocket cancel/error");
|
||||
|
||||
// Server won't be sending us a close code, so use what's passed in here.
|
||||
mCloseEventCode = aReasonCode;
|
||||
CopyUTF8toUTF16(aReasonString, mCloseEventReason);
|
||||
|
||||
mReadyState = nsIWebSocket::CLOSING;
|
||||
|
||||
// Can be called from Cancel() or Init() codepaths, so need to dispatch
|
||||
// onerror/onclose asynchronously
|
||||
ScheduleConnectionCloseEvents(
|
||||
nsnull,
|
||||
(aReasonCode == nsIWebSocketChannel::CLOSE_NORMAL ||
|
||||
aReasonCode == nsIWebSocketChannel::CLOSE_GOING_AWAY) ?
|
||||
NS_OK : NS_ERROR_FAILURE,
|
||||
false);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -191,14 +218,11 @@ nsWebSocket::FailConnection(PRUint16 aReasonCode,
|
||||
const nsACString& aReasonString)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
ConsoleError();
|
||||
|
||||
mFailed = true;
|
||||
CloseConnection(aReasonCode, aReasonString);
|
||||
|
||||
nsresult rv = CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("error"));
|
||||
if (NS_FAILED(rv))
|
||||
NS_WARNING("Failed to dispatch the error event");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -240,7 +264,11 @@ nsresult
|
||||
nsWebSocket::DoOnMessageAvailable(const nsACString & aMsg, bool isBinary)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
NS_ABORT_IF_FALSE(!mDisconnected, "Received message after disconnecting");
|
||||
|
||||
if (mReadyState == nsIWebSocket::CLOSED) {
|
||||
NS_ERROR("Received message after CLOSED");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
if (mReadyState == nsIWebSocket::OPEN) {
|
||||
// Dispatch New Message
|
||||
@ -251,8 +279,8 @@ nsWebSocket::DoOnMessageAvailable(const nsACString & aMsg, bool isBinary)
|
||||
} else {
|
||||
// CLOSING should be the only other state where it's possible to get msgs
|
||||
// from channel: Spec says to drop them.
|
||||
NS_ASSERTION(mReadyState == nsIWebSocket::CLOSING,
|
||||
"Received message while CONNECTING or CLOSED");
|
||||
MOZ_ASSERT(mReadyState == nsIWebSocket::CLOSING,
|
||||
"Received message while CONNECTING or CLOSED");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -275,13 +303,20 @@ NS_IMETHODIMP
|
||||
nsWebSocket::OnStart(nsISupports *aContext)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
if (mDisconnected)
|
||||
|
||||
// This is the only function that sets OPEN, and should be called only once
|
||||
MOZ_ASSERT(mReadyState != nsIWebSocket::OPEN,
|
||||
"readyState already OPEN! OnStart called twice?");
|
||||
|
||||
// Nothing to do if we've already closed/closing
|
||||
if (mReadyState != nsIWebSocket::CONNECTING) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Attempt to kill "ghost" websocket: but usually too early for check to fail
|
||||
nsresult rv = CheckInnerWindowCorrectness();
|
||||
if (NS_FAILED(rv)) {
|
||||
FailConnectionQuietly();
|
||||
CloseConnection(nsIWebSocketChannel::CLOSE_GOING_AWAY);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -292,35 +327,63 @@ nsWebSocket::OnStart(nsISupports *aContext)
|
||||
mChannel->GetExtensions(mEstablishedExtensions);
|
||||
UpdateURI();
|
||||
|
||||
SetReadyState(nsIWebSocket::OPEN);
|
||||
mReadyState = nsIWebSocket::OPEN;
|
||||
|
||||
// Call 'onopen'
|
||||
rv = CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("open"));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch the open event");
|
||||
}
|
||||
|
||||
UpdateMustKeepAlive();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWebSocket::OnStop(nsISupports *aContext, nsresult aStatusCode)
|
||||
{
|
||||
// We can be CONNECTING here if connection failed.
|
||||
// We can be OPEN if we have encountered a fatal protocol error
|
||||
// We can be CLOSING if close() was called and/or server initiated close.
|
||||
MOZ_ASSERT(mReadyState != nsIWebSocket::CLOSED,
|
||||
"Shouldn't already be CLOSED when OnStop called");
|
||||
|
||||
// called by network stack, not JS, so can dispatch JS events synchronously
|
||||
return ScheduleConnectionCloseEvents(aContext, aStatusCode, true);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsWebSocket::ScheduleConnectionCloseEvents(nsISupports *aContext,
|
||||
nsresult aStatusCode,
|
||||
bool sync)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
if (mDisconnected)
|
||||
return NS_OK;
|
||||
|
||||
mCloseEventWasClean = NS_SUCCEEDED(aStatusCode);
|
||||
// no-op if some other code has already initiated close event
|
||||
if (!mOnCloseScheduled) {
|
||||
mCloseEventWasClean = NS_SUCCEEDED(aStatusCode);
|
||||
|
||||
if (aStatusCode == NS_BASE_STREAM_CLOSED &&
|
||||
mReadyState >= nsIWebSocket::CLOSING) {
|
||||
// don't generate an error event just because of an unclean close
|
||||
aStatusCode = NS_OK;
|
||||
if (aStatusCode == NS_BASE_STREAM_CLOSED) {
|
||||
// don't generate an error event just because of an unclean close
|
||||
aStatusCode = NS_OK;
|
||||
}
|
||||
|
||||
if (NS_FAILED(aStatusCode)) {
|
||||
ConsoleError();
|
||||
mFailed = true;
|
||||
}
|
||||
|
||||
mOnCloseScheduled = true;
|
||||
|
||||
if (sync) {
|
||||
DispatchConnectionCloseEvents();
|
||||
} else {
|
||||
NS_DispatchToMainThread(new CallDispatchConnectionCloseEvents(this),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_FAILED(aStatusCode)) {
|
||||
ConsoleError();
|
||||
nsresult rv = CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("error"));
|
||||
if (NS_FAILED(rv))
|
||||
NS_WARNING("Failed to dispatch the error event");
|
||||
}
|
||||
|
||||
SetReadyState(nsIWebSocket::CLOSED);
|
||||
Disconnect();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -342,19 +405,17 @@ nsWebSocket::OnServerClose(nsISupports *aContext, PRUint16 aCode,
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
NS_ABORT_IF_FALSE(mReadyState != nsIWebSocket::CONNECTING,
|
||||
"Received server close before connected?");
|
||||
|
||||
if (mReadyState == nsIWebSocket::CLOSED) {
|
||||
NS_WARNING("Received server close after already closed!");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
MOZ_ASSERT(mReadyState != nsIWebSocket::CONNECTING,
|
||||
"Received server close before connected?");
|
||||
MOZ_ASSERT(mReadyState != nsIWebSocket::CLOSED,
|
||||
"Received server close after already closed!");
|
||||
|
||||
// store code/string for onclose DOM event
|
||||
mCloseEventCode = aCode;
|
||||
CopyUTF8toUTF16(aReason, mCloseEventReason);
|
||||
|
||||
if (mReadyState == nsIWebSocket::OPEN) {
|
||||
// Server initiating close.
|
||||
// RFC 6455, 5.5.1: "When sending a Close frame in response, the endpoint
|
||||
// typically echos the status code it received".
|
||||
// But never send certain codes, per section 7.4.1
|
||||
@ -364,9 +425,8 @@ nsWebSocket::OnServerClose(nsISupports *aContext, PRUint16 aCode,
|
||||
CloseConnection(aCode, aReason);
|
||||
}
|
||||
} else {
|
||||
// Nothing else to do: OnStop does the rest of the work.
|
||||
NS_ASSERTION (mReadyState == nsIWebSocket::CLOSING, "unknown state");
|
||||
NS_ASSERTION(!mDisconnected, "should not be disconnected during CLOSING");
|
||||
// We initiated close, and server has replied: OnStop does rest of the work.
|
||||
MOZ_ASSERT(mReadyState == nsIWebSocket::CLOSING, "unknown state");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -381,7 +441,7 @@ nsWebSocket::GetInterface(const nsIID &aIID, void **aResult)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
if (mDisconnected)
|
||||
if (mReadyState == nsIWebSocket::CLOSED)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsIAuthPrompt)) ||
|
||||
@ -411,7 +471,8 @@ nsWebSocket::GetInterface(const nsIID &aIID, void **aResult)
|
||||
|
||||
nsWebSocket::nsWebSocket() : mKeepingAlive(false),
|
||||
mCheckMustKeepAlive(true),
|
||||
mTriggeredCloseEvent(false),
|
||||
mOnCloseScheduled(false),
|
||||
mFailed(false),
|
||||
mDisconnected(false),
|
||||
mCloseEventWasClean(false),
|
||||
mCloseEventCode(nsIWebSocketChannel::CLOSE_ABNORMAL),
|
||||
@ -429,7 +490,10 @@ nsWebSocket::~nsWebSocket()
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
Disconnect();
|
||||
// If we threw during Init we never called disconnect
|
||||
if (!mDisconnected) {
|
||||
Disconnect();
|
||||
}
|
||||
nsLayoutStatics::Release();
|
||||
}
|
||||
|
||||
@ -511,7 +575,7 @@ nsWebSocket::DisconnectFromOwner()
|
||||
NS_DISCONNECT_EVENT_HANDLER(Message)
|
||||
NS_DISCONNECT_EVENT_HANDLER(Close)
|
||||
NS_DISCONNECT_EVENT_HANDLER(Error)
|
||||
FailConnectionQuietly();
|
||||
CloseConnection(nsIWebSocketChannel::CLOSE_GOING_AWAY);
|
||||
DontKeepAliveAnyMore();
|
||||
}
|
||||
|
||||
@ -705,31 +769,30 @@ nsWebSocket::EstablishConnection()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
class nsWSCloseEvent : public nsRunnable
|
||||
void
|
||||
nsWebSocket::DispatchConnectionCloseEvents()
|
||||
{
|
||||
public:
|
||||
nsWSCloseEvent(nsWebSocket *aWebSocket, bool aWasClean,
|
||||
PRUint16 aCode, const nsString &aReason)
|
||||
: mWebSocket(aWebSocket),
|
||||
mWasClean(aWasClean),
|
||||
mCode(aCode),
|
||||
mReason(aReason)
|
||||
{}
|
||||
nsresult rv;
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
nsresult rv = mWebSocket->CreateAndDispatchCloseEvent(mWasClean,
|
||||
mCode, mReason);
|
||||
mWebSocket->UpdateMustKeepAlive();
|
||||
return rv;
|
||||
mReadyState = nsIWebSocket::CLOSED;
|
||||
|
||||
// Call 'onerror' if needed
|
||||
if (mFailed) {
|
||||
nsresult rv = CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("error"));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch the error event");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<nsWebSocket> mWebSocket;
|
||||
bool mWasClean;
|
||||
PRUint16 mCode;
|
||||
nsString mReason;
|
||||
};
|
||||
rv = CreateAndDispatchCloseEvent(mCloseEventWasClean, mCloseEventCode,
|
||||
mCloseEventReason);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch the close event");
|
||||
}
|
||||
|
||||
UpdateMustKeepAlive();
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsWebSocket::CreateAndDispatchSimpleEvent(const nsString& aName)
|
||||
@ -855,8 +918,6 @@ nsWebSocket::CreateAndDispatchCloseEvent(bool aWasClean,
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
nsresult rv;
|
||||
|
||||
mTriggeredCloseEvent = true;
|
||||
|
||||
rv = CheckInnerWindowCorrectness();
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_OK;
|
||||
@ -888,58 +949,6 @@ nsWebSocket::PrefEnabled()
|
||||
return Preferences::GetBool("network.websocket.enabled", true);
|
||||
}
|
||||
|
||||
void
|
||||
nsWebSocket::SetReadyState(PRUint16 aNewReadyState)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
nsresult rv;
|
||||
|
||||
if (mReadyState == aNewReadyState) {
|
||||
return;
|
||||
}
|
||||
|
||||
NS_ABORT_IF_FALSE((aNewReadyState == nsIWebSocket::OPEN) ||
|
||||
(aNewReadyState == nsIWebSocket::CLOSING) ||
|
||||
(aNewReadyState == nsIWebSocket::CLOSED),
|
||||
"unexpected readyState");
|
||||
|
||||
if (aNewReadyState == nsIWebSocket::OPEN) {
|
||||
NS_ABORT_IF_FALSE(mReadyState == nsIWebSocket::CONNECTING,
|
||||
"unexpected readyState transition");
|
||||
mReadyState = aNewReadyState;
|
||||
|
||||
rv = CreateAndDispatchSimpleEvent(NS_LITERAL_STRING("open"));
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch the open event");
|
||||
}
|
||||
UpdateMustKeepAlive();
|
||||
return;
|
||||
}
|
||||
|
||||
if (aNewReadyState == nsIWebSocket::CLOSING) {
|
||||
NS_ABORT_IF_FALSE((mReadyState == nsIWebSocket::CONNECTING) ||
|
||||
(mReadyState == nsIWebSocket::OPEN),
|
||||
"unexpected readyState transition");
|
||||
mReadyState = aNewReadyState;
|
||||
return;
|
||||
}
|
||||
|
||||
if (aNewReadyState == nsIWebSocket::CLOSED) {
|
||||
mReadyState = aNewReadyState;
|
||||
|
||||
// The close event must be dispatched asynchronously.
|
||||
rv = NS_DispatchToMainThread(new nsWSCloseEvent(this, mCloseEventWasClean,
|
||||
mCloseEventCode,
|
||||
mCloseEventReason),
|
||||
NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch the close event");
|
||||
mTriggeredCloseEvent = true;
|
||||
UpdateMustKeepAlive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsWebSocket::ParseURL(const nsString& aURL)
|
||||
{
|
||||
@ -1066,9 +1075,7 @@ nsWebSocket::UpdateMustKeepAlive()
|
||||
|
||||
case nsIWebSocket::CLOSED:
|
||||
{
|
||||
shouldKeepAlive =
|
||||
(!mTriggeredCloseEvent &&
|
||||
mListenerManager->HasListenersFor(NS_LITERAL_STRING("close")));
|
||||
shouldKeepAlive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1093,14 +1100,6 @@ nsWebSocket::DontKeepAliveAnyMore()
|
||||
mCheckMustKeepAlive = false;
|
||||
}
|
||||
|
||||
void
|
||||
nsWebSocket::FailConnectionQuietly()
|
||||
{
|
||||
// Fail without console error or JS onerror message: onmessage/onclose will
|
||||
// also be blocked so long as CheckInnerWindowCorrectness is failing.
|
||||
CloseConnection(nsIWebSocketChannel::CLOSE_GOING_AWAY);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsWebSocket::UpdateURI()
|
||||
{
|
||||
@ -1292,8 +1291,8 @@ nsWebSocket::Send(nsIVariant *aData, JSContext *aCx)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mReadyState == nsIWebSocket::OPEN,
|
||||
"Unknown state in nsWebSocket::Send");
|
||||
MOZ_ASSERT(mReadyState == nsIWebSocket::OPEN,
|
||||
"Unknown state in nsWebSocket::Send");
|
||||
|
||||
if (msgStream) {
|
||||
rv = mChannel->SendBinaryStream(msgStream, msgLen);
|
||||
@ -1471,10 +1470,6 @@ nsWebSocket::Close(PRUint16 code, const nsAString & reason, PRUint8 argc)
|
||||
}
|
||||
|
||||
if (mReadyState == nsIWebSocket::CONNECTING) {
|
||||
// FailConnection() can release the object, so we keep a reference
|
||||
// before calling it
|
||||
nsRefPtr<nsWebSocket> kungfuDeathGrip = this;
|
||||
|
||||
FailConnection(closeCode, closeReason);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1618,7 +1613,7 @@ nsWebSocket::Observe(nsISupports* aSubject,
|
||||
if ((strcmp(aTopic, DOM_WINDOW_FROZEN_TOPIC) == 0) ||
|
||||
(strcmp(aTopic, DOM_WINDOW_DESTROYED_TOPIC) == 0))
|
||||
{
|
||||
FailConnectionQuietly();
|
||||
CloseConnection(nsIWebSocketChannel::CLOSE_GOING_AWAY);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -1639,7 +1634,7 @@ nsWebSocket::GetName(nsACString &aName)
|
||||
NS_IMETHODIMP
|
||||
nsWebSocket::IsPending(bool *aValue)
|
||||
{
|
||||
*aValue = !mDisconnected;
|
||||
*aValue = (mReadyState != nsIWebSocket::CLOSED);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1656,10 +1651,12 @@ nsWebSocket::Cancel(nsresult aStatus)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
if (mDisconnected)
|
||||
if (mReadyState == CLOSING || mReadyState == CLOSED) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ConsoleError();
|
||||
|
||||
return CloseConnection(nsIWebSocketChannel::CLOSE_GOING_AWAY);
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
#define NS_WEBSOCKET_CONTRACTID "@mozilla.org/websocket;1"
|
||||
|
||||
class nsWSCloseEvent;
|
||||
class CallDispatchConnectionCloseEvents;
|
||||
class nsAutoCloseWS;
|
||||
|
||||
class nsWebSocket: public nsDOMEventTargetHelper,
|
||||
@ -47,7 +47,7 @@ class nsWebSocket: public nsDOMEventTargetHelper,
|
||||
public nsSupportsWeakReference,
|
||||
public nsIRequest
|
||||
{
|
||||
friend class nsWSCloseEvent;
|
||||
friend class CallDispatchConnectionCloseEvents;
|
||||
friend class nsAutoCloseWS;
|
||||
|
||||
public:
|
||||
@ -87,7 +87,6 @@ protected:
|
||||
// These methods when called can release the WebSocket object
|
||||
nsresult FailConnection(PRUint16 reasonCode,
|
||||
const nsACString& aReasonString = EmptyCString());
|
||||
void FailConnectionQuietly();
|
||||
nsresult CloseConnection(PRUint16 reasonCode,
|
||||
const nsACString& aReasonString = EmptyCString());
|
||||
nsresult Disconnect();
|
||||
@ -107,6 +106,18 @@ protected:
|
||||
JSContext *aCx);
|
||||
|
||||
nsresult DoOnMessageAvailable(const nsACString & aMsg, bool isBinary);
|
||||
|
||||
// ConnectionCloseEvents: 'error' event if needed, then 'close' event.
|
||||
// - These must not be dispatched while we are still within an incoming call
|
||||
// from JS (ex: close()). Set 'sync' to false in that case to dispatch in a
|
||||
// separate new event.
|
||||
nsresult ScheduleConnectionCloseEvents(nsISupports *aContext,
|
||||
nsresult aStatusCode,
|
||||
bool sync);
|
||||
// 2nd half of ScheduleConnectionCloseEvents, sometimes run in its own event.
|
||||
void DispatchConnectionCloseEvents();
|
||||
|
||||
// These methods actually do the dispatch for various events.
|
||||
nsresult CreateAndDispatchSimpleEvent(const nsString& aName);
|
||||
nsresult CreateAndDispatchMessageEvent(const nsACString& aData,
|
||||
bool isBinary);
|
||||
@ -115,8 +126,6 @@ protected:
|
||||
nsresult CreateResponseBlob(const nsACString& aData, JSContext *aCx,
|
||||
jsval &jsData);
|
||||
|
||||
void SetReadyState(PRUint16 aNewReadyState);
|
||||
|
||||
// if there are "strong event listeners" (see comment in nsWebSocket.cpp) or
|
||||
// outgoing not sent messages then this method keeps the object alive
|
||||
// when js doesn't have strong references to it.
|
||||
@ -142,7 +151,8 @@ protected:
|
||||
|
||||
bool mKeepingAlive;
|
||||
bool mCheckMustKeepAlive;
|
||||
bool mTriggeredCloseEvent;
|
||||
bool mOnCloseScheduled;
|
||||
bool mFailed;
|
||||
bool mDisconnected;
|
||||
|
||||
// Set attributes of DOM 'onclose' message
|
||||
|
@ -246,6 +246,24 @@ public:
|
||||
|
||||
// event handler
|
||||
IMPL_EVENT_HANDLER(readystatechange, Readystatechange)
|
||||
JSObject* GetOnuploadprogress(JSContext* /* unused */)
|
||||
{
|
||||
nsIDocument* doc = GetOwner() ? GetOwner()->GetExtantDoc() : NULL;
|
||||
if (doc) {
|
||||
doc->WarnOnceAbout(nsIDocument::eOnuploadprogress);
|
||||
}
|
||||
return GetListenerAsJSObject(mOnUploadProgressListener);
|
||||
}
|
||||
void SetOnuploadprogress(JSContext* aCx, JSObject* aCallback,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsIDocument* doc = GetOwner() ? GetOwner()->GetExtantDoc() : NULL;
|
||||
if (doc) {
|
||||
doc->WarnOnceAbout(nsIDocument::eOnuploadprogress);
|
||||
}
|
||||
aRv = SetJSObjectListener(aCx, NS_LITERAL_STRING("uploadprogress"),
|
||||
mOnUploadProgressListener, aCallback);
|
||||
}
|
||||
|
||||
// states
|
||||
uint16_t GetReadyState();
|
||||
|
@ -549,6 +549,7 @@ _TEST_FILES2 = \
|
||||
test_bug433662.html \
|
||||
test_bug749367.html \
|
||||
test_bug753278.html \
|
||||
test_XHR_onuploadprogress.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
41
content/base/test/test_XHR_onuploadprogress.html
Normal file
41
content/base/test/test_XHR_onuploadprogress.html
Normal file
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=743666
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 743666</title>
|
||||
<script type="application/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=743666">Mozilla Bug 743666</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 743666 **/
|
||||
|
||||
var called = false;
|
||||
function uploadprogress()
|
||||
{
|
||||
called = true;
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onuploadprogress = uploadprogress;
|
||||
var event = document.createEvent("ProgressEvent");
|
||||
event.initProgressEvent("uploadprogress", false, false, false, false, 0);
|
||||
xhr.dispatchEvent(event);
|
||||
ok(called,
|
||||
"XMLHttpRequest.onuploadprogress sets uploadprogress event listener");
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -69,10 +69,11 @@
|
||||
* 44. Test sending/receving binary ArrayBuffer
|
||||
* 45. Test sending/receving binary Blob
|
||||
* 46. Test that we don't dispatch incoming msgs once in CLOSING state
|
||||
* 47. Make sure onerror/onclose aren't called during close()
|
||||
*/
|
||||
|
||||
var first_test = 1;
|
||||
var last_test = 46;
|
||||
var last_test = 47;
|
||||
|
||||
|
||||
// Set this to >1 if you want to run the suite multiple times to probe for
|
||||
@ -282,6 +283,7 @@ function test3()
|
||||
{
|
||||
shouldCloseNotCleanly(e);
|
||||
ok(hasError, "rcvd onerror event");
|
||||
ok(e.code == 1006, "test-3 close code should be 1006 but is:" + e.code);
|
||||
doTest(4);
|
||||
};
|
||||
}
|
||||
@ -1435,6 +1437,41 @@ function test46()
|
||||
}
|
||||
}
|
||||
|
||||
function test47()
|
||||
{
|
||||
var hasError = false;
|
||||
var ws = CreateTestWS("ws://another.websocket.server.that.probably.does.not.exist");
|
||||
ws.onopen = shouldNotOpen;
|
||||
|
||||
ws.onerror = function (e)
|
||||
{
|
||||
ok(ws.readyState == 3, "test-47: readyState should be CLOSED(3) in onerror: got "
|
||||
+ ws.readyState);
|
||||
ok(!ws._withinClose, "onerror() called during close()!");
|
||||
hasError = true;
|
||||
}
|
||||
|
||||
ws.onclose = function(e)
|
||||
{
|
||||
shouldCloseNotCleanly(e);
|
||||
ok(hasError, "test-47: should have called onerror before onclose");
|
||||
ok(ws.readyState == 3, "test-47: readyState should be CLOSED(3) in onclose: got "
|
||||
+ ws.readyState);
|
||||
ok(!ws._withinClose, "onclose() called during close()!");
|
||||
ok(e.code == 1006, "test-47 close code should be 1006 but is:" + e.code);
|
||||
doTest(48);
|
||||
};
|
||||
|
||||
// Call close before we're connected: throws error
|
||||
// Make sure we call onerror/onclose asynchronously
|
||||
ws._withinClose = 1;
|
||||
ws.close(3333, "Closed before we were open: error");
|
||||
ws._withinClose = 0;
|
||||
ok(ws.readyState == 2, "test-47: readyState should be CLOSING(2) after close(): got "
|
||||
+ ws.readyState);
|
||||
}
|
||||
|
||||
|
||||
var ranAllTests = false;
|
||||
|
||||
function maybeFinished()
|
||||
|
@ -599,6 +599,29 @@ test(
|
||||
|
||||
});
|
||||
|
||||
test(
|
||||
function test_bug634773_noneAndStarAreDifferent() {
|
||||
/**
|
||||
* Bug 634773 is that allow * and allow 'none' end up "equal" via
|
||||
* CSPSourceList.prototype.equals(), which is wrong. This tests that
|
||||
* doesn't happen.
|
||||
*/
|
||||
|
||||
var p_none = CSPSourceList.fromString("'none'", "http://foo.com", false);
|
||||
var p_all = CSPSourceList.fromString("*", "http://foo.com", false);
|
||||
var p_one = CSPSourceList.fromString("bar.com", "http://foo.com", false);
|
||||
|
||||
do_check_false(p_none.equals(p_all));
|
||||
do_check_false(p_none.equals(p_one));
|
||||
do_check_false(p_all.equals(p_none));
|
||||
do_check_false(p_all.equals(p_one));
|
||||
|
||||
do_check_true(p_all.permits("http://bar.com"));
|
||||
do_check_true(p_one.permits("http://bar.com"));
|
||||
do_check_false(p_none.permits("http://bar.com"));
|
||||
});
|
||||
|
||||
|
||||
/*
|
||||
|
||||
test(function test_CSPRep_fromPolicyURI_failswhenmixed() {
|
||||
|
@ -301,6 +301,9 @@ nsEventListenerManager::IsDeviceType(PRUint32 aType)
|
||||
switch (aType) {
|
||||
case NS_DEVICE_ORIENTATION:
|
||||
case NS_DEVICE_MOTION:
|
||||
case NS_DEVICE_LIGHT:
|
||||
case NS_DEVICE_PROXIMITY:
|
||||
case NS_USER_PROXIMITY:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
@ -401,7 +404,7 @@ nsEventListenerManager::RemoveEventListener(nsIDOMEventListener *aListener,
|
||||
mNoListenerForEvent = NS_EVENT_TYPE_NULL;
|
||||
mNoListenerForEventAtom = nsnull;
|
||||
|
||||
if (deviceType) {
|
||||
if (!deviceType) {
|
||||
return;
|
||||
}
|
||||
--typeCount;
|
||||
|
@ -49,6 +49,10 @@ public:
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
virtual nsIDOMNode* AsDOMNode() { return this; }
|
||||
|
||||
protected:
|
||||
virtual void GetItemValueText(nsAString& text);
|
||||
virtual void SetItemValueText(const nsAString& text);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -60,6 +60,10 @@ public:
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
virtual nsIDOMNode* AsDOMNode() { return this; }
|
||||
|
||||
protected:
|
||||
virtual void GetItemValueText(nsAString& text);
|
||||
virtual void SetItemValueText(const nsAString& text);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
610
content/html/content/src/HTMLPropertiesCollection.cpp
Normal file
610
content/html/content/src/HTMLPropertiesCollection.cpp
Normal file
@ -0,0 +1,610 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "HTMLPropertiesCollection.h"
|
||||
#include "dombindings.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsVariant.h"
|
||||
#include "nsDOMSettableTokenList.h"
|
||||
#include "nsAttrValue.h"
|
||||
|
||||
DOMCI_DATA(HTMLPropertiesCollection, mozilla::dom::HTMLPropertiesCollection)
|
||||
DOMCI_DATA(PropertyNodeList, mozilla::dom::PropertyNodeList)
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
static PLDHashOperator
|
||||
TraverseNamedProperties(const nsAString& aKey, PropertyNodeList* aEntry, void* aData)
|
||||
{
|
||||
nsCycleCollectionTraversalCallback* cb = static_cast<nsCycleCollectionTraversalCallback*>(aData);
|
||||
cb->NoteXPCOMChild(static_cast<nsIDOMPropertyNodeList*>(aEntry));
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLPropertiesCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(HTMLPropertiesCollection)
|
||||
// SetDocument(nsnull) ensures that we remove ourselves as a mutation observer
|
||||
tmp->SetDocument(nsnull);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRoot)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNames)
|
||||
tmp->mNamedItemEntries.Clear();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSTARRAY(mProperties)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(HTMLPropertiesCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDoc)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRoot)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNames)
|
||||
tmp->mNamedItemEntries.EnumerateRead(TraverseNamedProperties, &cb);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_OF_NSCOMPTR(mProperties)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(HTMLPropertiesCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
HTMLPropertiesCollection::HTMLPropertiesCollection(nsGenericHTMLElement* aRoot)
|
||||
: mRoot(aRoot)
|
||||
, mDoc(aRoot->GetCurrentDoc())
|
||||
, mIsDirty(true)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
mNames = new PropertyStringList(this);
|
||||
if (mDoc) {
|
||||
mDoc->AddMutationObserver(this);
|
||||
}
|
||||
mNamedItemEntries.Init();
|
||||
}
|
||||
|
||||
HTMLPropertiesCollection::~HTMLPropertiesCollection()
|
||||
{
|
||||
if (mDoc) {
|
||||
mDoc->RemoveMutationObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD(HTMLPropertiesCollection)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_TABLE4(HTMLPropertiesCollection,
|
||||
nsIDOMHTMLPropertiesCollection,
|
||||
nsIDOMHTMLCollection,
|
||||
nsIHTMLCollection,
|
||||
nsIMutationObserver)
|
||||
NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(HTMLPropertiesCollection)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(HTMLPropertiesCollection)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(HTMLPropertiesCollection)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(HTMLPropertiesCollection)
|
||||
|
||||
|
||||
static PLDHashOperator
|
||||
SetPropertyListDocument(const nsAString& aKey, PropertyNodeList* aEntry, void* aData)
|
||||
{
|
||||
aEntry->SetDocument(static_cast<nsIDocument*>(aData));
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLPropertiesCollection::SetDocument(nsIDocument* aDocument) {
|
||||
if (mDoc) {
|
||||
mDoc->RemoveMutationObserver(this);
|
||||
}
|
||||
mDoc = aDocument;
|
||||
if (mDoc) {
|
||||
mDoc->AddMutationObserver(this);
|
||||
}
|
||||
mNamedItemEntries.EnumerateRead(SetPropertyListDocument, aDocument);
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
HTMLPropertiesCollection::WrapObject(JSContext* cx, JSObject* scope,
|
||||
bool* triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::HTMLPropertiesCollection::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLPropertiesCollection::GetLength(PRUint32* aLength)
|
||||
{
|
||||
EnsureFresh();
|
||||
*aLength = mProperties.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLPropertiesCollection::Item(PRUint32 aIndex, nsIDOMNode** aResult)
|
||||
{
|
||||
EnsureFresh();
|
||||
nsGenericHTMLElement* property = mProperties.SafeElementAt(aIndex);
|
||||
*aResult = property ? property->AsDOMNode() : NULL;
|
||||
NS_IF_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLPropertiesCollection::NamedItem(const nsAString& aName,
|
||||
nsIDOMNode** aResult)
|
||||
{
|
||||
*aResult = NULL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
HTMLPropertiesCollection::GetNamedItem(const nsAString& aName,
|
||||
nsWrapperCache **aCache)
|
||||
{
|
||||
EnsureFresh();
|
||||
if (!mNames->ContainsInternal(aName)) {
|
||||
*aCache = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsRefPtr<PropertyNodeList> propertyList;
|
||||
if (!mNamedItemEntries.Get(aName, getter_AddRefs(propertyList))) {
|
||||
propertyList = new PropertyNodeList(this, mRoot, aName);
|
||||
mNamedItemEntries.Put(aName, propertyList);
|
||||
}
|
||||
*aCache = propertyList;
|
||||
return static_cast<nsIDOMPropertyNodeList*>(propertyList);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
HTMLPropertiesCollection::GetNodeAt(PRUint32 aIndex)
|
||||
{
|
||||
EnsureFresh();
|
||||
return mProperties.SafeElementAt(aIndex);
|
||||
}
|
||||
|
||||
nsINode*
|
||||
HTMLPropertiesCollection::GetParentObject()
|
||||
{
|
||||
return mRoot;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLPropertiesCollection::NamedItem(const nsAString& aName,
|
||||
nsIDOMPropertyNodeList** aResult)
|
||||
{
|
||||
EnsureFresh();
|
||||
|
||||
nsRefPtr<PropertyNodeList> propertyList;
|
||||
if (!mNamedItemEntries.Get(aName, getter_AddRefs(propertyList))) {
|
||||
propertyList = new PropertyNodeList(this, mRoot, aName);
|
||||
mNamedItemEntries.Put(aName, propertyList);
|
||||
}
|
||||
propertyList.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
HTMLPropertiesCollection::GetNames(nsIDOMDOMStringList** aResult)
|
||||
{
|
||||
EnsureFresh();
|
||||
NS_ADDREF(*aResult = mNames);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLPropertiesCollection::AttributeChanged(nsIDocument *aDocument, Element* aElement,
|
||||
PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRInt32 aModType)
|
||||
{
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLPropertiesCollection::ContentAppended(nsIDocument* aDocument, nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent,
|
||||
PRInt32 aNewIndexInContainer)
|
||||
{
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLPropertiesCollection::ContentInserted(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLPropertiesCollection::ContentRemoved(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
class TreeOrderComparator {
|
||||
public:
|
||||
bool Equals(const nsGenericHTMLElement* aElem1,
|
||||
const nsGenericHTMLElement* aElem2) const {
|
||||
return aElem1 == aElem2;
|
||||
}
|
||||
bool LessThan(const nsGenericHTMLElement* aElem1,
|
||||
const nsGenericHTMLElement* aElem2) const {
|
||||
return nsContentUtils::PositionIsBefore(const_cast<nsGenericHTMLElement*>(aElem1),
|
||||
const_cast<nsGenericHTMLElement*>(aElem2));
|
||||
}
|
||||
};
|
||||
|
||||
static PLDHashOperator
|
||||
MarkDirty(const nsAString& aKey, PropertyNodeList* aEntry, void* aData)
|
||||
{
|
||||
aEntry->SetDirty();
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLPropertiesCollection::EnsureFresh()
|
||||
{
|
||||
if (mDoc && !mIsDirty) {
|
||||
return;
|
||||
}
|
||||
mIsDirty = false;
|
||||
|
||||
mProperties.Clear();
|
||||
mNames->Clear();
|
||||
// We don't clear NamedItemEntries because the PropertyNodeLists must be live.
|
||||
mNamedItemEntries.EnumerateRead(MarkDirty, NULL);
|
||||
if (!mRoot->HasAttr(kNameSpaceID_None, nsGkAtoms::itemscope)) {
|
||||
return;
|
||||
}
|
||||
|
||||
CrawlProperties();
|
||||
TreeOrderComparator comparator;
|
||||
mProperties.Sort(comparator);
|
||||
|
||||
// Create the names DOMStringList
|
||||
PRUint32 count = mProperties.Length();
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
const nsAttrValue* attr = mProperties.ElementAt(i)->GetParsedAttr(nsGkAtoms::itemprop);
|
||||
for (PRUint32 i = 0; i < attr->GetAtomCount(); i++) {
|
||||
nsDependentAtomString propName(attr->AtomAt(i));
|
||||
// ContainsInternal must not call EnsureFresh
|
||||
bool contains = mNames->ContainsInternal(propName);
|
||||
if (!contains) {
|
||||
mNames->Add(propName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Element*
|
||||
GetElementByIdForConnectedSubtree(nsIContent* aContent, const nsIAtom* aId)
|
||||
{
|
||||
aContent = static_cast<nsIContent*>(aContent->SubtreeRoot());
|
||||
do {
|
||||
if (aContent->GetID() == aId) {
|
||||
return aContent->AsElement();
|
||||
}
|
||||
aContent = aContent->GetNextNode();
|
||||
} while(aContent);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
HTMLPropertiesCollection::CrawlProperties()
|
||||
{
|
||||
nsIDocument* doc = mRoot->GetCurrentDoc();
|
||||
|
||||
const nsAttrValue* attr = mRoot->GetParsedAttr(nsGkAtoms::itemref);
|
||||
if (attr) {
|
||||
for (PRUint32 i = 0; i < attr->GetAtomCount(); i++) {
|
||||
nsIAtom* ref = attr->AtomAt(i);
|
||||
Element* element;
|
||||
if (doc) {
|
||||
element = doc->GetElementById(nsDependentAtomString(ref));
|
||||
} else {
|
||||
element = GetElementByIdForConnectedSubtree(mRoot, ref);
|
||||
}
|
||||
if (element && element != mRoot) {
|
||||
CrawlSubtree(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CrawlSubtree(mRoot);
|
||||
}
|
||||
|
||||
void
|
||||
HTMLPropertiesCollection::CrawlSubtree(Element* aElement)
|
||||
{
|
||||
nsIContent* aContent = aElement;
|
||||
while (aContent) {
|
||||
// We must check aContent against mRoot because
|
||||
// an element must not be its own property
|
||||
if (aContent == mRoot || !aContent->IsHTML()) {
|
||||
// Move on to the next node in the tree
|
||||
aContent = aContent->GetNextNode(aElement);
|
||||
} else {
|
||||
MOZ_ASSERT(aContent->IsElement(), "IsHTML() returned true!");
|
||||
Element* element = aContent->AsElement();
|
||||
if (element->HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop) &&
|
||||
!mProperties.Contains(element)) {
|
||||
mProperties.AppendElement(static_cast<nsGenericHTMLElement*>(element));
|
||||
}
|
||||
|
||||
if (element->HasAttr(kNameSpaceID_None, nsGkAtoms::itemscope)) {
|
||||
aContent = element->GetNextNonChildNode(aElement);
|
||||
} else {
|
||||
aContent = element->GetNextNode(aElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PropertyNodeList::PropertyNodeList(HTMLPropertiesCollection* aCollection,
|
||||
nsIContent* aParent, const nsAString& aName)
|
||||
: mName(aName),
|
||||
mDoc(aParent->GetCurrentDoc()),
|
||||
mCollection(aCollection),
|
||||
mParent(aParent),
|
||||
mIsDirty(true)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
if (mDoc) {
|
||||
mDoc->AddMutationObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
PropertyNodeList::~PropertyNodeList()
|
||||
{
|
||||
if (mDoc) {
|
||||
mDoc->RemoveMutationObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PropertyNodeList::SetDocument(nsIDocument* aDoc)
|
||||
{
|
||||
if (mDoc) {
|
||||
mDoc->RemoveMutationObserver(this);
|
||||
}
|
||||
mDoc = aDoc;
|
||||
if (mDoc) {
|
||||
mDoc->AddMutationObserver(this);
|
||||
}
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PropertyNodeList::GetLength(PRUint32* aLength)
|
||||
{
|
||||
EnsureFresh();
|
||||
*aLength = mElements.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PropertyNodeList::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
|
||||
{
|
||||
EnsureFresh();
|
||||
nsINode* element = mElements.SafeElementAt(aIndex);
|
||||
if (!element) {
|
||||
*aReturn = NULL;
|
||||
return NS_OK;
|
||||
}
|
||||
return CallQueryInterface(element, aReturn);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
PropertyNodeList::GetNodeAt(PRUint32 aIndex)
|
||||
{
|
||||
EnsureFresh();
|
||||
return mElements.SafeElementAt(aIndex);
|
||||
}
|
||||
|
||||
PRInt32
|
||||
PropertyNodeList::IndexOf(nsIContent* aContent)
|
||||
{
|
||||
EnsureFresh();
|
||||
return mElements.IndexOf(aContent);
|
||||
}
|
||||
|
||||
nsINode*
|
||||
PropertyNodeList::GetParentObject()
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
JSObject*
|
||||
PropertyNodeList::WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap)
|
||||
{
|
||||
return mozilla::dom::binding::PropertyNodeList::create(cx, scope, this,
|
||||
triedToWrap);
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(PropertyNodeList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(PropertyNodeList)
|
||||
// SetDocument(nsnull) ensures that we remove ourselves as a mutation observer
|
||||
tmp->SetDocument(nsnull);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(PropertyNodeList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDoc)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mCollection, nsIDOMHTMLPropertiesCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_OF_NSCOMPTR(mElements)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(PropertyNodeList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(PropertyNodeList)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(PropertyNodeList)
|
||||
|
||||
NS_INTERFACE_TABLE_HEAD(PropertyNodeList)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_TABLE4(PropertyNodeList,
|
||||
nsIDOMPropertyNodeList,
|
||||
nsIDOMNodeList,
|
||||
nsINodeList,
|
||||
nsIMutationObserver)
|
||||
NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(PropertyNodeList)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(PropertyNodeList)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMETHODIMP
|
||||
PropertyNodeList::GetValues(nsIVariant** aValues)
|
||||
{
|
||||
EnsureFresh();
|
||||
nsCOMPtr<nsIWritableVariant> out = new nsVariant();
|
||||
|
||||
// We have to use an nsTArray<nsIVariant*> here and do manual refcounting because
|
||||
// nsWritableVariant::SetAsArray takes an nsIVariant**.
|
||||
nsTArray<nsIVariant*> values;
|
||||
|
||||
PRUint32 length = mElements.Length();
|
||||
if (length == 0) {
|
||||
out->SetAsEmptyArray();
|
||||
} else {
|
||||
for (PRUint32 i = 0; i < length; ++i) {
|
||||
nsIVariant* itemValue;
|
||||
mElements.ElementAt(i)->GetItemValue(&itemValue);
|
||||
values.AppendElement(itemValue);
|
||||
}
|
||||
out->SetAsArray(nsIDataType::VTYPE_INTERFACE_IS,
|
||||
&NS_GET_IID(nsIVariant),
|
||||
values.Length(),
|
||||
values.Elements());
|
||||
}
|
||||
|
||||
out.forget(aValues);
|
||||
|
||||
for (PRUint32 i = 0; i < values.Length(); ++i) {
|
||||
NS_RELEASE(values[i]);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PropertyNodeList::AttributeChanged(nsIDocument* aDocument, Element* aElement,
|
||||
PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRInt32 aModType)
|
||||
{
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
void
|
||||
PropertyNodeList::ContentAppended(nsIDocument* aDocument, nsIContent* aContainer,
|
||||
nsIContent* aFirstNewContent,
|
||||
PRInt32 aNewIndexInContainer)
|
||||
{
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
void
|
||||
PropertyNodeList::ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
void
|
||||
PropertyNodeList::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
mIsDirty = true;
|
||||
}
|
||||
|
||||
void
|
||||
PropertyNodeList::EnsureFresh()
|
||||
{
|
||||
if (mDoc && !mIsDirty) {
|
||||
return;
|
||||
}
|
||||
mIsDirty = false;
|
||||
|
||||
mCollection->EnsureFresh();
|
||||
Clear();
|
||||
|
||||
PRUint32 count = mCollection->mProperties.Length();
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
nsGenericHTMLElement* element = mCollection->mProperties.ElementAt(i);
|
||||
const nsAttrValue* attr = element->GetParsedAttr(nsGkAtoms::itemprop);
|
||||
if (attr->Contains(mName)) {
|
||||
AppendElement(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PropertyStringList::PropertyStringList(HTMLPropertiesCollection* aCollection)
|
||||
: nsDOMStringList()
|
||||
, mCollection(aCollection)
|
||||
{ }
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(PropertyStringList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(PropertyStringList)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(PropertyStringList)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mCollection, nsIDOMHTMLPropertiesCollection)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(PropertyStringList)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(PropertyStringList)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PropertyStringList)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMDOMStringList)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMStringList)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMETHODIMP
|
||||
PropertyStringList::Item(PRUint32 aIndex, nsAString& aResult)
|
||||
{
|
||||
mCollection->EnsureFresh();
|
||||
return nsDOMStringList::Item(aIndex, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PropertyStringList::GetLength(PRUint32* aLength)
|
||||
{
|
||||
mCollection->EnsureFresh();
|
||||
return nsDOMStringList::GetLength(aLength);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PropertyStringList::Contains(const nsAString& aString, bool* aResult)
|
||||
{
|
||||
mCollection->EnsureFresh();
|
||||
return nsDOMStringList::Contains(aString, aResult);
|
||||
}
|
||||
|
||||
bool
|
||||
PropertyStringList::ContainsInternal(const nsAString& aString)
|
||||
{
|
||||
// This method should not call EnsureFresh, otherwise we may become stuck in an infinite loop.
|
||||
bool result;
|
||||
nsDOMStringList::Contains(aString, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
175
content/html/content/src/HTMLPropertiesCollection.h
Normal file
175
content/html/content/src/HTMLPropertiesCollection.h
Normal file
@ -0,0 +1,175 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set tw=80 expandtab softtabstop=2 ts=2 sw=2: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef HTMLPropertiesCollection_h_
|
||||
#define HTMLPropertiesCollection_h_
|
||||
|
||||
#include "nsDOMLists.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsIDOMHTMLPropertiesCollection.h"
|
||||
#include "nsIDOMPropertyNodeList.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIMutationObserver.h"
|
||||
#include "nsStubMutationObserver.h"
|
||||
#include "nsBaseHashtable.h"
|
||||
#include "nsINodeList.h"
|
||||
#include "nsIHTMLCollection.h"
|
||||
#include "nsHashKeys.h"
|
||||
#include "nsGenericHTMLElement.h"
|
||||
|
||||
class nsXPCClassInfo;
|
||||
class nsIDocument;
|
||||
class nsINode;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class HTMLPropertiesCollection;
|
||||
class PropertyNodeList;
|
||||
|
||||
class PropertyStringList : public nsDOMStringList
|
||||
{
|
||||
public:
|
||||
PropertyStringList(HTMLPropertiesCollection* aCollection);
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(PropertyStringList)
|
||||
NS_DECL_NSIDOMDOMSTRINGLIST
|
||||
|
||||
bool ContainsInternal(const nsAString& aString);
|
||||
|
||||
protected:
|
||||
nsRefPtr<HTMLPropertiesCollection> mCollection;
|
||||
};
|
||||
|
||||
class HTMLPropertiesCollection : public nsIDOMHTMLPropertiesCollection,
|
||||
public nsStubMutationObserver,
|
||||
public nsWrapperCache,
|
||||
public nsIHTMLCollection
|
||||
{
|
||||
friend class PropertyNodeList;
|
||||
friend class PropertyStringList;
|
||||
public:
|
||||
HTMLPropertiesCollection(nsGenericHTMLElement* aRoot);
|
||||
virtual ~HTMLPropertiesCollection();
|
||||
|
||||
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap);
|
||||
|
||||
NS_IMETHOD NamedItem(const nsAString& aName, nsIDOMNode** aResult);
|
||||
void SetDocument(nsIDocument* aDocument);
|
||||
nsINode* GetParentObject();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_NSIDOMHTMLPROPERTIESCOLLECTION
|
||||
|
||||
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(HTMLPropertiesCollection,
|
||||
nsIHTMLCollection)
|
||||
|
||||
nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
protected:
|
||||
// Make sure this collection is up to date, in case the DOM has been mutated.
|
||||
void EnsureFresh();
|
||||
|
||||
// Crawl the properties of mRoot, following any itemRefs it may have
|
||||
void CrawlProperties();
|
||||
|
||||
// Crawl startNode and its descendants, looking for items
|
||||
void CrawlSubtree(Element* startNode);
|
||||
|
||||
// the items that make up this collection
|
||||
nsTArray<nsRefPtr<nsGenericHTMLElement> > mProperties;
|
||||
|
||||
// the itemprop attribute of the properties
|
||||
nsRefPtr<PropertyStringList> mNames;
|
||||
|
||||
// The cached PropertyNodeLists that are NamedItems of this collection
|
||||
nsRefPtrHashtable<nsStringHashKey, PropertyNodeList> mNamedItemEntries;
|
||||
|
||||
// The element this collection is rooted at
|
||||
nsCOMPtr<nsGenericHTMLElement> mRoot;
|
||||
|
||||
// The document mRoot is in, if any
|
||||
nsCOMPtr<nsIDocument> mDoc;
|
||||
|
||||
// True if there have been DOM modifications since the last EnsureFresh call.
|
||||
bool mIsDirty;
|
||||
};
|
||||
|
||||
class PropertyNodeList : public nsINodeList,
|
||||
public nsIDOMPropertyNodeList,
|
||||
public nsStubMutationObserver
|
||||
{
|
||||
public:
|
||||
PropertyNodeList(HTMLPropertiesCollection* aCollection,
|
||||
nsIContent* aRoot, const nsAString& aName);
|
||||
virtual ~PropertyNodeList();
|
||||
|
||||
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
|
||||
bool *triedToWrap);
|
||||
|
||||
void SetDocument(nsIDocument* aDocument);
|
||||
|
||||
NS_DECL_NSIDOMPROPERTYNODELIST
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(PropertyNodeList,
|
||||
nsINodeList)
|
||||
|
||||
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
||||
|
||||
// nsINodeList interface
|
||||
virtual PRInt32 IndexOf(nsIContent* aContent);
|
||||
virtual nsINode* GetParentObject();
|
||||
|
||||
void AppendElement(nsGenericHTMLElement* aElement)
|
||||
{
|
||||
mElements.AppendElement(aElement);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
mElements.Clear();
|
||||
}
|
||||
|
||||
void SetDirty() { mIsDirty = true; }
|
||||
|
||||
protected:
|
||||
// Make sure this list is up to date, in case the DOM has been mutated.
|
||||
void EnsureFresh();
|
||||
|
||||
// the the name that this list corresponds to
|
||||
nsString mName;
|
||||
|
||||
// the document mParent is in, if any
|
||||
nsCOMPtr<nsIDocument> mDoc;
|
||||
|
||||
// the collection that this list is a named item of
|
||||
nsRefPtr<HTMLPropertiesCollection> mCollection;
|
||||
|
||||
// the node this list is rooted at
|
||||
nsCOMPtr<nsINode> mParent;
|
||||
|
||||
// the properties that make up this list
|
||||
nsTArray<nsRefPtr<nsGenericHTMLElement> > mElements;
|
||||
|
||||
// True if there have been DOM modifications since the last EnsureFresh call.
|
||||
bool mIsDirty;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
#endif // HTMLPropertiesCollection_h_
|
@ -22,6 +22,7 @@ EXPORTS = \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
HTMLPropertiesCollection.cpp \
|
||||
nsClientRect.cpp \
|
||||
nsHTMLDNSPrefetch.cpp \
|
||||
nsGenericHTMLElement.cpp \
|
||||
|
@ -91,6 +91,9 @@
|
||||
#include "mozilla/dom/FromParser.h"
|
||||
#include "mozilla/BloomFilter.h"
|
||||
|
||||
#include "HTMLPropertiesCollection.h"
|
||||
#include "nsVariant.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
@ -248,7 +251,6 @@ NS_INTERFACE_TABLE_HEAD(nsGenericHTMLElementTearoff)
|
||||
NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsGenericHTMLElementTearoff)
|
||||
NS_INTERFACE_MAP_END_AGGREGATED(mElement)
|
||||
|
||||
|
||||
NS_IMPL_INT_ATTR_DEFAULT_VALUE(nsGenericHTMLElement, TabIndex, tabindex, -1)
|
||||
NS_IMPL_BOOL_ATTR(nsGenericHTMLElement, Hidden, hidden)
|
||||
|
||||
@ -1699,6 +1701,13 @@ nsGenericHTMLElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aDocument) {
|
||||
if (HasProperties()) {
|
||||
HTMLPropertiesCollection* properties =
|
||||
static_cast<HTMLPropertiesCollection*>(GetProperty(nsGkAtoms::microdataProperties));
|
||||
if (properties) {
|
||||
properties->SetDocument(aDocument);
|
||||
}
|
||||
}
|
||||
RegAccessKey();
|
||||
if (HasName()) {
|
||||
aDocument->
|
||||
@ -1721,6 +1730,14 @@ nsGenericHTMLElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
if (IsInDoc()) {
|
||||
UnregAccessKey();
|
||||
}
|
||||
|
||||
if(HasProperties()) {
|
||||
HTMLPropertiesCollection* properties =
|
||||
static_cast<HTMLPropertiesCollection*>(GetProperty(nsGkAtoms::microdataProperties));
|
||||
if (properties) {
|
||||
properties->SetDocument(nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
RemoveFromNameTable();
|
||||
|
||||
@ -2073,6 +2090,13 @@ nsGenericHTMLElement::ParseAttribute(PRInt32 aNamespaceID,
|
||||
aResult.ParseAtom(aValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (aAttribute == nsGkAtoms::itemref ||
|
||||
aAttribute == nsGkAtoms::itemprop ||
|
||||
aAttribute == nsGkAtoms::itemtype) {
|
||||
aResult.ParseAtomArray(aValue);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElementBase::ParseAttribute(aNamespaceID, aAttribute,
|
||||
@ -4081,3 +4105,162 @@ nsGenericHTMLElement::ChangeEditableState(PRInt32 aChange)
|
||||
nsAutoScriptBlocker scriptBlocker;
|
||||
MakeContentDescendantsEditable(this, document);
|
||||
}
|
||||
|
||||
NS_IMPL_BOOL_ATTR(nsGenericHTMLElement, ItemScope, itemscope)
|
||||
NS_IMPL_URI_ATTR(nsGenericHTMLElement, ItemId, itemid)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLElement::GetItemValue(nsIVariant** aValue)
|
||||
{
|
||||
nsCOMPtr<nsIWritableVariant> out = new nsVariant();
|
||||
|
||||
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop)) {
|
||||
out->SetAsEmpty();
|
||||
out.forget(aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool itemScope;
|
||||
GetItemScope(&itemScope);
|
||||
if (itemScope) {
|
||||
out->SetAsISupports(static_cast<nsISupports*>(this));
|
||||
} else {
|
||||
nsAutoString string;
|
||||
GetItemValueText(string);
|
||||
out->SetAsAString(string);
|
||||
}
|
||||
|
||||
out.forget(aValue);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLElement::SetItemValue(nsIVariant* aValue)
|
||||
{
|
||||
if (!HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop) ||
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::itemscope)) {
|
||||
return NS_ERROR_DOM_INVALID_ACCESS_ERR;
|
||||
}
|
||||
|
||||
nsAutoString string;
|
||||
aValue->GetAsAString(string);
|
||||
SetItemValueText(string);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLElement::GetItemValueText(nsAString& text)
|
||||
{
|
||||
GetTextContent(text);
|
||||
}
|
||||
|
||||
void
|
||||
nsGenericHTMLElement::SetItemValueText(const nsAString& text)
|
||||
{
|
||||
SetTextContent(text);
|
||||
}
|
||||
|
||||
static void
|
||||
nsDOMSettableTokenListPropertyDestructor(void *aObject, nsIAtom *aProperty,
|
||||
void *aPropertyValue, void *aData)
|
||||
{
|
||||
nsDOMSettableTokenList* list =
|
||||
static_cast<nsDOMSettableTokenList*>(aPropertyValue);
|
||||
NS_IF_RELEASE(list);
|
||||
}
|
||||
|
||||
nsDOMSettableTokenList*
|
||||
nsGenericHTMLElement::GetTokenList(nsIAtom* aAtom)
|
||||
{
|
||||
nsDOMSettableTokenList* list = NULL;
|
||||
if (HasProperties()) {
|
||||
list = static_cast<nsDOMSettableTokenList*>(GetProperty(aAtom));
|
||||
}
|
||||
if (!list) {
|
||||
list = new nsDOMSettableTokenList(this, aAtom);
|
||||
NS_ADDREF(list);
|
||||
SetProperty(aAtom, list, nsDOMSettableTokenListPropertyDestructor);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLElement::GetItemRef(nsIVariant** aResult)
|
||||
{
|
||||
nsIDOMDOMSettableTokenList* itemRef = GetTokenList(nsGkAtoms::itemref);
|
||||
nsCOMPtr<nsIWritableVariant> out = new nsVariant();
|
||||
out->SetAsInterface(NS_GET_IID(nsIDOMDOMSettableTokenList), itemRef);
|
||||
out.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLElement::SetItemRef(nsIVariant* aValue)
|
||||
{
|
||||
nsDOMSettableTokenList* itemRef = GetTokenList(nsGkAtoms::itemref);
|
||||
nsAutoString string;
|
||||
aValue->GetAsAString(string);
|
||||
return itemRef->SetValue(string);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLElement::GetItemProp(nsIVariant** aResult)
|
||||
{
|
||||
nsIDOMDOMSettableTokenList* itemProp = GetTokenList(nsGkAtoms::itemprop);
|
||||
nsCOMPtr<nsIWritableVariant> out = new nsVariant();
|
||||
out->SetAsInterface(NS_GET_IID(nsIDOMDOMSettableTokenList), itemProp);
|
||||
out.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLElement::SetItemProp(nsIVariant* aValue)
|
||||
{
|
||||
nsDOMSettableTokenList* itemProp = GetTokenList(nsGkAtoms::itemprop);
|
||||
nsAutoString string;
|
||||
aValue->GetAsAString(string);
|
||||
return itemProp->SetValue(string);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLElement::GetItemType(nsIVariant** aResult)
|
||||
{
|
||||
nsIDOMDOMSettableTokenList* itemType = GetTokenList(nsGkAtoms::itemtype);
|
||||
nsCOMPtr<nsIWritableVariant> out = new nsVariant();
|
||||
out->SetAsInterface(NS_GET_IID(nsIDOMDOMSettableTokenList), itemType);
|
||||
out.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLElement::SetItemType(nsIVariant* aValue)
|
||||
{
|
||||
nsDOMSettableTokenList* itemType = GetTokenList(nsGkAtoms::itemtype);
|
||||
nsAutoString string;
|
||||
aValue->GetAsAString(string);
|
||||
return itemType->SetValue(string);
|
||||
}
|
||||
|
||||
static void
|
||||
nsIDOMHTMLPropertiesCollectionDestructor(void *aObject, nsIAtom *aProperty,
|
||||
void *aPropertyValue, void *aData)
|
||||
{
|
||||
nsIDOMHTMLPropertiesCollection* properties =
|
||||
static_cast<nsIDOMHTMLPropertiesCollection*>(aPropertyValue);
|
||||
NS_IF_RELEASE(properties);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLElement::GetProperties(nsIDOMHTMLPropertiesCollection** aReturn)
|
||||
{
|
||||
nsIDOMHTMLPropertiesCollection* properties =
|
||||
static_cast<nsIDOMHTMLPropertiesCollection*>(GetProperty(nsGkAtoms::microdataProperties));
|
||||
if (!properties) {
|
||||
properties = new HTMLPropertiesCollection(this);
|
||||
NS_ADDREF(properties);
|
||||
SetProperty(nsGkAtoms::microdataProperties, properties, nsIDOMHTMLPropertiesCollectionDestructor);
|
||||
}
|
||||
NS_ADDREF(*aReturn = properties);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsDOMSettableTokenList.h"
|
||||
#include "nsIDOMHTMLPropertiesCollection.h"
|
||||
|
||||
class nsIDOMAttr;
|
||||
class nsIDOMEventListener;
|
||||
@ -33,6 +35,7 @@ struct nsSize;
|
||||
class nsHTMLFormElement;
|
||||
class nsIDOMDOMStringMap;
|
||||
class nsIDOMHTMLMenuElement;
|
||||
class nsIDOMHTMLCollection;
|
||||
|
||||
typedef nsMappedAttributeElement nsGenericHTMLElementBase;
|
||||
|
||||
@ -114,6 +117,26 @@ public:
|
||||
NS_IMETHOD SetSpellcheck(bool aSpellcheck);
|
||||
NS_IMETHOD GetDraggable(bool* aDraggable);
|
||||
NS_IMETHOD SetDraggable(bool aDraggable);
|
||||
NS_IMETHOD GetItemScope(bool* aItemScope);
|
||||
NS_IMETHOD SetItemScope(bool aItemScope);
|
||||
NS_IMETHOD GetItemValue(nsIVariant** aValue);
|
||||
NS_IMETHOD SetItemValue(nsIVariant* aValue);
|
||||
protected:
|
||||
// These methods are used to implement element-specific behavior of Get/SetItemValue
|
||||
// when an element has @itemprop but no @itemscope.
|
||||
virtual void GetItemValueText(nsAString& text);
|
||||
virtual void SetItemValueText(const nsAString& text);
|
||||
nsDOMSettableTokenList* GetTokenList(nsIAtom* aAtom);
|
||||
public:
|
||||
NS_IMETHOD GetItemType(nsIVariant** aType);
|
||||
NS_IMETHOD SetItemType(nsIVariant* aType);
|
||||
NS_IMETHOD GetItemId(nsAString& aId);
|
||||
NS_IMETHOD SetItemId(const nsAString& aId);
|
||||
NS_IMETHOD GetItemRef(nsIVariant** aRef);
|
||||
NS_IMETHOD SetItemRef(nsIVariant* aValue);
|
||||
NS_IMETHOD GetItemProp(nsIVariant** aProp);
|
||||
NS_IMETHOD SetItemProp(nsIVariant* aValue);
|
||||
NS_IMETHOD GetProperties(nsIDOMHTMLPropertiesCollection** aReturn);
|
||||
NS_IMETHOD GetAccessKey(nsAString &aAccessKey);
|
||||
NS_IMETHOD SetAccessKey(const nsAString& aAccessKey);
|
||||
NS_IMETHOD GetAccessKeyLabel(nsAString& aLabel);
|
||||
@ -771,9 +794,6 @@ private:
|
||||
void ChangeEditableState(PRInt32 aChange);
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
class nsHTMLFieldSetElement;
|
||||
|
||||
/**
|
||||
@ -1376,6 +1396,45 @@ PR_STATIC_ASSERT(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + 1 < 32);
|
||||
NS_SCRIPTABLE NS_IMETHOD Blur() { \
|
||||
return _to Blur(); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetItemScope(bool* aItemScope) { \
|
||||
return _to GetItemScope(aItemScope); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetItemScope(bool aItemScope) { \
|
||||
return _to SetItemScope(aItemScope); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetItemType(nsIVariant** aType) { \
|
||||
return _to GetItemType(aType); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetItemType(nsIVariant* aType) { \
|
||||
return _to SetItemType(aType); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetItemId(nsAString& aId) { \
|
||||
return _to GetItemId(aId); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetItemId(const nsAString& aId) { \
|
||||
return _to SetItemId(aId); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetProperties(nsIDOMHTMLPropertiesCollection** aReturn) { \
|
||||
return _to GetProperties(aReturn); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetItemValue(nsIVariant** aValue) { \
|
||||
return _to GetItemValue(aValue); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetItemValue(nsIVariant* aValue) { \
|
||||
return _to SetItemValue(aValue); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetItemRef(nsIVariant** aRef) { \
|
||||
return _to GetItemRef(aRef); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetItemRef(nsIVariant* aRef) { \
|
||||
return _to SetItemRef(aRef); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetItemProp(nsIVariant** aProp) { \
|
||||
return _to GetItemProp(aProp); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD SetItemProp(nsIVariant* aProp) { \
|
||||
return _to SetItemProp(aProp); \
|
||||
} \
|
||||
NS_SCRIPTABLE NS_IMETHOD GetAccessKey(nsAString& aAccessKey) { \
|
||||
return _to GetAccessKey(aAccessKey); \
|
||||
} \
|
||||
|
@ -110,6 +110,10 @@ public:
|
||||
virtual void OnDNSPrefetchDeferred();
|
||||
virtual void OnDNSPrefetchRequested();
|
||||
virtual bool HasDeferredDNSPrefetchRequest();
|
||||
|
||||
protected:
|
||||
virtual void GetItemValueText(nsAString& text);
|
||||
virtual void SetItemValueText(const nsAString& text);
|
||||
};
|
||||
|
||||
// Indicates that a DNS Prefetch has been requested from this Anchor elem
|
||||
@ -166,6 +170,18 @@ NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Shape, shape)
|
||||
NS_IMPL_INT_ATTR(nsHTMLAnchorElement, TabIndex, tabindex)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Type, type)
|
||||
|
||||
void
|
||||
nsHTMLAnchorElement::GetItemValueText(nsAString& aValue)
|
||||
{
|
||||
GetHref(aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLAnchorElement::SetItemValueText(const nsAString& aValue)
|
||||
{
|
||||
SetHref(aValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAnchorElement::GetDraggable(bool* aDraggable)
|
||||
{
|
||||
|
@ -95,6 +95,10 @@ public:
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
virtual nsIDOMNode* AsDOMNode() { return this; }
|
||||
|
||||
protected:
|
||||
virtual void GetItemValueText(nsAString& text);
|
||||
virtual void SetItemValueText(const nsAString& text);
|
||||
};
|
||||
|
||||
|
||||
@ -137,6 +141,18 @@ NS_IMPL_BOOL_ATTR(nsHTMLAreaElement, NoHref, nohref)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLAreaElement, Shape, shape)
|
||||
NS_IMPL_INT_ATTR(nsHTMLAreaElement, TabIndex, tabindex)
|
||||
|
||||
void
|
||||
nsHTMLAreaElement::GetItemValueText(nsAString& aValue)
|
||||
{
|
||||
GetHref(aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLAreaElement::SetItemValueText(const nsAString& aValue)
|
||||
{
|
||||
SetHref(aValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAreaElement::GetTarget(nsAString& aValue)
|
||||
{
|
||||
|
@ -83,6 +83,20 @@ nsHTMLAudioElement::~nsHTMLAudioElement()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLAudioElement::GetItemValueText(nsAString& aValue)
|
||||
{
|
||||
// Can't call GetSrc because we don't have a JSContext
|
||||
GetURIAttr(nsGkAtoms::src, nsnull, aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLAudioElement::SetItemValueText(const nsAString& aValue)
|
||||
{
|
||||
// Can't call SetSrc because we don't have a JSContext
|
||||
SetAttr(kNameSpaceID_None, nsGkAtoms::src, aValue, true);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLAudioElement::Initialize(nsISupports* aOwner, JSContext* aContext,
|
||||
JSObject *aObj, PRUint32 argc, jsval *argv)
|
||||
|
@ -58,6 +58,10 @@ public:
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
virtual nsIDOMNode* AsDOMNode() { return this; }
|
||||
|
||||
protected:
|
||||
virtual void GetItemValueText(nsAString& text);
|
||||
virtual void SetItemValueText(const nsAString& text);
|
||||
};
|
||||
|
||||
|
||||
@ -106,6 +110,18 @@ NS_IMPL_URI_ATTR(nsHTMLIFrameElement, Src, src)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Width, width)
|
||||
NS_IMPL_BOOL_ATTR(nsHTMLIFrameElement, MozAllowFullScreen, mozallowfullscreen)
|
||||
|
||||
void
|
||||
nsHTMLIFrameElement::GetItemValueText(nsAString& aValue)
|
||||
{
|
||||
GetSrc(aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLIFrameElement::SetItemValueText(const nsAString& aValue)
|
||||
{
|
||||
SetSrc(aValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLIFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
|
||||
{
|
||||
|
@ -116,6 +116,18 @@ NS_IMPL_URI_ATTR(nsHTMLImageElement, Src, src)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLImageElement, UseMap, usemap)
|
||||
NS_IMPL_INT_ATTR(nsHTMLImageElement, Vspace, vspace)
|
||||
|
||||
void
|
||||
nsHTMLImageElement::GetItemValueText(nsAString& aValue)
|
||||
{
|
||||
GetSrc(aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLImageElement::SetItemValueText(const nsAString& aValue)
|
||||
{
|
||||
SetSrc(aValue);
|
||||
}
|
||||
|
||||
// crossorigin is not "limited to only known values" per spec, so it's
|
||||
// just a string attr purposes of the DOM crossOrigin property.
|
||||
NS_IMPL_STRING_ATTR(nsHTMLImageElement, CrossOrigin, crossorigin)
|
||||
|
@ -103,6 +103,8 @@ public:
|
||||
protected:
|
||||
nsIntPoint GetXY();
|
||||
nsSize GetWidthHeight();
|
||||
virtual void GetItemValueText(nsAString& text);
|
||||
virtual void SetItemValueText(const nsAString& text);
|
||||
};
|
||||
|
||||
#endif /* nsHTMLImageElement_h */
|
||||
|
@ -95,6 +95,9 @@ protected:
|
||||
nsAString& aType,
|
||||
nsAString& aMedia,
|
||||
bool* aIsAlternate);
|
||||
protected:
|
||||
virtual void GetItemValueText(nsAString& text);
|
||||
virtual void SetItemValueText(const nsAString& text);
|
||||
};
|
||||
|
||||
|
||||
@ -172,6 +175,18 @@ NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Rev, rev)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Target, target)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Type, type)
|
||||
|
||||
void
|
||||
nsHTMLLinkElement::GetItemValueText(nsAString& aValue)
|
||||
{
|
||||
GetHref(aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLLinkElement::SetItemValueText(const nsAString& aValue)
|
||||
{
|
||||
SetHref(aValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLLinkElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
|
@ -45,6 +45,10 @@ public:
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
virtual nsIDOMNode* AsDOMNode() { return this; }
|
||||
|
||||
protected:
|
||||
virtual void GetItemValueText(nsAString& text);
|
||||
virtual void SetItemValueText(const nsAString& text);
|
||||
};
|
||||
|
||||
|
||||
@ -83,6 +87,19 @@ NS_IMPL_STRING_ATTR(nsHTMLMetaElement, HttpEquiv, httpEquiv)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLMetaElement, Name, name)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLMetaElement, Scheme, scheme)
|
||||
|
||||
void
|
||||
nsHTMLMetaElement::GetItemValueText(nsAString& aValue)
|
||||
{
|
||||
GetContent(aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLMetaElement::SetItemValueText(const nsAString& aValue)
|
||||
{
|
||||
SetContent(aValue);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsHTMLMetaElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
|
@ -136,6 +136,9 @@ private:
|
||||
* value. This is used to know the default tabindex value.
|
||||
*/
|
||||
bool IsFocusableForTabIndex();
|
||||
|
||||
virtual void GetItemValueText(nsAString& text);
|
||||
virtual void SetItemValueText(const nsAString& text);
|
||||
|
||||
bool mIsDoneAddingChildren;
|
||||
};
|
||||
@ -224,6 +227,18 @@ nsHTMLObjectElement::GetForm(nsIDOMHTMLFormElement **aForm)
|
||||
return nsGenericHTMLFormElement::GetForm(aForm);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLObjectElement::GetItemValueText(nsAString& aValue)
|
||||
{
|
||||
GetData(aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLObjectElement::SetItemValueText(const nsAString& aValue)
|
||||
{
|
||||
SetData(aValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLObjectElement::BindToTree(nsIDocument *aDocument,
|
||||
nsIContent *aParent,
|
||||
|
@ -153,6 +153,9 @@ private:
|
||||
// mIsDoneAddingChildren is only really used for <applet>. This boolean is
|
||||
// always true for <embed>, per the documentation in nsIContent.h.
|
||||
bool mIsDoneAddingChildren;
|
||||
|
||||
virtual void GetItemValueText(nsAString& text);
|
||||
virtual void SetItemValueText(const nsAString& text);
|
||||
};
|
||||
|
||||
|
||||
@ -171,6 +174,26 @@ nsHTMLSharedObjectElement::nsHTMLSharedObjectElement(already_AddRefed<nsINodeInf
|
||||
AddStatesSilently(NS_EVENT_STATE_LOADING);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLSharedObjectElement::GetItemValueText(nsAString& aValue)
|
||||
{
|
||||
if (mNodeInfo->Equals(nsGkAtoms::applet)) {
|
||||
nsGenericHTMLElement::GetItemValueText(aValue);
|
||||
} else {
|
||||
GetSrc(aValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLSharedObjectElement::SetItemValueText(const nsAString& aValue)
|
||||
{
|
||||
if (mNodeInfo->Equals(nsGkAtoms::applet)) {
|
||||
nsGenericHTMLElement::SetItemValueText(aValue);
|
||||
} else {
|
||||
SetSrc(aValue);
|
||||
}
|
||||
}
|
||||
|
||||
nsHTMLSharedObjectElement::~nsHTMLSharedObjectElement()
|
||||
{
|
||||
UnregisterFreezableElement();
|
||||
|
@ -47,6 +47,10 @@ public:
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
virtual nsIDOMNode* AsDOMNode() { return this; }
|
||||
|
||||
protected:
|
||||
virtual void GetItemValueText(nsAString& text);
|
||||
virtual void SetItemValueText(const nsAString& text);
|
||||
};
|
||||
|
||||
|
||||
@ -84,6 +88,18 @@ NS_IMPL_URI_ATTR(nsHTMLSourceElement, Src, src)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLSourceElement, Type, type)
|
||||
NS_IMPL_STRING_ATTR(nsHTMLSourceElement, Media, media)
|
||||
|
||||
void
|
||||
nsHTMLSourceElement::GetItemValueText(nsAString& aValue)
|
||||
{
|
||||
GetSrc(aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLSourceElement::SetItemValueText(const nsAString& aValue)
|
||||
{
|
||||
SetSrc(aValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLSourceElement::BindToTree(nsIDocument *aDocument,
|
||||
nsIContent *aParent,
|
||||
|
@ -80,6 +80,20 @@ nsHTMLVideoElement::~nsHTMLVideoElement()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLVideoElement::GetItemValueText(nsAString& aValue)
|
||||
{
|
||||
// Can't call GetSrc because we don't have a JSContext
|
||||
GetURIAttr(nsGkAtoms::src, nsnull, aValue);
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLVideoElement::SetItemValueText(const nsAString& aValue)
|
||||
{
|
||||
// Can't call SetSrc because we don't have a JSContext
|
||||
SetAttr(kNameSpaceID_None, nsGkAtoms::src, aValue, true);
|
||||
}
|
||||
|
||||
nsresult nsHTMLVideoElement::GetVideoSize(nsIntSize* size)
|
||||
{
|
||||
if (mMediaSize.width == -1 && mMediaSize.height == -1) {
|
||||
|
@ -1765,6 +1765,84 @@ nsHTMLDocument::GetElementsByName(const nsAString& aElementName,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static bool MatchItems(nsIContent* aContent, PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAtom, void* aData)
|
||||
{
|
||||
if (!(aContent->IsElement() && aContent->AsElement()->IsHTML())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsGenericHTMLElement* elem = static_cast<nsGenericHTMLElement*>(aContent);
|
||||
if (!elem->HasAttr(kNameSpaceID_None, nsGkAtoms::itemscope) ||
|
||||
elem->HasAttr(kNameSpaceID_None, nsGkAtoms::itemprop)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsTArray<nsCOMPtr<nsIAtom> >* tokens = static_cast<nsTArray<nsCOMPtr<nsIAtom> >*>(aData);
|
||||
if (tokens->IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const nsAttrValue* attr = elem->GetParsedAttr(nsGkAtoms::itemtype);
|
||||
if (!attr)
|
||||
return false;
|
||||
|
||||
for (PRUint32 i = 0; i < tokens->Length(); i++) {
|
||||
if (!attr->Contains(tokens->ElementAt(i), eCaseMatters)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void DestroyTokens(void* aData)
|
||||
{
|
||||
nsTArray<nsCOMPtr<nsIAtom> >* tokens = static_cast<nsTArray<nsCOMPtr<nsIAtom> >*>(aData);
|
||||
delete tokens;
|
||||
}
|
||||
|
||||
static void* CreateTokens(nsINode* aRootNode, const nsString* types)
|
||||
{
|
||||
nsTArray<nsCOMPtr<nsIAtom> >* tokens = new nsTArray<nsCOMPtr<nsIAtom> >();
|
||||
nsAString::const_iterator iter, end;
|
||||
types->BeginReading(iter);
|
||||
types->EndReading(end);
|
||||
|
||||
// skip initial whitespace
|
||||
while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
|
||||
++iter;
|
||||
}
|
||||
|
||||
// parse the tokens
|
||||
while (iter != end) {
|
||||
nsAString::const_iterator start(iter);
|
||||
|
||||
do {
|
||||
++iter;
|
||||
} while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter));
|
||||
|
||||
tokens->AppendElement(do_GetAtom(Substring(start, iter)));
|
||||
|
||||
// skip whitespace
|
||||
while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
return tokens;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLDocument::GetItems(const nsAString& types, nsIDOMNodeList** aReturn)
|
||||
{
|
||||
nsRefPtr<nsContentList> elements =
|
||||
NS_GetFuncStringContentList(this, MatchItems, DestroyTokens,
|
||||
CreateTokens, types);
|
||||
NS_ENSURE_TRUE(elements, NS_ERROR_OUT_OF_MEMORY);
|
||||
elements.forget(aReturn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsHTMLDocument::AddedForm()
|
||||
{
|
||||
|
@ -112,7 +112,6 @@ public:
|
||||
UseExistingNameString, aName);
|
||||
}
|
||||
|
||||
|
||||
virtual nsresult ResolveName(const nsAString& aName,
|
||||
nsIContent *aForm,
|
||||
nsISupports **aResult,
|
||||
|
@ -278,7 +278,7 @@ nsresult nsGStreamerReader::ReadMetadata(nsVideoInfo* aInfo)
|
||||
if (gst_element_query_duration(GST_ELEMENT(mPlayBin),
|
||||
&format, &duration) && format == GST_FORMAT_TIME) {
|
||||
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
|
||||
LOG(PR_LOG_DEBUG, ("returning duration %"GST_TIME_FORMAT,
|
||||
LOG(PR_LOG_DEBUG, ("returning duration %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (duration)));
|
||||
duration = GST_TIME_AS_USECONDS (duration);
|
||||
mDecoder->GetStateMachine()->SetDuration(duration);
|
||||
@ -422,8 +422,8 @@ bool nsGStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
|
||||
nextTimestamp += gst_util_uint64_scale(GST_USECOND, fpsNum, fpsDen);
|
||||
|
||||
if (timestamp < aTimeThreshold) {
|
||||
LOG(PR_LOG_DEBUG, ("skipping frame %"GST_TIME_FORMAT
|
||||
" threshold %"GST_TIME_FORMAT,
|
||||
LOG(PR_LOG_DEBUG, ("skipping frame %" GST_TIME_FORMAT
|
||||
" threshold %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS(timestamp), GST_TIME_ARGS(aTimeThreshold)));
|
||||
gst_buffer_unref(buffer);
|
||||
buffer = NULL;
|
||||
@ -452,6 +452,8 @@ bool nsGStreamerReader::DecodeVideoFrame(bool &aKeyFrameSkip,
|
||||
i, height);
|
||||
b.mPlanes[i].mWidth = gst_video_format_get_component_width(format,
|
||||
i, width);
|
||||
b.mPlanes[i].mOffset = 0;
|
||||
b.mPlanes[i].mSkip = 0;
|
||||
}
|
||||
|
||||
bool isKeyframe = !GST_BUFFER_FLAG_IS_SET(buffer,
|
||||
@ -487,7 +489,7 @@ nsresult nsGStreamerReader::Seek(PRInt64 aTarget,
|
||||
NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");
|
||||
|
||||
gint64 seekPos = aTarget * GST_USECOND;
|
||||
LOG(PR_LOG_DEBUG, ("%p About to seek to %"GST_TIME_FORMAT,
|
||||
LOG(PR_LOG_DEBUG, ("%p About to seek to %" GST_TIME_FORMAT,
|
||||
mDecoder, GST_TIME_ARGS(seekPos)));
|
||||
|
||||
if (!gst_element_seek_simple(mPlayBin, GST_FORMAT_TIME,
|
||||
@ -590,7 +592,7 @@ PRInt64 nsGStreamerReader::QueryDuration()
|
||||
if (gst_element_query_duration(GST_ELEMENT(mPlayBin),
|
||||
&format, &duration)) {
|
||||
if (format == GST_FORMAT_TIME) {
|
||||
LOG(PR_LOG_DEBUG, ("pipeline duration %"GST_TIME_FORMAT,
|
||||
LOG(PR_LOG_DEBUG, ("pipeline duration %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (duration)));
|
||||
duration = GST_TIME_AS_USECONDS (duration);
|
||||
}
|
||||
|
@ -828,6 +828,11 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(HTMLCollection, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(HTMLPropertiesCollection, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(PropertyNodeList,
|
||||
nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
// HTML element classes
|
||||
NS_DEFINE_CLASSINFO_DATA(HTMLElement, nsElementSH,
|
||||
@ -2731,6 +2736,16 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLCollection)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(HTMLPropertiesCollection, nsIDOMHTMLPropertiesCollection)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLPropertiesCollection)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLCollection)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(PropertyNodeList, nsIDOMPropertyNodeList)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMPropertyNodeList)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeList)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(HTMLElement, nsIDOMHTMLElement)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMHTMLElement)
|
||||
DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES
|
||||
|
@ -58,6 +58,8 @@ DOMCI_CLASS(DeviceRotationRate)
|
||||
DOMCI_CLASS(HTMLDocument)
|
||||
DOMCI_CLASS(HTMLOptionsCollection)
|
||||
DOMCI_CLASS(HTMLCollection)
|
||||
DOMCI_CLASS(HTMLPropertiesCollection)
|
||||
DOMCI_CLASS(PropertyNodeList)
|
||||
|
||||
// HTML element classes
|
||||
DOMCI_CLASS(HTMLElement)
|
||||
|
@ -232,7 +232,7 @@ DOMInterfaces = {
|
||||
'multipart', 'channel', 'upload', 'status'
|
||||
],
|
||||
'getterOnly': [
|
||||
'responseType', 'timeout', 'onreadystatechange'
|
||||
'responseType', 'timeout', 'onreadystatechange', 'onuploadprogress'
|
||||
]
|
||||
},
|
||||
# XXXbz need a JSContext for send() and sendAsBinary because of
|
||||
|
@ -88,6 +88,9 @@ class Location(object):
|
||||
self._line = self._lexdata[startofline:]
|
||||
self._colno = self._lexpos - startofline
|
||||
|
||||
# Our line number seems to point to the start of self._lexdata
|
||||
self._lineno += self._lexdata.count('\n', 0, startofline)
|
||||
|
||||
def get(self):
|
||||
self.resolve()
|
||||
return "%s line %s:%s" % (self._file, self._lineno, self._colno)
|
||||
@ -460,6 +463,10 @@ class IDLInterface(IDLObjectWithScope):
|
||||
for member in self.members:
|
||||
member.finish(scope)
|
||||
|
||||
ctor = self.ctor()
|
||||
if ctor is not None:
|
||||
ctor.finish(scope)
|
||||
|
||||
def isInterface(self):
|
||||
return True
|
||||
|
||||
@ -2919,7 +2926,7 @@ class Parser(Tokenizer):
|
||||
self.lexer.input(Parser._builtins)
|
||||
self._filename = None
|
||||
|
||||
self.parser.parse(lexer=self.lexer)
|
||||
self.parser.parse(lexer=self.lexer,tracking=True)
|
||||
|
||||
def _installBuiltins(self, scope):
|
||||
assert isinstance(scope, IDLScope)
|
||||
@ -2939,7 +2946,7 @@ class Parser(Tokenizer):
|
||||
# print tok
|
||||
|
||||
self._filename = filename
|
||||
self._productions.extend(self.parser.parse(lexer=self.lexer))
|
||||
self._productions.extend(self.parser.parse(lexer=self.lexer,tracking=True))
|
||||
self._filename = None
|
||||
|
||||
def finish(self):
|
||||
|
29
dom/bindings/parser/tests/test_error_lineno.py
Normal file
29
dom/bindings/parser/tests/test_error_lineno.py
Normal file
@ -0,0 +1,29 @@
|
||||
import WebIDL
|
||||
|
||||
def WebIDLTest(parser, harness):
|
||||
# Check that error messages put the '^' in the right place.
|
||||
|
||||
threw = False
|
||||
input = """\
|
||||
// This is a comment.
|
||||
interface Foo {
|
||||
};
|
||||
|
||||
/* This is also a comment. */
|
||||
interface ?"""
|
||||
try:
|
||||
parser.parse(input)
|
||||
results = parser.finish()
|
||||
except WebIDL.WebIDLError as e:
|
||||
threw = True
|
||||
lines = str(e).split('\n')
|
||||
print lines
|
||||
|
||||
harness.check(len(lines), 3, 'Expected number of lines in error message')
|
||||
harness.ok(lines[0].endswith('line 6:10'), 'First line of error should end with "line 6:10", but was "%s".' % lines[0])
|
||||
harness.check(lines[1], 'interface ?', 'Second line of error message is the line which caused the error.')
|
||||
harness.check(lines[2], ' ' * (len('interface ?') - 1) + '^',
|
||||
'Correct column pointer in error message.')
|
||||
|
||||
harness.ok(threw, "Should have thrown.")
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user