Merge m-c to Ionmonkey.
Merge m-c to Ionmonkey.
--- a/accessible/src/base/Makefile.in
+++ b/accessible/src/base/Makefile.in
@@ -26,17 +26,16 @@ CPPSRCS = \
nsAccDocManager.cpp \
nsAccessNode.cpp \
nsARIAMap.cpp \
nsCoreUtils.cpp \
nsAccUtils.cpp \
nsAccessibilityService.cpp \
nsAccessiblePivot.cpp \
nsAccTreeWalker.cpp \
- nsBaseWidgetAccessible.cpp \
nsEventShell.cpp \
nsCaretAccessible.cpp \
nsTextEquivUtils.cpp \
RoleAsserts.cpp \
StyleInfo.cpp \
TextAttrs.cpp \
TextUpdater.cpp \
$(NULL)
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -10,25 +10,25 @@
#include "ApplicationAccessibleWrap.h"
#include "ARIAGridAccessibleWrap.h"
#ifdef MOZ_ACCESSIBILITY_ATK
#include "AtkSocketAccessible.h"
#endif
#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"
#include "nsAccUtils.h"
#include "nsARIAMap.h"
#include "nsIAccessibleProvider.h"
#include "nsHTMLCanvasAccessible.h"
-#include "nsHTMLImageMapAccessible.h"
-#include "nsHTMLLinkAccessible.h"
#include "nsHTMLSelectAccessible.h"
#include "nsHTMLTableAccessibleWrap.h"
#include "nsXFormsFormControlsAccessible.h"
#include "nsXFormsWidgetsAccessible.h"
#include "OuterDocAccessible.h"
#include "Role.h"
#include "RootAccessibleWrap.h"
#include "States.h"
@@ -165,17 +165,17 @@ nsAccessibilityService::GetRootDocumentA
}
return aCanCreate ?
GetDocAccessible(documentNode) : GetDocAccessibleFromCache(documentNode);
}
}
return nsnull;
}
-
+
already_AddRefed<Accessible>
nsAccessibilityService::CreateOuterDocAccessible(nsIContent* aContent,
nsIPresShell* aPresShell)
{
Accessible* accessible =
new OuterDocAccessible(aContent, GetDocAccessible(aPresShell));
NS_ADDREF(accessible);
return accessible;
@@ -261,17 +261,17 @@ nsAccessibilityService::CreateHTMLImageA
return accessible;
}
already_AddRefed<Accessible>
nsAccessibilityService::CreateHTMLImageMapAccessible(nsIContent* aContent,
nsIPresShell* aPresShell)
{
Accessible* accessible =
- new nsHTMLImageMapAccessible(aContent, GetDocAccessible(aPresShell));
+ new HTMLImageMapAccessible(aContent, GetDocAccessible(aPresShell));
NS_ADDREF(accessible);
return accessible;
}
already_AddRefed<Accessible>
nsAccessibilityService::CreateHTMLGroupboxAccessible(nsIContent* aContent,
nsIPresShell* aPresShell)
{
@@ -291,18 +291,18 @@ nsAccessibilityService::CreateHTMLListbo
return accessible;
}
already_AddRefed<Accessible>
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;
}
already_AddRefed<Accessible>
nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame,
nsIContent* aContent,
nsIPresShell* aPresShell)
@@ -400,17 +400,17 @@ nsAccessibilityService::CreateHTMLTableC
return accessible;
}
already_AddRefed<Accessible>
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;
}
already_AddRefed<Accessible>
nsAccessibilityService::CreateTextLeafAccessible(nsIContent* aContent,
nsIPresShell* aPresShell)
{
@@ -557,17 +557,17 @@ void
nsAccessibilityService::UpdateImageMap(nsImageFrame* aImageFrame)
{
nsIPresShell* presShell = aImageFrame->PresContext()->PresShell();
DocAccessible* document = GetDocAccessible(presShell);
if (document) {
Accessible* accessible =
document->GetAccessible(aImageFrame->GetContent());
if (accessible) {
- nsHTMLImageMapAccessible* imageMap = accessible->AsImageMap();
+ HTMLImageMapAccessible* imageMap = accessible->AsImageMap();
if (imageMap) {
imageMap->UpdateChildAreas();
return;
}
// If image map was initialized after we created an accessible (that'll
// be an image accessible) then recreate it.
RecreateAccessible(presShell, aImageFrame->GetContent());
@@ -1010,17 +1010,17 @@ nsAccessibilityService::GetOrCreateAcces
bool isHTML = content->IsHTML();
if (isHTML && content->Tag() == nsGkAtoms::map) {
// Create hyper text accessible for HTML map if it is used to group links
// (see http://www.w3.org/TR/WCAG10-HTML-TECHS/#group-bypass). If the HTML
// 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,
weakFrame->GetParent()).IsEmpty()) {
if (aIsSubtreeHidden)
*aIsSubtreeHidden = true;
return nsnull;
@@ -1168,35 +1168,33 @@ nsAccessibilityService::GetOrCreateAcces
// Elements may implement nsIAccessibleProvider via XBL. This allows them to
// say what kind of accessible to create.
newAcc = CreateAccessibleByType(content, docAcc);
}
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);
}
}
if (!newAcc) {
newAcc = CreateAccessibleForDeckChild(weakFrame.GetFrame(), content,
docAcc);
}
// 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 ||
HasRelatedContent(content) || nsCoreUtils::IsXLink(content))) {
// This content is focusable or has an interesting dynamic content accessibility property.
// If it's interesting we need it in the accessibility hierarchy so that events or
// other accessibles can point to it, or so that it can hold a state, etc.
if (isHTML) {
@@ -1414,18 +1412,17 @@ nsAccessibilityService::CreateAccessible
break;
}
case nsIAccessibleProvider::XULMenuSeparator:
accessible = new nsXULMenuSeparatorAccessible(aContent, aDoc);
break;
case nsIAccessibleProvider::XULPane:
- accessible = new nsEnumRoleAccessible(aContent, aDoc,
- roles::PANE);
+ accessible = new EnumRoleAccessible(aContent, aDoc, roles::PANE);
break;
case nsIAccessibleProvider::XULProgressMeter:
accessible = new XULProgressMeterAccessible(aContent, aDoc);
break;
case nsIAccessibleProvider::XULStatusBar:
accessible = new XULStatusBarAccessible(aContent, aDoc);
@@ -1621,27 +1618,27 @@ nsAccessibilityService::CreateHTMLAccess
if (tag == nsGkAtoms::ul || tag == nsGkAtoms::ol ||
tag == nsGkAtoms::dl) {
Accessible* accessible = new HTMLListAccessible(aContent, aDoc);
NS_IF_ADDREF(accessible);
return accessible;
}
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 &&
roleMapEntry->role != roles::LINK) {
Accessible* accessible = new HyperTextAccessibleWrap(aContent, aDoc);
NS_IF_ADDREF(accessible);
return accessible;
}
- Accessible* accessible = new nsHTMLLinkAccessible(aContent, aDoc);
+ Accessible* accessible = new HTMLLinkAccessible(aContent, aDoc);
NS_IF_ADDREF(accessible);
return accessible;
}
if (tag == nsGkAtoms::dt ||
(tag == nsGkAtoms::li &&
aFrame->GetType() != nsGkAtoms::blockFrame)) {
// Normally for li, it is created by the list item frame (in nsBlockFrame)
@@ -1781,18 +1778,18 @@ nsAccessibilityService::CreateAccessible
#ifdef MOZ_XUL
if (parentContent->NodeInfo()->Equals(nsGkAtoms::tabpanels,
kNameSpaceID_XUL)) {
Accessible* accessible = new nsXULTabpanelAccessible(aContent, aDoc);
NS_IF_ADDREF(accessible);
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;
}
}
return nsnull;
}
--- a/accessible/src/generic/Accessible.h
+++ b/accessible/src/generic/Accessible.h
@@ -22,23 +22,23 @@
#include "nsRefPtrHashtable.h"
class AccEvent;
class AccGroupInfo;
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;
class TextLeafAccessible;
/**
* Name type flags.
*/
@@ -499,17 +499,17 @@ public:
inline bool IsHTMLListItem() const { return mFlags & eHTMLListItemAccessible; }
mozilla::a11y::HTMLLIAccessible* AsHTMLListItem();
inline bool IsImage() const { return mFlags & eImageAccessible; }
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();
inline bool IsListControl() const { return mFlags & eListControlAccessible; }
inline bool IsMenuButton() const { return mFlags & eMenuButtonAccessible; }
@@ -874,17 +874,17 @@ protected:
PRUint32 mFlags;
nsAutoPtr<EmbeddedObjCollector> mEmbeddedObjCollector;
PRInt32 mIndexOfEmbeddedChild;
friend class EmbeddedObjCollector;
nsAutoPtr<AccGroupInfo> mGroupInfo;
friend class AccGroupInfo;
-
+
/**
* Non-null indicates author-supplied role; possibly state & value as well
*/
nsRoleMapEntry* mRoleMapEntry;
};
NS_DEFINE_STATIC_IID_ACCESSOR(Accessible,
NS_ACCESSIBLE_IMPL_IID)
rename from accessible/src/base/nsBaseWidgetAccessible.cpp
rename to accessible/src/generic/BaseAccessibles.cpp
--- a/accessible/src/base/nsBaseWidgetAccessible.cpp
+++ b/accessible/src/generic/BaseAccessibles.cpp
@@ -1,14 +1,14 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 "nsBaseWidgetAccessible.h"
+#include "BaseAccessibles.h"
#include "Accessible-inl.h"
#include "HyperTextAccessibleWrap.h"
#include "nsAccessibilityService.h"
#include "nsAccUtils.h"
#include "nsCoreUtils.h"
#include "Role.h"
#include "States.h"
@@ -17,173 +17,173 @@
#include "nsILink.h"
#include "nsIFrame.h"
#include "nsINameSpaceManager.h"
#include "nsIURI.h"
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),
mIsOnclick(false)
{
}
-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);
return 0;
}
void
-nsLinkableAccessible::Value(nsString& aValue)
+LinkableAccessible::Value(nsString& aValue)
{
aValue.Truncate();
Accessible::Value(aValue);
if (!aValue.IsEmpty())
return;
if (aValue.IsEmpty() && mIsLink)
mActionAcc->Value(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;
}
else if (mIsOnclick) {
aName.AssignLiteral("click");
return NS_OK;
}
return NS_ERROR_NOT_IMPLEMENTED;
}
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP
-nsLinkableAccessible::DoAction(PRUint8 aIndex)
+LinkableAccessible::DoAction(PRUint8 aIndex)
{
if (aIndex != eAction_Jump)
return NS_ERROR_INVALID_ARG;
return mActionAcc ? mActionAcc->DoAction(aIndex) :
AccessibleWrap::DoAction(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;
mActionAcc = nsnull;
AccessibleWrap::Shutdown();
}
////////////////////////////////////////////////////////////////////////////////
-// nsLinkableAccessible: HyperLinkAccessible
+// LinkableAccessible: HyperLinkAccessible
already_AddRefed<nsIURI>
-nsLinkableAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
+LinkableAccessible::AnchorURIAt(PRUint32 aAnchorIndex)
{
if (mIsLink) {
NS_ASSERTION(mActionAcc->IsLink(),
"nsIAccessibleHyperLink isn't implemented.");
if (mActionAcc->IsLink())
return mActionAcc->AnchorURIAt(aAnchorIndex);
}
return nsnull;
}
////////////////////////////////////////////////////////////////////////////////
-// nsLinkableAccessible: Accessible protected
+// LinkableAccessible: Accessible protected
void
-nsLinkableAccessible::BindToParent(Accessible* aParent,
- PRUint32 aIndexInParent)
+LinkableAccessible::BindToParent(Accessible* aParent,
+ PRUint32 aIndexInParent)
{
AccessibleWrap::BindToParent(aParent, aIndexInParent);
// Cache action content.
mActionAcc = nsnull;
mIsLink = false;
mIsOnclick = false;
@@ -207,35 +207,34 @@ nsLinkableAccessible::BindToParent(Acces
mActionAcc = walkUpAcc;
mIsOnclick = true;
return;
}
}
}
void
-nsLinkableAccessible::UnbindFromParent()
+LinkableAccessible::UnbindFromParent()
{
mActionAcc = nsnull;
mIsLink = false;
mIsOnclick = false;
AccessibleWrap::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;
}
rename from accessible/src/base/nsBaseWidgetAccessible.h
rename to accessible/src/generic/BaseAccessibles.h
--- a/accessible/src/base/nsBaseWidgetAccessible.h
+++ b/accessible/src/generic/BaseAccessibles.h
@@ -1,34 +1,37 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 _nsBaseWidgetAccessible_H_
-#define _nsBaseWidgetAccessible_H_
+#ifndef mozilla_a11y_BaseAccessibles_h__
+#define mozilla_a11y_BaseAccessibles_h__
#include "AccessibleWrap.h"
#include "HyperTextAccessibleWrap.h"
#include "nsIContent.h"
/**
* This file contains a number of classes that are used as base
* classes for the different accessibility implementations of
* 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
// Accessible
virtual Accessible* ChildAtPoint(PRInt32 aX, PRInt32 aY,
EWhichChildAtPoint aWhichChild);
@@ -39,22 +42,22 @@ protected:
};
/**
* Used for text or image accessible nodes contained by link accessibles or
* accessibles for nodes with registered click event handler. It knows how to
* 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
// nsIAccessible
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
NS_IMETHOD TakeFocus();
@@ -82,26 +85,29 @@ protected:
*/
Accessible* mActionAcc;
bool mIsLink;
bool mIsOnclick;
};
/**
* 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
--- a/accessible/src/generic/FormControlAccessible.cpp
+++ b/accessible/src/generic/FormControlAccessible.cpp
@@ -21,41 +21,41 @@ using namespace mozilla::a11y;
template class mozilla::a11y::ProgressMeterAccessible<1>;
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)
////////////////////////////////////////////////////////////////////////////////
// Accessible
template<int Max>
role
ProgressMeterAccessible<Max>::NativeRole()
{
return roles::PROGRESSBAR;
}
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;
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue);
if (attrValue.IsEmpty())
state |= states::MIXED;
@@ -74,17 +74,17 @@ ProgressMeterAccessible<Max>::IsWidget()
////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleValue
template<int Max>
void
ProgressMeterAccessible<Max>::Value(nsString& aValue)
{
- nsLeafAccessible::Value(aValue);
+ LeafAccessible::Value(aValue);
if (!aValue.IsEmpty())
return;
double maxValue = 0;
nsresult rv = GetMaximumValue(&maxValue);
if (NS_FAILED(rv) || maxValue == 0)
return;
@@ -100,17 +100,17 @@ ProgressMeterAccessible<Max>::Value(nsSt
aValue.AppendFloat(percentValue);
aValue.AppendLiteral("%");
}
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;
nsAutoString value;
if (mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::max, value)) {
PRInt32 result = NS_OK;
*aMaximumValue = value.ToDouble(&result);
return result;
@@ -119,41 +119,41 @@ ProgressMeterAccessible<Max>::GetMaximum
*aMaximumValue = Max;
return NS_OK;
}
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;
*aMinimumValue = 0;
return NS_OK;
}
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;
*aMinimumIncrement = 0;
return NS_OK;
}
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;
nsAutoString attrValue;
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, attrValue);
// Return zero value if there is no attribute or its value is empty.
if (attrValue.IsEmpty())
@@ -176,17 +176,17 @@ ProgressMeterAccessible<Max>::SetCurrent
}
////////////////////////////////////////////////////////////////////////////////
// RadioButtonAccessible
////////////////////////////////////////////////////////////////////////////////
RadioButtonAccessible::
RadioButtonAccessible(nsIContent* aContent, DocAccessible* aDoc) :
- nsLeafAccessible(aContent, aDoc)
+ LeafAccessible(aContent, aDoc)
{
}
PRUint8
RadioButtonAccessible::ActionCount()
{
return 1;
}
--- a/accessible/src/generic/FormControlAccessible.h
+++ b/accessible/src/generic/FormControlAccessible.h
@@ -1,30 +1,30 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 MOZILLA_A11Y_FormControlAccessible_H_
#define MOZILLA_A11Y_FormControlAccessible_H_
-#include "nsBaseWidgetAccessible.h"
+#include "BaseAccessibles.h"
namespace mozilla {
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)
{
}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIACCESSIBLEVALUE
// Accessible
virtual void Value(nsString& aValue);
@@ -33,17 +33,17 @@ public:
// Widgets
virtual bool IsWidget() const;
};
/**
* Generic class used for radio buttons.
*/
-class RadioButtonAccessible : public nsLeafAccessible
+class RadioButtonAccessible : public LeafAccessible
{
public:
RadioButtonAccessible(nsIContent* aContent, DocAccessible* aDoc);
// nsIAccessible
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
--- a/accessible/src/generic/ImageAccessible.cpp
+++ b/accessible/src/generic/ImageAccessible.cpp
@@ -25,34 +25,34 @@
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// ImageAccessible
////////////////////////////////////////////////////////////////////////////////
ImageAccessible::
ImageAccessible(nsIContent* aContent, DocAccessible* aDoc) :
- nsLinkableAccessible(aContent, aDoc)
+ LinkableAccessible(aContent, aDoc)
{
mFlags |= eImageAccessible;
}
NS_IMPL_ISUPPORTS_INHERITED1(ImageAccessible, Accessible,
nsIAccessibleImage)
////////////////////////////////////////////////////////////////////////////////
// Accessible public
PRUint64
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;
if (content)
content->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
getter_AddRefs(imageRequest));
@@ -99,44 +99,44 @@ ImageAccessible::NativeRole()
}
////////////////////////////////////////////////////////////////////////////////
// nsIAccessible
PRUint8
ImageAccessible::ActionCount()
{
- PRUint8 actionCount = nsLinkableAccessible::ActionCount();
+ PRUint8 actionCount = LinkableAccessible::ActionCount();
return HasLongDesc() ? actionCount + 1 : actionCount;
}
NS_IMETHODIMP
ImageAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
{
aName.Truncate();
if (IsDefunct())
return NS_ERROR_FAILURE;
if (IsLongDescIndex(aIndex) && HasLongDesc()) {
aName.AssignLiteral("showlongdesc");
return NS_OK;
}
- return nsLinkableAccessible::GetActionName(aIndex, aName);
+ return LinkableAccessible::GetActionName(aIndex, aName);
}
NS_IMETHODIMP
ImageAccessible::DoAction(PRUint8 aIndex)
{
if (IsDefunct())
return NS_ERROR_FAILURE;
// 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)
return NS_ERROR_INVALID_ARG;
nsCAutoString utf8spec;
uri->GetSpec(utf8spec);
NS_ConvertUTF8toUTF16 spec(utf8spec);
@@ -174,17 +174,17 @@ ImageAccessible::GetImageSize(PRInt32* a
// Accessible
nsresult
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;
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src);
if (!src.IsEmpty())
nsAccUtils::SetAccAttr(aAttributes, nsGkAtoms::src, src);
return NS_OK;
@@ -223,11 +223,11 @@ ImageAccessible::GetLongDescURI() const
}
return nsnull;
}
bool
ImageAccessible::IsLongDescIndex(PRUint8 aIndex)
{
- return aIndex == nsLinkableAccessible::ActionCount();
+ return aIndex == LinkableAccessible::ActionCount();
}
--- a/accessible/src/generic/ImageAccessible.h
+++ b/accessible/src/generic/ImageAccessible.h
@@ -1,30 +1,30 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 mozilla_a11y_ImageAccessible_h__
#define mozilla_a11y_ImageAccessible_h__
-#include "nsBaseWidgetAccessible.h"
+#include "BaseAccessibles.h"
#include "nsIAccessibleImage.h"
class nsGenericHTMLElement;
namespace mozilla {
namespace a11y {
/* Accessible for supporting images
* supports:
* - gets name, role
* - support basic state
*/
-class ImageAccessible : public nsLinkableAccessible,
+class ImageAccessible : public LinkableAccessible,
public nsIAccessibleImage
{
public:
ImageAccessible(nsIContent* aContent, DocAccessible* aDoc);
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
--- a/accessible/src/generic/Makefile.in
+++ b/accessible/src/generic/Makefile.in
@@ -13,16 +13,17 @@ MODULE = accessibility
LIBRARY_NAME = accessibility_generic_s
LIBXUL_LIBRARY = 1
CPPSRCS = \
Accessible.cpp \
ApplicationAccessible.cpp \
ARIAGridAccessible.cpp \
+ BaseAccessibles.cpp \
DocAccessible.cpp \
FormControlAccessible.cpp \
HyperTextAccessible.cpp \
ImageAccessible.cpp \
OuterDocAccessible.cpp \
RootAccessible.cpp \
TextLeafAccessible.cpp \
$(NULL)
--- a/accessible/src/generic/TextLeafAccessible.cpp
+++ b/accessible/src/generic/TextLeafAccessible.cpp
@@ -12,17 +12,17 @@
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// TextLeafAccessible
////////////////////////////////////////////////////////////////////////////////
TextLeafAccessible::
TextLeafAccessible(nsIContent* aContent, DocAccessible* aDoc) :
- nsLinkableAccessible(aContent, aDoc)
+ LinkableAccessible(aContent, aDoc)
{
mFlags |= eTextLeafAccessible;
}
TextLeafAccessible::~TextLeafAccessible()
{
}
--- a/accessible/src/generic/TextLeafAccessible.h
+++ b/accessible/src/generic/TextLeafAccessible.h
@@ -1,25 +1,25 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 mozilla_a11y_TextLeafAccessible_h__
#define mozilla_a11y_TextLeafAccessible_h__
-#include "nsBaseWidgetAccessible.h"
+#include "BaseAccessibles.h"
namespace mozilla {
namespace a11y {
/**
* Generic class used for text nodes.
*/
-class TextLeafAccessible : public nsLinkableAccessible
+class TextLeafAccessible : public LinkableAccessible
{
public:
TextLeafAccessible(nsIContent* aContent, DocAccessible* aDoc);
virtual ~TextLeafAccessible();
// Accessible
virtual mozilla::a11y::role NativeRole();
virtual void AppendTextTo(nsAString& aText, PRUint32 aStartOffset = 0,
--- a/accessible/src/html/HTMLElementAccessibles.h
+++ b/accessible/src/html/HTMLElementAccessibles.h
@@ -1,45 +1,45 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 mozilla_a11y_HTMLElementAccessibles_h__
#define mozilla_a11y_HTMLElementAccessibles_h__
+#include "BaseAccessibles.h"
#include "nsAutoPtr.h"
-#include "nsBaseWidgetAccessible.h"
namespace mozilla {
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();
};
/**
* 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);
virtual a11y::role NativeRole();
virtual PRUint64 NativeState();
};
/**
--- a/accessible/src/html/HTMLFormControlAccessible.cpp
+++ b/accessible/src/html/HTMLFormControlAccessible.cpp
@@ -38,17 +38,17 @@ using namespace mozilla;
using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// HTMLCheckboxAccessible
////////////////////////////////////////////////////////////////////////////////
HTMLCheckboxAccessible::
HTMLCheckboxAccessible(nsIContent* aContent, DocAccessible* aDoc) :
- nsLeafAccessible(aContent, aDoc)
+ LeafAccessible(aContent, aDoc)
{
}
role
HTMLCheckboxAccessible::NativeRole()
{
return roles::CHECKBUTTON;
}
@@ -86,17 +86,17 @@ HTMLCheckboxAccessible::DoAction(PRUint8
DoCommand();
return NS_OK;
}
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
nsCOMPtr<nsIDOMHTMLInputElement> htmlCheckboxElement =
do_QueryInterface(mContent);
if (htmlCheckboxElement) {
--- a/accessible/src/html/HTMLFormControlAccessible.h
+++ b/accessible/src/html/HTMLFormControlAccessible.h
@@ -15,17 +15,17 @@ namespace a11y {
/**
* Accessible for HTML progress element.
*/
typedef ProgressMeterAccessible<1> HTMLProgressMeterAccessible;
/**
* Accessible for HTML input@type="checkbox".
*/
-class HTMLCheckboxAccessible : public nsLeafAccessible
+class HTMLCheckboxAccessible : public LeafAccessible
{
public:
enum { eAction_Click = 0 };
HTMLCheckboxAccessible(nsIContent* aContent, DocAccessible* aDoc);
// nsIAccessible
rename from accessible/src/html/nsHTMLImageMapAccessible.cpp
rename to accessible/src/html/HTMLImageMapAccessible.cpp
--- a/accessible/src/html/nsHTMLImageMapAccessible.cpp
+++ b/accessible/src/html/HTMLImageMapAccessible.cpp
@@ -1,14 +1,14 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 "nsHTMLImageMapAccessible.h"
+#include "HTMLImageMapAccessible.h"
#include "nsAccUtils.h"
#include "nsARIAMap.h"
#include "DocAccessible.h"
#include "Role.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIServiceManager.h"
@@ -16,71 +16,71 @@
#include "nsIDOMHTMLAreaElement.h"
#include "nsIFrame.h"
#include "nsImageFrame.h"
#include "nsImageMap.h"
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)
return nsnull;
nsIContent* linkContent = area->GetContent();
return linkContent ? linkContent->GetHrefURI() : nsnull;
}
////////////////////////////////////////////////////////////////////////////////
-// nsHTMLImageMapAccessible: public
+// HTMLImageMapAccessible: public
void
-nsHTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
+HTMLImageMapAccessible::UpdateChildAreas(bool aDoFireEvents)
{
nsImageFrame* imageFrame = do_QueryFrame(mContent->GetPrimaryFrame());
// If image map is not initialized yet then we trigger one time more later.
nsImageMap* imageMapObj = imageFrame->GetExistingImageMap();
if (!imageMapObj)
return;
@@ -103,17 +103,17 @@ nsHTMLImageMapAccessible::UpdateChildAre
// Insert new areas into the tree.
PRUint32 areaElmCount = imageMapObj->AreaCount();
for (PRUint32 idx = 0; idx < areaElmCount; idx++) {
nsIContent* areaContent = imageMapObj->GetAreaAt(idx);
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;
if (!InsertChildAt(idx, area)) {
mDoc->UnbindFromDocument(area);
break;
}
@@ -130,117 +130,117 @@ nsHTMLImageMapAccessible::UpdateChildAre
nsRefPtr<AccEvent> reorderEvent =
new AccEvent(nsIAccessibleEvent::EVENT_REORDER, mContent,
eAutoDetect, AccEvent::eCoalesceFromSameSubtree);
mDoc->FireDelayedAccessibleEvent(reorderEvent);
}
}
////////////////////////////////////////////////////////////////////////////////
-// 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);
if (!aName.IsEmpty())
return NS_OK;
if (!mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::alt, aName))
return GetValue(aName);
return NS_OK;
}
void
-nsHTMLAreaAccessible::Description(nsString& aDescription)
+HTMLAreaAccessible::Description(nsString& aDescription)
{
aDescription.Truncate();
// Still to do - follow IE's standard here
nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(mContent));
if (area)
area->GetShape(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.
return false;
}
////////////////////////////////////////////////////////////////////////////////
-// 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.
// We return index in parent because image map contains area links only which
// are embedded objects.
// XXX: image map should be a hypertext accessible.
return IndexInParent();
}
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)
return;
nsImageFrame* imageFrame = do_QueryFrame(frame);
nsImageMap* map = imageFrame->GetImageMap();
rename from accessible/src/html/nsHTMLImageMapAccessible.h
rename to accessible/src/html/HTMLImageMapAccessible.h
--- a/accessible/src/html/nsHTMLImageMapAccessible.h
+++ b/accessible/src/html/HTMLImageMapAccessible.h
@@ -1,35 +1,37 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 _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"
-#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();
virtual Accessible* AnchorAt(PRUint32 aAnchorIndex);
virtual already_AddRefed<nsIURI> AnchorURIAt(PRUint32 aAnchorIndex);
/**
* Update area children of the image map.
@@ -37,35 +39,24 @@ public:
void UpdateChildAreas(bool aDoFireEvents = true);
protected:
// Accessible
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;
// Accessible
virtual void Description(nsString& aDescription);
virtual nsresult GetNameInternal(nsAString& aName);
virtual Accessible* ChildAtPoint(PRInt32 aX, PRInt32 aY,
@@ -77,9 +68,22 @@ public:
virtual PRUint32 EndOffset();
protected:
// Accessible
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
rename from accessible/src/html/nsHTMLLinkAccessible.cpp
rename to accessible/src/html/HTMLLinkAccessible.cpp
--- a/accessible/src/html/nsHTMLLinkAccessible.cpp
+++ b/accessible/src/html/HTMLLinkAccessible.cpp
@@ -1,119 +1,119 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 "nsHTMLLinkAccessible.h"
+#include "HTMLLinkAccessible.h"
#include "nsCoreUtils.h"
#include "DocAccessible.h"
#include "Role.h"
#include "States.h"
#include "nsContentUtils.h"
#include "nsEventStates.h"
#include "mozilla/dom/Element.h"
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))
return states::LINKED;
if (eventState.HasState(NS_EVENT_STATE_VISITED))
return states::LINKED | states::TRAVERSED;
// This is a either named anchor (a link with also a name attribute) or
// it doesn't have any attributes. Check if 'click' event handler is
// registered, otherwise bail out.
return nsCoreUtils::HasClickListener(mContent) ? states::LINKED : 0;
}
PRUint64
-nsHTMLLinkAccessible::NativeInteractiveState() const
+HTMLLinkAccessible::NativeInteractiveState() const
{
PRUint64 state = HyperTextAccessibleWrap::NativeInteractiveState();
// This is how we indicate it is a named anchor. In other words, this anchor
// can be selected as a location :) There is no other better state to use to
// indicate this.
if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::name))
state |= states::SELECTABLE;
return state;
}
void
-nsHTMLLinkAccessible::Value(nsString& aValue)
+HTMLLinkAccessible::Value(nsString& aValue)
{
aValue.Truncate();
HyperTextAccessible::Value(aValue);
if (aValue.IsEmpty())
nsContentUtils::GetLinkLocation(mContent->AsElement(), 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();
if (!IsLinked())
return HyperTextAccessible::GetActionName(aIndex, aName);
// Action 0 (default action): Jump to link
if (aIndex != eAction_Jump)
return NS_ERROR_INVALID_ARG;
aName.AssignLiteral("jump");
return NS_OK;
}
NS_IMETHODIMP
-nsHTMLLinkAccessible::DoAction(PRUint8 aIndex)
+HTMLLinkAccessible::DoAction(PRUint8 aIndex)
{
if (!IsLinked())
return HyperTextAccessible::DoAction(aIndex);
// Action 0 (default action): Jump to link
if (aIndex != eAction_Jump)
return NS_ERROR_INVALID_ARG;
@@ -123,33 +123,33 @@ nsHTMLLinkAccessible::DoAction(PRUint8 a
DoCommand();
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// 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;
}
////////////////////////////////////////////////////////////////////////////////
// Protected members
bool
-nsHTMLLinkAccessible::IsLinked()
+HTMLLinkAccessible::IsLinked()
{
if (IsDefunct())
return false;
nsEventStates state = mContent->AsElement()->State();
return state.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED |
NS_EVENT_STATE_UNVISITED);
}
rename from accessible/src/html/nsHTMLLinkAccessible.h
rename to accessible/src/html/HTMLLinkAccessible.h
--- a/accessible/src/html/nsHTMLLinkAccessible.h
+++ b/accessible/src/html/HTMLLinkAccessible.h
@@ -1,32 +1,35 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 _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
// nsIAccessible
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
// 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;
// ActionAccessible
virtual PRUint8 ActionCount();
// HyperLinkAccessible
@@ -37,9 +40,12 @@ protected:
enum { eAction_Jump = 0 };
/**
* Returns true if the link has href attribute.
*/
bool IsLinked();
};
-#endif
+} // namespace a11y
+} // namespace mozilla
+
+#endif
--- a/accessible/src/html/HTMLListAccessible.cpp
+++ b/accessible/src/html/HTMLListAccessible.cpp
@@ -183,17 +183,17 @@ role
HTMLListBulletAccessible::NativeRole()
{
return roles::STATICTEXT;
}
PRUint64
HTMLListBulletAccessible::NativeState()
{
- return nsLeafAccessible::NativeState() | states::READONLY;
+ return LeafAccessible::NativeState() | states::READONLY;
}
void
HTMLListBulletAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
PRUint32 aLength)
{
nsAutoString bulletText;
nsBlockFrame* blockFrame = do_QueryFrame(mContent->GetPrimaryFrame());
--- a/accessible/src/html/HTMLListAccessible.h
+++ b/accessible/src/html/HTMLListAccessible.h
@@ -2,18 +2,18 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* 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 mozilla_a11y_HTMLListAccessible_h__
#define mozilla_a11y_HTMLListAccessible_h__
+#include "BaseAccessibles.h"
#include "HyperTextAccessibleWrap.h"
-#include "nsBaseWidgetAccessible.h"
namespace mozilla {
namespace a11y {
class HTMLListBulletAccessible;
/**
* Used for HTML list (like HTML ul).
@@ -67,21 +67,21 @@ protected:
private:
nsRefPtr<HTMLListBulletAccessible> mBullet;
};
/**
* 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
virtual nsIFrame* GetFrame() const;
virtual bool IsPrimaryForNode() const;
// Accessible
virtual ENameValueFlag Name(nsString& aName);
--- a/accessible/src/html/Makefile.in
+++ b/accessible/src/html/Makefile.in
@@ -14,20 +14,20 @@ MODULE = accessibility
LIBRARY_NAME = accessibility_html_s
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)
# we don't want the shared lib, but we want to force the creation of a static lib.
FORCE_STATIC_LIB = 1
include $(topsrcdir)/config/rules.mk
--- a/accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp
+++ b/accessible/src/msaa/nsHTMLWin32ObjectAccessible.cpp
@@ -60,18 +60,18 @@ nsHTMLWin32ObjectOwnerAccessible::CacheC
AppendChild(mNativeAccessible);
}
////////////////////////////////////////////////////////////////////////////////
// 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.
mFlags |= eIsDefunct;
mHwnd = aHwnd;
if (mHwnd) {
// The plugin is not windowless. In this situation we use
--- a/accessible/src/msaa/nsHTMLWin32ObjectAccessible.h
+++ b/accessible/src/msaa/nsHTMLWin32ObjectAccessible.h
@@ -1,17 +1,17 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 _nsHTMLWin32ObjectAccessible_H_
#define _nsHTMLWin32ObjectAccessible_H_
-#include "nsBaseWidgetAccessible.h"
+#include "BaseAccessibles.h"
struct IAccessible;
class nsHTMLWin32ObjectOwnerAccessible : public AccessibleWrap
{
public:
// This will own the nsHTMLWin32ObjectAccessible. We create this where the
// <object> or <embed> exists in the tree, so that get_accNextSibling() etc.
@@ -43,21 +43,21 @@ protected:
* This class is used only internally, we never! send out an IAccessible linked
* back to this object. This class is used to represent a plugin object when
* referenced as a child or sibling of another Accessible node. We need only
* a limited portion of the nsIAccessible interface implemented here. The
* in depth accessible information will be returned by the actual IAccessible
* 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
NS_IMETHOD GetNativeInterface(void** aNativeAccessible) MOZ_OVERRIDE;
protected:
void* mHwnd;
--- a/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
+++ b/accessible/src/xforms/nsXFormsWidgetsAccessible.cpp
@@ -12,17 +12,17 @@ using namespace mozilla::a11y;
////////////////////////////////////////////////////////////////////////////////
// nsXFormsDropmarkerWidgetAccessible
////////////////////////////////////////////////////////////////////////////////
nsXFormsDropmarkerWidgetAccessible::
nsXFormsDropmarkerWidgetAccessible(nsIContent* aContent,
DocAccessible* aDoc) :
- nsLeafAccessible(aContent, aDoc)
+ LeafAccessible(aContent, aDoc)
{
}
role
nsXFormsDropmarkerWidgetAccessible::NativeRole()
{
return roles::PUSHBUTTON;
}
--- a/accessible/src/xforms/nsXFormsWidgetsAccessible.h
+++ b/accessible/src/xforms/nsXFormsWidgetsAccessible.h
@@ -1,25 +1,25 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 _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:
nsXFormsDropmarkerWidgetAccessible(nsIContent* aContent,
DocAccessible* aDoc);
// nsIAccessible
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
--- a/accessible/src/xul/XULFormControlAccessible.cpp
+++ b/accessible/src/xul/XULFormControlAccessible.cpp
@@ -234,17 +234,17 @@ XULButtonAccessible::ContainsMenu()
}
////////////////////////////////////////////////////////////////////////////////
// XULDropmarkerAccessible
////////////////////////////////////////////////////////////////////////////////
XULDropmarkerAccessible::
XULDropmarkerAccessible(nsIContent* aContent, DocAccessible* aDoc) :
- nsLeafAccessible(aContent, aDoc)
+ LeafAccessible(aContent, aDoc)
{
}
PRUint8
XULDropmarkerAccessible::ActionCount()
{
return 1;
}
@@ -318,17 +318,17 @@ XULDropmarkerAccessible::NativeState()
}
////////////////////////////////////////////////////////////////////////////////
// XULCheckboxAccessible
////////////////////////////////////////////////////////////////////////////////
XULCheckboxAccessible::
XULCheckboxAccessible(nsIContent* aContent, DocAccessible* aDoc) :
- nsLeafAccessible(aContent, aDoc)
+ LeafAccessible(aContent, aDoc)
{
}
role
XULCheckboxAccessible::NativeRole()
{
return roles::CHECKBUTTON;
}
@@ -371,17 +371,17 @@ XULCheckboxAccessible::DoAction(PRUint8
return NS_OK;
}
PRUint64
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;
// Determine Checked state
nsCOMPtr<nsIDOMXULCheckboxElement> xulCheckboxElement =
do_QueryInterface(mContent);
if (xulCheckboxElement) {
bool checked = false;
@@ -463,17 +463,17 @@ XULRadioButtonAccessible::
XULRadioButtonAccessible(nsIContent* aContent, DocAccessible* aDoc) :
RadioButtonAccessible(aContent, aDoc)
{
}
PRUint64
XULRadioButtonAccessible::NativeState()
{
- PRUint64 state = nsLeafAccessible::NativeState();
+ PRUint64 state = LeafAccessible::NativeState();
state |= states::CHECKABLE;
nsCOMPtr<nsIDOMXULSelectControlItemElement> radioButton =
do_QueryInterface(mContent);
if (radioButton) {
bool selected = false; // Radio buttons can be selected
radioButton->GetSelected(&selected);
if (selected) {
@@ -654,17 +654,17 @@ XULToolbarAccessible::GetNameInternal(ns
////////////////////////////////////////////////////////////////////////////////
// XULToolbarAccessible
////////////////////////////////////////////////////////////////////////////////
XULToolbarSeparatorAccessible::
XULToolbarSeparatorAccessible(nsIContent* aContent, DocAccessible* aDoc) :
- nsLeafAccessible(aContent, aDoc)
+ LeafAccessible(aContent, aDoc)
{
}
role
XULToolbarSeparatorAccessible::NativeRole()
{
return roles::SEPARATOR;
}
--- a/accessible/src/xul/XULFormControlAccessible.h
+++ b/accessible/src/xul/XULFormControlAccessible.h
@@ -18,17 +18,17 @@ namespace a11y {
/**
* Used for XUL progressmeter element.
*/
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
{
public:
enum { eAction_Click = 0 };
XULButtonAccessible(nsIContent* aContent, DocAccessible* aDoc);
@@ -60,17 +60,17 @@ protected:
// XULButtonAccessible
bool ContainsMenu();
};
/**
* Used for XUL checkbox element.
*/
-class XULCheckboxAccessible : public nsLeafAccessible
+class XULCheckboxAccessible : public LeafAccessible
{
public:
enum { eAction_Click = 0 };
XULCheckboxAccessible(nsIContent* aContent, DocAccessible* aDoc);
// nsIAccessible
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@@ -81,17 +81,17 @@ public:
// ActionAccessible
virtual PRUint8 ActionCount();
};
/**
* Used for XUL dropmarker element.
*/
-class XULDropmarkerAccessible : public nsLeafAccessible
+class XULDropmarkerAccessible : public LeafAccessible
{
public:
enum { eAction_Click = 0 };
XULDropmarkerAccessible(nsIContent* aContent, DocAccessible* aDoc);
// nsIAccessible
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
@@ -195,17 +195,17 @@ public:
// Accessible
virtual mozilla::a11y::role NativeRole();
virtual nsresult GetNameInternal(nsAString& aName);
};
/**
* Used for XUL toolbarseparator element.
*/
-class XULToolbarSeparatorAccessible : public nsLeafAccessible
+class XULToolbarSeparatorAccessible : public LeafAccessible
{
public:
XULToolbarSeparatorAccessible(nsIContent* aContent,
DocAccessible* aDoc);
// Accessible
virtual mozilla::a11y::role NativeRole();
virtual PRUint64 NativeState();
--- a/accessible/src/xul/nsXULListboxAccessible.cpp
+++ b/accessible/src/xul/nsXULListboxAccessible.cpp
@@ -47,17 +47,17 @@ nsXULColumAccessible::NativeState()
////////////////////////////////////////////////////////////////////////////////
// nsXULColumnItemAccessible
////////////////////////////////////////////////////////////////////////////////
nsXULColumnItemAccessible::
nsXULColumnItemAccessible(nsIContent* aContent, DocAccessible* aDoc) :
- nsLeafAccessible(aContent, aDoc)
+ LeafAccessible(aContent, aDoc)
{
}
role
nsXULColumnItemAccessible::NativeRole()
{
return roles::COLUMNHEADER;
}
--- a/accessible/src/xul/nsXULListboxAccessible.h
+++ b/accessible/src/xul/nsXULListboxAccessible.h
@@ -1,18 +1,17 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 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 __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"
#include "XULSelectControlAccessible.h"
class nsIWeakReference;
/**
@@ -28,17 +27,17 @@ public:
virtual mozilla::a11y::role NativeRole();
virtual PRUint64 NativeState();
};
/**
* 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);
// nsIAccessible
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 aIndex);
--- a/accessible/src/xul/nsXULTabAccessible.h
+++ b/accessible/src/xul/nsXULTabAccessible.h
@@ -2,17 +2,16 @@
/* 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 _nsXULTabAccessible_H_
#define _nsXULTabAccessible_H_
// NOTE: alphabetically ordered
-#include "nsBaseWidgetAccessible.h"
#include "nsXULMenuAccessible.h"
#include "XULSelectControlAccessible.h"
/**
* An individual tab, xul:tab element.
*/
class nsXULTabAccessible : public AccessibleWrap
{
--- a/accessible/src/xul/nsXULTextAccessible.cpp
+++ b/accessible/src/xul/nsXULTextAccessible.cpp
@@ -2,18 +2,18 @@
/* 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/. */
// NOTE: groups are alphabetically ordered
#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"
#include "Role.h"
#include "States.h"
#include "nsIAccessibleRelation.h"
#include "nsIDOMXULDescriptionElement.h"
@@ -75,24 +75,24 @@ nsXULTextAccessible::RelationByType(PRUi
////////////////////////////////////////////////////////////////////////////////
// nsXULTooltipAccessible
////////////////////////////////////////////////////////////////////////////////
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
nsXULTooltipAccessible::NativeRole()
{
return roles::TOOLTIP;
}
--- a/accessible/src/xul/nsXULTextAccessible.h
+++ b/accessible/src/xul/nsXULTextAccessible.h
@@ -1,18 +1,18 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 _nsXULTextAccessible_H_
#define _nsXULTextAccessible_H_
+#include "BaseAccessibles.h"
#include "HyperTextAccessibleWrap.h"
-#include "nsBaseWidgetAccessible.h"
/**
* Used for XUL description and label elements.
*/
class nsXULTextAccessible : public HyperTextAccessibleWrap
{
public:
nsXULTextAccessible(nsIContent* aContent, DocAccessible* aDoc);
@@ -22,17 +22,17 @@ public:
virtual mozilla::a11y::role NativeRole();
virtual PRUint64 NativeState();
virtual Relation RelationByType(PRUint32 aRelationType);
};
/**
* Used for XUL tooltip element.
*/
-class nsXULTooltipAccessible : public nsLeafAccessible
+class nsXULTooltipAccessible : public mozilla::a11y::LeafAccessible
{
public:
nsXULTooltipAccessible(nsIContent* aContent, DocAccessible* aDoc);
// Accessible
virtual mozilla::a11y::role NativeRole();
virtual PRUint64 NativeState();
--- a/accessible/src/xul/nsXULTreeGridAccessible.cpp
+++ b/accessible/src/xul/nsXULTreeGridAccessible.cpp
@@ -714,46 +714,46 @@ nsXULTreeGridRowAccessible::CacheChildre
// nsXULTreeGridCellAccessible
////////////////////////////////////////////////////////////////////////////////
nsXULTreeGridCellAccessible::
nsXULTreeGridCellAccessible(nsIContent* aContent, DocAccessible* aDoc,
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;
}
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridCellAccessible: nsISupports implementation
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
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
Accessible*
nsXULTreeGridCellAccessible::FocusedChild()
{
return nsnull;
@@ -1024,17 +1024,17 @@ nsXULTreeGridCellAccessible::IsSelected(
}
////////////////////////////////////////////////////////////////////////////////
// nsXULTreeGridCellAccessible: nsAccessNode implementation
bool
nsXULTreeGridCellAccessible::Init()
{
- if (!nsLeafAccessible::Init() || !mTreeView)
+ if (!LeafAccessible::Init() || !mTreeView)
return false;
PRInt16 type;
mColumn->GetType(&type);
if (type == nsITreeColumn::TYPE_CHECKBOX)
mTreeView->GetCellValue(mRow, mColumn, mCachedTextEquiv);
else
mTreeView->GetCellText(mRow, mColumn, mCachedTextEquiv);
--- a/accessible/src/xul/nsXULTreeGridAccessible.h
+++ b/accessible/src/xul/nsXULTreeGridAccessible.h
@@ -99,50 +99,50 @@ protected:
#define NS_XULTREEGRIDCELLACCESSIBLE_IMPL_CID \
{ /* 84588ad4-549c-4196-a932-4c5ca5de5dff */ \
0x84588ad4, \
0x549c, \
0x4196, \
{ 0xa9, 0x32, 0x4c, 0x5c, 0xa5, 0xde, 0x5d, 0xff } \
}
-class nsXULTreeGridCellAccessible : public nsLeafAccessible,
+class nsXULTreeGridCellAccessible : public mozilla::a11y::LeafAccessible,
public nsIAccessibleTableCell
{
public:
nsXULTreeGridCellAccessible(nsIContent* aContent, DocAccessible* aDoc,
nsXULTreeGridRowAccessible* aRowAcc,
nsITreeBoxObject* aTree, nsITreeView* aTreeView,
PRInt32 aRow, nsITreeColumn* aColumn);
// 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);
// nsIAccessibleTableCell
NS_DECL_NSIACCESSIBLETABLECELL
// nsAccessNode
virtual bool Init();
virtual bool IsPrimaryForNode() const;
// 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();
virtual PRUint64 NativeState();
virtual PRUint64 NativeInteractiveState() const;
// ActionAccessible
virtual PRUint8 ActionCount();
@@ -159,18 +159,18 @@ public:
* Fire name or state change event if the accessible text or value has been
* changed.
*/
void CellInvalidated();
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
/**
* Return true if value of cell can be modified.
*/
bool IsEditable() const;
--- a/accessible/tests/mochitest/states/test_aria.html
+++ b/accessible/tests/mochitest/states/test_aria.html
@@ -125,17 +125,17 @@
testStates(fileBrowseButton,
STATE_BUSY | STATE_UNAVAILABLE | STATE_REQUIRED | STATE_HASPOPUP | STATE_INVALID);
// offscreen test
testStates("aria_offscreen_textbox", STATE_OFFSCREEN);
//
// This section tests aria roles on links/anchors for underlying
- // nsHTMLLinkAccessible creation. (see closed bug 494807)
+ // HTMLLinkAccessible creation. (see closed bug 494807)
//
// strong roles
testStates("aria_menuitem_link", 0, 0, STATE_LINKED);
testStates("aria_button_link", 0, 0, STATE_LINKED);
testStates("aria_checkbox_link", 0, 0, STATE_LINKED);
// strong landmark
--- a/accessible/tests/mochitest/value/test_general.html
+++ b/accessible/tests/mochitest/value/test_general.html
@@ -34,23 +34,23 @@
if (!acc)
return;
is(acc.value, aValue, "Wrong value for " + aID + "!");
}
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);
// HTML controls
testValue("combobox1", "item1");
testValue("combobox2", "item2");
--- a/b2g/chrome/content/shell.js
+++ b/b2g/chrome/content/shell.js
@@ -7,16 +7,17 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
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',
'@mozilla.org/process/environment;1',
'nsIEnvironment');
XPCOMUtils.defineLazyServiceGetter(Services, 'ss',
'@mozilla.org/content/style-sheet-service;1',
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1155,12 +1155,24 @@ pref("full-screen-api.enabled", true);
// approval.
pref("full-screen-api.approval-required", true);
// Startup Crash Tracking
// number of startup crashes that can occur before starting into safe mode automatically
// (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.)
pref("image.mem.max_decoded_image_kb", 256000);
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -26,16 +26,19 @@ XPCOMUtils.defineLazyModuleGetter(this,
"resource://gre/modules/BookmarkHTMLUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "webappsUI",
"resource:///modules/webappsUI.jsm");
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";
// We try to backup bookmarks at idle times, to avoid doing that at shutdown.
// Number of idle seconds before trying to backup bookmarks. 15 minutes.
const BOOKMARKS_BACKUP_IDLE_TIME = 15 * 60;
// Minimum interval in milliseconds between backups.
const BOOKMARKS_BACKUP_INTERVAL = 86400 * 1000;
@@ -324,16 +327,18 @@ BrowserGlue.prototype = {
// handle any UI migration
this._migrateUI();
// Initialize webapps UI
webappsUI.init();
PageThumbs.init();
+ PdfJs.init();
+
Services.obs.notifyObservers(null, "browser-ui-startup-complete", "");
},
// the first browser window has finished initializing
_onFirstWindowLoaded: function BG__onFirstWindowLoaded() {
#ifdef XP_WIN
// For windows seven, initialize the jump list module.
const WINTASKBAR_CONTRACTID = "@mozilla.org/windows-taskbar;1";
--- a/browser/components/preferences/applications.js
+++ b/browser/components/preferences/applications.js
@@ -12,20 +12,25 @@
#ifndef XP_MACOSX
*/
var Cc = Components.classes;
var Ci = Components.interfaces;
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";
// Preferences that affect which entries to show in the list.
const PREF_SHOW_PLUGINS_IN_LIST = "browser.download.show_plugins_in_list";
const PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS =
"browser.download.hide_plugins_without_extensions";
@@ -805,16 +810,56 @@ var audioFeedHandlerInfo = {
_prefSelectedApp: PREF_AUDIO_FEED_SELECTED_APP,
_prefSelectedWeb: PREF_AUDIO_FEED_SELECTED_WEB,
_prefSelectedAction: PREF_AUDIO_FEED_SELECTED_ACTION,
_prefSelectedReader: PREF_AUDIO_FEED_SELECTED_READER,
_smallIcon: "chrome://browser/skin/feeds/audioFeedIcon16.png",
_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
var gApplicationsPane = {
// The set of types the app knows how to handle. A hash of HandlerInfoWrapper
// objects, indexed by type.
_handledTypes: {},
@@ -994,32 +1039,46 @@ var gApplicationsPane = {
},
//**************************************************************************//
// Composed Model Construction
_loadData: function() {
this._loadFeedHandler();
+ this._loadInternalHandlers();
this._loadPluginHandlers();
this._loadApplicationHandlers();
},
_loadFeedHandler: function() {
this._handledTypes[TYPE_MAYBE_FEED] = feedHandlerInfo;
feedHandlerInfo.handledOnlyByPlugin = false;
this._handledTypes[TYPE_MAYBE_VIDEO_FEED] = videoFeedHandlerInfo;
videoFeedHandlerInfo.handledOnlyByPlugin = false;
this._handledTypes[TYPE_MAYBE_AUDIO_FEED] = audioFeedHandlerInfo;
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.
*
* Note: if there's more than one plugin for a given MIME type, we assume
* the last one is the one that the application will use. That may not be
* correct, but it's how we've been doing it for years.
*
* Perhaps we should instead query navigator.mimeTypes for the set of types
* supported by the application and then get the plugin from each MIME type's
@@ -1211,19 +1270,25 @@ var gApplicationsPane = {
if (preferredApp instanceof Ci.nsILocalHandlerApp)
name = getFileDisplayName(preferredApp.executable);
else
name = preferredApp.name;
return this._prefsBundle.getFormattedString("useApp", [name]);
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
// handler app.
if (this.isValidHandlerApp(aHandlerInfo.preferredApplicationHandler))
return aHandlerInfo.preferredApplicationHandler.name;
return aHandlerInfo.defaultDescription;
@@ -1314,16 +1379,28 @@ var gApplicationsPane = {
var menu =
document.getAnonymousElementByAttribute(typeItem, "class", "actionsMenu");
var menuPopup = menu.menupopup;
// Clear out existing items.
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");
let label;
if (isFeedType(handlerInfo.type))
label = this._prefsBundle.getFormattedString("previewInApp",
[this._brandShortName]);
else
@@ -1734,16 +1811,19 @@ var gApplicationsPane = {
case Ci.nsIHandlerInfo.saveToDisk:
aElement.setAttribute(APP_ICON_ATTR_NAME, "save");
return true;
case Ci.nsIHandlerInfo.handleInternally:
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;
case kActionUsePlugin:
aElement.setAttribute(APP_ICON_ATTR_NAME, "plugin");
return true;
}
aElement.removeAttribute(APP_ICON_ATTR_NAME);
old mode 100644
new mode 100755
--- a/browser/components/preferences/in-content/applications.js
+++ b/browser/components/preferences/in-content/applications.js
@@ -1,18 +1,23 @@
/* 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/. */
//****************************************************************************//
// 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";
// Preferences that affect which entries to show in the list.
const PREF_SHOW_PLUGINS_IN_LIST = "browser.download.show_plugins_in_list";
const PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS =
"browser.download.hide_plugins_without_extensions";
@@ -792,16 +797,56 @@ var audioFeedHandlerInfo = {
_prefSelectedApp: PREF_AUDIO_FEED_SELECTED_APP,
_prefSelectedWeb: PREF_AUDIO_FEED_SELECTED_WEB,
_prefSelectedAction: PREF_AUDIO_FEED_SELECTED_ACTION,
_prefSelectedReader: PREF_AUDIO_FEED_SELECTED_READER,
_smallIcon: "chrome://browser/skin/feeds/audioFeedIcon16.png",
_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
var gApplicationsPane = {
// The set of types the app knows how to handle. A hash of HandlerInfoWrapper
// objects, indexed by type.
_handledTypes: {},
@@ -981,32 +1026,46 @@ var gApplicationsPane = {
},
//**************************************************************************//
// Composed Model Construction
_loadData: function() {
this._loadFeedHandler();
+ this._loadInternalHandlers();
this._loadPluginHandlers();
this._loadApplicationHandlers();
},
_loadFeedHandler: function() {
this._handledTypes[TYPE_MAYBE_FEED] = feedHandlerInfo;
feedHandlerInfo.handledOnlyByPlugin = false;
this._handledTypes[TYPE_MAYBE_VIDEO_FEED] = videoFeedHandlerInfo;
videoFeedHandlerInfo.handledOnlyByPlugin = false;
this._handledTypes[TYPE_MAYBE_AUDIO_FEED] = audioFeedHandlerInfo;
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.
*
* Note: if there's more than one plugin for a given MIME type, we assume
* the last one is the one that the application will use. That may not be
* correct, but it's how we've been doing it for years.
*
* Perhaps we should instead query navigator.mimeTypes for the set of types
* supported by the application and then get the plugin from each MIME type's
@@ -1198,19 +1257,25 @@ var gApplicationsPane = {
if (preferredApp instanceof Ci.nsILocalHandlerApp)
name = getFileDisplayName(preferredApp.executable);
else
name = preferredApp.name;
return this._prefsBundle.getFormattedString("useApp", [name]);
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
// handler app.
if (this.isValidHandlerApp(aHandlerInfo.preferredApplicationHandler))
return aHandlerInfo.preferredApplicationHandler.name;
return aHandlerInfo.defaultDescription;
@@ -1301,16 +1366,28 @@ var gApplicationsPane = {
var menu =
document.getAnonymousElementByAttribute(typeItem, "class", "actionsMenu");
var menuPopup = menu.menupopup;
// Clear out existing items.
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");
let label;
if (isFeedType(handlerInfo.type))
label = this._prefsBundle.getFormattedString("previewInApp",
[this._brandShortName]);
else
@@ -1721,16 +1798,19 @@ var gApplicationsPane = {
case Ci.nsIHandlerInfo.saveToDisk:
aElement.setAttribute(APP_ICON_ATTR_NAME, "save");
return true;
case Ci.nsIHandlerInfo.handleInternally:
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;
case kActionUsePlugin:
aElement.setAttribute(APP_ICON_ATTR_NAME, "plugin");
return true;
}
aElement.removeAttribute(APP_ICON_ATTR_NAME);
--- a/browser/extensions/pdfjs/README.mozilla
+++ b/browser/extensions/pdfjs/README.mozilla
@@ -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
--- a/browser/extensions/pdfjs/chrome.manifest
+++ b/browser/extensions/pdfjs/chrome.manifest
@@ -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/
--- a/browser/extensions/pdfjs/components/PdfStreamConverter.js
+++ b/browser/extensions/pdfjs/components/PdfStreamConverter.js
@@ -4,30 +4,37 @@
'use strict';
var EXPORTED_SYMBOLS = ['PdfStreamConverter'];
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}';
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']
.getService(Ci.nsIPrivateBrowsingService);
inPrivateBrowsing = privateBrowsing.privateBrowsingEnabled;
} else if (appInfo.ID === SEAMONKEY_ID) {
privateBrowsing = null;
inPrivateBrowsing = false;
@@ -52,29 +59,46 @@ function getStringPref(pref, def) {
try {
return Services.prefs.getComplexValue(pref, Ci.nsISupportsString).data;
} catch (ex) {
return 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);
dump(msg + '\n');
}
function getDOMWindow(aChannel) {
var requestor = aChannel.notificationCallbacks;
var win = requestor.getInterface(Components.interfaces.nsIDOMWindow);
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).
createBundle('chrome://pdf.js/locale/' + path);
var map = {};
var enumerator = stringBundle.getSimpleEnumeration();
while (enumerator.hasMoreElements()) {
@@ -86,26 +110,32 @@ function getLocalizedStrings(path) {
key = key.substring(0, i);
}
if (!(key in map))
map[key] = {};
map[key][property] = string.value;
}
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 =
Cc['@mozilla.org/uriloader/external-helper-app-service;1'].
getService(Ci.nsIExternalHelperAppService);
var frontWindow = Cc['@mozilla.org/embedcomp/window-watcher;1'].
getService(Ci.nsIWindowWatcher).activeWindow;
var ioService = Services.io;
@@ -131,22 +161,22 @@ ChromeActions.prototype = {
channel.asyncOpen(listener, null);
},
setDatabase: function(data) {
if (inPrivateBrowsing)
return;
// 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');
},
getStrings: function(data) {
try {
// Lazy initialization of localizedStrings
if (!('localizedStrings' in this))
@@ -155,21 +185,44 @@ ChromeActions.prototype = {
var result = this.localizedStrings[data];
return JSON.stringify(result || null);
} catch (e) {
log('Unable to retrive localized strings: ' + e);
return 'null';
}
},
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;
}
// Receive an event and synchronously responds.
RequestListener.prototype.receive = function(event) {
var message = event.target;
var action = message.getUserData('action');
@@ -185,17 +238,17 @@ RequestListener.prototype.receive = func
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=*/*',
QueryInterface: XPCOMUtils.generateQI([
Ci.nsISupports,
Ci.nsIStreamConverter,
Ci.nsIStreamListener,
Ci.nsIRequestObserver
@@ -213,16 +266,18 @@ PdfStreamConverter.prototype = {
// nsIStreamConverter::convert
convert: function(aFromStream, aFromType, aToType, aCtxt) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
// 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 {
var request = aCtxt;
request.QueryInterface(Ci.nsIHttpChannel);
skipConversion = (request.requestMethod !== 'GET');
} catch (e) {
// Non-HTTP request... continue normally.
@@ -262,17 +317,18 @@ PdfStreamConverter.prototype = {
},
onDataAvailable: function() {
listener.onDataAvailable.apply(listener, arguments);
},
onStopRequest: function() {
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);
}
listener.onStopRequest.apply(listener, arguments);
}
};
new file mode 100644
--- /dev/null
+++ b/browser/extensions/pdfjs/content/PdfJs.jsm
@@ -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;
+ }
+};
--- a/browser/extensions/pdfjs/content/web/viewer.css
+++ b/browser/extensions/pdfjs/content/web/viewer.css
@@ -233,16 +233,20 @@ html[dir='rtl'] .splitToolbarButton > .t
height: 0;
overflow: hidden;
}
.toolbarButton[disabled] {
opacity: .5;
}
+.toolbarButton.group {
+ margin-right:0;
+}
+
.splitToolbarButton:hover > .toolbarButton,
.splitToolbarButton:focus > .toolbarButton,
.splitToolbarButton.toggled > .toolbarButton {
background-color: hsla(0,0%,0%,.12);
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
background-image: -webkit-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
background-clip: padding-box;
border: 1px solid hsla(0,0%,0%,.35);
@@ -528,16 +532,22 @@ html[dir='rtl'] .toolbarButton.pageDown:
content: url(images/toolbarButton-viewThumbnail.png);
}
#viewOutline.toolbarButton::before {
display: inline-block;
content: url(images/toolbarButton-viewOutline.png);
}
+#viewSearch.toolbarButton::before {
+ display: inline-block;
+ content: url(images/toolbarButton-search.png);
+}
+
+
.toolbarField {
min-width: 16px;
width: 32px;
padding: 3px 6px;
margin: 4px 0 4px 0;
border: 1px solid transparent;
border-radius: 2px;
background-color: hsla(0,0%,100%,.09);
@@ -692,16 +702,63 @@ a:focus > .thumbnail > .thumbnailSelecti
background-image: -moz-linear-gradient(hsla(0,0%,100%,.05), hsla(0,0%,100%,0));
background-clip: padding-box;
box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset,
0 0 1px hsla(0,0%,100%,.2) inset,
0 0 1px hsla(0,0%,0%,.2);
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));
background-clip: padding-box;
box-shadow: 0 1px 0 hsla(0,0%,100%,.05) inset,
0 0 1px hsla(0,0%,100%,.1) inset,
0 0 1px hsla(0,0%,0%,.2);
color: hsla(0,0%,100%,1);
@@ -932,16 +989,40 @@ canvas {
}
#PDFBug .stats .title {
font-weight: bold;
}
#PDFBug table {
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 {
float: left;
left: 180px;
}
html[dir='rtl'] #outerContainer.sidebarMoving .outerCenter,
html[dir='rtl'] #outerContainer.sidebarOpen .outerCenter {
--- a/browser/extensions/pdfjs/content/web/viewer.html
+++ b/browser/extensions/pdfjs/content/web/viewer.html
@@ -17,29 +17,29 @@
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
var PDFJS = {};
(function pdfjsWrapper() {
// Use strict in our context only - users might not want it
'use strict';
- PDFJS.build = '5ac7513';
+ PDFJS.build = '121040a';
// Files are inserted below - see Makefile
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
'use strict';
var globalScope = (typeof window === 'undefined') ? this : window;
var isWorker = (typeof window == 'undefined');
-var ERRORS = 0, WARNINGS = 1, TODOS = 5;
+var ERRORS = 0, WARNINGS = 1, INFOS = 5;
var verbosity = WARNINGS;
// The global PDFJS object exposes the API
// In production, it will be declared outside a global wrapper
// In development, it will be declared here
if (!globalScope.PDFJS) {
globalScope.PDFJS = {};
}
@@ -173,32 +173,74 @@ var Page = (function PageClosure() {
getOperatorList: function Page_getOperatorList(handler, dependency) {
var xref = this.xref;
var content = this.content;
var resources = this.resources;
if (isArray(content)) {
// fetching items
var streams = [];
var i, n = content.length;
+ var streams = [];
for (i = 0; i < n; ++i)
streams.push(xref.fetchIfRef(content[i]));
content = new StreamsSequenceStream(streams);
} else if (isStream(content)) {
content.reset();
} else if (!content) {
// replacing non-existent page content with empty one
content = new Stream(new Uint8Array(0));
}
var pe = this.pe = new PartialEvaluator(
xref, handler, 'p' + this.pageNumber + '_');
return pe.getOperatorList(content, resources, dependency);
},
-
+ extractTextContent: function Page_extractTextContent() {
+ var handler = {
+ on: function nullHandlerOn() {},
+ send: function nullHandlerSend() {}
+ };
+
+ var xref = this.xref;
+ var content = xref.fetchIfRef(this.content);
+ var resources = xref.fetchIfRef(this.resources);
+ if (isArray(content)) {
+ // fetching items
+ var i, n = content.length;
+ var streams = [];
+ for (i = 0; i < n; ++i)
+ streams.push(xref.fetchIfRef(content[i]));
+ content = new StreamsSequenceStream(streams);
+ } else if (isStream(content)) {
+ content.reset();
+ }
+
+ var pe = new PartialEvaluator(
+ xref, handler, 'p' + this.pageNumber + '_');
+ return pe.getTextContent(content, resources);
+ },
+
+ ensureFonts: function Page_ensureFonts(fonts, callback) {
+ this.stats.time('Font Loading');
+ // Convert the font names to the corresponding font obj.
+ for (var i = 0, ii = fonts.length; i < ii; i++) {
+ fonts[i] = this.objs.objs[fonts[i]].data;
+ }
+
+ // Load all the fonts
+ FontLoader.bind(
+ fonts,
+ function pageEnsureFontsFontObjs(fontObjs) {
+ this.stats.timeEnd('Font Loading');
+
+ callback.call(this);
+ }.bind(this)
+ );
+ },
getLinks: function Page_getLinks() {
var links = [];
var annotations = pageGetAnnotations();
var i, n = annotations.length;
for (i = 0; i < n; ++i) {
if (annotations[i].type != 'Link')
continue;
links.push(annotations[i]);
@@ -503,67 +545,98 @@ var PDFDocument = (function PDFDocumentC
getPage: function PDFDocument_getPage(n) {
return this.catalog.getPage(n);
}
};
return PDFDocument;
})();
+
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
'use strict';
+// Use only for debugging purposes. This should not be used in any code that is
+// in mozilla master.
function log(msg) {
if (console && console.log)
console.log(msg);
else if (print)
print(msg);
}
+// A notice for devs that will not trigger the fallback UI. These are good
+// for things that are helpful to devs, such as warning that Workers were
+// disabled, which is important to devs but not end users.
+function info(msg) {
+ if (verbosity >= INFOS) {
+ log('Info: ' + msg);
+ PDFJS.LogManager.notify('info', msg);
+ }
+}
+
+// Non-fatal warnings that should trigger the fallback UI.
function warn(msg) {
- if (verbosity >= WARNINGS)
+ if (verbosity >= WARNINGS) {
log('Warning: ' + msg);
+ PDFJS.LogManager.notify('warn', msg);
+ }
+}
+
+// Fatal errors that should trigger the fallback UI and halt execution by
+// throwing an exception.
+function error(msg) {
+ log('Error: ' + msg);
+ log(backtrace());
+ PDFJS.LogManager.notify('error', msg);
+ throw new Error(msg);
+}
+
+// Missing features that should trigger the fallback UI.
+function TODO(what) {
+ warn('TODO: ' + what);
}
function backtrace() {
try {
throw new Error();
} catch (e) {
return e.stack ? e.stack.split('\n').slice(2).join('\n') : '';
}
}
-function error(msg) {
- log('Error: ' + msg);
- log(backtrace());
- throw new Error(msg);
-}
-
-function TODO(what) {
- if (verbosity >= TODOS)
- log('TODO: ' + what);
-}
-
-function malformed(msg) {
- error('Malformed PDF: ' + msg);
-}
-
function assert(cond, msg) {
if (!cond)
error(msg);
}
// In a well-formed PDF, |cond| holds. If it doesn't, subsequent
// behavior is undefined.
function assertWellFormed(cond, msg) {
if (!cond)
- malformed(msg);
-}
+ error(msg);
+}
+
+var LogManager = PDFJS.LogManager = (function LogManagerClosure() {
+ var loggers = [];
+ return {
+ addLogger: function logManager_addLogger(logger) {
+ loggers.push(logger);
+ },
+ notify: function(type, message) {
+ for (var i = 0, ii = loggers.length; i < ii; i++) {
+ var logger = loggers[i];
+ if (logger[type])
+ logger[type](message);
+ }
+ }
+ };
+})();
function shadow(obj, prop, value) {
Object.defineProperty(obj, prop, { value: value,
enumerable: true,
configurable: true,
writable: false });
return value;
}
@@ -807,16 +880,20 @@ function stringToPDFString(str) {
for (i = 0; i < n; ++i) {
var code = PDFStringTranslateTable[str.charCodeAt(i)];
str2 += code ? String.fromCharCode(code) : str.charAt(i);
}
}
return str2;
}
+function stringToUTF8String(str) {
+ return decodeURIComponent(escape(str));
+}
+
function isBool(v) {
return typeof v == 'boolean';
}
function isInt(v) {
return typeof v == 'number' && ((v | 0) == v);
}
@@ -1448,22 +1525,28 @@ var PDFPageProxy = (function PDFPageProx
stats.timeEnd('Rendering');
stats.timeEnd('Overall');
if (callback) callback();
}
}
next();
},
/**
- * Stub for future feature.
+ * @return {Promise} That is resolved with the a {string} that is the text
+ * content from the page.
*/
getTextContent: function PDFPageProxy_getTextContent() {
var promise = new PDFJS.Promise();
- var textContent = 'page text'; // not implemented
- promise.resolve(textContent);
+ this.transport.messageHandler.send('GetTextContent', {
+ pageIndex: this.pageNumber - 1
+ },
+ function textContentCallback(textContent) {
+ promise.resolve(textContent);
+ }
+ );
return promise;
},
/**
* Stub for future feature.
*/
getOperationList: function PDFPageProxy_getOperationList() {
var promise = new PDFJS.Promise();
var operationList = { // not implemented
@@ -1539,17 +1622,17 @@ var WorkerTransport = (function WorkerTr
}.bind(this));
var testObj = new Uint8Array(1);
// Some versions of Opera throw a DATA_CLONE_ERR on
// serializing the typed array.
messageHandler.send('test', testObj);
return;
} catch (e) {
- warn('The worker has been disabled.');
+ info('The worker has been disabled.');
}
}
// Either workers are disabled, not supported or have thrown an exception.
// Thus, we fallback to a faked worker.
globalScope.PDFJS.disableWorker = true;
this.setupFakeWorker();
}
WorkerTransport.prototype = {
@@ -2061,20 +2144,23 @@ var CanvasGraphics = (function CanvasGra
},
setDash: function CanvasGraphics_setDash(dashArray, dashPhase) {
this.ctx.mozDash = dashArray;
this.ctx.mozDashOffset = dashPhase;
this.ctx.webkitLineDash = dashArray;
this.ctx.webkitLineDashOffset = dashPhase;
},
setRenderingIntent: function CanvasGraphics_setRenderingIntent(intent) {
- TODO('set rendering intent: ' + intent);
+ // Maybe if we one day fully support color spaces this will be important
+ // for now we can ignore.
+ // TODO set rendering intent?
},
setFlatness: function CanvasGraphics_setFlatness(flatness) {
- TODO('set flatness: ' + flatness);
+ // There's no way to control this with canvas, but we can safely ignore.
+ // TODO set flatness?
},
setGState: function CanvasGraphics_setGState(states) {
for (var i = 0, ii = states.length; i < ii; i++) {
var state = states[i];
var key = state[0];
var value = state[1];
switch (key) {
@@ -2559,17 +2645,17 @@ var CanvasGraphics = (function CanvasGra
text.str += '\u00A0';
} else {
text.str += shownText.str;
}
text.canvasWidth += shownText.canvasWidth;
text.length += shownText.length;
}
} else {
- malformed('TJ array element ' + e + ' is not string or num');
+ error('TJ array element ' + e + ' is not string or num');
}
}
if (textSelection)
this.textLayer.appendText(text, font.loadedName, fontSize);
},
nextLineShowText: function CanvasGraphics_nextLineShowText(text) {
this.nextLine();
@@ -3097,25 +3183,41 @@ var Catalog = (function CatalogClosure()
this.xref = xref;
var obj = xref.getCatalogObj();
assertWellFormed(isDict(obj), 'catalog object is not a dictionary');
this.catDict = obj;
}
Catalog.prototype = {
get metadata() {
- var stream = this.catDict.get('Metadata');
+ var streamRef = this.catDict.getRaw('Metadata');
+ if (!isRef(streamRef))
+ return shadow(this, 'metadata', null);
+
+ var encryptMetadata = !this.xref.encrypt ? false :
+ this.xref.encrypt.encryptMetadata;
+
+ var stream = this.xref.fetch(streamRef, !encryptMetadata);
var metadata;
if (stream && isDict(stream.dict)) {
var type = stream.dict.get('Type');
var subtype = stream.dict.get('Subtype');
if (isName(type) && isName(subtype) &&
type.name === 'Metadata' && subtype.name === 'XML') {
- metadata = stringToPDFString(bytesToString(stream.getBytes()));
+ // XXX: This should examine the charset the XML document defines,
+ // however since there are currently no real means to decode
+ // arbitrary charsets, let's just hope that the author of the PDF
+ // was reasonable enough to stick with the XML default charset,
+ // which is UTF-8.
+ try {
+ metadata = stringToUTF8String(bytesToString(stream.getBytes()));
+ } catch (e) {
+ info('Skipping invalid metadata.');
+ }
}
}
return shadow(this, 'metadata', metadata);
},
get toplevelPagesDict() {
var pagesObj = this.catDict.get('Pages');
assertWellFormed(isDict(pagesObj), 'invalid top-level pages dictionary');
@@ -12150,22 +12252,22 @@ var LabCS = (function LabCSClosure() {
this.YB = blackPoint[1];
this.ZB = blackPoint[2];
// Validate vars as per spec
if (this.XW < 0 || this.ZW < 0 || this.YW !== 1)
error('Invalid WhitePoint components, no fallback available');
if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
- warn('Invalid BlackPoint, falling back to default');
+ info('Invalid BlackPoint, falling back to default');
this.XB = this.YB = this.ZB = 0;
}
if (this.amin > this.amax || this.bmin > this.bmax) {
- warn('Invalid Range, falling back to defaults');
+ info('Invalid Range, falling back to defaults');
this.amin = -100;
this.amax = 100;
this.bmin = -100;
this.bmax = 100;
}
};
// Function g(x) from spec
@@ -12778,18 +12880,20 @@ var CipherTransformFactory = (function C
if (!isInt(keyLength) ||
keyLength < 40 || (keyLength % 8) != 0)
error('invalid key length');
// prepare keys
var ownerPassword = stringToBytes(dict.get('O'));
var userPassword = stringToBytes(dict.get('U'));
var flags = dict.get('P');
var revision = dict.get('R');
- var encryptMetadata =
+ var encryptMetadata = algorithm == 4 && // meaningful when V is 4
dict.get('EncryptMetadata') !== false; // makes true as default value
+ this.encryptMetadata = encryptMetadata;
+
var fileIdBytes = stringToBytes(fileId);
var passwordBytes;
if (password)
passwordBytes = stringToBytes(password);
var encryptionKey = prepareKeyData(fileIdBytes, passwordBytes,
ownerPassword, userPassword, flags,
revision, keyLength, encryptMetadata);
@@ -13035,18 +13139,19 @@ var PartialEvaluator = (function Partial
var loadedName = null;
var fontRes = resources.get('Font');
assert(fontRes, 'fontRes not available');
font = xref.fetchIfRef(font) || fontRes.get(fontName);
assertWellFormed(isDict(font));
+
++self.objIdCounter;
- if (!font.translated) {
+ if (!font.loadedName) {
font.translated = self.translateFont(font, xref, resources,
dependency);
if (font.translated) {
// keep track of each font we translated so the caller can
// load them asynchronously before calling display on a page
loadedName = 'font_' + uniquePrefix + self.objIdCounter;
font.translated.properties.loadedName = loadedName;
font.loadedName = loadedName;
@@ -13299,36 +13404,47 @@ var PartialEvaluator = (function Partial
break;
case 'Font':
gsStateObj.push([
'Font',
handleSetFont(null, value[0]),
value[1]
]);
break;
+ case 'BM':
+ // We support the default so don't trigger the TODO.
+ if (!isName(value) || value.name != 'Normal')
+ TODO('graphic state operator ' + key);
+ break;
+ case 'SMask':
+ // We support the default so don't trigger the TODO.
+ if (!isName(value) || value.name != 'None')
+ TODO('graphic state operator ' + key);
+ break;
+ // Only generate info log messages for the following since
+ // they are unlikey to have a big impact on the rendering.
case 'OP':
case 'op':
case 'OPM':
case 'BG':
case 'BG2':
case 'UCR':
case 'UCR2':
case 'TR':
case 'TR2':
case 'HT':
case 'SM':
case 'SA':
- case 'BM':
- case 'SMask':
case 'AIS':
case 'TK':
- TODO('graphic state operator ' + key);
+ // TODO implement these operators.
+ info('graphic state operator ' + key);
break;
default:
- warn('Unknown graphic state operator ' + key);
+ info('Unknown graphic state operator ' + key);
break;
}
}
);
args = [gsStateObj];
break;
} // switch
@@ -13339,16 +13455,91 @@ var PartialEvaluator = (function Partial
assertWellFormed(args.length <= 33, 'Too many arguments');
args.push(obj instanceof Dict ? obj.getAll() : obj);
}
}
return queue;
},
+ getTextContent: function partialEvaluatorGetIRQueue(stream, resources) {
+
+ var self = this;
+ var xref = this.xref;
+
+ function handleSetFont(fontName, fontRef) {
+ var fontRes = resources.get('Font');
+
+ // TODO: TOASK: Is it possible to get here? If so, what does
+ // args[0].name should be like???
+ assert(fontRes, 'fontRes not available');
+
+ fontRes = xref.fetchIfRef(fontRes);
+ fontRef = fontRef || fontRes.get(fontName);
+ var font = xref.fetchIfRef(fontRef), tra;
+ assertWellFormed(isDict(font));
+ if (!font.translated) {
+ font.translated = self.translateFont(font, xref, resources);
+ }
+ return font;
+ }
+
+ resources = xref.fetchIfRef(resources) || new Dict();
+
+ var parser = new Parser(new Lexer(stream), false);
+ var res = resources;
+ var args = [], obj;
+
+ var text = '';
+ var chunk = '';
+ var font = null;
+ while (!isEOF(obj = parser.getObj())) {
+ if (isCmd(obj)) {
+ var cmd = obj.cmd;
+ switch (cmd) {
+ case 'Tf':
+ font = handleSetFont(args[0].name);
+ break;
+ case 'TJ':
+ var items = args[0];
+ for (var j = 0, jj = items.length; j < jj; j++) {
+ if (typeof items[j] === 'string') {
+ chunk += items[j];
+ } else if (items[j] < 0) {
+ // making all negative offsets a space - better to have
+ // a space in incorrect place than not have them at all
+ chunk += ' ';
+ }
+ }
+ break;
+ case 'Tj':
+ chunk += args[0];
+ break;
+ case "'":
+ chunk += args[0] + ' ';
+ break;
+ case '"':
+ chunk += args[2] + ' ';
+ break;
+ } // switch
+ if (chunk !== '') {
+ text += fontCharsToUnicode(chunk, font.translated.properties);
+ chunk = '';
+ }
+
+ args = [];
+ } else if (obj != null) {
+ assertWellFormed(args.length <= 33, 'Too many arguments');
+ args.push(obj);
+ }
+ }
+
+ return text;
+ },
+
extractDataStructures: function
partialEvaluatorExtractDataStructures(dict, baseDict,
xref, properties) {
// 9.10.2
var toUnicode = dict.get('ToUnicode') ||
baseDict.get('ToUnicode');
if (toUnicode)
properties.toUnicode = this.readToUnicode(toUnicode, xref, properties);
@@ -13492,18 +13683,19 @@ var PartialEvaluator = (function Partial
while (tokens.length &&
(item = tokens.pop()) != beginArrayToken)
items.unshift(item);
tokens.push(items);
break;
}
} else if (octet == 0x3E) {
if (token.length) {
- // XXX guessing chars size by checking number size in the CMap
- if (token.length <= 2 && properties.composite)
+ // Heuristic: guessing chars size by checking numbers sizes
+ // in the CMap entries.
+ if (token.length == 2 && properties.composite)
properties.wideChars = false;
if (token.length <= 4) {
// parsing hex number
tokens.push(parseInt(token, 16));
token = '';
} else {
// parsing hex UTF-16BE numbers
@@ -14533,16 +14725,746 @@ function isRTLRangeFor(value) {
}
function isSpecialUnicode(unicode) {
return (unicode <= 0x1F || (unicode >= 127 && unicode < kSizeOfGlyphArea)) ||
(unicode >= kCmapGlyphOffset &&
unicode < kCmapGlyphOffset + kSizeOfGlyphArea);
}
+// The normalization table is obtained by filtering the Unicode characters
+// database with <compat> entries.
+var NormalizedUnicodes = {
+ '\u00A8': '\u0020\u0308',
+ '\u00AF': '\u0020\u0304',
+ '\u00B4': '\u0020\u0301',
+ '\u00B5': '\u03BC',
+ '\u00B8': '\u0020\u0327',
+ '\u0132': '\u0049\u004A',
+ '\u0133': '\u0069\u006A',
+ '\u013F': '\u004C\u00B7',
+ '\u0140': '\u006C\u00B7',
+ '\u0149': '\u02BC\u006E',
+ '\u017F': '\u0073',
+ '\u01C4': '\u0044\u017D',
+ '\u01C5': '\u0044\u017E',
+ '\u01C6': '\u0064\u017E',
+ '\u01C7': '\u004C\u004A',
+ '\u01C8': '\u004C\u006A',
+ '\u01C9': '\u006C\u006A',
+ '\u01CA': '\u004E\u004A',
+ '\u01CB': '\u004E\u006A',
+ '\u01CC': '\u006E\u006A',
+ '\u01F1': '\u0044\u005A',
+ '\u01F2': '\u0044\u007A',
+ '\u01F3': '\u0064\u007A',
+ '\u02D8': '\u0020\u0306',
+ '\u02D9': '\u0020\u0307',
+ '\u02DA': '\u0020\u030A',
+ '\u02DB': '\u0020\u0328',
+ '\u02DC': '\u0020\u0303',
+ '\u02DD': '\u0020\u030B',
+ '\u037A': '\u0020\u0345',
+ '\u0384': '\u0020\u0301',
+ '\u03D0': '\u03B2',
+ '\u03D1': '\u03B8',
+ '\u03D2': '\u03A5',
+ '\u03D5': '\u03C6',
+ '\u03D6': '\u03C0',
+ '\u03F0': '\u03BA',
+ '\u03F1': '\u03C1',
+ '\u03F2': '\u03C2',
+ '\u03F4': '\u0398',
+ '\u03F5': '\u03B5',
+ '\u03F9': '\u03A3',
+ '\u0587': '\u0565\u0582',
+ '\u0675': '\u0627\u0674',
+ '\u0676': '\u0648\u0674',
+ '\u0677': '\u06C7\u0674',
+ '\u0678': '\u064A\u0674',
+ '\u0E33': '\u0E4D\u0E32',
+ '\u0EB3': '\u0ECD\u0EB2',
+ '\u0EDC': '\u0EAB\u0E99',
+ '\u0EDD': '\u0EAB\u0EA1',
+ '\u0F77': '\u0FB2\u0F81',
+ '\u0F79': '\u0FB3\u0F81',
+ '\u1E9A': '\u0061\u02BE',
+ '\u1FBD': '\u0020\u0313',
+ '\u1FBF': '\u0020\u0313',
+ '\u1FC0': '\u0020\u0342',
+ '\u1FFE': '\u0020\u0314',
+ '\u2002': '\u0020',
+ '\u2003': '\u0020',
+ '\u2004': '\u0020',
+ '\u2005': '\u0020',
+ '\u2006': '\u0020',
+ '\u2008': '\u0020',
+ '\u2009': '\u0020',
+ '\u200A': '\u0020',
+ '\u2017': '\u0020\u0333',
+ '\u2024': '\u002E',
+ '\u2025': '\u002E\u002E',
+ '\u2026': '\u002E\u002E\u002E',
+ '\u2033': '\u2032\u2032',
+ '\u2034': '\u2032\u2032\u2032',
+ '\u2036': '\u2035\u2035',
+ '\u2037': '\u2035\u2035\u2035',
+ '\u203C': '\u0021\u0021',
+ '\u203E': '\u0020\u0305',
+ '\u2047': '\u003F\u003F',
+ '\u2048': '\u003F\u0021',
+ '\u2049': '\u0021\u003F',
+ '\u2057': '\u2032\u2032\u2032\u2032',
+ '\u205F': '\u0020',
+ '\u20A8': '\u0052\u0073',
+ '\u2100': '\u0061\u002F\u0063',
+ '\u2101': '\u0061\u002F\u0073',
+ '\u2103': '\u00B0\u0043',
+ '\u2105': '\u0063\u002F\u006F',
+ '\u2106': '\u0063\u002F\u0075',
+ '\u2107': '\u0190',
+ '\u2109': '\u00B0\u0046',
+ '\u2116': '\u004E\u006F',
+ '\u2121': '\u0054\u0045\u004C',
+ '\u2135': '\u05D0',
+ '\u2136': '\u05D1',
+ '\u2137': '\u05D2',
+ '\u2138': '\u05D3',
+ '\u213B': '\u0046\u0041\u0058',
+ '\u2160': '\u0049',
+ '\u2161': '\u0049\u0049',
+ '\u2162': '\u0049\u0049\u0049',
+ '\u2163': '\u0049\u0056',
+ '\u2164': '\u0056',
+ '\u2165': '\u0056\u0049',
+ '\u2166': '\u0056\u0049\u0049',
+ '\u2167': '\u0056\u0049\u0049\u0049',
+ '\u2168': '\u0049\u0058',
+ '\u2169': '\u0058',
+ '\u216A': '\u0058\u0049',
+ '\u216B': '\u0058\u0049\u0049',
+ '\u216C': '\u004C',
+ '\u216D': '\u0043',
+ '\u216E': '\u0044',
+ '\u216F': '\u004D',
+ '\u2170': '\u0069',
+ '\u2171': '\u0069\u0069',
+ '\u2172': '\u0069\u0069\u0069',
+ '\u2173': '\u0069\u0076',
+ '\u2174': '\u0076',
+ '\u2175': '\u0076\u0069',
+ '\u2176': '\u0076\u0069\u0069',
+ '\u2177': '\u0076\u0069\u0069\u0069',
+ '\u2178': '\u0069\u0078',
+ '\u2179': '\u0078',
+ '\u217A': '\u0078\u0069',
+ '\u217B': '\u0078\u0069\u0069',
+ '\u217C': '\u006C',
+ '\u217D': '\u0063',
+ '\u217E': '\u0064',
+ '\u217F': '\u006D',
+ '\u222C': '\u222B\u222B',
+ '\u222D': '\u222B\u222B\u222B',
+ '\u222F': '\u222E\u222E',
+ '\u2230': '\u222E\u222E\u222E',
+ '\u2474': '\u0028\u0031\u0029',
+ '\u2475': '\u0028\u0032\u0029',
+ '\u2476': '\u0028\u0033\u0029',
+ '\u2477': '\u0028\u0034\u0029',
+ '\u2478': '\u0028\u0035\u0029',
+ '\u2479': '\u0028\u0036\u0029',
+ '\u247A': '\u0028\u0037\u0029',
+ '\u247B': '\u0028\u0038\u0029',
+ '\u247C': '\u0028\u0039\u0029',
+ '\u247D': '\u0028\u0031\u0030\u0029',
+ '\u247E': '\u0028\u0031\u0031\u0029',
+ '\u247F': '\u0028\u0031\u0032\u0029',
+ '\u2480': '\u0028\u0031\u0033\u0029',
+ '\u2481': '\u0028\u0031\u0034\u0029',
+ '\u2482': '\u0028\u0031\u0035\u0029',
+ '\u2483': '\u0028\u0031\u0036\u0029',
+ '\u2484': '\u0028\u0031\u0037\u0029',
+ '\u2485': '\u0028\u0031\u0038\u0029',
+ '\u2486': '\u0028\u0031\u0039\u0029',
+ '\u2487': '\u0028\u0032\u0030\u0029',
+ '\u2488': '\u0031\u002E',
+ '\u2489': '\u0032\u002E',
+ '\u248A': '\u0033\u002E',
+ '\u248B': '\u0034\u002E',
+ '\u248C': '\u0035\u002E',
+ '\u248D': '\u0036\u002E',
+ '\u248E': '\u0037\u002E',
+ '\u248F': '\u0038\u002E',
+ '\u2490': '\u0039\u002E',
+ '\u2491': '\u0031\u0030\u002E',
+ '\u2492': '\u0031\u0031\u002E',
+ '\u2493': '\u0031\u0032\u002E',
+ '\u2494': '\u0031\u0033\u002E',
+ '\u2495': '\u0031\u0034\u002E',
+ '\u2496': '\u0031\u0035\u002E',
+ '\u2497': '\u0031\u0036\u002E',
+ '\u2498': '\u0031\u0037\u002E',
+ '\u2499': '\u0031\u0038\u002E',
+ '\u249A': '\u0031\u0039\u002E',
+ '\u249B': '\u0032\u0030\u002E',
+ '\u249C': '\u0028\u0061\u0029',
+ '\u249D': '\u0028\u0062\u0029',
+ '\u249E': '\u0028\u0063\u0029',
+ '\u249F': '\u0028\u0064\u0029',
+ '\u24A0': '\u0028\u0065\u0029',
+ '\u24A1': '\u0028\u0066\u0029',
+ '\u24A2': '\u0028\u0067\u0029',
+ '\u24A3': '\u0028\u0068\u0029',
+ '\u24A4': '\u0028\u0069\u0029',
+ '\u24A5': '\u0028\u006A\u0029',
+ '\u24A6': '\u0028\u006B\u0029',
+ '\u24A7': '\u0028\u006C\u0029',
+ '\u24A8': '\u0028\u006D\u0029',
+ '\u24A9': '\u0028\u006E\u0029',
+ '\u24AA': '\u0028\u006F\u0029',
+ '\u24AB': '\u0028\u0070\u0029',
+ '\u24AC': '\u0028\u0071\u0029',
+ '\u24AD': '\u0028\u0072\u0029',
+ '\u24AE': '\u0028\u0073\u0029',
+ '\u24AF': '\u0028\u0074\u0029',
+ '\u24B0': '\u0028\u0075\u0029',
+ '\u24B1': '\u0028\u0076\u0029',
+ '\u24B2': '\u0028\u0077\u0029',
+ '\u24B3': '\u0028\u0078\u0029',
+ '\u24B4': '\u0028\u0079\u0029',
+ '\u24B5': '\u0028\u007A\u0029',
+ '\u2A0C': '\u222B\u222B\u222B\u222B',
+ '\u2A74': '\u003A\u003A\u003D',
+ '\u2A75': '\u003D\u003D',
+ '\u2A76': '\u003D\u003D\u003D',
+ '\u2E9F': '\u6BCD',
+ '\u2EF3': '\u9F9F',
+ '\u2F00': '\u4E00',
+ '\u2F01': '\u4E28',
+ '\u2F02': '\u4E36',
+ '\u2F03': '\u4E3F',
+ '\u2F04': '\u4E59',
+ '\u2F05': '\u4E85',
+ '\u2F06': '\u4E8C',
+ '\u2F07': '\u4EA0',
+ '\u2F08': '\u4EBA',
+ '\u2F09': '\u513F',
+ '\u2F0A': '\u5165',
+ '\u2F0B': '\u516B',
+ '\u2F0C': '\u5182',
+ '\u2F0D': '\u5196',
+ '\u2F0E': '\u51AB',
+ '\u2F0F': '\u51E0',
+ '\u2F10': '\u51F5',
+ '\u2F11': '\u5200',
+ '\u2F12': '\u529B',
+ '\u2F13': '\u52F9',
+ '\u2F14': '\u5315',
+ '\u2F15': '\u531A',
+ '\u2F16': '\u5338',
+ '\u2F17': '\u5341',
+ '\u2F18': '\u535C',
+ '\u2F19': '\u5369',
+ '\u2F1A': '\u5382',
+ '\u2F1B': '\u53B6',
+ '\u2F1C': '\u53C8',
+ '\u2F1D': '\u53E3',
+ '\u2F1E': '\u56D7',
+ '\u2F1F': '\u571F',
+ '\u2F20': '\u58EB',
+ '\u2F21': '\u5902',
+ '\u2F22': '\u590A',
+ '\u2F23': '\u5915',
+ '\u2F24': '\u5927',
+ '\u2F25': '\u5973',
+ '\u2F26': '\u5B50',
+ '\u2F27': '\u5B80',
+ '\u2F28': '\u5BF8',
+ '\u2F29': '\u5C0F',
+ '\u2F2A': '\u5C22',
+ '\u2F2B': '\u5C38',
+ '\u2F2C': '\u5C6E',
+ '\u2F2D': '\u5C71',
+ '\u2F2E': '\u5DDB',
+ '\u2F2F': '\u5DE5',
+ '\u2F30': '\u5DF1',
+ '\u2F31': '\u5DFE',
+ '\u2F32': '\u5E72',
+ '\u2F33': '\u5E7A',
+ '\u2F34': '\u5E7F',
+ '\u2F35': '\u5EF4',
+ '\u2F36': '\u5EFE',
+ '\u2F37': '\u5F0B',
+ '\u2F38': '\u5F13',
+ '\u2F39': '\u5F50',
+ '\u2F3A': '\u5F61',
+ '\u2F3B': '\u5F73',
+ '\u2F3C': '\u5FC3',
+ '\u2F3D': '\u6208',
+ '\u2F3E': '\u6236',
+ '\u2F3F': '\u624B',
+ '\u2F40': '\u652F',
+ '\u2F41': '\u6534',
+ '\u2F42': '\u6587',
+ '\u2F43': '\u6597',
+ '\u2F44': '\u65A4',
+ '\u2F45': '\u65B9',
+ '\u2F46': '\u65E0',
+ '\u2F47': '\u65E5',
+ '\u2F48': '\u66F0',
+ '\u2F49': '\u6708',
+ '\u2F4A': '\u6728',
+ '\u2F4B': '\u6B20',
+ '\u2F4C': '\u6B62',
+ '\u2F4D': '\u6B79',
+ '\u2F4E': '\u6BB3',
+ '\u2F4F': '\u6BCB',
+ '\u2F50': '\u6BD4',
+ '\u2F51': '\u6BDB',
+ '\u2F52': '\u6C0F',
+ '\u2F53': '\u6C14',
+ '\u2F54': '\u6C34',
+ '\u2F55': '\u706B',
+ '\u2F56': '\u722A',
+ '\u2F57': '\u7236',
+ '\u2F58': '\u723B',
+ '\u2F59': '\u723F',
+ '\u2F5A': '\u7247',
+ '\u2F5B': '\u7259',
+ '\u2F5C': '\u725B',
+ '\u2F5D': '\u72AC',
+ '\u2F5E': '\u7384',
+ '\u2F5F': '\u7389',
+ '\u2F60': '\u74DC',
+ '\u2F61': '\u74E6',
+ '\u2F62': '\u7518',
+ '\u2F63': '\u751F',
+ '\u2F64': '\u7528',
+ '\u2F65': '\u7530',
+ '\u2F66': '\u758B',
+ '\u2F67': '\u7592',
+ '\u2F68': '\u7676',
+ '\u2F69': '\u767D',
+ '\u2F6A': '\u76AE',
+ '\u2F6B': '\u76BF',
+ '\u2F6C': '\u76EE',
+ '\u2F6D': '\u77DB',
+ '\u2F6E': '\u77E2',
+ '\u2F6F': '\u77F3',
+ '\u2F70': '\u793A',
+ '\u2F71': '\u79B8',
+ '\u2F72': '\u79BE',
+ '\u2F73': '\u7A74',
+ '\u2F74': '\u7ACB',
+ '\u2F75': '\u7AF9',
+ '\u2F76': '\u7C73',
+ '\u2F77': '\u7CF8',
+ '\u2F78': '\u7F36',
+ '\u2F79': '\u7F51',
+ '\u2F7A': '\u7F8A',
+ '\u2F7B': '\u7FBD',
+ '\u2F7C': '\u8001',
+ '\u2F7D': '\u800C',
+ '\u2F7E': '\u8012',
+ '\u2F7F': '\u8033',
+ '\u2F80': '\u807F',
+ '\u2F81': '\u8089',
+ '\u2F82': '\u81E3',
+ '\u2F83': '\u81EA',
+ '\u2F84': '\u81F3',
+ '\u2F85': '\u81FC',
+ '\u2F86': '\u820C',
+ '\u2F87': '\u821B',
+ '\u2F88': '\u821F',
+ '\u2F89': '\u826E',
+ '\u2F8A': '\u8272',
+ '\u2F8B': '\u8278',
+ '\u2F8C': '\u864D',
+ '\u2F8D': '\u866B',
+ '\u2F8E': '\u8840',
+ '\u2F8F': '\u884C',
+ '\u2F90': '\u8863',
+ '\u2F91': '\u897E',
+ '\u2F92': '\u898B',
+ '\u2F93': '\u89D2',
+ '\u2F94': '\u8A00',
+ '\u2F95': '\u8C37',
+ '\u2F96': '\u8C46',
+ '\u2F97': '\u8C55',
+ '\u2F98': '\u8C78',
+ '\u2F99': '\u8C9D',
+ '\u2F9A': '\u8D64',
+ '\u2F9B': '\u8D70',
+ '\u2F9C': '\u8DB3',
+ '\u2F9D': '\u8EAB',
+ '\u2F9E': '\u8ECA',
+ '\u2F9F': '\u8F9B',
+ '\u2FA0': '\u8FB0',
+ '\u2FA1': '\u8FB5',
+ '\u2FA2': '\u9091',
+ '\u2FA3': '\u9149',
+ '\u2FA4': '\u91C6',
+ '\u2FA5': '\u91CC',
+ '\u2FA6': '\u91D1',
+ '\u2FA7': '\u9577',
+ '\u2FA8': '\u9580',
+ '\u2FA9': '\u961C',
+ '\u2FAA': '\u96B6',
+ '\u2FAB': '\u96B9',
+ '\u2FAC': '\u96E8',
+ '\u2FAD': '\u9751',
+ '\u2FAE': '\u975E',
+ '\u2FAF': '\u9762',
+ '\u2FB0': '\u9769',
+ '\u2FB1': '\u97CB',
+ '\u2FB2': '\u97ED',
+ '\u2FB3': '\u97F3',
+ '\u2FB4': '\u9801',
+ '\u2FB5': '\u98A8',
+ '\u2FB6': '\u98DB',
+ '\u2FB7': '\u98DF',
+ '\u2FB8': '\u9996',
+ '\u2FB9': '\u9999',
+ '\u2FBA': '\u99AC',
+ '\u2FBB': '\u9AA8',
+ '\u2FBC': '\u9AD8',
+ '\u2FBD': '\u9ADF',
+ '\u2FBE': '\u9B25',
+ '\u2FBF': '\u9B2F',
+ '\u2FC0': '\u9B32',
+ '\u2FC1': '\u9B3C',
+ '\u2FC2': '\u9B5A',
+ '\u2FC3': '\u9CE5',
+ '\u2FC4': '\u9E75',
+ '\u2FC5': '\u9E7F',
+ '\u2FC6': '\u9EA5',
+ '\u2FC7': '\u9EBB',
+ '\u2FC8': '\u9EC3',
+ '\u2FC9': '\u9ECD',
+ '\u2FCA': '\u9ED1',
+ '\u2FCB': '\u9EF9',
+ '\u2FCC': '\u9EFD',
+ '\u2FCD': '\u9F0E',
+ '\u2FCE': '\u9F13',
+ '\u2FCF': '\u9F20',
+ '\u2FD0': '\u9F3B',
+ '\u2FD1': '\u9F4A',
+ '\u2FD2': '\u9F52',
+ '\u2FD3': '\u9F8D',
+ '\u2FD4': '\u9F9C',
+ '\u2FD5': '\u9FA0',
+ '\u3036': '\u3012',
+ '\u3038': '\u5341',
+ '\u3039': '\u5344',
+ '\u303A': '\u5345',
+ '\u309B': '\u0020\u3099',
+ '\u309C': '\u0020\u309A',
+ '\u3131': '\u1100',
+ '\u3132': '\u1101',
+ '\u3133': '\u11AA',
+ '\u3134': '\u1102',
+ '\u3135': '\u11AC',
+ '\u3136': '\u11AD',
+ '\u3137': '\u1103',
+ '\u3138': '\u1104',
+ '\u3139': '\u1105',
+ '\u313A': '\u11B0',
+ '\u313B': '\u11B1',
+ '\u313C': '\u11B2',
+ '\u313D': '\u11B3',
+ '\u313E': '\u11B4',
+ '\u313F': '\u11B5',
+ '\u3140': '\u111A',
+ '\u3141': '\u1106',
+ '\u3142': '\u1107',
+ '\u3143': '\u1108',
+ '\u3144': '\u1121',
+ '\u3145': '\u1109',
+ '\u3146': '\u110A',
+ '\u3147': '\u110B',
+ '\u3148': '\u110C',
+ '\u3149': '\u110D',
+ '\u314A': '\u110E',
+ '\u314B': '\u110F',
+ '\u314C': '\u1110',
+ '\u314D': '\u1111',
+ '\u314E': '\u1112',
+ '\u314F': '\u1161',
+ '\u3150': '\u1162',
+ '\u3151': '\u1163',
+ '\u3152': '\u1164',
+ '\u3153': '\u1165',
+ '\u3154': '\u1166',
+ '\u3155': '\u1167',
+ '\u3156': '\u1168',
+ '\u3157': '\u1169',
+ '\u3158': '\u116A',
+ '\u3159': '\u116B',
+ '\u315A': '\u116C',
+ '\u315B': '\u116D',
+ '\u315C': '\u116E',
+ '\u315D': '\u116F',
+ '\u315E': '\u1170',
+ '\u315F': '\u1171',
+ '\u3160': '\u1172',
+ '\u3161': '\u1173',
+ '\u3162': '\u1174',
+ '\u3163': '\u1175',
+ '\u3164': '\u1160',
+ '\u3165': '\u1114',
+ '\u3166': '\u1115',
+ '\u3167': '\u11C7',
+ '\u3168': '\u11C8',
+ '\u3169': '\u11CC',
+ '\u316A': '\u11CE',
+ '\u316B': '\u11D3',
+ '\u316C': '\u11D7',
+ '\u316D': '\u11D9',
+ '\u316E': '\u111C',
+ '\u316F': '\u11DD',
+ '\u3170': '\u11DF',
+ '\u3171': '\u111D',
+ '\u3172': '\u111E',
+ '\u3173': '\u1120',
+ '\u3174': '\u1122',
+ '\u3175': '\u1123',
+ '\u3176': '\u1127',
+ '\u3177': '\u1129',
+ '\u3178': '\u112B',
+ '\u3179': '\u112C',
+ '\u317A': '\u112D',
+ '\u317B': '\u112E',
+ '\u317C': '\u112F',
+ '\u317D': '\u1132',
+ '\u317E': '\u1136',
+ '\u317F': '\u1140',
+ '\u3180': '\u1147',
+ '\u3181': '\u114C',
+ '\u3182': '\u11F1',
+ '\u3183': '\u11F2',
+ '\u3184': '\u1157',
+ '\u3185': '\u1158',
+ '\u3186': '\u1159',
+ '\u3187': '\u1184',
+ '\u3188': '\u1185',
+ '\u3189': '\u1188',
+ '\u318A': '\u1191',
+ '\u318B': '\u1192',
+ '\u318C': '\u1194',
+ '\u318D': '\u119E',
+ '\u318E': '\u11A1',
+ '\u3200': '\u0028\u1100\u0029',
+ '\u3201': '\u0028\u1102\u0029',
+ '\u3202': '\u0028\u1103\u0029',
+ '\u3203': '\u0028\u1105\u0029',
+ '\u3204': '\u0028\u1106\u0029',
+ '\u3205': '\u0028\u1107\u0029',
+ '\u3206': '\u0028\u1109\u0029',
+ '\u3207': '\u0028\u110B\u0029',
+ '\u3208': '\u0028\u110C\u0029',
+ '\u3209': '\u0028\u110E\u0029',
+ '\u320A': '\u0028\u110F\u0029',
+ '\u320B': '\u0028\u1110\u0029',
+ '\u320C': '\u0028\u1111\u0029',
+ '\u320D': '\u0028\u1112\u0029',
+ '\u320E': '\u0028\u1100\u1161\u0029',
+ '\u320F': '\u0028\u1102\u1161\u0029',
+ '\u3210': '\u0028\u1103\u1161\u0029',
+ '\u3211': '\u0028\u1105\u1161\u0029',
+ '\u3212': '\u0028\u1106\u1161\u0029',
+ '\u3213': '\u0028\u1107\u1161\u0029',
+ '\u3214': '\u0028\u1109\u1161\u0029',
+ '\u3215': '\u0028\u110B\u1161\u0029',
+ '\u3216': '\u0028\u110C\u1161\u0029',
+ '\u3217': '\u0028\u110E\u1161\u0029',
+ '\u3218': '\u0028\u110F\u1161\u0029',
+ '\u3219': '\u0028\u1110\u1161\u0029',
+ '\u321A': '\u0028\u1111\u1161\u0029',
+ '\u321B': '\u0028\u1112\u1161\u0029',
+ '\u321C': '\u0028\u110C\u116E\u0029',
+ '\u321D': '\u0028\u110B\u1169\u110C\u1165\u11AB\u0029',
+ '\u321E': '\u0028\u110B\u1169\u1112\u116E\u0029',
+ '\u3220': '\u0028\u4E00\u0029',
+ '\u3221': '\u0028\u4E8C\u0029',
+ '\u3222': '\u0028\u4E09\u0029',
+ '\u3223': '\u0028\u56DB\u0029',
+ '\u3224': '\u0028\u4E94\u0029',
+ '\u3225': '\u0028\u516D\u0029',
+ '\u3226': '\u0028\u4E03\u0029',
+ '\u3227': '\u0028\u516B\u0029',
+ '\u3228': '\u0028\u4E5D\u0029',
+ '\u3229': '\u0028\u5341\u0029',
+ '\u322A': '\u0028\u6708\u0029',
+ '\u322B': '\u0028\u706B\u0029',
+ '\u322C': '\u0028\u6C34\u0029',
+ '\u322D': '\u0028\u6728\u0029',
+ '\u322E': '\u0028\u91D1\u0029',
+ '\u322F': '\u0028\u571F\u0029',
+ '\u3230': '\u0028\u65E5\u0029',
+ '\u3231': '\u0028\u682A\u0029',
+ '\u3232': '\u0028\u6709\u0029',
+ '\u3233': '\u0028\u793E\u0029',
+ '\u3234': '\u0028\u540D\u0029',
+ '\u3235': '\u0028\u7279\u0029',
+ '\u3236': '\u0028\u8CA1\u0029',
+ '\u3237': '\u0028\u795D\u0029',
+ '\u3238': '\u0028\u52B4\u0029',
+ '\u3239': '\u0028\u4EE3\u0029',
+ '\u323A': '\u0028\u547C\u0029',
+ '\u323B': '\u0028\u5B66\u0029',
+ '\u323C': '\u0028\u76E3\u0029',
+ '\u323D': '\u0028\u4F01\u0029',
+ '\u323E': '\u0028\u8CC7\u0029',
+ '\u323F': '\u0028\u5354\u0029',
+ '\u3240': '\u0028\u796D\u0029',
+ '\u3241': '\u0028\u4F11\u0029',
+ '\u3242': '\u0028\u81EA\u0029',
+ '\u3243': '\u0028\u81F3\u0029',
+ '\u32C0': '\u0031\u6708',
+ '\u32C1': '\u0032\u6708',
+ '\u32C2': '\u0033\u6708',
+ '\u32C3': '\u0034\u6708',
+ '\u32C4': '\u0035\u6708',
+ '\u32C5': '\u0036\u6708',
+ '\u32C6': '\u0037\u6708',
+ '\u32C7': '\u0038\u6708',
+ '\u32C8': '\u0039\u6708',
+ '\u32C9': '\u0031\u0030\u6708',
+ '\u32CA': '\u0031\u0031\u6708',
+ '\u32CB': '\u0031\u0032\u6708',
+ '\u3358': '\u0030\u70B9',
+ '\u3359': '\u0031\u70B9',
+ '\u335A': '\u0032\u70B9',
+ '\u335B': '\u0033\u70B9',
+ '\u335C': '\u0034\u70B9',
+ '\u335D': '\u0035\u70B9',
+ '\u335E': '\u0036\u70B9',
+ '\u335F': '\u0037\u70B9',
+ '\u3360': '\u0038\u70B9',
+ '\u3361': '\u0039\u70B9',
+ '\u3362': '\u0031\u0030\u70B9',
+ '\u3363': '\u0031\u0031\u70B9',
+ '\u3364': '\u0031\u0032\u70B9',
+ '\u3365': '\u0031\u0033\u70B9',
+ '\u3366': '\u0031\u0034\u70B9',
+ '\u3367': '\u0031\u0035\u70B9',
+ '\u3368': '\u0031\u0036\u70B9',
+ '\u3369': '\u0031\u0037\u70B9',
+ '\u336A': '\u0031\u0038\u70B9',
+ '\u336B': '\u0031\u0039\u70B9',
+ '\u336C': '\u0032\u0030\u70B9',
+ '\u336D': '\u0032\u0031\u70B9',
+ '\u336E': '\u0032\u0032\u70B9',
+ '\u336F': '\u0032\u0033\u70B9',
+ '\u3370': '\u0032\u0034\u70B9',
+ '\u33E0': '\u0031\u65E5',
+ '\u33E1': '\u0032\u65E5',
+ '\u33E2': '\u0033\u65E5',
+ '\u33E3': '\u0034\u65E5',
+ '\u33E4': '\u0035\u65E5',
+ '\u33E5': '\u0036\u65E5',
+ '\u33E6': '\u0037\u65E5',
+ '\u33E7': '\u0038\u65E5',
+ '\u33E8': '\u0039\u65E5',
+ '\u33E9': '\u0031\u0030\u65E5',
+ '\u33EA': '\u0031\u0031\u65E5',
+ '\u33EB': '\u0031\u0032\u65E5',
+ '\u33EC': '\u0031\u0033\u65E5',
+ '\u33ED': '\u0031\u0034\u65E5',
+ '\u33EE': '\u0031\u0035\u65E5',
+ '\u33EF': '\u0031\u0036\u65E5',
+ '\u33F0': '\u0031\u0037\u65E5',
+ '\u33F1': '\u0031\u0038\u65E5',
+ '\u33F2': '\u0031\u0039\u65E5',
+ '\u33F3': '\u0032\u0030\u65E5',
+ '\u33F4': '\u0032\u0031\u65E5',
+ '\u33F5': '\u0032\u0032\u65E5',
+ '\u33F6': '\u0032\u0033\u65E5',
+ '\u33F7': '\u0032\u0034\u65E5',
+ '\u33F8': '\u0032\u0035\u65E5',
+ '\u33F9': '\u0032\u0036\u65E5',
+ '\u33FA': '\u0032\u0037\u65E5',
+ '\u33FB': '\u0032\u0038\u65E5',
+ '\u33FC': '\u0032\u0039\u65E5',
+ '\u33FD': '\u0033\u0030\u65E5',
+ '\u33FE': '\u0033\u0031\u65E5',
+ '\uFB00': '\u0066\u0066',
+ '\uFB01': '\u0066\u0069',
+ '\uFB02': '\u0066\u006C',
+ '\uFB03': '\u0066\u0066\u0069',
+ '\uFB04': '\u0066\u0066\u006C',
+ '\uFB05': '\u017F\u0074',
+ '\uFB06': '\u0073\u0074',
+ '\uFB13': '\u0574\u0576',
+ '\uFB14': '\u0574\u0565',
+ '\uFB15': '\u0574\u056B',
+ '\uFB16': '\u057E\u0576',
+ '\uFB17': '\u0574\u056D',
+ '\uFB4F': '\u05D0\u05DC',
+ '\uFE49': '\u203E',
+ '\uFE4A': '\u203E',
+ '\uFE4B': '\u203E',
+ '\uFE4C': '\u203E',
+ '\uFE4D': '\u005F',
+ '\uFE4E': '\u005F',
+ '\uFE4F': '\u005F'
+};
+
+function fontCharsToUnicode(charCodes, fontProperties) {
+ var toUnicode = fontProperties.toUnicode;
+ var composite = fontProperties.composite;
+ var encoding, differences, cidToUnicode;
+ var result = '';
+ if (composite) {
+ cidToUnicode = fontProperties.cidToUnicode;
+ for (var i = 0, ii = charCodes.length; i < ii; i += 2) {
+ var charCode = (charCodes.charCodeAt(i) << 8) |
+ charCodes.charCodeAt(i + 1);
+ if (toUnicode && charCode in toUnicode) {
+ var unicode = toUnicode[charCode];
+ result += typeof unicode !== 'number' ? unicode :
+ String.fromCharCode(unicode);
+ continue;
+ }
+ result += String.fromCharCode(!cidToUnicode ? charCode :
+ cidToUnicode[charCode] || charCode);
+ }
+ } else {
+ differences = fontProperties.differences;
+ encoding = fontProperties.baseEncoding;
+ for (var i = 0, ii = charCodes.length; i < ii; i++) {
+ var charCode = charCodes.charCodeAt(i);
+ var unicode;
+ if (toUnicode && charCode in toUnicode) {
+ var unicode = toUnicode[charCode];
+ result += typeof unicode !== 'number' ? unicode :
+ String.fromCharCode(unicode);
+ continue;
+ }
+
+ var glyphName = charCode in differences ? differences[charCode] :
+ encoding[charCode];
+ if (glyphName in GlyphsUnicode) {
+ result += String.fromCharCode(GlyphsUnicode[glyphName]);
+ continue;
+ }
+ result += String.fromCharCode(charCode);
+ }
+ }
+ // normalizing the unicode characters
+ for (var i = 0, ii = result.length; i < ii; i++) {
+ if (!(result[i] in NormalizedUnicodes))
+ continue;
+ result = result.substring(0, i) + NormalizedUnicodes[result[i]] +
+ result.substring(i + 1);
+ ii = result.length;
+ }
+ return result;
+}
+
/**
* 'Font' is the class the outside world should use, it encapsulate all the font
* decoding logics whatever type it is (assuming the font type is supported).
*
* For example to read a Type1 font and to attach it to the document:
* var type1Font = new Font("MyFontName", binaryFile, propertiesObject);
* type1Font.bind();
*/
@@ -15756,19 +16678,19 @@ var Font = (function FontClosure() {
minUnicode = Math.min(minUnicode, unicode);
maxUnicode = Math.max(maxUnicode, unicode);
}
// high byte must be the same for min and max unicodes
if ((maxUnicode & 0xFF00) != (minUnicode & 0xFF00))
this.isSymbolicFont = false;
}
- // heuristics: if removed more than 2 glyphs encoding WinAnsiEncoding
- // does not set properly
- if (glyphsRemoved > 2) {
+ // heuristics: if removed more than 10 glyphs encoding WinAnsiEncoding
+ // does not set properly (broken PDFs have about 100 removed glyphs)
+ if (glyphsRemoved > 10) {
warn('Switching TrueType encoding to MacRomanEncoding for ' +
this.name + ' font');
encoding = Encodings.MacRomanEncoding;
}
if (hasShortCmap && this.hasEncoding && !this.isSymbolicFont) {
// Re-encode short map encoding to unicode -- that simplifies the
// resolution of MacRoman encoded glyphs logic for TrueType fonts:
@@ -16258,16 +17180,17 @@ var Font = (function FontClosure() {
}
if (!this.hasEncoding || this.isSymbolicFont) {
fontCharCode = this.useToFontChar ? this.toFontChar[charcode] :
charcode;
break;
}
// MacRoman encoding address by re-encoding the cmap table
+
fontCharCode = glyphName in this.glyphNameMap ?
this.glyphNameMap[glyphName] : GlyphsUnicode[glyphName];
break;
default:
warn('Unsupported font type: ' + this.type);
break;
}
@@ -17428,17 +18351,17 @@ var CFFParser = (function CFFParserClosu
parseHeader: function CFFParser_parseHeader() {
var bytes = this.bytes;
var offset = 0;
while (bytes[offset] != 1)
++offset;
if (offset != 0) {
- warn('cff data is shifted');
+ info('cff data is shifted');
bytes = bytes.subarray(offset);
this.bytes = bytes;
}
var major = bytes[0];
var minor = bytes[1];
var hdrSize = bytes[2];
var offSize = bytes[3];
var header = new CFFHeader(major, minor, hdrSize, offSize);
@@ -28664,17 +29587,17 @@ var CCITTFaxStream = (function CCITTFaxS
CCITTFaxStream.prototype.addPixels =
function ccittFaxStreamAddPixels(a1, blackPixels) {
var codingLine = this.codingLine;
var codingPos = this.codingPos;
if (a1 > codingLine[codingPos]) {
if (a1 > this.columns) {
- warn('row is wrong length');
+ info('row is wrong length');
this.err = true;
a1 = this.columns;
}
if ((codingPos & 1) ^ blackPixels) {
++codingPos;
}
codingLine[codingPos] = a1;
@@ -28684,27 +29607,27 @@ var CCITTFaxStream = (function CCITTFaxS
CCITTFaxStream.prototype.addPixelsNeg =
function ccittFaxStreamAddPixelsNeg(a1, blackPixels) {
var codingLine = this.codingLine;
var codingPos = this.codingPos;
if (a1 > codingLine[codingPos]) {
if (a1 > this.columns) {
- warn('row is wrong length');
+ info('row is wrong length');
this.err = true;
a1 = this.columns;
}
if ((codingPos & 1) ^ blackPixels)
++codingPos;
codingLine[codingPos] = a1;
} else if (a1 < codingLine[codingPos]) {
if (a1 < 0) {
- warn('invalid code');
+ info('invalid code');
this.err = true;
a1 = 0;
}
while (codingPos > 0 && a1 < codingLine[codingPos - 1])
--codingPos;
codingLine[codingPos] = a1;
}
@@ -28856,17 +29779,17 @@ var CCITTFaxStream = (function CCITTFaxS
refPos += 2;
}
break;
case EOF:
this.addPixels(columns, 0);
this.eof = true;
break;
default:
- warn('bad 2d code');
+ info('bad 2d code');
this.addPixels(columns, 0);
this.err = true;
}
}
} else {
codingLine[0] = 0;
this.codingPos = 0;
blackPixels = 0;
@@ -28919,17 +29842,17 @@ var CCITTFaxStream = (function CCITTFaxS
if (this.encoding > 0) {
this.lookBits(1);
this.eatBits(1);
}
if (this.encoding >= 0) {
for (var i = 0; i < 4; ++i) {
code1 = this.lookBits(12);
if (code1 != 1)
- warn('bad rtc code: ' + code1);
+ info('bad rtc code: ' + code1);
this.eatBits(12);
if (this.encoding > 0) {
this.lookBits(1);
this.eatBits(1);
}
}
}
this.eof = true;
@@ -29042,17 +29965,17 @@ var CCITTFaxStream = (function CCITTFaxS
this.eatBits(p[0]);
return p[1];
}
} else {
var result = this.findTableCode(1, 7, twoDimTable);
if (result[0] && result[2])
return result[1];
}
- warn('Bad two dim code');
+ info('Bad two dim code');
return EOF;
};
CCITTFaxStream.prototype.getWhiteCode =
function ccittFaxStreamGetWhiteCode() {
var code = 0;
var p;
@@ -29075,17 +29998,17 @@ var CCITTFaxStream = (function CCITTFaxS
var result = this.findTableCode(1, 9, whiteTable2);
if (result[0])
return result[1];
result = this.findTableCode(11, 12, whiteTable1);
if (result[0])
return result[1];
}
- warn('bad white code');
+ info('bad white code');
this.eatBits(1);
return 1;
};
CCITTFaxStream.prototype.getBlackCode =
function ccittFaxStreamGetBlackCode() {
var code, p;
@@ -29112,17 +30035,17 @@ var CCITTFaxStream = (function CCITTFaxS
result = this.findTableCode(7, 12, blackTable2, 64);
if (result[0])
return result[1];
result = this.findTableCode(10, 13, blackTable1);
if (result[0])
return result[1];
}
- warn('bad black code');
+ info('bad black code');
this.eatBits(1);
return 1;
};
CCITTFaxStream.prototype.lookBits = function CCITTFaxStream_lookBits(n) {
var c;
while (this.inputBits < n) {
if ((c = this.str.getByte()) == null) {
@@ -29283,20 +30206,23 @@ var LZWStream = (function LZWStreamClosu
function MessageHandler(name, comObj) {
this.name = name;
this.comObj = comObj;
this.callbackIndex = 1;
var callbacks = this.callbacks = {};
var ah = this.actionHandler = {};
ah['console_log'] = [function ahConsoleLog(data) {
- console.log.apply(console, data);
+ console.log.apply(console, data);
}];
ah['console_error'] = [function ahConsoleError(data) {
- console.error.apply(console, data);
+ console.error.apply(console, data);
+ }];
+ ah['_warn'] = [function ah_Warn(data) {
+ warn(data);
}];
comObj.onmessage = function messageHandlerComObjOnMessage(event) {
var data = event.data;
if (data.isReply) {
var callbackId = data.callbackId;
if (data.callbackId in callbacks) {
var callback = callbacks[callbackId];
@@ -29416,17 +30342,16 @@ var WorkerMessageHandler = {
pageIndex: data.pageIndex,
annotations: pdfPage.getAnnotations()
});
});
handler.on('RenderPageRequest', function wphSetupRenderPage(data) {
var pageNum = data.pageIndex + 1;
-
// The following code does quite the same as
// Page.prototype.startRendering, but stops at one point and sends the
// result back to the main thread.
var gfx = new CanvasGraphics(null);
var start = Date.now();
var dependency = [];
@@ -29476,16 +30401,34 @@ var WorkerMessageHandler = {
}
}
handler.send('RenderPage', {
pageIndex: data.pageIndex,
operatorList: operatorList,
depFonts: Object.keys(fonts)
});
}, this);
+
+ handler.on('GetTextContent', function wphExtractText(data, promise) {
+ var pageNum = data.pageIndex + 1;
+ var start = Date.now();
+
+ var textContent = '';
+ try {
+ var page = pdfModel.getPage(pageNum);
+ textContent = page.extractTextContent();
+ promise.resolve(textContent);
+ } catch (e) {
+ // Skip errored pages
+ promise.reject(e);
+ }
+
+ console.log('text indexing: page=%d - time=%dms',
+ pageNum, Date.now() - start);
+ });
}
};
var consoleTimer = {};
var workerConsole = {
log: function log() {
var args = Array.prototype.slice.call(arguments);
@@ -29516,16 +30459,27 @@ var workerConsole = {
this.log('Timer:', name, Date.now() - time);
}
};
// Worker thread?
if (typeof window === 'undefined') {
globalScope.console = workerConsole;
+ // Add a logger so we can pass warnings on to the main thread, errors will
+ // throw an exception which will be forwarded on automatically.
+ PDFJS.LogManager.addLogger({
+ warn: function(msg) {
+ postMessage({
+ action: '_warn',
+ data: msg
+ });
+ }
+ });
+
var handler = new MessageHandler('worker_processor', this);
WorkerMessageHandler.setup(handler);
}
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- /
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
@@ -32841,60 +33795,68 @@ var Metadata = PDFJS.Metadata = (functio
<script type="text/javascript" src="viewer.js"></script>
</head>
<body>
<div id="outerContainer">
<div id="sidebarContainer">
<div id="toolbarSidebar">
- <div class="splitToolbarButton toggled">
- <button id="viewThumbnail" class="toolbarButton toggled" title="Show Thumbnails" onclick="PDFView.switchSidebarView('thumbs')" tabindex="1" data-l10n-id="thumbs">
- <span data-l10n-id="thumbs_label">Thumbnails</span>
- </button>
- <button id="viewOutline" class="toolbarButton" title="Show Document Outline" onclick="PDFView.switchSidebarView('outline')" tabindex="2" data-l10n-id="outline">
- <span data-l10n-id="outline_label">Document Outline</span>
- </button>
- </div>
+ <button id="viewThumbnail" class="toolbarButton group toggled" title="Show Thumbnails" onclick="PDFView.switchSidebarView('thumbs')" tabindex="1" data-l10n-id="thumbs">
+ <span data-l10n-id="thumbs_label">Thumbnails</span>
+ </button>
+ <button id="viewOutline" class="toolbarButton group" title="Show Document Outline" onclick="PDFView.switchSidebarView('outline')" tabindex="2" data-l10n-id="outline">
+ <span data-l10n-id="outline_label">Document Outline</span>
+ </button>
+ <button id="viewSearch" class="toolbarButton group hidden" title="Search Document" onclick="PDFView.switchSidebarView('search')" tabindex="3" data-l10n-id="search">
+ <span data-l10n-id="search_label">Search Document</span>
+ </button>
</div>
<div id="sidebarContent">
<div id="thumbnailView">
</div>
<div id="outlineView" class="hidden">
</div>
+ <div id="searchView" class="hidden">
+ <div id="searchToolbar">
+ <input id="searchTermsInput" onkeydown='if (event.keyCode == 13) PDFView.search()'>
+ <button id="searchButton" onclick='PDFView.search()' data-l10n-id="search_button">Find</button>
+ </div>
+ <div id="searchResults"></div>
+ </div>
</div>
</div> <!-- sidebarContainer -->
<div id="mainContainer">
<div class="toolbar">
<div id="toolbarContainer">
<div id="toolbarViewer">
<div id="toolbarViewerLeft">
- <button id="sidebarToggle" class="toolbarButton" title="Toggle Sidebar" tabindex="3" data-l10n-id="toggle_slider">
+ <button id="sidebarToggle" class="toolbarButton" title="Toggle Sidebar" tabindex="4" data-l10n-id="toggle_slider">
<span data-l10n-id="toggle_slider_label">Toggle Sidebar</span>
</button>
<div class="toolbarButtonSpacer"></div>
<div class="splitToolbarButton">
- <button class="toolbarButton pageUp" title="Previous Page" onclick="PDFView.page--" id="previous" tabindex="4" data-l10n-id="previous">
+ <button class="toolbarButton pageUp" title="Previous Page" onclick="PDFView.page--" id="previous" tabindex="5" data-l10n-id="previous">
<span data-l10n-id="previous_label">Previous</span>
</button>
<div class="splitToolbarButtonSeparator"></div>
- <button class="toolbarButton pageDown" title="Next Page" onclick="PDFView.page++" id="next" tabindex="5" data-l10n-id="next">
+ <button class="toolbarButton pageDown" title="Next Page" onclick="PDFView.page++" id="next" tabindex="6" data-l10n-id="next">
<span data-l10n-id="next_label">Next</span>
</button>
</div>
<label id="pageNumberLabel" class="toolbarLabel" for="pageNumber" data-l10n-id="page_label">Page: </label>
- <input type="number" id="pageNumber" class="toolbarField pageNumber" onchange="PDFView.page = this.value;" value="1" size="4" min="1" tabindex="6">
+ <input type="number" id="pageNumber" class="toolbarField pageNumber" onchange="PDFView.page = this.value;" value="1" size="4" min="1" tabindex="7">
</input>
<span id="numPages" class="toolbarLabel"></span>
</div>
<div id="toolbarViewerRight">
<input id="fileInput" class="fileInput" type="file" oncontextmenu="return false;" style="visibility: hidden; position: fixed; right: 0; top: 0" />
- <button id="openFile" class="toolbarButton openFile" title="Open File" tabindex="10" data-l10n-id="open_file" onclick="document.getElementById('fileInput').click()">
+ <button id="openFile" class="toolbarButton openFile" title="Open File" tabindex="11" data-l10n-id="open_file" onclick="document.getElementById('fileInput').click()">
<span data-l10n-id="open_file_label">Open</span>
</button>
<!--
<button id="print" class="toolbarButton print" title="Print" tabindex="11" data-l10n-id="print" onclick="window.print()">
<span data-l10n-id="print_label">Print</span>
</button>
-->
@@ -32903,26 +33865,26 @@ var Metadata = PDFJS.Metadata = (functio
<span data-l10n-id="download_label">Download</span>
</button>
<!-- <div class="toolbarButtonSpacer"></div> -->
<a href="#" id="viewBookmark" class="toolbarButton bookmark" title="Current view (copy or open in new window)" tabindex="13" data-l10n-id="bookmark"><span data-l10n-id="bookmark_label">Current View</span></a>
</div>
<div class="outerCenter">
<div class="innerCenter" id="toolbarViewerMiddle">
<div class="splitToolbarButton">
- <button class="toolbarButton zoomOut" title="Zoom Out" onclick="PDFView.zoomOut();" tabindex="7" data-l10n-id="zoom_out">
+ <button class="toolbarButton zoomOut" title="Zoom Out" onclick="PDFView.zoomOut();" tabindex="8" data-l10n-id="zoom_out">
<span data-l10n-id="zoom_out_label">Zoom Out</span>
</button>
<div class="splitToolbarButtonSeparator"></div>
- <button class="toolbarButton zoomIn" title="Zoom In" onclick="PDFView.zoomIn();" tabindex="8" data-l10n-id="zoom_in">
+ <button class="toolbarButton zoomIn" title="Zoom In" onclick="PDFView.zoomIn();" tabindex="9" data-l10n-id="zoom_in">
<span data-l10n-id="zoom_in_label">Zoom In</span>
</button>
</div>
<span id="scaleSelectContainer" class="dropdownToolbarButton">
- <select id="scaleSelect" onchange="PDFView.parseScale(this.value);" title="Zoom" oncontextmenu="return false;" tabindex="9" data-l10n-id="zoom">
+ <select id="scaleSelect" onchange="PDFView.parseScale(this.value);" title="Zoom" oncontextmenu="return false;" tabindex="10" data-l10n-id="zoom">
<option id="pageAutoOption" value="auto" selected="selected" data-l10n-id="page_scale_auto">Automatic Zoom</option>
<option id="pageActualOption" value="page-actual" data-l10n-id="page_scale_actual">Actual Size</option>
<option id="pageFitOption" value="page-fit" data-l10n-id="page_scale_fit">Fit Page</option>
<option id="pageWidthOption" value="page-width" data-l10n-id="page_scale_width">Full Width</option>
<option id="customScaleOption" value="custom"></option>
<option value="0.5">50%</option>
<option value="0.75">75%</option>
<option value="1">100%</option>
--- a/browser/extensions/pdfjs/content/web/viewer.js
+++ b/browser/extensions/pdfjs/content/web/viewer.js
@@ -214,18 +214,21 @@ var renderingQueue = new RenderingQueue(
var currentPageNumber = 1;
var PDFView = {
pages: [],
thumbnails: [],
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');
this.initialized = true;
},
setScale: function pdfViewSetScale(val, resetAutoSettings) {
if (val == this.currentScale)
@@ -385,16 +388,28 @@ var PDFView = {
if (PDFJS.isFirefoxExtension) {
FirefoxCom.request('download', url);
} else {
url += '#pdfjs.action=download', '_parent';
window.open(url, '_parent');
}
},
+ 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];
if (!(dest instanceof Array))
return; // invalid destination
// dest array looks like that: <page-ref> </XYZ|FitXXX> <args..>
var destRef = dest[0];
var pageNumber = destRef instanceof Object ?
@@ -447,16 +462,44 @@ var PDFView = {
/**
* Show the error box.
* @param {String} message A message that is human readable.
* @param {Object} moreInfo (optional) Further information about the error
* that is more technical. Should have a 'message'
* 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');
var errorMessage = document.getElementById('errorMessage');
errorMessage.textContent = message;
var closeButton = document.getElementById('errorClose');
closeButton.onclick = function() {
@@ -473,42 +516,19 @@ var PDFView = {
};
lessInfoButton.onclick = function() {
errorMoreInfo.setAttribute('hidden', 'true');
moreInfoButton.removeAttribute('hidden');
lessInfoButton.setAttribute('hidden', 'true');
};
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) {
var percent = Math.round(level * 100);
var loadingIndicator = document.getElementById('loading');
loadingIndicator.textContent = mozL10n.get('loading', {percent: percent},
'Loading... {{percent}}%');
@@ -556,16 +576,18 @@ var PDFView = {
var zoom = store.get('zoom', PDFView.currentScale);
var left = store.get('scrollLeft', '0');
var top = store.get('scrollTop', '0');
storedHash = 'page=' + page + '&zoom=' + zoom + ',' + left + ',' + top;
}
var pages = this.pages = [];
+ this.pageText = [];
+ this.startedTextExtraction = false;
var pagesRefMap = {};
var thumbnails = this.thumbnails = [];
var pagePromises = [];
for (var i = 1; i <= pagesCount; i++)
pagePromises.push(pdfDocument.getPage(i));
var self = this;
var pagesPromise = PDFJS.Promise.all(pagePromises);
pagesPromise.then(function(promisedPages) {
@@ -636,16 +658,77 @@ var PDFView = {
if (PDFView.currentScale === kUnknownScale) {
// Scale was not initialized: invalid bookmark or scale was not specified.
// Setting the default one.
this.parseScale(kDefaultScale, true);
}
},
+ 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;
if (hash.indexOf('=') >= 0) {
var params = PDFView.parseQueryString(hash);
// borrowing syntax from "Parameters for Opening PDF Files"
if ('nameddest' in params) {
@@ -678,36 +761,80 @@ var PDFView = {
this.page = hash;
else // named destination
PDFView.navigateTo(unescape(hash));
},
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;
var kTopPadding = 30;
var visiblePages = [];
var currentHeight = kTopPadding + kBottomMargin;
var container = this.container;
@@ -911,16 +1038,20 @@ var PageView = function pageView(contain
bindLink(link, ('dest' in item) ? item.dest : null);
div.appendChild(link);
break;
case 'Text':
var comment = createCommentAnnotation(item.name, item);
if (comment)
div.appendChild(comment);
break;
+ case 'Widget':
+ // TODO: support forms
+ PDFView.fallback();
+ break;
}
}
});
}
this.getPagePoint = function pageViewGetPagePoint(x, y) {
return this.viewport.convertToPdfPoint(x, y);
};
@@ -1392,16 +1523,29 @@ window.addEventListener('load', function
(!PDFJS.isFirefoxExtension || FirefoxCom.request('pdfBugEnabled'))) {
PDFJS.pdfBug = true;
var pdfBug = hashParams['pdfBug'];
var enabled = pdfBug.split(',');
PDFBug.enable(enabled);
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);
var mainContainer = document.getElementById('mainContainer');
var outerContainer = document.getElementById('outerContainer');
mainContainer.addEventListener('transitionend', function(e) {
if (e.target == mainContainer) {
var event = document.createEvent('UIEvents');
--- a/browser/extensions/pdfjs/extension-files
+++ b/browser/extensions/pdfjs/extension-files
@@ -1,28 +1,27 @@
-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
content/web/images/annotation-text.svg
content/web/images/loading-icon.gif
content/web/images/texture.png
content/web/images/toolbarButton-bookmark.png
content/web/images/toolbarButton-download.png
content/web/images/toolbarButton-menuArrows.png
content/web/images/toolbarButton-openFile.png
content/web/images/toolbarButton-pageDown-rtl.png
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
content/web/images/toolbarButton-zoomIn.png
content/web/images/toolbarButton-zoomOut.png
content/web/l10n.js
content/web/viewer.css
content/web/viewer.html
--- a/browser/extensions/pdfjs/test/Makefile.in
+++ b/browser/extensions/pdfjs/test/Makefile.in
@@ -8,13 +8,14 @@ srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = browser/extensions/pdfjs/test
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_BROWSER_TEST_FILES = \
browser_pdfjs_main.js \
+ browser_pdfjs_savedialog.js \
file_pdfjs_test.pdf \
$(NULL)
libs:: $(_BROWSER_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
--- a/browser/extensions/pdfjs/test/browser_pdfjs_main.js
+++ b/browser/extensions/pdfjs/test/browser_pdfjs_main.js
@@ -1,40 +1,50 @@
/* 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;
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);
});
tab = gBrowser.addTab(TESTROOT + "file_pdfjs_test.pdf");
var newTabBrowser = gBrowser.getBrowserForTab(tab);
newTabBrowser.addEventListener("load", function eventHandler() {
newTabBrowser.removeEventListener("load", eventHandler, true);
var document = newTabBrowser.contentDocument,
window = newTabBrowser.contentWindow;
// 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
//
ok(document.querySelector('div#viewer'), "document content has viewer UI");
ok('PDFJS' in window.wrappedJSObject, "window content has PDFJS object");
//
// Sidebar: open
@@ -62,10 +72,10 @@ function runTests(document, window) {
//
// Bookmark button
//
var viewBookmark = document.querySelector('a#viewBookmark');
viewBookmark.click();
ok(viewBookmark.href.length > 0, 'viewBookmark button has href');
- finish();
+ callback();
}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/pdfjs/test/browser_pdfjs_savedialog.js
@@ -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) { }
+ });
+}
--- a/browser/locales/en-US/chrome/browser/preferences/preferences.properties
+++ b/browser/locales/en-US/chrome/browser/preferences/preferences.properties
@@ -58,16 +58,17 @@ useDefault=Use %S (default)
useOtherApp=Use other…
fpTitleChooseApp=Select Helper Application
manageApp=Application Details…
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")
# %2$S = brandShortName from brand.properties (for example "Minefield")
usePluginIn=Use %S (in %S)
# LOCALIZATION NOTE (previewInApp, addLiveBookmarksInApp): %S = brandShortName
previewInApp=Preview in %S
new file mode 100644
--- /dev/null
+++ b/browser/locales/en-US/pdfviewer/chrome.properties
@@ -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
--- a/browser/locales/en-US/pdfviewer/viewer.properties
+++ b/browser/locales/en-US/pdfviewer/viewer.properties
@@ -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
+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
-zoom_out.title=Zoom Out
-zoom_in.title=Zoom In
+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
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -111,13 +111,16 @@
* locale/browser/appstrings.properties (%chrome/overrides/appstrings.properties)
* locale/browser/downloads/settingsChange.dtd (%chrome/overrides/settingsChange.dtd)
% override chrome://global/locale/netError.dtd chrome://browser/locale/netError.dtd
% override chrome://global/locale/appstrings.properties chrome://browser/locale/appstrings.properties
% override chrome://mozapps/locale/downloads/settingsChange.dtd chrome://browser/locale/downloads/settingsChange.dtd
% 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)
locale/webapprt/webapp.properties (%webapprt/webapp.properties)
#endif
--- a/configure.in
+++ b/configure.in
@@ -4588,17 +4588,25 @@ NECKO_WIFI=1
NECKO_COOKIES=1
NECKO_PROTOCOLS_DEFAULT="about data file ftp http res viewsource websocket wyciwyg device"
USE_ARM_KUSER=
BUILD_CTYPES=1
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*)
NS_ENABLE_TSF=1
AC_DEFINE(NS_ENABLE_TSF)
;;
esac
@@ -5521,19 +5529,20 @@ MOZ_ARG_DISABLE_BOOL(dbm,
NSS_DISABLE_DBM=)
dnl bi-directional support always on
IBMBIDI=1
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
AC_DEFINE(ACCESSIBILITY)
fi
dnl ========================================================
dnl Disable printing
--- a/content/base/public/nsDeprecatedOperationList.h
+++ b/content/base/public/nsDeprecatedOperationList.h
@@ -43,8 +43,9 @@ DEPRECATED_OPERATION(Position)
DEPRECATED_OPERATION(TotalSize)
DEPRECATED_OPERATION(InputEncoding)
DEPRECATED_OPERATION(MozBeforePaint)
DEPRECATED_OPERATION(MozBlobBuilder)
DEPRECATED_OPERATION(DOMExceptionCode)
DEPRECATED_OPERATION(NoExposedProps)
DEPRECATED_OPERATION(MutationEvent)
DEPRECATED_OPERATION(MozSlice)
+DEPRECATED_OPERATION(Onuploadprogress)
--- a/content/base/src/CSPUtils.jsm
+++ b/content/base/src/CSPUtils.jsm
@@ -621,16 +621,21 @@ CSPSourceList.prototype = {
*
* @param that
* another CSPSourceList
* @returns
* true if they have the same data
*/
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;
}
// sort both arrays and compare like a zipper
// XXX (sid): I think we can make this more efficient
var sortfn = function(a,b) {
return a.toString() > b.toString();
};
--- a/content/base/src/nsDOMLists.h
+++ b/content/base/src/nsDOMLists.h
@@ -23,13 +23,18 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMDOMSTRINGLIST
bool Add(const nsAString& aName)
{
return mNames.AppendElement(aName) != nsnull;
}
+ void Clear()
+ {
+ mNames.Clear();
+ }
+
private:
nsTArray<nsString> mNames;
};
#endif /* nsDOMLists_h___ */
--- a/content/base/src/nsDOMSettableTokenList.h
+++ b/content/base/src/nsDOMSettableTokenList.h
@@ -11,28 +11,29 @@
#include "nsIDOMDOMSettableTokenList.h"
#include "nsDOMTokenList.h"
class nsGenericElement;
class nsIAtom;
+// nsISupports must be on the primary inheritance chain
+// because nsDOMSettableTokenList is traversed by nsGenericElement.
class nsDOMSettableTokenList : public nsDOMTokenList,
public nsIDOMDOMSettableTokenList
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIDOMDOMSETTABLETOKENLIST
NS_FORWARD_NSIDOMDOMTOKENLIST(nsDOMTokenList::);
nsDOMSettableTokenList(nsGenericElement* aElement, nsIAtom* aAttrAtom);
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap);
-protected:
virtual ~nsDOMSettableTokenList();
};
#endif // nsDOMSettableTokenList_h___
--- a/content/base/src/nsDOMTokenList.h
+++ b/content/base/src/nsDOMTokenList.h
@@ -9,16 +9,18 @@
#ifndef nsDOMTokenList_h___
#define nsDOMTokenList_h___
#include "nsGenericElement.h"
#include "nsIDOMDOMTokenList.h"
class nsAttrValue;
+// nsISupports must be on the primary inheritance chain
+// because nsDOMSettableTokenList is traversed by nsGenericElement.
class nsDOMTokenList : public nsIDOMDOMTokenList,
public nsWrapperCache
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsDOMTokenList)
NS_DECL_NSIDOMDOMTOKENLIST
@@ -29,26 +31,26 @@ public:
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap);
nsINode *GetParentObject()
{
return mElement;
}
-protected:
- ~nsDOMTokenList();
-
const nsAttrValue* GetParsedAttr() {
if (!mElement) {
return nsnull;
}
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);
nsGenericElement* mElement;
nsCOMPtr<nsIAtom> mAttrAtom;
};
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -4482,19 +4482,26 @@ private:
static ContentUnbinder* sContentUnbinder;
};
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).
if (UnoptimizableCCNode(tmp) || !nsCCUncollectableMarker::sGeneration) {
PRUint32 childCount = tmp->mAttrsAndChildren.ChildCount();
if (childCount) {
// Don't allow script to run while we're unbinding everything.
nsAutoScriptBlocker scriptBlocker;
@@ -4982,24 +4989,35 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
if (!nsINode::Traverse(tmp, cb)) {
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
}
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.
{
PRUint32 i;
PRUint32 attrs = tmp->mAttrsAndChildren.AttrCount();
for (i = 0; i < attrs; i++) {
const nsAttrName* name = tmp->mAttrsAndChildren.AttrNameAt(i);
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -90,19 +90,17 @@ GK_ATOM(assign, "assign")
GK_ATOM(async, "async")
GK_ATOM(attribute, "attribute")
GK_ATOM(attributeSet, "attribute-set")
GK_ATOM(aural, "aural")
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")
GK_ATOM(background, "background")
GK_ATOM(base, "base")
GK_ATOM(basefont, "basefont")
GK_ATOM(baseline, "baseline")
GK_ATOM(bdi, "bdi")
@@ -215,19 +213,17 @@ GK_ATOM(headerContentLanguage, "content-
GK_ATOM(contentLocation, "content-location")
GK_ATOM(headerContentScriptType, "content-script-type")
GK_ATOM(headerContentStyleType, "content-style-type")
GK_ATOM(headerContentType, "content-type")
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")
GK_ATOM(count, "count")
GK_ATOM(crop, "crop")
GK_ATOM(crossorigin, "crossorigin")
GK_ATOM(curpos, "curpos")
GK_ATOM(current, "current")
@@ -248,19 +244,17 @@ GK_ATOM(declare, "declare")
GK_ATOM(decrement, "decrement")
GK_ATOM(_default, "default")
GK_ATOM(headerDefaultStyle, "default-style")
GK_ATOM(defaultAction, "defaultAction")
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")
GK_ATOM(descendantOrSelf, "descendant-or-self")
GK_ATOM(descending, "descending")
GK_ATOM(description, "description")
GK_ATOM(destructor, "destructor")
GK_ATOM(details, "details")
@@ -500,19 +494,17 @@ GK_ATOM(listhead, "listhead")
GK_ATOM(listheader, "listheader")
GK_ATOM(listing, "listing")
GK_ATOM(listitem, "listitem")
GK_ATOM(listrows, "listrows")
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")
GK_ATOM(lowsrc, "lowsrc")
GK_ATOM(ltr, "ltr")
GK_ATOM(lwtheme, "lwtheme")
GK_ATOM(lwthemetextcolor, "lwthemetextcolor")
GK_ATOM(map, "map")
@@ -539,16 +531,17 @@ GK_ATOM(menuButton, "menu-button")
GK_ATOM(menuitem, "menuitem")
GK_ATOM(menulist, "menulist")
GK_ATOM(menupopup, "menupopup")
GK_ATOM(menuseparator, "menuseparator")
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")
GK_ATOM(minimum_scale, "minimum-scale")
GK_ATOM(minpos, "minpos")
GK_ATOM(minusSign, "minus-sign")
GK_ATOM(minwidth, "minwidth")
GK_ATOM(mod, "mod")
@@ -566,19 +559,17 @@ GK_ATOM(mozfullscreenerror, "mozfullscre
GK_ATOM(mozpointerlockchange, "mozpointerlockchange")
GK_ATOM(mozpointerlockerror, "mozpointerlockerror")
GK_ATOM(moz_opaque, "moz-opaque")
GK_ATOM(moz_action_hint, "mozactionhint")
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")
GK_ATOM(namespaceUri, "namespace-uri")
GK_ATOM(NaN, "NaN")
GK_ATOM(nav, "nav")
GK_ATOM(negate, "negate")
GK_ATOM(never, "never")
@@ -756,45 +747,39 @@ GK_ATOM(pattern, "pattern")
GK_ATOM(patternSeparator, "pattern-separator")
GK_ATOM(perMille, "per-mille")
GK_ATOM(percent, "percent")
GK_ATOM(persist, "persist")
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")
GK_ATOM(popup, "popup")
GK_ATOM(popupalign, "popupalign")
GK_ATOM(popupanchor, "popupanchor")
GK_ATOM(popupgroup, "popupgroup")
GK_ATOM(popuphidden, "popuphidden")
GK_ATOM(popuphiding, "popuphiding")
GK_ATOM(popuplistener, "popuplistener")
GK_ATOM(popupset, "popupset")
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")
GK_ATOM(primary, "primary")
GK_ATOM(print, "print")
GK_ATOM(priority, "priority")
GK_ATOM(processingInstruction, "processing-instruction")
GK_ATOM(profile, "profile")
@@ -905,19 +890,17 @@ GK_ATOM(sortActive, "sortActive")
GK_ATOM(sortDirection, "sortDirection")
GK_ATOM(sorted, "sorted")
GK_ATOM(sorthints, "sorthints")
GK_ATOM(sortLocked, "sortLocked")
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")
GK_ATOM(spellcheck, "spellcheck")
GK_ATOM(spinner, "spinner")
GK_ATOM(split, "split")
GK_ATOM(splitmenu, "splitmenu")
GK_ATOM(splitter, "splitter")
@@ -1043,21 +1026,19 @@ GK_ATOM(var, "var")
GK_ATOM(variable, "variable")
GK_ATOM(vbox, "vbox")
GK_ATOM(vcard_name, "vcard_name")
GK_ATOM(vendor, "vendor")
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")
GK_ATOM(viewport_maximum_scale, "viewport-maximum-scale")
GK_ATOM(viewport_minimum_scale, "viewport-minimum-scale")
GK_ATOM(viewport_user_scalable, "viewport-user-scalable")
GK_ATOM(viewport_width, "viewport-width")
GK_ATOM(visibility, "visibility")
@@ -1696,16 +1677,17 @@ GK_ATOM(blockFrame, "BlockFrame")
GK_ATOM(boxFrame, "BoxFrame")
GK_ATOM(brFrame, "BRFrame")
GK_ATOM(bulletFrame, "BulletFrame")
GK_ATOM(columnSetFrame, "ColumnSetFrame")
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")
GK_ATOM(HTMLCanvasFrame, "HTMLCanvasFrame")
GK_ATOM(subDocumentFrame, "subDocumentFrame")
GK_ATOM(imageBoxFrame, "ImageBoxFrame")
GK_ATOM(imageFrame, "ImageFrame")
GK_ATOM(imageControlFrame, "ImageControlFrame")
--- a/content/base/src/nsWebSocket.cpp
+++ b/content/base/src/nsWebSocket.cpp
@@ -69,16 +69,37 @@ using namespace mozilla;
nsresult __rv = res; \
if (NS_FAILED(__rv)) { \
NS_ENSURE_SUCCESS_BODY(res, ret) \
FailConnection(nsIWebSocketChannel::CLOSE_INTERNAL_ERROR); \
return ret; \
} \
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,
const PRUnichar **aFormatStrings,
PRUint32 aFormatStringsLen)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
nsresult rv;
@@ -119,47 +140,53 @@ nsWebSocket::PrintErrorOnConsole(const c
// print the error message directly to the JS console
rv = console->LogMessage(errorObject);
NS_ENSURE_SUCCESS(rv, rv);
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
nsWebSocket::ConsoleError()
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
nsresult rv;
@@ -186,24 +213,21 @@ nsWebSocket::ConsoleError()
}
nsresult
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;
}
nsresult
nsWebSocket::Disconnect()
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
@@ -235,29 +259,33 @@ nsWebSocket::Disconnect()
//-----------------------------------------------------------------------------
// nsWebSocket::nsIWebSocketListener methods:
//-----------------------------------------------------------------------------
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
nsresult rv = CreateAndDispatchMessageEvent(aMsg, isBinary);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to dispatch the message event");
}
} 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;
}
NS_IMETHODIMP
nsWebSocket::OnMessageAvailable(nsISupports *aContext, const nsACString & aMsg)
{
@@ -270,62 +298,97 @@ nsWebSocket::OnBinaryMessageAvailable(ns
{
return DoOnMessageAvailable(aMsg, true);
}
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;
}
if (!mRequestedProtocolList.IsEmpty()) {
mChannel->GetProtocol(mEstablishedProtocol);
}
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) {
+ // don't generate an error event just because of an unclean close
+ aStatusCode = NS_OK;
+ }
- 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 (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;
}
NS_IMETHODIMP
nsWebSocket::OnAcknowledge(nsISupports *aContext, PRUint32 aSize)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
@@ -337,56 +400,53 @@ nsWebSocket::OnAcknowledge(nsISupports *
}
NS_IMETHODIMP
nsWebSocket::OnServerClose(nsISupports *aContext, PRUint16 aCode,
const nsACString &aReason)
{
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
if (aCode == 1005 || aCode == 1006 || aCode == 1015) {
CloseConnection(0, EmptyCString());
} else {
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;
}
//-----------------------------------------------------------------------------
// nsWebSocket::nsIInterfaceRequestor
//-----------------------------------------------------------------------------
NS_IMETHODIMP
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)) ||
aIID.Equals(NS_GET_IID(nsIAuthPrompt2))) {
nsresult rv;
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
nsCOMPtr<nsIDocument> doc =
@@ -406,17 +466,18 @@ nsWebSocket::GetInterface(const nsIID &a
}
////////////////////////////////////////////////////////////////////////////////
// nsWebSocket
////////////////////////////////////////////////////////////////////////////////
nsWebSocket::nsWebSocket() : mKeepingAlive(false),
mCheckMustKeepAlive(true),
- mTriggeredCloseEvent(false),
+ mOnCloseScheduled(false),
+ mFailed(false),
mDisconnected(false),
mCloseEventWasClean(false),
mCloseEventCode(nsIWebSocketChannel::CLOSE_ABNORMAL),
mReadyState(nsIWebSocket::CONNECTING),
mOutgoingBufferedAmount(0),
mBinaryType(WS_BINARY_TYPE_BLOB),
mScriptLine(0),
mInnerWindowID(0)
@@ -424,17 +485,20 @@ nsWebSocket::nsWebSocket() : mKeepingAli
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
nsLayoutStatics::AddRef();
}
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();
}
NS_IMPL_CYCLE_COLLECTION_CLASS(nsWebSocket)
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsWebSocket)
bool isBlack = tmp->IsBlack();
if (isBlack|| tmp->mKeepingAlive) {
@@ -506,17 +570,17 @@ NS_IMPL_RELEASE_INHERITED(nsWebSocket, n
void
nsWebSocket::DisconnectFromOwner()
{
nsDOMEventTargetHelper::DisconnectFromOwner();
NS_DISCONNECT_EVENT_HANDLER(Open)
NS_DISCONNECT_EVENT_HANDLER(Message)
NS_DISCONNECT_EVENT_HANDLER(Close)
NS_DISCONNECT_EVENT_HANDLER(Error)
- FailConnectionQuietly();
+ CloseConnection(nsIWebSocketChannel::CLOSE_GOING_AWAY);
DontKeepAliveAnyMore();
}
//-----------------------------------------------------------------------------
// nsWebSocket::nsIJSNativeInitializer methods:
//-----------------------------------------------------------------------------
/**
@@ -700,41 +764,40 @@ nsWebSocket::EstablishConnection()
rv = wsChannel->AsyncOpen(mURI, asciiOrigin, this, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
mChannel = wsChannel;
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;
+
+ mReadyState = nsIWebSocket::CLOSED;
- NS_IMETHOD Run()
- {
- nsresult rv = mWebSocket->CreateAndDispatchCloseEvent(mWasClean,
- mCode, mReason);
- mWebSocket->UpdateMustKeepAlive();
- return rv;
+ // 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)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
nsresult rv;
rv = CheckInnerWindowCorrectness();
@@ -850,18 +913,16 @@ nsWebSocket::CreateResponseBlob(const ns
nsresult
nsWebSocket::CreateAndDispatchCloseEvent(bool aWasClean,
PRUint16 aCode,
const nsString &aReason)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
nsresult rv;
- mTriggeredCloseEvent = true;
-
rv = CheckInnerWindowCorrectness();
if (NS_FAILED(rv)) {
return NS_OK;
}
// create an event that uses the CloseEvent interface,
// which does not bubble, is not cancelable, and has no default action
@@ -883,68 +944,16 @@ nsWebSocket::CreateAndDispatchCloseEvent
}
bool
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)
{
nsresult rv;
NS_ENSURE_TRUE(!aURL.IsEmpty(), NS_ERROR_DOM_SYNTAX_ERR);
nsCOMPtr<nsIURI> uri;
@@ -1061,19 +1070,17 @@ nsWebSocket::UpdateMustKeepAlive()
mOutgoingBufferedAmount != 0) {
shouldKeepAlive = true;
}
}
break;
case nsIWebSocket::CLOSED:
{
- shouldKeepAlive =
- (!mTriggeredCloseEvent &&
- mListenerManager->HasListenersFor(NS_LITERAL_STRING("close")));
+ shouldKeepAlive = false;
}
}
}
if (mKeepingAlive && !shouldKeepAlive) {
mKeepingAlive = false;
static_cast<nsIDOMEventTarget*>(this)->Release();
} else if (!mKeepingAlive && shouldKeepAlive) {
@@ -1088,24 +1095,16 @@ nsWebSocket::DontKeepAliveAnyMore()
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
if (mKeepingAlive) {
mKeepingAlive = false;
static_cast<nsIDOMEventTarget*>(this)->Release();
}
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()
{
// Check for Redirections
nsCOMPtr<nsIURI> uri;
nsresult rv = mChannel->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
@@ -1287,18 +1286,18 @@ nsWebSocket::Send(nsIVariant *aData, JSC
// Always increment outgoing buffer len, even if closed
mOutgoingBufferedAmount += msgLen;
if (mReadyState == nsIWebSocket::CLOSING ||
mReadyState == nsIWebSocket::CLOSED) {
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);
} else {
if (isBinary) {
rv = mChannel->SendBinaryMsg(msgString);
} else {
rv = mChannel->SendMsg(msgString);
@@ -1466,20 +1465,16 @@ nsWebSocket::Close(PRUint16 code, const
}
if (mReadyState == nsIWebSocket::CLOSING ||
mReadyState == nsIWebSocket::CLOSED) {
return NS_OK;
}
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;
}
// mReadyState == nsIWebSocket::OPEN
CloseConnection(closeCode, closeReason);
return NS_OK;
@@ -1613,17 +1608,17 @@ nsWebSocket::Observe(nsISupports* aSubje
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aSubject);
if (!GetOwner() || window != GetOwner()) {
return NS_OK;
}
if ((strcmp(aTopic, DOM_WINDOW_FROZEN_TOPIC) == 0) ||
(strcmp(aTopic, DOM_WINDOW_DESTROYED_TOPIC) == 0))
{
- FailConnectionQuietly();
+ CloseConnection(nsIWebSocketChannel::CLOSE_GOING_AWAY);
}
return NS_OK;
}
//-----------------------------------------------------------------------------
// nsWebSocket::nsIRequest
@@ -1634,37 +1629,39 @@ nsWebSocket::GetName(nsACString &aName)
{
CopyUTF16toUTF8(mOriginalURL, aName);
return NS_OK;
}
NS_IMETHODIMP
nsWebSocket::IsPending(bool *aValue)
{
- *aValue = !mDisconnected;
+ *aValue = (mReadyState != nsIWebSocket::CLOSED);
return NS_OK;
}
NS_IMETHODIMP
nsWebSocket::GetStatus(nsresult *aStatus)
{
*aStatus = NS_OK;
return NS_OK;
}
// Window closed, stop/reload button pressed, user navigated away from page, etc.
NS_IMETHODIMP
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);
}
NS_IMETHODIMP
nsWebSocket::Suspend()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
--- a/content/base/src/nsWebSocket.h
+++ b/content/base/src/nsWebSocket.h
@@ -30,29 +30,29 @@
#define NS_WEBSOCKET_CID \
{ /* 7ca25214-98dc-40a6-bc1f-41ddbe41f46c */ \
0x7ca25214, 0x98dc, 0x40a6, \
{0xbc, 0x1f, 0x41, 0xdd, 0xbe, 0x41, 0xf4, 0x6c} }
#define NS_WEBSOCKET_CONTRACTID "@mozilla.org/websocket;1"
-class nsWSCloseEvent;
+class CallDispatchConnectionCloseEvents;
class nsAutoCloseWS;
class nsWebSocket: public nsDOMEventTargetHelper,
public nsIWebSocket,
public nsIJSNativeInitializer,
public nsIInterfaceRequestor,
public nsIWebSocketListener,
public nsIObserver,
public nsSupportsWeakReference,
public nsIRequest
{
-friend class nsWSCloseEvent;
+friend class CallDispatchConnectionCloseEvents;
friend class nsAutoCloseWS;
public:
nsWebSocket();
virtual ~nsWebSocket();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED(nsWebSocket,
nsDOMEventTargetHelper)
@@ -82,17 +82,16 @@ public:
virtual void DisconnectFromOwner();
protected:
nsresult ParseURL(const nsString& aURL);
nsresult EstablishConnection();
// 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();
nsresult ConsoleError();
nsresult PrintErrorOnConsole(const char *aBundleURI,
const PRUnichar *aError,
const PRUnichar **aFormatStrings,
@@ -102,26 +101,36 @@ protected:
// Get msg info out of JS variable being sent (string, arraybuffer, blob)
nsresult GetSendParams(nsIVariant *aData, nsCString &aStringOut,
nsCOMPtr<nsIInputStream> &aStreamOut,
bool &aIsBinary, PRUint32 &aOutgoingLength,
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);
nsresult CreateAndDispatchCloseEvent(bool aWasClean, PRUint16 aCode,
const nsString &aReason);
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.
void UpdateMustKeepAlive();
// ATTENTION, when calling this method the object can be released
// (and possibly collected).
void DontKeepAliveAnyMore();
@@ -137,17 +146,18 @@ protected:
// related to the WebSocket constructor steps
nsString mOriginalURL;
nsString mEffectiveURL; // after redirects
bool mSecure; // if true it is using SSL and the wss scheme,
// otherwise it is using the ws scheme with no SSL
bool mKeepingAlive;
bool mCheckMustKeepAlive;
- bool mTriggeredCloseEvent;
+ bool mOnCloseScheduled;
+ bool mFailed;
bool mDisconnected;
// Set attributes of DOM 'onclose' message
bool mCloseEventWasClean;
nsString mCloseEventReason;
PRUint16 mCloseEventCode;
nsCString mAsciiHost; // hostname
--- a/content/base/src/nsXMLHttpRequest.h
+++ b/content/base/src/nsXMLHttpRequest.h
@@ -241,16 +241,34 @@ public:
NS_FORWARD_NSIDOMEVENTTARGET(nsXHREventTarget::)
#ifdef DEBUG
void StaticAssertions();
#endif
// 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();
// request
void Open(const nsAString& aMethod, const nsAString& aUrl, bool aAsync,
const mozilla::dom::Optional<nsAString>& aUser,
const mozilla::dom::Optional<nsAString>& aPassword,
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -544,16 +544,17 @@ include $(topsrcdir)/config/rules.mk
test_bug650386_redirect_307.html \
file_bug650386_content.sjs \
file_bug650386_report.sjs \
test_bug719533.html \
test_bug737087.html \
test_bug433662.html \
test_bug749367.html \
test_bug753278.html \
+ test_XHR_onuploadprogress.html \
$(NULL)
_CHROME_FILES = \
test_bug357450.js \
$(NULL)
# This test fails on the Mac for some reason
ifneq (,$(filter gtk2 windows,$(MOZ_WIDGET_TOOLKIT)))
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_XHR_onuploadprogress.html
@@ -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>
--- a/content/base/test/test_websocket.html
+++ b/content/base/test/test_websocket.html
@@ -64,20 +64,21 @@
* 39. a basic wss:// connectivity test
* 40. negative test for wss:// with no cert
* 41. HSTS
* 42. non-char utf-8 sequences
* 43. Test setting binaryType attribute
* 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
// random orange failures.
// - Do NOT check into mozilla-central with a value != 1.
// - Too large a count will wind up causing tryserver to timeout the test (which
// is ok, but means all testruns will be orange). If I set first_test to >22
// (i.e don't run any of the tests that require waiting) I can get ~250-300
@@ -277,16 +278,17 @@ function test3()
{
hasError = true;
}
ws.onclose = function(e)
{
shouldCloseNotCleanly(e);
ok(hasError, "rcvd onerror event");
+ ok(e.code == 1006, "test-3 close code should be 1006 but is:" + e.code);
doTest(4);
};
}
function test4()
{
try {
var ws = CreateTestWS("file_websocket");
@@ -1430,16 +1432,51 @@ function test46()
ws.onclose = function(e)
{
ok(ws.readyState == 3, "onclose bad readyState in test-46!");
shouldCloseCleanly(e);
doTest(47);
}
}
+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()
{
if (!ranAllTests)
return;
if (waitTest2Part1 || waitTest2Part2 || waitTest9 || waitTest10 ||
--- a/content/base/test/unit/test_csputils.js
+++ b/content/base/test/unit/test_csputils.js
@@ -594,16 +594,39 @@ test(
do_check_false(src.permits("https://foobar.com:443"));
//"src should inherit and require https scheme from self
do_check_false(src.permits("http://foobar.com:4443"));
do_check_false(src.permits("http://foobar.com"));
});
+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() {
var cspr;
var self = "http://localhost:" + POLICY_PORT;
var closed_policy = CSPRep.fromString("allow 'none'");
var my_uri_policy = "policy-uri " + POLICY_URI;
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -296,16 +296,19 @@ nsEventListenerManager::AddEventListener
}
bool
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;
}
return false;
}
void
@@ -396,17 +399,17 @@ nsEventListenerManager::RemoveEventListe
if (ls->mListener == aListener &&
(ls->mFlags & ~NS_PRIV_EVENT_UNTRUSTED_PERMITTED) == aFlags) {
nsRefPtr<nsEventListenerManager> kungFuDeathGrip = this;
mListeners.RemoveElementAt(i);
--count;
mNoListenerForEvent = NS_EVENT_TYPE_NULL;
mNoListenerForEventAtom = nsnull;
- if (deviceType) {
+ if (!deviceType) {
return;
}
--typeCount;
}
}
}
if (deviceType && typeCount == 0) {
--- a/content/html/content/public/nsHTMLAudioElement.h
+++ b/content/html/content/public/nsHTMLAudioElement.h
@@ -44,11 +44,15 @@ public:
JSObject* aObj, PRUint32 argc, jsval* argv);
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel);
virtual nsXPCClassInfo* GetClassInfo();
virtual nsIDOMNode* AsDOMNode() { return this; }
+
+protected:
+ virtual void GetItemValueText(nsAString& text);
+ virtual void SetItemValueText(const nsAString& text);
};
#endif
--- a/content/html/content/public/nsHTMLVideoElement.h
+++ b/content/html/content/public/nsHTMLVideoElement.h
@@ -55,11 +55,15 @@ public:
// If there is no video frame, returns NS_ERROR_FAILURE.
nsresult GetVideoSize(nsIntSize* size);
virtual nsresult SetAcceptHeader(nsIHttpChannel* aChannel);
virtual nsXPCClassInfo* GetClassInfo();
virtual nsIDOMNode* AsDOMNode() { return this; }
+
+protected:
+ virtual void GetItemValueText(nsAString& text);
+ virtual void SetItemValueText(const nsAString& text);
};
#endif
new file mode 100644
--- /dev/null
+++ b/content/html/content/src/HTMLPropertiesCollection.cpp
@@ -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
new file mode 100644
--- /dev/null
+++ b/content/html/content/src/HTMLPropertiesCollection.h
@@ -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_
--- a/content/html/content/src/Makefile.in
+++ b/content/html/content/src/Makefile.in
@@ -17,16 +17,17 @@ FAIL_ON_WARNINGS = 1
EXPORTS = \
nsClientRect.h \
nsHTMLDNSPrefetch.h \
$(NULL)
CPPSRCS = \
+ HTMLPropertiesCollection.cpp \
nsClientRect.cpp \
nsHTMLDNSPrefetch.cpp \
nsGenericHTMLElement.cpp \
nsGenericHTMLFrameElement.cpp \
nsFormSubmission.cpp \
nsTextEditorState.cpp \
nsHTMLElement.cpp \
nsHTMLAnchorElement.cpp \
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -86,16 +86,19 @@
#include "nsHTMLMenuElement.h"
#include "nsAsyncDOMEvent.h"
#include "nsIScriptError.h"
#include "nsDOMMutationObserver.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/FromParser.h"
#include "mozilla/BloomFilter.h"
+#include "HTMLPropertiesCollection.h"
+#include "nsVariant.h"
+
using namespace mozilla;
using namespace mozilla::dom;
#include "nsThreadUtils.h"
class nsINodeInfo;
class nsIDOMNodeList;
class nsRuleWalker;
@@ -243,17 +246,16 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(nsGeneri
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsGenericHTMLElementTearoff)
NS_INTERFACE_TABLE_HEAD(nsGenericHTMLElementTearoff)
NS_INTERFACE_TABLE_INHERITED1(nsGenericHTMLElementTearoff,
nsIDOMElementCSSInlineStyle)
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)
nsresult
nsGenericHTMLElement::DOMQueryInterface(nsIDOMHTMLElement *aElement,
REFNSIID aIID, void **aInstancePtr)
{
NS_PRECONDITION(aInstancePtr, "null out param");
@@ -1694,16 +1696,23 @@ nsGenericHTMLElement::BindToTree(nsIDocu
bool aCompileEventHandlers)
{
nsresult rv = nsGenericHTMLElementBase::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
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->
AddToNameTable(this, GetParsedAttr(nsGkAtoms::name)->GetAtomValue());
}
if (HasFlag(NODE_IS_EDITABLE) && GetContentEditableValue() == eTrue) {
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(aDocument);
if (htmlDocument) {
@@ -1716,16 +1725,24 @@ nsGenericHTMLElement::BindToTree(nsIDocu
}
void
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();
if (GetContentEditableValue() == eTrue) {
nsCOMPtr<nsIHTMLDocument> htmlDocument = do_QueryInterface(GetCurrentDoc());
if (htmlDocument) {
htmlDocument->ChangeContentEditableCount(this, -1);
}
@@ -2068,16 +2085,23 @@ nsGenericHTMLElement::ParseAttribute(PRI
return true;
}
if (aAttribute == nsGkAtoms::contenteditable) {
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,
aValue, aResult);
}
bool
nsGenericHTMLElement::IsAttributeMapped(const nsIAtom* aAttribute) const
@@ -4076,8 +4100,167 @@ nsGenericHTMLElement::ChangeEditableStat
}
// MakeContentDescendantsEditable is going to call ContentStateChanged for
// this element and all descendants if editable state has changed.
// We might as well wrap it all in one script blocker.
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;
+}
+
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -8,16 +8,18 @@
#include "nsMappedAttributeElement.h"
#include "nsIDOMHTMLElement.h"
#include "nsINameSpaceManager.h" // for kNameSpaceID_None
#include "nsIFormControl.h"
#include "nsFrameLoader.h"
#include "nsGkAtoms.h"
#include "nsContentCreatorFunctions.h"
+#include "nsDOMSettableTokenList.h"
+#include "nsIDOMHTMLPropertiesCollection.h"
class nsIDOMAttr;
class nsIDOMEventListener;
class nsIDOMNodeList;
class nsIFrame;
class nsIStyleRule;
class nsChildContentList;
class nsDOMCSSDeclaration;
@@ -28,16 +30,17 @@ class nsIForm;
class nsPresState;
class nsILayoutHistoryState;
class nsIEditor;
struct nsRect;
struct nsSize;
class nsHTMLFormElement;
class nsIDOMDOMStringMap;
class nsIDOMHTMLMenuElement;
+class nsIDOMHTMLCollection;
typedef nsMappedAttributeElement nsGenericHTMLElementBase;
/**
* A common superclass for HTML elements
*/
class nsGenericHTMLElement : public nsGenericHTMLElementBase
{
@@ -109,16 +112,36 @@ public:
NS_IMETHOD GetTabIndex(PRInt32 *aTabIndex);
NS_IMETHOD SetTabIndex(PRInt32 aTabIndex);
NS_IMETHOD GetHidden(bool* aHidden);
NS_IMETHOD SetHidden(bool aHidden);
NS_IMETHOD GetSpellcheck(bool* aSpellcheck);
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);
nsresult GetContentEditable(nsAString& aContentEditable);
nsresult GetIsContentEditable(bool* aContentEditable);
nsresult SetContentEditable(const nsAString &aContentEditable);
nsresult GetDataset(nsIDOMDOMStringMap** aDataset);
// Callback for destructor of of dataset to ensure to null out weak pointer.
@@ -766,19 +789,16 @@ protected:
* made editable through contentEditable or designMode.
*/
bool IsEditableRoot() const;
private:
void ChangeEditableState(PRInt32 aChange);
};
-
-//----------------------------------------------------------------------
-
class nsHTMLFieldSetElement;
/**
* A helper class for form elements that can contain children
*/
class nsGenericHTMLFormElement : public nsGenericHTMLElement,
public nsIFormControl
{
@@ -1371,16 +1391,55 @@ PR_STATIC_ASSERT(ELEMENT_TYPE_SPECIFIC_B
return _to GetHidden(aHidden); \
} \
NS_SCRIPTABLE NS_IMETHOD SetHidden(bool aHidden) { \
return _to SetHidden(aHidden); \
} \
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); \
} \
NS_SCRIPTABLE NS_IMETHOD SetAccessKey(const nsAString& aAccessKey) { \
return _to SetAccessKey(aAccessKey); \
} \
NS_SCRIPTABLE NS_IMETHOD GetAccessKeyLabel(nsAString& aAccessKeyLabel) { \
return _to GetAccessKeyLabel(aAccessKeyLabel); \
--- a/content/html/content/src/nsHTMLAnchorElement.cpp
+++ b/content/html/content/src/nsHTMLAnchorElement.cpp
@@ -105,16 +105,20 @@ public:
virtual nsXPCClassInfo* GetClassInfo();
virtual nsIDOMNode* AsDOMNode() { return this; }
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
#define HTML_ANCHOR_DNS_PREFETCH_REQUESTED \
(1 << ELEMENT_TYPE_SPECIFIC_BITS_OFFSET)
// Indicates that a DNS Prefetch was added to the deferral queue
#define HTML_ANCHOR_DNS_PREFETCH_DEFERRED \
(1 << (ELEMENT_TYPE_SPECIFIC_BITS_OFFSET+1))
@@ -161,16 +165,28 @@ NS_IMPL_URI_ATTR(nsHTMLAnchorElement, Hr
NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Hreflang, hreflang)
NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Name, name)
NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Rel, rel)
NS_IMPL_STRING_ATTR(nsHTMLAnchorElement, Rev, rev)
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)
{
// links can be dragged as long as there is an href and the
// draggable attribute isn't false
if (HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
*aDraggable = !AttrValueIs(kNameSpaceID_None, nsGkAtoms::draggable,
nsGkAtoms::_false, eIgnoreCase);
--- a/content/html/content/src/nsHTMLAreaElement.cpp
+++ b/content/html/content/src/nsHTMLAreaElement.cpp
@@ -90,16 +90,20 @@ public:
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
virtual nsEventStates IntrinsicState() const;
virtual nsXPCClassInfo* GetClassInfo();
virtual nsIDOMNode* AsDOMNode() { return this; }
+
+protected:
+ virtual void GetItemValueText(nsAString& text);
+ virtual void SetItemValueText(const nsAString& text);
};
NS_IMPL_NS_NEW_HTML_ELEMENT(Area)
nsHTMLAreaElement::nsHTMLAreaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsGenericHTMLElement(aNodeInfo),
@@ -132,16 +136,28 @@ NS_IMPL_ELEMENT_CLONE(nsHTMLAreaElement)
NS_IMPL_STRING_ATTR(nsHTMLAreaElement, Alt, alt)
NS_IMPL_STRING_ATTR(nsHTMLAreaElement, Coords, coords)
NS_IMPL_URI_ATTR(nsHTMLAreaElement, Href, href)
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)
{
if (!GetAttr(kNameSpaceID_None, nsGkAtoms::target, aValue)) {
GetBaseTarget(aValue);
}
return NS_OK;
}
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -78,16 +78,30 @@ nsHTMLAudioElement::nsHTMLAudioElement(a
: nsHTMLMediaElement(aNodeInfo)
{
}
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)
{
// Audio elements created using "new Audio(...)" should have
// 'preload' set to 'auto' (since the script must intend to
// play the audio)
nsresult rv = SetAttr(kNameSpaceID_None, nsGkAtoms::preload,
--- a/content/html/content/src/nsHTMLIFrameElement.cpp
+++ b/content/html/content/src/nsHTMLIFrameElement.cpp
@@ -53,16 +53,20 @@ public:
const nsAString& aValue,
nsAttrValue& aResult);
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
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);
};
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(IFrame)
nsHTMLIFrameElement::nsHTMLIFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
FromParser aFromParser)
@@ -101,16 +105,28 @@ NS_IMPL_URI_ATTR(nsHTMLIFrameElement, Lo
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, MarginHeight, marginheight)
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, MarginWidth, marginwidth)
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Name, name)
NS_IMPL_STRING_ATTR(nsHTMLIFrameElement, Scrolling, scrolling)
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)
{
return nsGenericHTMLFrameElement::GetContentDocument(aContentDocument);
}
NS_IMETHODIMP
nsHTMLIFrameElement::GetContentWindow(nsIDOMWindow** aContentWindow)
--- a/content/html/content/src/nsHTMLImageElement.cpp
+++ b/content/html/content/src/nsHTMLImageElement.cpp
@@ -111,16 +111,28 @@ NS_IMPL_STRING_ATTR(nsHTMLImageElement,
NS_IMPL_INT_ATTR(nsHTMLImageElement, Hspace, hspace)
NS_IMPL_BOOL_ATTR(nsHTMLImageElement, IsMap, ismap)
NS_IMPL_URI_ATTR(nsHTMLImageElement, LongDesc, longdesc)
NS_IMPL_STRING_ATTR(nsHTMLImageElement, Lowsrc, lowsrc)
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)
NS_IMETHODIMP
nsHTMLImageElement::GetDraggable(bool* aDraggable)
{
// images may be dragged unless the draggable attribute is false
--- a/content/html/content/src/nsHTMLImageElement.h
+++ b/content/html/content/src/nsHTMLImageElement.h
@@ -98,11 +98,13 @@ public:
nsresult CopyInnerTo(nsGenericElement* aDest) const;
void MaybeLoadImage();
virtual nsXPCClassInfo* GetClassInfo();
virtual nsIDOMNode* AsDOMNode() { return this; }
protected:
nsIntPoint GetXY();
nsSize GetWidthHeight();
+ virtual void GetItemValueText(nsAString& text);
+ virtual void SetItemValueText(const nsAString& text);
};
#endif /* nsHTMLImageElement_h */
--- a/content/html/content/src/nsHTMLLinkElement.cpp
+++ b/content/html/content/src/nsHTMLLinkElement.cpp
@@ -90,16 +90,19 @@ public:
virtual nsXPCClassInfo* GetClassInfo();
virtual nsIDOMNode* AsDOMNode() { return this; }
protected:
virtual already_AddRefed<nsIURI> GetStyleSheetURL(bool* aIsInline);
virtual void GetStyleSheetInfo(nsAString& aTitle,
nsAString& aType,
nsAString& aMedia,
bool* aIsAlternate);
+protected:
+ virtual void GetItemValueText(nsAString& text);
+ virtual void SetItemValueText(const nsAString& text);
};
NS_IMPL_NS_NEW_HTML_ELEMENT(Link)
nsHTMLLinkElement::nsHTMLLinkElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsGenericHTMLElement(aNodeInfo),
@@ -167,16 +170,28 @@ NS_IMPL_STRING_ATTR(nsHTMLLinkElement, C
NS_IMPL_URI_ATTR(nsHTMLLinkElement, Href, href)
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Hreflang, hreflang)
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Media, media)
NS_IMPL_STRING_ATTR(nsHTMLLinkElement, Rel, rel)
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,
bool aCompileEventHandlers)
{
Link::ResetLinkState(false);
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
--- a/content/html/content/src/nsHTMLMetaElement.cpp
+++ b/content/html/content/src/nsHTMLMetaElement.cpp
@@ -40,16 +40,20 @@ public:
bool aNullParent = true);
void CreateAndDispatchEvent(nsIDocument* aDoc, const nsAString& aEventName);
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);
};
NS_IMPL_NS_NEW_HTML_ELEMENT(Meta)
nsHTMLMetaElement::nsHTMLMetaElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
@@ -78,16 +82,29 @@ NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLA
NS_IMPL_ELEMENT_CLONE(nsHTMLMetaElement)
NS_IMPL_STRING_ATTR(nsHTMLMetaElement, Content, content)
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,
bool aCompileEventHandlers)
{
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
aBindingParent,
aCompileEventHandlers);
--- a/content/html/content/src/nsHTMLObjectElement.cpp
+++ b/content/html/content/src/nsHTMLObjectElement.cpp
@@ -131,16 +131,19 @@ private:
*/
NS_HIDDEN_(void) StartObjectLoad(bool aNotify);
/**
* Returns if the element is currently focusable regardless of it's tabindex
* 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;
};
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Object)
@@ -219,16 +222,28 @@ NS_IMPL_ELEMENT_CLONE(nsHTMLObjectElemen
NS_IMPL_NSICONSTRAINTVALIDATION(nsHTMLObjectElement)
NS_IMETHODIMP
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,
nsIContent *aBindingParent,
bool aCompileEventHandlers)
{
nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent,
aBindingParent,
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp
+++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp
@@ -148,16 +148,19 @@ private:
return mNodeInfo->Equals(nsGkAtoms::applet) ?
nsGkAtoms::code :
nsGkAtoms::src;
}
// 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);
};
NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(SharedObject)
nsHTMLSharedObjectElement::nsHTMLSharedObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo,
FromParser aFromParser)
@@ -166,16 +169,36 @@ nsHTMLSharedObjectElement::nsHTMLSharedO
{
RegisterFreezableElement();
SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK);
// By default we're in the loading state
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();
DestroyImageLoadingContent();
}
bool
nsHTMLSharedObjectElement::IsDoneAddingChildren()
--- a/content/html/content/src/nsHTMLSourceElement.cpp
+++ b/content/html/content/src/nsHTMLSourceElement.cpp
@@ -42,16 +42,20 @@ public:
// child source element.
virtual nsresult BindToTree(nsIDocument *aDocument, nsIContent *aParent,
nsIContent *aBindingParent,
bool aCompileEventHandlers);
virtual nsXPCClassInfo* GetClassInfo();
virtual nsIDOMNode* AsDOMNode() { return this; }
+
+protected:
+ virtual void GetItemValueText(nsAString& text);
+ virtual void SetItemValueText(const nsAString& text);
};
NS_IMPL_NS_NEW_HTML_ELEMENT(Source)
nsHTMLSourceElement::nsHTMLSourceElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsGenericHTMLElement(aNodeInfo)
@@ -79,16 +83,28 @@ NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLA
NS_IMPL_ELEMENT_CLONE(nsHTMLSourceElement)
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,
nsIContent *aBindingParent,
bool aCompileEventHandlers)
{
nsresult rv = nsGenericHTMLElement::BindToTree(aDocument,
aParent,
--- a/content/html/content/src/nsHTMLVideoElement.cpp
+++ b/content/html/content/src/nsHTMLVideoElement.cpp
@@ -75,16 +75,30 @@ nsHTMLVideoElement::nsHTMLVideoElement(a
: nsHTMLMediaElement(aNodeInfo)
{
}
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) {
return NS_ERROR_FAILURE;
}
size->height = mMediaSize.height;
size->width = mMediaSize.width;
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1760,16 +1760,94 @@ nsHTMLDocument::GetElementsByName(const
NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY);
// Transfer ownership
list.forget(aReturn);
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()
{
++mNumForms;
}
void
nsHTMLDocument::RemovedForm()
--- a/content/html/document/src/nsHTMLDocument.h
+++ b/content/html/document/src/nsHTMLDocument.h
@@ -107,17 +107,16 @@ public:
nsIContent *GetBody();
Element *GetHead() { return GetHeadElement(); }
already_AddRefed<nsContentList> GetElementsByName(const nsAString & aName)
{
return NS_GetFuncStringContentList(this, MatchNameAttribute, nsnull,
UseExistingNameString, aName);
}
-
virtual nsresult ResolveName(const nsAString& aName,
nsIContent *aForm,
nsISupports **aResult,
nsWrapperCache **aCache);
virtual void AddedForm();
virtual void RemovedForm();
virtual PRInt32 GetNumFormsSynchronous();
--- a/content/media/gstreamer/nsGStreamerReader.cpp
+++ b/content/media/gstreamer/nsGStreamerReader.cpp
@@ -273,17 +273,17 @@ nsresult nsGStreamerReader::ReadMetadata
}
/* report the duration */
gint64 duration;
GstFormat format = GST_FORMAT_TIME;
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);
}
int n_video = 0, n_audio = 0;
g_object_get(mPlayBin, "n-video", &n_video, "n-audio", &n_audio, NULL);
mInfo.mHasVideo = n_video != 0;<