зеркало из https://github.com/mozilla/gecko-dev.git
Merge of 3.1a2 release branch back to default, with version bumps to 3.1b1pre
This commit is contained in:
Коммит
5f333d09a5
|
@ -4,6 +4,7 @@
|
|||
~$
|
||||
\.pyc$
|
||||
(^|/)TAGS$
|
||||
\.DS_Store$
|
||||
|
||||
# User files that may appear at the root
|
||||
^\.mozconfig$
|
||||
|
|
|
@ -170,6 +170,7 @@ ACCESSIBILITY_ATOM(href, "href") // XUL, XLink
|
|||
ACCESSIBILITY_ATOM(increment, "increment") // XUL
|
||||
ACCESSIBILITY_ATOM(lang, "lang")
|
||||
ACCESSIBILITY_ATOM(linkedPanel, "linkedpanel") // XUL
|
||||
ACCESSIBILITY_ATOM(longDesc, "longdesc")
|
||||
ACCESSIBILITY_ATOM(maxpos, "maxpos") // XUL
|
||||
ACCESSIBILITY_ATOM(minpos, "minpos") // XUL
|
||||
ACCESSIBILITY_ATOM(multiline, "multiline") // XUL
|
||||
|
@ -187,6 +188,7 @@ ACCESSIBILITY_ATOM(type, "type")
|
|||
ACCESSIBILITY_ATOM(value, "value")
|
||||
|
||||
// Alphabetical list of text attributes (AT API)
|
||||
ACCESSIBILITY_ATOM(backgroundColor, "background-color")
|
||||
ACCESSIBILITY_ATOM(invalid, "invalid")
|
||||
ACCESSIBILITY_ATOM(language, "language")
|
||||
|
||||
|
|
|
@ -801,6 +801,20 @@ nsAccUtils::GetDocShellTreeItemFor(nsIDOMNode *aNode)
|
|||
return docShellTreeItem;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsAccUtils::GetFrameFor(nsIDOMElement *aElm)
|
||||
{
|
||||
nsCOMPtr<nsIPresShell> shell = nsAccessNode::GetPresShellFor(aElm);
|
||||
if (!shell)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aElm));
|
||||
if (!content)
|
||||
return nsnull;
|
||||
|
||||
return shell->GetPrimaryFrameFor(content);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccUtils::GetID(nsIContent *aContent, nsAString& aID)
|
||||
{
|
||||
|
|
|
@ -307,6 +307,11 @@ public:
|
|||
static already_AddRefed<nsIDocShellTreeItem>
|
||||
GetDocShellTreeItemFor(nsIDOMNode *aNode);
|
||||
|
||||
/**
|
||||
* Retrun frame for the given DOM element.
|
||||
*/
|
||||
static nsIFrame* GetFrameFor(nsIDOMElement *aElm);
|
||||
|
||||
/**
|
||||
* Get the ID for an element, in some types of XML this may not be the ID attribute
|
||||
* @param aContent Node to get the ID for
|
||||
|
|
|
@ -105,6 +105,8 @@ nsApplicationAccessible::Init()
|
|||
NS_IMETHODIMP
|
||||
nsApplicationAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||
do_GetService(NS_STRINGBUNDLE_CONTRACTID);
|
||||
|
||||
|
|
|
@ -118,8 +118,11 @@ nsRootAccessible::~nsRootAccessible()
|
|||
|
||||
// helpers
|
||||
/* readonly attribute AString name; */
|
||||
NS_IMETHODIMP nsRootAccessible::GetName(nsAString& aName)
|
||||
NS_IMETHODIMP
|
||||
nsRootAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
if (!mDocument) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -39,12 +39,13 @@
|
|||
#include "nsTextUtils.h"
|
||||
|
||||
#include "nsAccessNode.h"
|
||||
#include "nsAccessibilityUtils.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLangTextAttr
|
||||
|
||||
PRBool
|
||||
nsLangTextAttr::equal(nsIDOMElement *aElm)
|
||||
nsLangTextAttr::Equal(nsIDOMElement *aElm)
|
||||
{
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aElm));
|
||||
if (!content)
|
||||
|
@ -80,7 +81,6 @@ const char* const kCopyValue = nsnull;
|
|||
|
||||
static nsCSSTextAttrMapItem gCSSTextAttrsMap[] = {
|
||||
// CSS name CSS value Attribute name Attribute name
|
||||
{ "background-color", kAnyValue, kCopyName, kCopyValue },
|
||||
{ "color", kAnyValue, kCopyName, kCopyValue },
|
||||
{ "font-family", kAnyValue, kCopyName, kCopyValue },
|
||||
{ "font-size", kAnyValue, kCopyName, kCopyValue },
|
||||
|
@ -106,7 +106,7 @@ nsCSSTextAttr::nsCSSTextAttr(PRBool aIncludeDefAttrValue, nsIDOMElement *aElm,
|
|||
}
|
||||
|
||||
PRBool
|
||||
nsCSSTextAttr::equal(nsIDOMElement *aElm)
|
||||
nsCSSTextAttr::Equal(nsIDOMElement *aElm)
|
||||
{
|
||||
if (!aElm || !mStyleDecl)
|
||||
return PR_FALSE;
|
||||
|
@ -130,13 +130,13 @@ nsCSSTextAttr::equal(nsIDOMElement *aElm)
|
|||
}
|
||||
|
||||
PRBool
|
||||
nsCSSTextAttr::iterate()
|
||||
nsCSSTextAttr::Iterate()
|
||||
{
|
||||
return ++mIndex < static_cast<PRInt32>(NS_ARRAY_LENGTH(gCSSTextAttrsMap));
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsCSSTextAttr::get(nsACString& aName, nsAString& aValue)
|
||||
nsCSSTextAttr::Get(nsACString& aName, nsAString& aValue)
|
||||
{
|
||||
if (!mStyleDecl)
|
||||
return PR_FALSE;
|
||||
|
@ -179,3 +179,65 @@ nsCSSTextAttr::get(nsACString& aName, nsAString& aValue)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsBackgroundTextAttr
|
||||
|
||||
nsBackgroundTextAttr::nsBackgroundTextAttr(nsIFrame *aFrame,
|
||||
nsIFrame *aRootFrame) :
|
||||
mFrame(aFrame), mRootFrame(aRootFrame)
|
||||
{
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsBackgroundTextAttr::Equal(nsIDOMElement *aElm)
|
||||
{
|
||||
nsIFrame *frame = nsAccUtils::GetFrameFor(aElm);
|
||||
if (!frame)
|
||||
return PR_FALSE;
|
||||
|
||||
return GetColor(mFrame) == GetColor(frame);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsBackgroundTextAttr::Get(nsAString& aValue)
|
||||
{
|
||||
// Do not expose "background-color" text attribute if its value is matched
|
||||
// with the default value.
|
||||
nscolor color = GetColor(mFrame);
|
||||
if (mRootFrame && color == GetColor(mRootFrame))
|
||||
return PR_FALSE;
|
||||
|
||||
// Combine the string like rgb(R, G, B) from nscolor.
|
||||
nsAutoString value;
|
||||
value.AppendLiteral("rgb(");
|
||||
value.AppendInt(NS_GET_R(color));
|
||||
value.AppendLiteral(", ");
|
||||
value.AppendInt(NS_GET_G(color));
|
||||
value.AppendLiteral(", ");
|
||||
value.AppendInt(NS_GET_B(color));
|
||||
value.Append(')');
|
||||
|
||||
aValue = value;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nscolor
|
||||
nsBackgroundTextAttr::GetColor(nsIFrame *aFrame)
|
||||
{
|
||||
const nsStyleBackground *styleBackground = aFrame->GetStyleBackground();
|
||||
|
||||
if (!styleBackground->IsTransparent())
|
||||
return styleBackground->mBackgroundColor;
|
||||
|
||||
nsIFrame *parentFrame = aFrame->GetParent();
|
||||
if (!parentFrame)
|
||||
return styleBackground->mBackgroundColor;
|
||||
|
||||
// Each frame of parents chain for the initially passed 'aFrame' has
|
||||
// transparent background color. So background color isn't changed from
|
||||
// 'mRootFrame' to initially passed 'aFrame'.
|
||||
if (parentFrame == mRootFrame)
|
||||
return GetColor(mRootFrame);
|
||||
|
||||
return GetColor(parentFrame);
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "nsIDOMCSSStyleDeclaration.h"
|
||||
|
||||
#include "nsIContent.h"
|
||||
#include "nsIFrame.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
|
@ -57,7 +58,7 @@ public:
|
|||
* Return true if the text attribute for the given element equals with
|
||||
* predefined attribute.
|
||||
*/
|
||||
virtual PRBool equal(nsIDOMElement *aElm) = 0;
|
||||
virtual PRBool Equal(nsIDOMElement *aElm) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -70,7 +71,7 @@ public:
|
|||
nsLangTextAttr(nsAString& aLang, nsIContent *aRootContent) :
|
||||
mLang(aLang), mRootContent(aRootContent) { }
|
||||
|
||||
virtual PRBool equal(nsIDOMElement *aElm);
|
||||
virtual PRBool Equal(nsIDOMElement *aElm);
|
||||
|
||||
private:
|
||||
nsString mLang;
|
||||
|
@ -88,18 +89,18 @@ public:
|
|||
nsIDOMElement *aRootElm);
|
||||
|
||||
// nsTextAttr
|
||||
virtual PRBool equal(nsIDOMElement *aElm);
|
||||
virtual PRBool Equal(nsIDOMElement *aElm);
|
||||
|
||||
// nsCSSTextAttr
|
||||
/**
|
||||
* Interates through attributes.
|
||||
*/
|
||||
PRBool iterate();
|
||||
PRBool Iterate();
|
||||
|
||||
/**
|
||||
* Get name and value of attribute.
|
||||
*/
|
||||
PRBool get(nsACString& aName, nsAString& aValue);
|
||||
PRBool Get(nsACString& aName, nsAString& aValue);
|
||||
|
||||
private:
|
||||
PRInt32 mIndex;
|
||||
|
@ -109,4 +110,40 @@ private:
|
|||
nsCOMPtr<nsIDOMCSSStyleDeclaration> mDefStyleDecl;
|
||||
};
|
||||
|
||||
/**
|
||||
* Class is used for the work with "background-color" text attribute. It is
|
||||
* used in nsHyperTextAccessible.
|
||||
*/
|
||||
class nsBackgroundTextAttr : public nsTextAttr
|
||||
{
|
||||
public:
|
||||
nsBackgroundTextAttr(nsIFrame *aFrame, nsIFrame *aRootFrame);
|
||||
|
||||
// nsTextAttr
|
||||
virtual PRBool Equal(nsIDOMElement *aElm);
|
||||
|
||||
/**
|
||||
* Returns true and background color value if "background-color" text
|
||||
* attribute should be exposed.
|
||||
*/
|
||||
virtual PRBool Get(nsAString& aValue);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Return background color for the given frame.
|
||||
*
|
||||
* @note If background color for the given frame is transparent then walk
|
||||
* trhough the frame parents chain until we'll got either a frame with
|
||||
* not transparent background color or the given root frame. In the
|
||||
* last case return background color for the root frame.
|
||||
*
|
||||
* @param aFrame [in] the given frame to calculate background-color
|
||||
* @return background color
|
||||
*/
|
||||
nscolor GetColor(nsIFrame *aFrame);
|
||||
|
||||
nsIFrame *mFrame;
|
||||
nsIFrame *mRootFrame;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -275,8 +275,11 @@ NS_IMETHODIMP nsHTMLButtonAccessible::GetRole(PRUint32 *_retval)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLButtonAccessible::GetName(nsAString& aName)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLButtonAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
if (!content) {
|
||||
return NS_ERROR_FAILURE; // Node shut down
|
||||
|
@ -398,8 +401,11 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetRole(PRUint32 *aRole)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetName(nsAString& aName)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLTextFieldAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
|
||||
if (!content) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -606,12 +612,14 @@ nsIContent* nsHTMLGroupboxAccessible::GetLegend()
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLGroupboxAccessible::GetName(nsAString& aName)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLGroupboxAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
if (!mDOMNode) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
aName.Truncate();
|
||||
if (mRoleMapEntry) {
|
||||
nsAccessible::GetName(aName);
|
||||
if (!aName.IsEmpty()) {
|
||||
|
|
|
@ -210,9 +210,46 @@ void nsHTMLImageAccessible::CacheChildren()
|
|||
mAccChildCount = childCount;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLImageAccessible::DoAction(PRUint8 index)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLImageAccessible::GetNumActions(PRUint8 *aNumActions)
|
||||
{
|
||||
if (index == eAction_ShowLongDescription) {
|
||||
NS_ENSURE_ARG_POINTER(aNumActions);
|
||||
*aNumActions = 0;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv= nsLinkableAccessible::GetNumActions(aNumActions);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (HasLongDesc())
|
||||
(*aNumActions)++;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLImageAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (IsValidLongDescIndex(aIndex)) {
|
||||
aName.AssignLiteral("showlongdesc");
|
||||
return NS_OK;
|
||||
}
|
||||
return nsLinkableAccessible::GetActionName(aIndex, aName);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLImageAccessible::DoAction(PRUint8 aIndex)
|
||||
{
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (IsValidLongDescIndex(aIndex)) {
|
||||
//get the long description uri and open in a new window
|
||||
nsCOMPtr<nsIDOMHTMLImageElement> element(do_QueryInterface(mDOMNode));
|
||||
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
|
||||
|
@ -230,7 +267,7 @@ NS_IMETHODIMP nsHTMLImageAccessible::DoAction(PRUint8 index)
|
|||
return win->Open(longDesc, NS_LITERAL_STRING(""), NS_LITERAL_STRING(""),
|
||||
getter_AddRefs(tmp));
|
||||
}
|
||||
return nsLinkableAccessible::DoAction(index);
|
||||
return nsLinkableAccessible::DoAction(aIndex);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -405,3 +442,29 @@ nsHTMLImageAccessible::GetAreaAccessible(nsIDOMHTMLCollection *aAreaCollection,
|
|||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Private methods
|
||||
|
||||
PRBool
|
||||
nsHTMLImageAccessible::HasLongDesc()
|
||||
{
|
||||
if (IsDefunct())
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
return (content->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::longDesc));
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLImageAccessible::IsValidLongDescIndex(PRUint8 aIndex)
|
||||
{
|
||||
if (!HasLongDesc())
|
||||
return PR_FALSE;
|
||||
|
||||
PRUint8 numActions = 0;
|
||||
nsresult rv = nsLinkableAccessible::GetNumActions(&numActions);
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
|
||||
return (aIndex == numActions);
|
||||
}
|
||||
|
|
|
@ -55,15 +55,14 @@ class nsHTMLImageAccessible : public nsLinkableAccessible,
|
|||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
public:
|
||||
//action0 may exist depends on whether an onclick is associated with it
|
||||
enum { eAction_ShowLongDescription = 1 };
|
||||
|
||||
nsHTMLImageAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetName(nsAString& _retval);
|
||||
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
NS_IMETHOD GetRole(PRUint32 *_retval);
|
||||
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
|
||||
// nsIAccessibleHyperLink
|
||||
|
@ -95,6 +94,25 @@ protected:
|
|||
// share area elements but we need to have separate area accessibles for
|
||||
// each image accessible.
|
||||
nsAccessNodeHashtable *mAccessNodeCache;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Determine if this image accessible has a longdesc attribute.
|
||||
*
|
||||
* @returns true if the longdesc attribute is present.
|
||||
*/
|
||||
PRBool HasLongDesc();
|
||||
|
||||
/**
|
||||
* Used by GetActionName and DoAction to ensure the index for opening the
|
||||
* longdesc URL is valid.
|
||||
* It is always assumed that the highest possible index opens the longdesc.
|
||||
*
|
||||
* @param aIndex The 0-based index to be tested.
|
||||
*
|
||||
* @returns true if index is valid for longdesc action.
|
||||
*/
|
||||
PRBool IsValidLongDescIndex(PRUint8 aIndex);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -513,8 +513,11 @@ NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetRole(PRUint32 *aRole)
|
|||
/**
|
||||
* Get our Name from our Content's subtree
|
||||
*/
|
||||
NS_IMETHODIMP nsHTMLSelectOptionAccessible::GetName(nsAString& aName)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLSelectOptionAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
// CASE #1 -- great majority of the cases
|
||||
// find the label attribute - this is what the W3C says we should use
|
||||
nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(mDOMNode));
|
||||
|
@ -1383,8 +1386,11 @@ NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetParent(nsIAccessible **aParent)
|
|||
/**
|
||||
* Gets the name from GetActionName()
|
||||
*/
|
||||
NS_IMETHODIMP nsHTMLComboboxButtonAccessible::GetName(nsAString& aName)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLComboboxButtonAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
return GetActionName(eAction_Click, aName);
|
||||
}
|
||||
|
||||
|
|
|
@ -735,6 +735,30 @@ nsHyperTextAccessible::HypertextOffsetsToDOMRange(PRInt32 aStartHTOffset,
|
|||
NS_ENSURE_ARG_POINTER(aEndOffset);
|
||||
*aEndOffset = -1;
|
||||
|
||||
// If the given offsets are 0 and associated editor is empty then return
|
||||
// collapsed range with editor root element as range container.
|
||||
if (aStartHTOffset == 0 && aEndHTOffset == 0) {
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
if (editor) {
|
||||
PRBool isEmpty = PR_FALSE;
|
||||
editor->GetDocumentIsEmpty(&isEmpty);
|
||||
if (isEmpty) {
|
||||
nsCOMPtr<nsIDOMElement> editorRootElm;
|
||||
editor->GetRootElement(getter_AddRefs(editorRootElm));
|
||||
|
||||
nsCOMPtr<nsIDOMNode> editorRoot(do_QueryInterface(editorRootElm));
|
||||
if (editorRoot) {
|
||||
*aStartOffset = *aEndOffset = 0;
|
||||
NS_ADDREF(*aStartNode = editorRoot);
|
||||
NS_ADDREF(*aEndNode = editorRoot);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAccessible> startAcc, endAcc;
|
||||
PRInt32 startOffset = aStartHTOffset, endOffset = aEndHTOffset;
|
||||
nsIFrame *startFrame = nsnull, *endFrame = nsnull;
|
||||
|
@ -1180,12 +1204,24 @@ nsHyperTextAccessible::GetDefaultTextAttributes(nsIPersistentProperties **aAttri
|
|||
nsCOMPtr<nsIDOMElement> element = nsAccUtils::GetDOMElementFor(mDOMNode);
|
||||
|
||||
nsCSSTextAttr textAttr(PR_TRUE, element, nsnull);
|
||||
while (textAttr.iterate()) {
|
||||
while (textAttr.Iterate()) {
|
||||
nsCAutoString name;
|
||||
nsAutoString value, oldValue;
|
||||
if (textAttr.get(name, value))
|
||||
if (textAttr.Get(name, value))
|
||||
attributes->SetStringProperty(name, value, oldValue);
|
||||
}
|
||||
|
||||
nsIFrame *sourceFrame = nsAccUtils::GetFrameFor(element);
|
||||
if (sourceFrame) {
|
||||
nsBackgroundTextAttr backgroundTextAttr(sourceFrame, nsnull);
|
||||
|
||||
nsAutoString value;
|
||||
if (backgroundTextAttr.Get(value)) {
|
||||
nsAccUtils::SetAccAttr(attributes,
|
||||
nsAccessibilityAtoms::backgroundColor, value);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2288,10 +2324,10 @@ nsHyperTextAccessible::GetCSSTextAttributes(PRBool aIncludeDefAttrs,
|
|||
nsCOMPtr<nsIDOMElement> rootElm(nsAccUtils::GetDOMElementFor(mDOMNode));
|
||||
|
||||
nsCSSTextAttr textAttr(aIncludeDefAttrs, sourceElm, rootElm);
|
||||
while (textAttr.iterate()) {
|
||||
while (textAttr.Iterate()) {
|
||||
nsCAutoString name;
|
||||
nsAutoString value, oldValue;
|
||||
if (aAttributes && textAttr.get(name, value))
|
||||
if (aAttributes && textAttr.Get(name, value))
|
||||
aAttributes->SetStringProperty(name, value, oldValue);
|
||||
|
||||
nsresult rv = GetRangeForTextAttr(aSourceNode, &textAttr,
|
||||
|
@ -2299,6 +2335,25 @@ nsHyperTextAccessible::GetCSSTextAttributes(PRBool aIncludeDefAttrs,
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
nsIFrame *sourceFrame = nsAccUtils::GetFrameFor(sourceElm);
|
||||
if (sourceFrame) {
|
||||
nsIFrame *rootFrame = nsnull;
|
||||
|
||||
if (!aIncludeDefAttrs)
|
||||
rootFrame = nsAccUtils::GetFrameFor(rootElm);
|
||||
|
||||
nsBackgroundTextAttr backgroundTextAttr(sourceFrame, rootFrame);
|
||||
nsAutoString value;
|
||||
if (backgroundTextAttr.Get(value)) {
|
||||
nsAccUtils::SetAccAttr(aAttributes,
|
||||
nsAccessibilityAtoms::backgroundColor, value);
|
||||
}
|
||||
|
||||
nsresult rv = GetRangeForTextAttr(aSourceNode, &backgroundTextAttr,
|
||||
aStartHTOffset, aEndHTOffset);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2328,7 +2383,7 @@ nsHyperTextAccessible::GetRangeForTextAttr(nsIDOMNode *aNode,
|
|||
nsCOMPtr<nsIDOMElement> currElm(nsAccUtils::GetDOMElementFor(currNode));
|
||||
NS_ENSURE_STATE(currElm);
|
||||
|
||||
if (currNode != aNode && !aComparer->equal(currElm)) {
|
||||
if (currNode != aNode && !aComparer->Equal(currElm)) {
|
||||
PRInt32 startHTOffset = 0;
|
||||
nsCOMPtr<nsIAccessible> startAcc;
|
||||
nsresult rv = DOMPointToHypertextOffset(tmpNode, -1, &startHTOffset,
|
||||
|
@ -2364,7 +2419,7 @@ nsHyperTextAccessible::GetRangeForTextAttr(nsIDOMNode *aNode,
|
|||
|
||||
// Stop new end offset searching if the given text attribute changes its
|
||||
// value.
|
||||
if (!aComparer->equal(currElm)) {
|
||||
if (!aComparer->Equal(currElm)) {
|
||||
PRInt32 endHTOffset = 0;
|
||||
nsresult rv = DOMPointToHypertextOffset(currNode, -1, &endHTOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -2410,7 +2465,7 @@ nsHyperTextAccessible::FindEndOffsetInSubtree(nsIDOMNode *aCurrNode,
|
|||
|
||||
// If the given text attribute (pointed by nsTextAttr object) changes its
|
||||
// value on the traversed element then fit the end of range.
|
||||
if (!aComparer->equal(currElm)) {
|
||||
if (!aComparer->Equal(currElm)) {
|
||||
PRInt32 endHTOffset = 0;
|
||||
nsresult rv = DOMPointToHypertextOffset(aCurrNode, -1, &endHTOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -2461,7 +2516,7 @@ nsHyperTextAccessible::FindStartOffsetInSubtree(nsIDOMNode *aCurrNode,
|
|||
|
||||
// If the given text attribute (pointed by nsTextAttr object) changes its
|
||||
// value on the traversed element then fit the start of range.
|
||||
if (!aComparer->equal(currElm)) {
|
||||
if (!aComparer->Equal(currElm)) {
|
||||
PRInt32 startHTOffset = 0;
|
||||
nsCOMPtr<nsIAccessible> startAcc;
|
||||
nsresult rv = DOMPointToHypertextOffset(aPrevNode, -1, &startHTOffset,
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsAccessNodeWrap.h"
|
||||
#include <tchar.h>
|
||||
#include "ISimpleDOMNode_i.c"
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
#include "nsIAccessibilityService.h"
|
||||
|
@ -72,6 +71,10 @@ PRBool nsAccessNodeWrap::gIsIA2Disabled = PR_FALSE;
|
|||
|
||||
nsIAccessibleTextChangeEvent *nsAccessNodeWrap::gTextEvent = nsnull;
|
||||
|
||||
// Pref to disallow CtrlTab preview functionality if JAWS or Window-Eyes are
|
||||
// running.
|
||||
#define CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF "browser.ctrlTab.disallowForScreenReaders"
|
||||
|
||||
|
||||
/* For documentation of the accessibility architecture,
|
||||
* see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
|
||||
|
@ -592,7 +595,7 @@ void nsAccessNodeWrap::InitAccessibility()
|
|||
}
|
||||
|
||||
if (!gmUserLib) {
|
||||
gmUserLib =::LoadLibrary("USER32.DLL");
|
||||
gmUserLib =::LoadLibraryW(L"USER32.DLL");
|
||||
}
|
||||
|
||||
if (gmUserLib) {
|
||||
|
@ -662,7 +665,7 @@ GetHRESULT(nsresult aResult)
|
|||
|
||||
PRBool nsAccessNodeWrap::IsOnlyMsaaCompatibleJawsPresent()
|
||||
{
|
||||
HMODULE jhookhandle = ::GetModuleHandleW(NS_LITERAL_STRING("jhook").get());
|
||||
HMODULE jhookhandle = ::GetModuleHandleW(L"jhook");
|
||||
if (!jhookhandle)
|
||||
return PR_FALSE; // No JAWS, or some other screen reader, use IA2
|
||||
|
||||
|
@ -691,9 +694,44 @@ PRBool nsAccessNodeWrap::IsOnlyMsaaCompatibleJawsPresent()
|
|||
|| (dwLeftMost == 8 && dwSecondRight < 2173));
|
||||
}
|
||||
|
||||
void nsAccessNodeWrap::TurnOffNewTabSwitchingForJawsAndWE()
|
||||
{
|
||||
HMODULE srHandle = ::GetModuleHandleW(L"jhook");
|
||||
if (!srHandle) {
|
||||
// No JAWS, try Window-Eyes
|
||||
srHandle = ::GetModuleHandleW(L"gwm32inc");
|
||||
if (!srHandle) {
|
||||
// no screen reader we're interested in. Bail out.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check to see if the pref for disallowing CtrlTab is already set.
|
||||
// If so, bail out.
|
||||
// If not, set it.
|
||||
nsCOMPtr<nsIPrefBranch> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
if (prefs) {
|
||||
PRBool hasDisallowNewCtrlTabPref = PR_FALSE;
|
||||
nsresult rv = prefs->PrefHasUserValue(CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF,
|
||||
&hasDisallowNewCtrlTabPref);
|
||||
if (NS_SUCCEEDED(rv) && hasDisallowNewCtrlTabPref) {
|
||||
// This pref has been set before. There is no default for it.
|
||||
// Do nothing further, respect the setting that's there.
|
||||
// That way, if noone touches it, it'll stay on after toggled once.
|
||||
// If someone decided to turn it off, we respect that, too.
|
||||
return;
|
||||
}
|
||||
|
||||
// Value has never been set, set it.
|
||||
prefs->SetBoolPref(CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
void nsAccessNodeWrap::DoATSpecificProcessing()
|
||||
{
|
||||
if (IsOnlyMsaaCompatibleJawsPresent())
|
||||
// All versions below 8.0.2173 are not compatible
|
||||
gIsIA2Disabled = PR_TRUE;
|
||||
|
||||
TurnOffNewTabSwitchingForJawsAndWE();
|
||||
}
|
||||
|
|
|
@ -159,6 +159,9 @@ class nsAccessNodeWrap : public nsAccessNode,
|
|||
static int FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo);
|
||||
|
||||
static PRBool IsOnlyMsaaCompatibleJawsPresent();
|
||||
|
||||
static void TurnOffNewTabSwitchingForJawsAndWE();
|
||||
|
||||
static void DoATSpecificProcessing();
|
||||
protected:
|
||||
void GetAccessibleFor(nsIDOMNode *node, nsIAccessible **newAcc);
|
||||
|
|
|
@ -158,7 +158,7 @@ STDMETHODIMP nsAccessibleWrap::AccessibleObjectFromWindow(HWND hwnd,
|
|||
{
|
||||
// open the dll dynamically
|
||||
if (!gmAccLib)
|
||||
gmAccLib =::LoadLibrary("OLEACC.DLL");
|
||||
gmAccLib =::LoadLibraryW(L"OLEACC.DLL");
|
||||
|
||||
if (gmAccLib) {
|
||||
if (!gmAccessibleObjectFromWindow)
|
||||
|
|
|
@ -92,9 +92,12 @@ nsXULColorPickerTileAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULColorPickerTileAccessible::GetName(nsAString& _retval)
|
||||
NS_IMETHODIMP
|
||||
nsXULColorPickerTileAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
return GetXULName(_retval);
|
||||
aName.Truncate();
|
||||
|
||||
return GetXULName(aName);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULColorPickerTileAccessible::GetValue(nsAString& _retval)
|
||||
|
|
|
@ -389,13 +389,16 @@ nsXULMenuitemAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULMenuitemAccessible::GetName(nsAString& _retval)
|
||||
NS_IMETHODIMP
|
||||
nsXULMenuitemAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(mDOMNode));
|
||||
if (!element) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
element->GetAttribute(NS_LITERAL_STRING("label"), _retval);
|
||||
element->GetAttribute(NS_LITERAL_STRING("label"), aName);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -578,9 +581,11 @@ nsXULMenuSeparatorAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULMenuSeparatorAccessible::GetName(nsAString& _retval)
|
||||
NS_IMETHODIMP
|
||||
nsXULMenuSeparatorAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
_retval.Truncate();
|
||||
aName.Truncate();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -752,9 +757,10 @@ nsXULMenubarAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsXULMenubarAccessible::GetName(nsAString& _retval)
|
||||
NS_IMETHODIMP
|
||||
nsXULMenubarAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
_retval.AssignLiteral("Application");
|
||||
aName.AssignLiteral("Application");
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -110,6 +110,8 @@ nsXULColumnItemAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
|
|||
NS_IMETHODIMP
|
||||
nsXULColumnItemAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
return GetXULName(aName);
|
||||
}
|
||||
|
||||
|
@ -857,8 +859,11 @@ nsXULListitemAccessible::GetListAccessible()
|
|||
* If there is a Listcell as a child ( not anonymous ) use it, otherwise
|
||||
* default to getting the name from GetXULName
|
||||
*/
|
||||
NS_IMETHODIMP nsXULListitemAccessible::GetName(nsAString& _retval)
|
||||
NS_IMETHODIMP
|
||||
nsXULListitemAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
if (!mDOMNode)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -869,12 +874,12 @@ NS_IMETHODIMP nsXULListitemAccessible::GetName(nsAString& _retval)
|
|||
nsAutoString tagName;
|
||||
childElement->GetLocalName(tagName);
|
||||
if (tagName.EqualsLiteral("listcell")) {
|
||||
childElement->GetAttribute(NS_LITERAL_STRING("label"), _retval);
|
||||
childElement->GetAttribute(NS_LITERAL_STRING("label"), aName);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return GetXULName(_retval);
|
||||
return GetXULName(aName);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -297,9 +297,11 @@ NS_IMETHODIMP nsXULTabsAccessible::GetValue(nsAString& _retval)
|
|||
}
|
||||
|
||||
/** no name*/
|
||||
NS_IMETHODIMP nsXULTabsAccessible::GetName(nsAString& _retval)
|
||||
NS_IMETHODIMP
|
||||
nsXULTabsAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
_retval.Truncate();
|
||||
aName.Truncate();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,8 +56,11 @@ nsHyperTextAccessibleWrap(aDomNode, aShell)
|
|||
}
|
||||
|
||||
/* wstring getName (); */
|
||||
NS_IMETHODIMP nsXULTextAccessible::GetName(nsAString& aName)
|
||||
NS_IMETHODIMP
|
||||
nsXULTextAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mDOMNode));
|
||||
if (!content) {
|
||||
return NS_ERROR_FAILURE; // Node shut down
|
||||
|
@ -117,8 +120,11 @@ nsLeafAccessible(aDomNode, aShell)
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTooltipAccessible::GetName(nsAString& aName)
|
||||
NS_IMETHODIMP
|
||||
nsXULTooltipAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
return GetXULName(aName, PR_TRUE);
|
||||
}
|
||||
|
||||
|
|
|
@ -783,8 +783,11 @@ NS_IMETHODIMP nsXULTreeitemAccessible::Shutdown()
|
|||
return nsLeafAccessible::Shutdown();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTreeitemAccessible::GetName(nsAString& aName)
|
||||
NS_IMETHODIMP
|
||||
nsXULTreeitemAccessible::GetName(nsAString& aName)
|
||||
{
|
||||
aName.Truncate();
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
|
|
@ -47,9 +47,12 @@ include $(topsrcdir)/config/rules.mk
|
|||
|
||||
_TEST_FILES =\
|
||||
moz.png \
|
||||
longdesc_src.html \
|
||||
common.js \
|
||||
nsIAccessible_actions.js \
|
||||
nsIAccessible_name.css \
|
||||
nsIAccessible_name.xbl \
|
||||
nsIAccessibleEditableText.js \
|
||||
test_aria_activedescendant.html \
|
||||
test_aria_role_article.html \
|
||||
test_bug368835.xul \
|
||||
|
@ -61,16 +64,17 @@ _TEST_FILES =\
|
|||
test_nsIAccessible_actions.xul \
|
||||
test_nsIAccessible_name.html \
|
||||
test_nsIAccessible_name.xul \
|
||||
test_nsIAccessibleDocument.html \
|
||||
test_nsIAccessibleEditableText.html \
|
||||
test_nsIAccessibleHyperLink.html \
|
||||
test_nsIAccessibleHyperLink.xul \
|
||||
test_nsIAccessibleHyperText.html \
|
||||
test_nsIAccessibleImage.html \
|
||||
test_nsIAccessibleTable_1.html \
|
||||
test_nsIAccessibleTable_2.html \
|
||||
test_nsIAccessibleTable_3.html \
|
||||
test_nsIAccessibleTable_4.html \
|
||||
test_nsIAccessibleTable_listboxes.xul \
|
||||
test_nsIAccessibleDocument.html \
|
||||
test_nsIAccessibleHyperLink.html \
|
||||
test_nsIAccessibleHyperLink.xul \
|
||||
test_nsIAccessibleHyperText.html \
|
||||
test_nsIAccessibleImage.html \
|
||||
test_nsOuterDocAccessible.html \
|
||||
test_textattrs.html \
|
||||
test_textboxes.html \
|
||||
|
@ -78,6 +82,7 @@ _TEST_FILES =\
|
|||
testTextboxes.js \
|
||||
test_bug428479.html \
|
||||
test_bug429285.html \
|
||||
test_bug434464.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Interfaces
|
||||
|
||||
const nsIAccessibleRetrieval = Components.interfaces.nsIAccessibleRetrieval;
|
||||
|
||||
const nsIAccessibleEvent = Components.interfaces.nsIAccessibleEvent;
|
||||
const nsIAccessibleStates = Components.interfaces.nsIAccessibleStates;
|
||||
const nsIAccessibleRole = Components.interfaces.nsIAccessibleRole;
|
||||
const nsIAccessibleTypes = Components.interfaces.nsIAccessibleTypes;
|
||||
|
||||
const nsIAccessibleRelation = Components.interfaces.nsIAccessibleRelation;
|
||||
|
||||
const nsIAccessNode = Components.interfaces.nsIAccessNode;
|
||||
const nsIAccessible = Components.interfaces.nsIAccessible;
|
||||
|
||||
const nsIAccessibleDocument = Components.interfaces.nsIAccessibleDocument;
|
||||
|
||||
const nsIAccessibleText = Components.interfaces.nsIAccessibleText;
|
||||
const nsIAccessibleEditableText = Components.interfaces.nsIAccessibleEditableText;
|
||||
|
||||
const nsIAccessibleHyperLink = Components.interfaces.nsIAccessibleHyperLink;
|
||||
const nsIAccessibleHyperText = Components.interfaces.nsIAccessibleHyperText;
|
||||
|
||||
const nsIAccessibleImage = Components.interfaces.nsIAccessibleImage;
|
||||
const nsIAccessibleSelectable = Components.interfaces.nsIAccessibleSelectable;
|
||||
const nsIAccessibleTable = Components.interfaces.nsIAccessibleTable;
|
||||
const nsIAccessibleValue = Components.interfaces.nsIAccessibleValue;
|
||||
|
||||
const nsIObserverService = Components.interfaces.nsIObserverService;
|
||||
|
||||
const nsIDOMNode = Components.interfaces.nsIDOMNode;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// General
|
||||
|
||||
/**
|
||||
* nsIAccessibleRetrieval, initialized when test is loaded.
|
||||
*/
|
||||
var gAccRetrieval = null;
|
||||
|
||||
/**
|
||||
* Return accessible for the given ID attribute or DOM element.
|
||||
*
|
||||
* @param aElmOrID [in] the ID attribute or DOM element to get an accessible
|
||||
* for
|
||||
* @param aInterfaces [in, optional] the accessible interface or the array of
|
||||
* accessible interfaces to query it/them from obtained
|
||||
* accessible
|
||||
* @param aElmObj [out, optional] object to store DOM element which
|
||||
* accessible is created for
|
||||
*/
|
||||
function getAccessible(aElmOrID, aInterfaces, aElmObj)
|
||||
{
|
||||
var elm = null;
|
||||
|
||||
if (aElmOrID instanceof nsIDOMNode) {
|
||||
elm = aElmOrID;
|
||||
} else {
|
||||
var elm = document.getElementById(aElmOrID);
|
||||
if (!elm) {
|
||||
ok(false, "Can't get DOM element for " + aID);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (aElmObj && (typeof aElmObj == "object"))
|
||||
aElmObj.value = elm;
|
||||
|
||||
var acc = null;
|
||||
try {
|
||||
acc = gAccRetrieval.getAccessibleFor(elm);
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (!acc) {
|
||||
ok(false, "Can't get accessible for " + aID);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!aInterfaces)
|
||||
return acc;
|
||||
|
||||
if (aInterfaces instanceof Array) {
|
||||
for (var index = 0; index < aInterfaces.length; index++) {
|
||||
try {
|
||||
acc.QueryInterface(aInterfaces[index]);
|
||||
} catch (e) {
|
||||
ok(false, "Can't query " + aInterfaces[index] + " for " + aID);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return acc;
|
||||
}
|
||||
|
||||
try {
|
||||
acc.QueryInterface(aInterfaces);
|
||||
} catch (e) {
|
||||
ok(false, "Can't query " + aInterfaces + " for " + aID);
|
||||
return null;
|
||||
}
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Private
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// General
|
||||
|
||||
function initialize()
|
||||
{
|
||||
gAccRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
|
||||
getService(nsIAccessibleRetrieval);
|
||||
}
|
||||
|
||||
addLoadEvent(initialize);
|
|
@ -0,0 +1,8 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Mozilla logo</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>This file would contain a longer description of the Mozilla logo, if I knew what it looked like.</p>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,105 @@
|
|||
function nsEditableText(aElmOrID)
|
||||
{
|
||||
this.setTextContents = function setTextContents(aStr)
|
||||
{
|
||||
try {
|
||||
this.mAcc.setTextContents(aStr);
|
||||
|
||||
is(this.getValue(), aStr,
|
||||
"setTextContents: Can't set " + aStr +
|
||||
" to element with ID '" + this.mID + "'");
|
||||
} catch (e) {
|
||||
ok(false,
|
||||
"setTextContents: Can't set " + aStr +
|
||||
"to element with ID '" + this.mID +
|
||||
"', value '" + this.getValue() + "', exception" + e);
|
||||
}
|
||||
}
|
||||
|
||||
this.insertText = function insertText(aStr, aPos, aResStr)
|
||||
{
|
||||
try {
|
||||
this.mAcc.insertText(aStr, aPos);
|
||||
|
||||
is(this.getValue(), aResStr,
|
||||
"insertText: Can't insert " + aStr + " at " + aPos +
|
||||
" to element with ID '" + this.mID + "'");
|
||||
} catch (e) {
|
||||
ok(false,
|
||||
"insertText: Can't insert " + aStr + " at " + aPos +
|
||||
" to element with ID '" + this.mID +
|
||||
"', value '" + this.getValue() + "', exception " + e);
|
||||
}
|
||||
}
|
||||
|
||||
this.copyNPasteText = function copyNPasteText(aStartPos, aEndPos,
|
||||
aPos, aResStr)
|
||||
{
|
||||
try {
|
||||
this.mAcc.copyText(aStartPos, aEndPos);
|
||||
this.mAcc.pasteText(aPos);
|
||||
|
||||
is(this.getValue(), aResStr,
|
||||
"copyText & pasteText: Can't copy text from " + aStartPos +
|
||||
" to " + aEndPos + " and paste to " + aPos +
|
||||
" for element with ID '" + this.mID + "'");
|
||||
} catch (e) {
|
||||
ok(false,
|
||||
"copyText & pasteText: Can't copy text from " + aStartPos +
|
||||
" to " + aEndPos + " and paste to " + aPos +
|
||||
" for element with ID '" + this.mID +
|
||||
"', value '" + this.getValue() + "', exception " + e);
|
||||
}
|
||||
}
|
||||
|
||||
this.cutNPasteText = function copyNPasteText(aStartPos, aEndPos,
|
||||
aPos, aResStr)
|
||||
{
|
||||
try {
|
||||
this.mAcc.cutText(aStartPos, aEndPos);
|
||||
this.mAcc.pasteText(aPos);
|
||||
|
||||
is(this.getValue(), aResStr,
|
||||
"cutText & pasteText: Can't cut text from " + aStartPos +
|
||||
" to " + aEndPos + " and paste to " + aPos +
|
||||
" for element with ID '" + this.mID + "'");
|
||||
} catch (e) {
|
||||
ok(false,
|
||||
"cutText & pasteText: Can't cut text from " + aStartPos +
|
||||
" to " + aEndPos + " and paste to " + aPos +
|
||||
" for element with ID '" + this.mID +
|
||||
"', value '" + this.getValue() + "', exception " + e);
|
||||
}
|
||||
}
|
||||
|
||||
this.deleteText = function deleteText(aStartPos, aEndPos, aResStr)
|
||||
{
|
||||
try {
|
||||
this.mAcc.deleteText(aStartPos, aEndPos);
|
||||
|
||||
is(this.getValue(), aResStr,
|
||||
"deleteText: Can't delete text from " + aStartPos +
|
||||
" to " + aEndPos + " for element with ID '" + this.mID + "'");
|
||||
} catch (e) {
|
||||
ok(false,
|
||||
"deleteText: Can't delete text from " + aStartPos +
|
||||
" to " + aEndPos + " for element with ID '" + this.mID +
|
||||
"', value " + this.getValue() + ", exception " + e);
|
||||
}
|
||||
}
|
||||
|
||||
this.getValue = function getValue()
|
||||
{
|
||||
if (this.mElm instanceof Components.interfaces.nsIDOMNSEditableElement)
|
||||
return this.mElm.value;
|
||||
if (this.mElm instanceof Components.interfaces.nsIDOMHTMLDocument)
|
||||
return this.mElm.body.textContent;
|
||||
return this.mElm.textContent;
|
||||
}
|
||||
|
||||
var elmObj = { value: null };
|
||||
this.mAcc = getAccessible(aElmOrID, nsIAccessibleEditableText, elmObj);
|
||||
|
||||
this.mElm = elmObj.value;
|
||||
this.mID = aElmOrID;
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=434464
|
||||
-->
|
||||
<head>
|
||||
<title>Test NSIAccessNode cache invalidation</title>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript" src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
var accRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
|
||||
getService(Components.interfaces.nsIAccessibleRetrieval);
|
||||
|
||||
var parentElm = document.getElementById("parent");
|
||||
if (!parentElm) {
|
||||
ok(false, "no parent element for paragraph!");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
var elm = document.getElementById("para");
|
||||
if (!elm) {
|
||||
ok(false, "no element for paragraph!");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
// It's currently hidden. Ask for its parent's nsIAccessNode.
|
||||
var parentElmAccNode = null;
|
||||
try {
|
||||
parentElmAccNode = accRetrieval.getAccessibleFor(parentElm).
|
||||
QueryInterface(Components.interfaces.nsIAccessNode);
|
||||
} catch(e) {}
|
||||
|
||||
if (!parentElmAccNode) {
|
||||
ok(false, "No accessNode for parent of hidden paragraph!");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
// Get the paragraph's accessNode.
|
||||
var elmAccNode = null;
|
||||
try {
|
||||
elmAccNode = parentElmAccNode.firstChildNode;
|
||||
} catch(e) {}
|
||||
|
||||
if (!elmAccNode) {
|
||||
ok(false, "No accessNode for hidden paragraph!");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
// Now make the paragraph visible. This invalidates the just-retrieved
|
||||
// AccessNode. An nsIAccessible should then be retrievable.
|
||||
elm.style.display = "block";
|
||||
|
||||
// Now, get an accessible for it. Use a timeout so the layout engine can
|
||||
// catch up.
|
||||
window.setTimeout(
|
||||
function()
|
||||
{
|
||||
var elmAcc = null;
|
||||
try {
|
||||
elmAcc = accRetrieval.getAccessibleFor(elm);
|
||||
} catch(e) {}
|
||||
|
||||
ok(elmAcc, "No accessible for paragraph after it became visible!");
|
||||
|
||||
SimpleTest.finish();
|
||||
},
|
||||
200);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=434464">Mozilla Bug 434464</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="parent"><p style="display: none;" id="para">I'm hidden initially, but then made visible.</p></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,95 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=452161
|
||||
-->
|
||||
<head>
|
||||
<title>nsIAccessibleEditableText chrome tests</title>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/nsIAccessibleEditableText.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
var gParagraphAcc;
|
||||
|
||||
function testEditable(aID)
|
||||
{
|
||||
var et = new nsEditableText(aID);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// insertText
|
||||
et.insertText("hello", 0, "hello");
|
||||
et.insertText("ma ", 0, "ma hello");
|
||||
et.insertText("ma", 2, "mama hello");
|
||||
et.insertText(" hello", 10, "mama hello hello");
|
||||
|
||||
// XXX: bug 452584
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// setTextContents
|
||||
// et.setTextContents("hello", "hello");
|
||||
// et.setTextContents("olleh", "olleh");
|
||||
// et.setTextContents("", "");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// deleteText
|
||||
// et.deleteText(0, 5, "hello hello");
|
||||
// et.deleteText(5, 6, "hellohello");
|
||||
// et.deleteText(5, 10, "hello");
|
||||
// et.deleteText(0, 5, "");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// copyNPasteText
|
||||
// et.copyNPasteText(0, 0, 0, "");
|
||||
// et.insertText("hello", 0, "hello");
|
||||
// et.copyNPasteText(0, 1, 0, "hhello");
|
||||
// et.copyNPasteText(5, 6, 6, "hhelloo");
|
||||
// et.copyNPasteText(3, 4, 1, "hehelloo");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// // cutNPasteText
|
||||
// et.cutNPasteText(0, 1, 1, "ehhelloo");
|
||||
// et.cutNPasteText(1, 2, 0, "hehelloo");
|
||||
// et.cutNPasteText(7, 8, 8, "hehelloo");
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
testEditable("input");
|
||||
// testEditable("div"); XXX: bug 452599
|
||||
|
||||
var frame = document.getElementById("frame");
|
||||
frame.contentDocument.designMode = "on";
|
||||
testEditable(frame.contentDocument);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
title="nsIAccessibleEditableText chrome tests"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=452161">Mozilla Bug 452161</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<input id="input"/>
|
||||
|
||||
<div id="div" contentEditable="true"/>
|
||||
|
||||
<iframe id="frame"/>
|
||||
</body>
|
||||
</html>
|
|
@ -85,7 +85,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=429659
|
|||
is(height.value, aHeight, "wrong height for " + aID + "!");
|
||||
}
|
||||
|
||||
function testThis(aID, aName, aSRC, aWidth, aHeight)
|
||||
function testThis(aID, aName, aSRC, aWidth, aHeight,
|
||||
aNumActions, aActionNames)
|
||||
{
|
||||
var elem = document.getElementById(aID);
|
||||
var acc;
|
||||
|
@ -110,6 +111,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=429659
|
|||
ok(attributes, "no attributes on " + aID + "!");
|
||||
is(attributes.getStringProperty("src"), aSRC,
|
||||
"no correct src attribute for " + aID + "!");
|
||||
|
||||
if (aNumActions) {
|
||||
is(acc.numActions, aNumActions,
|
||||
"Wrong number of actions for " + aID + "!");
|
||||
|
||||
for (index = 0; index < aActionNames.length; index++) {
|
||||
is(acc.getActionName(index), aActionNames[index],
|
||||
"Wrong action name for " + aID + ", index " + index +"!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function doTest()
|
||||
|
@ -147,6 +158,23 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=429659
|
|||
// Test linked image with empty alt attribute and title
|
||||
testThis("linkedImageEmptyAltAndTitle", "Link to Mozilla Foundation", "moz.png", 93, 42);
|
||||
|
||||
// Image with long desc
|
||||
var actionNamesArray = new Array("showlongdesc");
|
||||
testThis("longdesc", "Image of Mozilla logo", "moz.png", 89, 38, 1,
|
||||
actionNamesArray);
|
||||
|
||||
// Image with click and long desc
|
||||
actionNamesArray = null;
|
||||
actionNamesArray = new Array("click", "showlongdesc");
|
||||
testThis("clickAndLongdesc", "Another image of Mozilla logo", "moz.png",
|
||||
89, 38, 2, actionNamesArray);
|
||||
|
||||
// Image with click
|
||||
actionNamesArray = null;
|
||||
actionNamesArray = new Array("click");
|
||||
testThis("click", "A third image of Mozilla logo", "moz.png",
|
||||
89, 38, 1, actionNamesArray);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
@ -182,5 +210,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=429659
|
|||
<br>Linked image with empty alt and title:<br>
|
||||
<a href="http://www.mozilla.org"><img id="linkedImageEmptyAltAndTitle" src="moz.png" alt=""
|
||||
title="Link to Mozilla Foundation"/></a>
|
||||
<br>Image with longdesc:<br>
|
||||
<img id="longdesc" src="moz.png" longdesc="longdesc_src.html"
|
||||
alt="Image of Mozilla logo"/>
|
||||
<br>Image with click and longdesc:<br>
|
||||
<img id="clickAndLongdesc" src="moz.png" longdesc="longdesc_src.html"
|
||||
alt="Another image of Mozilla logo" onclick="alert('Clicked!');"/>
|
||||
<br>Image with click:<br>
|
||||
<img id="click" src="moz.png"
|
||||
alt="A third image of Mozilla logo" onclick="alert('Clicked, too!');"/>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -28,29 +28,13 @@
|
|||
* @param aStartOffset the start offset where text attributes are
|
||||
* applied
|
||||
* @param aEndOffset the end offset where text attribute are applied
|
||||
* @param aDefAttrs the list of default text attributes (name/value
|
||||
* pairs)
|
||||
*/
|
||||
function testTextAttrs(aID, aOffset,
|
||||
aAttrs, aStartOffset, aEndOffset, aDefAttrs)
|
||||
aAttrs, aStartOffset, aEndOffset)
|
||||
{
|
||||
var node = document.getElementById(aID);
|
||||
if (!node) {
|
||||
ok(false, "Can't get the element with ID " + aID);
|
||||
var accessible = getTextAccessible(aID);
|
||||
if (!accessible)
|
||||
return;
|
||||
}
|
||||
|
||||
var accessible = null;
|
||||
try {
|
||||
accessible = gAccRetrieval.getAccessibleFor(node);
|
||||
accessible.QueryInterface(nsIAccessibleText);
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (!accessible) {
|
||||
ok(false, "Can't query nsIAccessibleText interface for " + aID);
|
||||
return;
|
||||
}
|
||||
|
||||
var startOffset = { value: -1 };
|
||||
var endOffset = { value: -1 };
|
||||
|
@ -67,13 +51,27 @@
|
|||
return;
|
||||
}
|
||||
|
||||
var errorMsg = " for " + aID + "at offset " + aOffset;
|
||||
var errorMsg = " for " + aID + " at offset " + aOffset;
|
||||
is(startOffset.value, aStartOffset,
|
||||
"Wrong start offset" + errorMsg);
|
||||
is(endOffset.value, aEndOffset,
|
||||
"Wrong end offset" + errorMsg);
|
||||
|
||||
compareTextAttrs(errorMsg, attrs, aAttrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test default text attributes.
|
||||
*
|
||||
* @param aID the ID of DOM element having text accessible
|
||||
* @param aDefAttrs the list of default text attributes (name/value
|
||||
* pairs)
|
||||
*/
|
||||
function testDefaultTextAttrs(aID, aDefAttrs)
|
||||
{
|
||||
var accessible = getTextAccessible(aID);
|
||||
if (!accessible)
|
||||
return;
|
||||
|
||||
var defAttrs = null;
|
||||
try{
|
||||
|
@ -86,9 +84,31 @@
|
|||
return;
|
||||
}
|
||||
|
||||
var errorMsg = ". Getting default attributes for " + aID;
|
||||
compareTextAttrs(errorMsg, defAttrs, aDefAttrs);
|
||||
}
|
||||
|
||||
function getTextAccessible(aID)
|
||||
{
|
||||
var node = document.getElementById(aID);
|
||||
if (!node) {
|
||||
ok(false, "Can't get the element with ID " + aID);
|
||||
return;
|
||||
}
|
||||
|
||||
var accessible = null;
|
||||
try {
|
||||
accessible = gAccRetrieval.getAccessibleFor(node);
|
||||
accessible.QueryInterface(nsIAccessibleText);
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (!accessible)
|
||||
ok(false, "Can't query nsIAccessibleText interface for " + aID);
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
function compareTextAttrs(aErrorMsg, aAttrs, aExpectedAttrs)
|
||||
{
|
||||
var enumerate = aAttrs.enumerate();
|
||||
|
@ -98,10 +118,10 @@
|
|||
|
||||
if (!(prop.key in aExpectedAttrs))
|
||||
ok(false,
|
||||
"Unexpected attribute '" + prop.key + "'" + aErrorMsg);
|
||||
"Unexpected attribute '" + prop.key + "' having '" + prop.value + "'" + aErrorMsg);
|
||||
else
|
||||
is(prop.value, aExpectedAttrs[prop.key],
|
||||
"Attribute '" + prop.key + "' has wrong value" + aErrorMsg);
|
||||
"Attribute '" + prop.key + " 'has wrong value" + aErrorMsg);
|
||||
}
|
||||
|
||||
for (var name in aExpectedAttrs) {
|
||||
|
@ -113,7 +133,7 @@
|
|||
|
||||
if (!value)
|
||||
ok(false,
|
||||
"There is no expected attribute '" + name + "'" + aErrorMsg);
|
||||
"There is no expected attribute '" + name + "' " + aErrorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,16 +187,17 @@
|
|||
"font-family": "Lucida Grande",
|
||||
"text-position": "baseline"
|
||||
};
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
||||
var attrs = { "background-color": "transparent" };
|
||||
var attrs = { };
|
||||
var misspelledAttrs = {
|
||||
"background-color": "transparent",
|
||||
"invalid": "spelling"
|
||||
};
|
||||
|
||||
testTextAttrs(ID, 0, attrs, 0, 11, defAttrs);
|
||||
testTextAttrs(ID, 11, misspelledAttrs, 11, 17, defAttrs);
|
||||
testTextAttrs(ID, 18, misspelledAttrs, 18, 22, defAttrs);
|
||||
testTextAttrs(ID, 0, attrs, 0, 11);
|
||||
testTextAttrs(ID, 11, misspelledAttrs, 11, 17);
|
||||
testTextAttrs(ID, 17, attrs, 17, 18);
|
||||
testTextAttrs(ID, 18, misspelledAttrs, 18, 22);
|
||||
|
||||
is(gA11yEventObserver.mTextAttrChangedEventCounter, 2,
|
||||
"Wrong count of 'text attribute changed' events for " + ID);
|
||||
|
@ -201,7 +222,7 @@
|
|||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "transparent",
|
||||
"background-color": "rgb(255, 255, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
|
@ -209,14 +230,16 @@
|
|||
"text-position": "baseline"
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
||||
var attrs = {};
|
||||
testTextAttrs(ID, 0, attrs, 0, 7, defAttrs);
|
||||
testTextAttrs(ID, 0, attrs, 0, 7);
|
||||
|
||||
attrs = {"font-weight": "401"};
|
||||
testTextAttrs(ID, 7, attrs, 7, 11, defAttrs);
|
||||
testTextAttrs(ID, 7, attrs, 7, 11);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 12, attrs, 11, 18, defAttrs);
|
||||
testTextAttrs(ID, 12, attrs, 11, 18);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area2
|
||||
|
@ -225,7 +248,7 @@
|
|||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "transparent",
|
||||
"background-color": "rgb(255, 255, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
|
@ -233,20 +256,22 @@
|
|||
"text-position": "baseline"
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 0, attrs, 0, 7, defAttrs);
|
||||
testTextAttrs(ID, 0, attrs, 0, 7);
|
||||
|
||||
attrs = {"font-weight": "401"};
|
||||
testTextAttrs(ID, 7, attrs, 7, 12, defAttrs);
|
||||
testTextAttrs(ID, 7, attrs, 7, 12);
|
||||
|
||||
attrs = {"font-style": "italic", "font-weight": "401"};
|
||||
testTextAttrs(ID, 13, attrs, 12, 19, defAttrs);
|
||||
testTextAttrs(ID, 13, attrs, 12, 19);
|
||||
|
||||
attrs = {"font-weight": "401"};
|
||||
testTextAttrs(ID, 20, attrs, 19, 23, defAttrs);
|
||||
testTextAttrs(ID, 20, attrs, 19, 23);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 24, attrs, 23, 30, defAttrs);
|
||||
testTextAttrs(ID, 24, attrs, 23, 30);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area3
|
||||
|
@ -255,7 +280,7 @@
|
|||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "transparent",
|
||||
"background-color": "rgb(0, 0, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
|
@ -263,14 +288,19 @@
|
|||
"text-position": "baseline"
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
||||
attrs = {"color": "rgb(0, 128, 0)"};
|
||||
testTextAttrs(ID, 0, attrs, 0, 6, defAttrs);
|
||||
testTextAttrs(ID, 0, attrs, 0, 6);
|
||||
|
||||
attrs = {"color": "rgb(255, 0, 0)"};
|
||||
testTextAttrs(ID, 6, attrs, 6, 26, defAttrs);
|
||||
testTextAttrs(ID, 6, attrs, 6, 26);
|
||||
|
||||
attrs = {"color": "rgb(0, 128, 0)"};
|
||||
testTextAttrs(ID, 26, attrs, 26, 50, defAttrs);
|
||||
testTextAttrs(ID, 26, attrs, 26, 27);
|
||||
|
||||
attrs = {"color": "rgb(0, 128, 0)", "background-color": "rgb(255, 255, 0)"};
|
||||
testTextAttrs(ID, 27, attrs, 27, 50);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area4
|
||||
|
@ -279,7 +309,7 @@
|
|||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "transparent",
|
||||
"background-color": "rgb(255, 255, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
|
@ -287,14 +317,16 @@
|
|||
"text-position": "baseline"
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
||||
attrs = {"color": "rgb(0, 128, 0)"};
|
||||
testTextAttrs(ID, 0, attrs, 0, 16, defAttrs);
|
||||
testTextAttrs(ID, 0, attrs, 0, 16);
|
||||
|
||||
attrs = {"color": "rgb(255, 0, 0)"};
|
||||
testTextAttrs(ID, 16, attrs, 16, 33, defAttrs);
|
||||
testTextAttrs(ID, 16, attrs, 16, 33);
|
||||
|
||||
attrs = {"color": "rgb(0, 128, 0)"};
|
||||
testTextAttrs(ID, 34, attrs, 33, 46, defAttrs);
|
||||
testTextAttrs(ID, 34, attrs, 33, 46);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area5
|
||||
|
@ -303,7 +335,7 @@
|
|||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "transparent",
|
||||
"background-color": "rgb(255, 255, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
|
@ -311,17 +343,19 @@
|
|||
"text-position": "baseline"
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
||||
attrs = {"color": "rgb(0, 128, 0)"};
|
||||
testTextAttrs(ID, 0, attrs, 0, 5, defAttrs);
|
||||
testTextAttrs(ID, 0, attrs, 0, 5);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 7, attrs, 5, 8, defAttrs);
|
||||
testTextAttrs(ID, 7, attrs, 5, 8);
|
||||
|
||||
attrs = {"color": "rgb(255, 0, 0)"};
|
||||
testTextAttrs(ID, 9, attrs, 8, 11, defAttrs);
|
||||
testTextAttrs(ID, 9, attrs, 8, 11);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 11, attrs, 11, 18, defAttrs);
|
||||
testTextAttrs(ID, 11, attrs, 11, 18);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area6 (CSS vertical-align property, bug 445938)
|
||||
|
@ -330,7 +364,7 @@
|
|||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "transparent",
|
||||
"background-color": "rgb(255, 255, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
|
@ -338,29 +372,31 @@
|
|||
"text-position": "baseline"
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 0, attrs, 0, 5, defAttrs);
|
||||
testTextAttrs(ID, 0, attrs, 0, 5);
|
||||
|
||||
attrs = {"text-position": "super", "font-size": "13px" };
|
||||
testTextAttrs(ID, 5, attrs, 5, 13, defAttrs);
|
||||
testTextAttrs(ID, 5, attrs, 5, 13);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 13, attrs, 13, 27, defAttrs);
|
||||
testTextAttrs(ID, 13, attrs, 13, 27);
|
||||
|
||||
attrs = {"text-position": "super" };
|
||||
testTextAttrs(ID, 27, attrs, 27, 35, defAttrs);
|
||||
testTextAttrs(ID, 27, attrs, 27, 35);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 35, attrs, 35, 39, defAttrs);
|
||||
testTextAttrs(ID, 35, attrs, 35, 39);
|
||||
|
||||
attrs = {"text-position": "sub", "font-size": "13px" };
|
||||
testTextAttrs(ID, 39, attrs, 39, 50, defAttrs);
|
||||
testTextAttrs(ID, 39, attrs, 39, 50);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 50, attrs, 50, 55, defAttrs);
|
||||
testTextAttrs(ID, 50, attrs, 50, 55);
|
||||
|
||||
attrs = {"text-position": "sub" };
|
||||
testTextAttrs(ID, 55, attrs, 55, 64, defAttrs);
|
||||
testTextAttrs(ID, 55, attrs, 55, 64);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// area7
|
||||
|
@ -369,7 +405,7 @@
|
|||
"font-style": "normal",
|
||||
"text-align": "start",
|
||||
"font-size": "16px",
|
||||
"background-color": "transparent",
|
||||
"background-color": "rgb(255, 255, 255)",
|
||||
"font-weight": "400",
|
||||
"text-indent": "0px",
|
||||
"color": "rgb(0, 0, 0)",
|
||||
|
@ -377,35 +413,37 @@
|
|||
"text-position": "baseline"
|
||||
};
|
||||
|
||||
testDefaultTextAttrs(ID, defAttrs);
|
||||
|
||||
attrs = {"language": "ru"};
|
||||
testTextAttrs(ID, 0, attrs, 0, 12, defAttrs);
|
||||
testTextAttrs(ID, 0, attrs, 0, 12);
|
||||
|
||||
attrs = {"language": "en"};
|
||||
testTextAttrs(ID, 12, attrs, 12, 13, defAttrs);
|
||||
testTextAttrs(ID, 12, attrs, 12, 13);
|
||||
|
||||
attrs = {"language" :"en", "background-color": "rgb(0, 0, 255)"};
|
||||
testTextAttrs(ID, 13, attrs, 13, 26, defAttrs);
|
||||
testTextAttrs(ID, 13, attrs, 13, 26);
|
||||
|
||||
attrs = {"language": "en" };
|
||||
testTextAttrs(ID, 26, attrs, 26, 27, defAttrs);
|
||||
testTextAttrs(ID, 26, attrs, 26, 27);
|
||||
|
||||
attrs = {"language": "de"};
|
||||
testTextAttrs(ID, 27, attrs, 27, 42, defAttrs);
|
||||
testTextAttrs(ID, 27, attrs, 27, 42);
|
||||
|
||||
attrs = {"language": "en"};
|
||||
testTextAttrs(ID, 42, attrs, 42, 43, defAttrs);
|
||||
testTextAttrs(ID, 42, attrs, 42, 43);
|
||||
|
||||
attrs = {};
|
||||
testTextAttrs(ID, 43, attrs, 43, 50, defAttrs);
|
||||
testTextAttrs(ID, 43, attrs, 43, 50);
|
||||
|
||||
attrs = {"color": "rgb(255, 0, 255)"};
|
||||
testTextAttrs(ID, 50, attrs, 50, 57, defAttrs);
|
||||
testTextAttrs(ID, 50, attrs, 50, 57);
|
||||
|
||||
attrs = {"font-weight": "401", "color": "rgb(255, 0, 255)" };
|
||||
testTextAttrs(ID, 57, attrs, 57, 61, defAttrs);
|
||||
testTextAttrs(ID, 57, attrs, 57, 61);
|
||||
|
||||
attrs = {"color": "rgb(255, 0, 255)"};
|
||||
testTextAttrs(ID, 61, attrs, 61, 68, defAttrs);
|
||||
testTextAttrs(ID, 61, attrs, 61, 68);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// test spelling text attributes
|
||||
|
@ -430,11 +468,11 @@
|
|||
|
||||
<p id="area1">Normal <b>Bold</b> Normal</p>
|
||||
<p id="area2">Normal <b>Bold <i>Italic </i>Bold</b> Normal</p>
|
||||
<p id="area3">
|
||||
<span style="color: green">
|
||||
<p id="area3" style="background-color: blue;">
|
||||
<span style="color: green; background-color: rgb(0, 0, 255)">
|
||||
Green
|
||||
<span style="color: red">but children are red</span>
|
||||
</span><span style="color: green">
|
||||
</span><span style="color: green; background-color: rgb(255, 255, 0);">
|
||||
Another green section.
|
||||
</span>
|
||||
</p>
|
||||
|
|
|
@ -13,7 +13,10 @@ builtin(include, build/autoconf/libart.m4)dnl
|
|||
builtin(include, build/autoconf/pkg.m4)dnl
|
||||
builtin(include, build/autoconf/freetype2.m4)dnl
|
||||
builtin(include, build/autoconf/codeset.m4)dnl
|
||||
dnl
|
||||
define(MOZ_TOPSRCDIR,.)dnl MOZ_TOPSRCDIR is used in altoptions.m4
|
||||
builtin(include, build/autoconf/altoptions.m4)dnl
|
||||
|
||||
# Read the user's .mozconfig script. We can't do this in
|
||||
# configure.in: autoconf puts the argument parsing code above anything
|
||||
# expanded from configure.in, and we need to get the configure options
|
||||
# from .mozconfig in place before that argument parsing code.
|
||||
MOZ_READ_MOZCONFIG(.)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
WIN32_MODULE_COMPANYNAME=Mozilla Corporation
|
||||
WIN32_MODULE_COPYRIGHT=©Firefox and Mozilla Developers, according to the MPL 1.1/GPL 2.0/LGPL 2.1 licenses, as applicable.
|
||||
WIN32_MODULE_PRODUCTVERSION=3,1,0,0
|
||||
WIN32_MODULE_PRODUCTVERSION_STRING=3.1a2
|
||||
WIN32_MODULE_PRODUCTVERSION_STRING=3.1b1pre
|
||||
WIN32_MODULE_TRADEMARKS=Firefox is a Trademark of The Mozilla Foundation.
|
||||
WIN32_MODULE_DESCRIPTION=Firefox
|
||||
WIN32_MODULE_PRODUCTNAME=Firefox
|
||||
|
|
|
@ -64,11 +64,9 @@ static void Output(const char *fmt, ... )
|
|||
va_start(ap, fmt);
|
||||
|
||||
#if defined(XP_WIN) && !MOZ_WINCONSOLE
|
||||
char msg[2048];
|
||||
|
||||
_vsnprintf(msg, sizeof(msg), fmt, ap);
|
||||
|
||||
MessageBox(NULL, msg, "XULRunner", MB_OK | MB_ICONERROR);
|
||||
PRUnichar msg[2048];
|
||||
_vsnwprintf(msg, sizeof(msg)/sizeof(msg[0]), NS_ConvertUTF8toUTF16(fmt).get(), ap);
|
||||
MessageBoxW(NULL, msg, L"XULRunner", MB_OK | MB_ICONERROR);
|
||||
#else
|
||||
vfprintf(stderr, fmt, ap);
|
||||
#endif
|
||||
|
|
|
@ -216,6 +216,7 @@ pref("browser.urlbar.matchOnlyTyped", false);
|
|||
// 0: Match anywhere (e.g., middle of words)
|
||||
// 1: Match on word boundaries and then try matching anywhere
|
||||
// 2: Match only on word boundaries (e.g., after / or .)
|
||||
// 3: Match at the beginning of the url or title
|
||||
pref("browser.urlbar.matchBehavior", 1);
|
||||
pref("browser.urlbar.filter.javascript", true);
|
||||
|
||||
|
|
|
@ -1082,7 +1082,9 @@ function delayedStartup()
|
|||
gBrowser.addEventListener("command", BrowserOnCommand, false);
|
||||
|
||||
tabPreviews.init();
|
||||
if (gPrefService.getBoolPref("browser.ctrlTab.mostRecentlyUsed"))
|
||||
if ((!gPrefService.prefHasUserValue("browser.ctrlTab.disallowForScreenReaders") ||
|
||||
!gPrefService.getBoolPref("browser.ctrlTab.disallowForScreenReaders")) &&
|
||||
gPrefService.getBoolPref("browser.ctrlTab.mostRecentlyUsed"))
|
||||
ctrlTab.init();
|
||||
|
||||
// Delayed initialization of the livemarks update timer.
|
||||
|
@ -5408,14 +5410,8 @@ var OfflineApps = {
|
|||
// XXX: duplicated in preferences/advanced.js
|
||||
_getOfflineAppUsage: function (host)
|
||||
{
|
||||
var cacheService = Components.classes["@mozilla.org/network/cache-service;1"].
|
||||
getService(Components.interfaces.nsICacheService);
|
||||
var cacheSession = cacheService.createSession("HTTP-offline",
|
||||
Components.interfaces.nsICache.STORE_OFFLINE,
|
||||
true).
|
||||
QueryInterface(Components.interfaces.nsIOfflineCacheSession);
|
||||
var usage = cacheSession.getDomainUsage(host);
|
||||
|
||||
// XXX Bug 442810: include offline cache usage.
|
||||
var usage = 0;
|
||||
var storageManager = Components.classes["@mozilla.org/dom/storagemanager;1"].
|
||||
getService(Components.interfaces.nsIDOMStorageManager);
|
||||
usage += storageManager.getUsage(host);
|
||||
|
|
|
@ -131,7 +131,16 @@ nsContextMenu.prototype = {
|
|||
},
|
||||
|
||||
initOpenItems: function CM_initOpenItems() {
|
||||
var shouldShow = this.onSaveableLink ||
|
||||
var isMailtoInternal = false;
|
||||
if (this.onMailtoLink) {
|
||||
var mailtoHandler = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
|
||||
getService(Ci.nsIExternalProtocolService).
|
||||
getProtocolHandlerInfo("mailto");
|
||||
isMailtoInternal = (!mailtoHandler.alwaysAskBeforeHandling &&
|
||||
mailtoHandler.preferredAction == Ci.nsIHandlerInfo.useHelperApp &&
|
||||
(mailtoHandler.preferredApplicationHandler instanceof Ci.nsIWebHandlerApp));
|
||||
}
|
||||
var shouldShow = this.onSaveableLink || isMailtoInternal ||
|
||||
(this.inDirList && this.onLink);
|
||||
this.showItem("context-openlink", shouldShow);
|
||||
this.showItem("context-openlinkintab", shouldShow);
|
||||
|
|
|
@ -188,10 +188,6 @@ var gImageHash = { };
|
|||
var gStrings = { };
|
||||
var gBundle;
|
||||
|
||||
const DRAGSERVICE_CONTRACTID = "@mozilla.org/widget/dragservice;1";
|
||||
const TRANSFERABLE_CONTRACTID = "@mozilla.org/widget/transferable;1";
|
||||
const ARRAY_CONTRACTID = "@mozilla.org/supports-array;1";
|
||||
const STRING_CONTRACTID = "@mozilla.org/supports-string;1";
|
||||
const PERMISSION_CONTRACTID = "@mozilla.org/permissionmanager;1";
|
||||
const PREFERENCES_CONTRACTID = "@mozilla.org/preferences-service;1";
|
||||
const ATOM_CONTRACTID = "@mozilla.org/atom-service;1";
|
||||
|
@ -663,32 +659,16 @@ function onBeginLinkDrag(event,urlField,descField)
|
|||
if (row == -1)
|
||||
return;
|
||||
|
||||
// Getting drag-system needed services
|
||||
var dragService = Components.classes[DRAGSERVICE_CONTRACTID].getService()
|
||||
.QueryInterface(Components.interfaces.nsIDragService);
|
||||
var transArray = Components.classes[ARRAY_CONTRACTID]
|
||||
.createInstance(Components.interfaces.nsISupportsArray);
|
||||
if (!transArray)
|
||||
return;
|
||||
|
||||
var trans = Components.classes[TRANSFERABLE_CONTRACTID]
|
||||
.createInstance(Components.interfaces.nsITransferable);
|
||||
if (!trans)
|
||||
return;
|
||||
|
||||
// Adding URL flavor
|
||||
trans.addDataFlavor("text/x-moz-url");
|
||||
var col = tree.columns[urlField];
|
||||
var url = tree.view.getCellText(row, col);
|
||||
col = tree.columns[descField];
|
||||
var desc = tree.view.getCellText(row, col);
|
||||
var stringURL = Components.classes[STRING_CONTRACTID]
|
||||
.createInstance(Components.interfaces.nsISupportsString);
|
||||
stringURL.data = url + "\n" + desc;
|
||||
trans.setTransferData("text/x-moz-url", stringURL, stringURL.data.length * 2 );
|
||||
transArray.AppendElement(trans.QueryInterface(Components.interfaces.nsISupports));
|
||||
|
||||
dragService.invokeDragSession(event.target, transArray, null, dragService.DRAGDROP_ACTION_NONE);
|
||||
var dt = event.dataTransfer;
|
||||
dt.setData("text/x-moz-url", url + "\n" + desc);
|
||||
dt.setData("text/url-list", url);
|
||||
dt.setData("text/plain", url);
|
||||
}
|
||||
|
||||
//******** Image Stuff
|
||||
|
|
|
@ -1543,7 +1543,7 @@
|
|||
if ("owner" in aTab && aTab.owner &&
|
||||
this.mPrefs.getBoolPref("browser.tabs.selectOwnerOnClose")) {
|
||||
for (var i = 0; i < length; ++i) {
|
||||
tab = this.mTabContainer.childNodes[i];
|
||||
var tab = this.mTabContainer.childNodes[i];
|
||||
if (tab == aTab.owner) {
|
||||
newIndex = i;
|
||||
break;
|
||||
|
|
|
@ -76,6 +76,14 @@ DistributionCustomizer.prototype = {
|
|||
return this.__annoSvc;
|
||||
},
|
||||
|
||||
__livemarkSvc: null,
|
||||
get _livemarkSvc() {
|
||||
if (!this.__livemarkSvc)
|
||||
this.__livemarkSvc = Cc["@mozilla.org/browser/livemark-service;2"].
|
||||
getService(Ci.nsILivemarkService);
|
||||
return this.__livemarkSvc;
|
||||
},
|
||||
|
||||
__dirSvc: null,
|
||||
get _dirSvc() {
|
||||
if (!this.__dirSvc)
|
||||
|
@ -179,6 +187,18 @@ DistributionCustomizer.prototype = {
|
|||
this._bmSvc.insertSeparator(parentId, index);
|
||||
break;
|
||||
|
||||
case "livemark":
|
||||
if (iid < defaultItemId)
|
||||
index = prependIndex++;
|
||||
|
||||
newId = this._livemarkSvc.
|
||||
createLivemark(parentId,
|
||||
items[iid]["title"],
|
||||
this._makeURI(items[iid]["siteLink"]),
|
||||
this._makeURI(items[iid]["feedLink"]),
|
||||
index);
|
||||
break;
|
||||
|
||||
case "bookmark":
|
||||
default:
|
||||
if (iid < defaultItemId)
|
||||
|
@ -218,8 +238,16 @@ DistributionCustomizer.prototype = {
|
|||
return;
|
||||
|
||||
let bmProcessed = false;
|
||||
let bmProcessedPref = "distribution." +
|
||||
this._ini.getString("Global", "id") + ".bookmarksProcessed";
|
||||
let bmProcessedPref;
|
||||
|
||||
try {
|
||||
bmProcessedPref = this._ini.getString("Global",
|
||||
"bookmarks.initialized.pref");
|
||||
} catch (e) {
|
||||
bmProcessedPref = "distribution." +
|
||||
this._ini.getString("Global", "id") + ".bookmarksProcessed";
|
||||
}
|
||||
|
||||
try {
|
||||
bmProcessed = this._prefs.getBoolPref(bmProcessedPref);
|
||||
} catch (e) {}
|
||||
|
|
|
@ -867,7 +867,7 @@ nsIEProfileMigrator::CopyPasswords(PRBool aReplace)
|
|||
nsresult rv;
|
||||
nsVoidArray signonsFound;
|
||||
|
||||
HMODULE pstoreDLL = ::LoadLibrary("pstorec.dll");
|
||||
HMODULE pstoreDLL = ::LoadLibraryW(L"pstorec.dll");
|
||||
if (!pstoreDLL) {
|
||||
// XXXben TODO
|
||||
// Need to figure out what to do here on Windows 98 etc... it may be that the key is universal read
|
||||
|
@ -1191,7 +1191,7 @@ nsIEProfileMigrator::CopyFormData(PRBool aReplace)
|
|||
{
|
||||
HRESULT hr;
|
||||
|
||||
HMODULE pstoreDLL = ::LoadLibrary("pstorec.dll");
|
||||
HMODULE pstoreDLL = ::LoadLibraryW(L"pstorec.dll");
|
||||
if (!pstoreDLL) {
|
||||
// XXXben TODO
|
||||
// Need to figure out what to do here on Windows 98 etc... it may be that the key is universal read
|
||||
|
@ -1424,20 +1424,19 @@ nsIEProfileMigrator::ResolveShortcut(const nsString &aFileName, char** aOutURL)
|
|||
{
|
||||
HRESULT result;
|
||||
|
||||
IUniformResourceLocator* urlLink = nsnull;
|
||||
IUniformResourceLocatorW* urlLink = nsnull;
|
||||
result = ::CoCreateInstance(CLSID_InternetShortcut, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_IUniformResourceLocator, (void**)&urlLink);
|
||||
IID_IUniformResourceLocatorW, (void**)&urlLink);
|
||||
if (SUCCEEDED(result) && urlLink) {
|
||||
IPersistFile* urlFile = nsnull;
|
||||
result = urlLink->QueryInterface(IID_IPersistFile, (void**)&urlFile);
|
||||
if (SUCCEEDED(result) && urlFile) {
|
||||
result = urlFile->Load(aFileName.get(), STGM_READ);
|
||||
if (SUCCEEDED(result) ) {
|
||||
LPSTR lpTemp = nsnull;
|
||||
LPWSTR lpTemp = nsnull;
|
||||
result = urlLink->GetURL(&lpTemp);
|
||||
if (SUCCEEDED(result) && lpTemp) {
|
||||
*aOutURL = PL_strdup(lpTemp);
|
||||
|
||||
*aOutURL = (char*)ToNewUTF8String(nsDependentString(lpTemp));
|
||||
// free the string that GetURL alloc'd
|
||||
::CoTaskMemFree(lpTemp);
|
||||
}
|
||||
|
|
|
@ -216,13 +216,8 @@ var gAdvancedPane = {
|
|||
// XXX: duplicated in browser.js
|
||||
_getOfflineAppUsage: function (host)
|
||||
{
|
||||
var cacheService = Components.classes["@mozilla.org/network/cache-service;1"].
|
||||
getService(Components.interfaces.nsICacheService);
|
||||
var cacheSession = cacheService.createSession("HTTP-offline",
|
||||
Components.interfaces.nsICache.STORE_OFFLINE,
|
||||
true).
|
||||
QueryInterface(Components.interfaces.nsIOfflineCacheSession);
|
||||
var usage = cacheSession.getDomainUsage(host);
|
||||
// XXX Bug 442710: include offline cache usage.
|
||||
var usage = 0;
|
||||
|
||||
var storageManager = Components.classes["@mozilla.org/dom/storagemanager;1"].
|
||||
getService(Components.interfaces.nsIDOMStorageManager);
|
||||
|
|
|
@ -42,7 +42,7 @@ VPATH = @srcdir@
|
|||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
|
||||
DIRS += chrome \
|
||||
DIRS += browser \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -45,6 +45,8 @@ include $(DEPTH)/config/autoconf.mk
|
|||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_BROWSER_TEST_FILES = \
|
||||
browser_350525.js \
|
||||
browser_393716.js \
|
||||
browser_448741.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
function test() {
|
||||
/** Test for Bug 350525 **/
|
||||
|
||||
function test(aLambda) {
|
||||
try {
|
||||
return aLambda() || true;
|
||||
}
|
||||
catch (ex) { }
|
||||
return false;
|
||||
}
|
||||
|
||||
// test setup
|
||||
let tabbrowser = getBrowser();
|
||||
waitForExplicitFinish();
|
||||
|
||||
// component
|
||||
let ssComponent = test(function() Cc["@mozilla.org/browser/sessionstore;1"]);
|
||||
ok(ssComponent, "reference the sessionstore component");
|
||||
|
||||
// service
|
||||
let ss = test(function() ssComponent.getService(Ci.nsISessionStore));
|
||||
ok(ss, "reference the sessionstore service");
|
||||
|
||||
////////////////////////////
|
||||
// setWindowValue, et al. //
|
||||
////////////////////////////
|
||||
let key = "Unique name: " + Date.now();
|
||||
let value = "Unique value: " + Math.random();
|
||||
|
||||
// test adding
|
||||
ok(test(function() ss.setWindowValue(window, key, value)), "set a window value");
|
||||
|
||||
// test retrieving
|
||||
is(ss.getWindowValue(window, key), value, "stored window value matches original");
|
||||
|
||||
// test deleting
|
||||
ok(test(function() ss.deleteWindowValue(window, key)), "delete the window value");
|
||||
|
||||
// value should not exist post-delete
|
||||
is(ss.getWindowValue(window, key), "", "window value was deleted");
|
||||
|
||||
/////////////////////////
|
||||
// setTabValue, et al. //
|
||||
/////////////////////////
|
||||
key = "Unique name: " + Math.random();
|
||||
value = "Unique value: " + Date.now();
|
||||
let tab = tabbrowser.addTab();
|
||||
|
||||
// test adding
|
||||
ok(test(function() ss.setTabValue(tab, key, value)), "store a tab value");
|
||||
|
||||
// test retrieving
|
||||
is(ss.getTabValue(tab, key), value, "stored tab value match original");
|
||||
|
||||
// test deleting
|
||||
ok(test(function() ss.deleteTabValue(tab, key)), "delete the tab value");
|
||||
// value should not exist post-delete
|
||||
is(ss.getTabValue(tab, key), "", "tab value was deleted");
|
||||
|
||||
// clean up
|
||||
tabbrowser.removeTab(tab);
|
||||
|
||||
/////////////////////////////////////
|
||||
// getClosedTabCount, undoCloseTab //
|
||||
/////////////////////////////////////
|
||||
|
||||
// get closed tab count
|
||||
let count = ss.getClosedTabCount(window);
|
||||
let max_tabs_undo = gPrefService.getIntPref("browser.sessionstore.max_tabs_undo");
|
||||
ok(0 <= count && count <= max_tabs_undo,
|
||||
"getClosedTabCount returns zero or at most max_tabs_undo");
|
||||
|
||||
// create a new tab
|
||||
let testURL = "about:";
|
||||
tab = tabbrowser.addTab(testURL);
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
// make sure that the next closed tab will increase getClosedTabCount
|
||||
gPrefService.setIntPref("browser.sessionstore.max_tabs_undo", max_tabs_undo + 1);
|
||||
|
||||
// remove tab
|
||||
tabbrowser.removeTab(tab);
|
||||
|
||||
// getClosedTabCount
|
||||
var newcount = ss.getClosedTabCount(window);
|
||||
ok(newcount > count, "after closing a tab, getClosedTabCount has been incremented");
|
||||
|
||||
// undoCloseTab
|
||||
ok(test(function() ss.undoCloseTab(window, 0)), "undoCloseTab doesn't throw")
|
||||
tab = tabbrowser.selectedTab;
|
||||
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
is(this.currentURI.spec, testURL, "correct tab was reopened");
|
||||
|
||||
// clean up
|
||||
gPrefService.setIntPref("browser.sessionstore.max_tabs_undo", max_tabs_undo);
|
||||
tabbrowser.removeTab(tab);
|
||||
finish();
|
||||
}, true);
|
||||
}, true);
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
function test() {
|
||||
/** Test for Bug 393716 **/
|
||||
|
||||
// set up the basics (SessionStore service, tabbrowser)
|
||||
try {
|
||||
var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||
}
|
||||
catch (ex) { }
|
||||
ok(ss, "SessionStore service is available");
|
||||
let tabbrowser = getBrowser();
|
||||
waitForExplicitFinish();
|
||||
|
||||
/////////////////
|
||||
// getTabState //
|
||||
/////////////////
|
||||
let key = "Unique key: " + Date.now();
|
||||
let value = "Unique value: " + Math.random();
|
||||
let testURL = "about:config";
|
||||
|
||||
// create a new tab
|
||||
let tab = tabbrowser.addTab(testURL);
|
||||
ss.setTabValue(tab, key, value);
|
||||
tab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
// get the tab's state
|
||||
let state = ss.getTabState(tab);
|
||||
ok(state, "get the tab's state");
|
||||
|
||||
// verify the tab state's integrity
|
||||
state = eval("(" + state + ")");
|
||||
ok(state instanceof Object && state.entries instanceof Array && state.entries.length > 0,
|
||||
"state object seems valid");
|
||||
ok(state.entries.length == 1 && state.entries[0].url == testURL,
|
||||
"Got the expected state object (test URL)");
|
||||
ok(state.extData && state.extData[key] == value,
|
||||
"Got the expected state object (test manually set tab value)");
|
||||
|
||||
// clean up
|
||||
tabbrowser.removeTab(tab);
|
||||
}, true);
|
||||
|
||||
//////////////////////////////////
|
||||
// setTabState and duplicateTab //
|
||||
//////////////////////////////////
|
||||
let key2 = "key2";
|
||||
let value2 = "Value " + Math.random();
|
||||
let value3 = "Another value: " + Date.now();
|
||||
let state = { entries: [{ url: testURL }], extData: { key2: value2 } };
|
||||
|
||||
// create a new tab
|
||||
let tab2 = tabbrowser.addTab();
|
||||
// set the tab's state
|
||||
ss.setTabState(tab2, state.toSource());
|
||||
tab2.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
// verify the correctness of the restored tab
|
||||
ok(ss.getTabValue(tab2, key2) == value2 && this.currentURI.spec == testURL,
|
||||
"the tab's state was correctly restored");
|
||||
|
||||
// add text data
|
||||
let textbox = this.contentDocument.getElementById("textbox");
|
||||
textbox.wrappedJSObject.value = value3;
|
||||
|
||||
// duplicate the tab
|
||||
let duplicateTab = ss.duplicateTab(window, tab2);
|
||||
tabbrowser.removeTab(tab2);
|
||||
|
||||
duplicateTab.linkedBrowser.addEventListener("load", function(aEvent) {
|
||||
// verify the correctness of the duplicated tab
|
||||
ok(ss.getTabValue(duplicateTab, key2) == value2 && this.currentURI.spec == testURL,
|
||||
"correctly duplicated the tab's state");
|
||||
let textbox = this.contentDocument.getElementById("textbox");
|
||||
is(textbox.wrappedJSObject.value, value3, "also duplicated text data");
|
||||
|
||||
// clean up
|
||||
tabbrowser.removeTab(duplicateTab);
|
||||
finish();
|
||||
}, true);
|
||||
}, true);
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=350525
|
||||
-->
|
||||
<window title="Mozilla Bug 350525"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<title>Test for Bug 350525</title>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=350525">Mozilla Bug 350525</a>
|
||||
|
||||
<p id="display"></p>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript">
|
||||
|
||||
/** Test for Bug 350525 **/
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
|
||||
// component
|
||||
try {
|
||||
Cc["@mozilla.org/browser/sessionstore;1"];
|
||||
ok(1==1, "Able to reference the sessionstore component?");
|
||||
} catch(ex) {
|
||||
alert(ex);
|
||||
ok(1==2, "Able to reference the sessionstore component?");
|
||||
}
|
||||
|
||||
// service
|
||||
try {
|
||||
var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||
ok(true, "Able to reference the sessionstore service?");
|
||||
} catch(ex) {
|
||||
ok(false, "Able to reference the sessionstore service?");
|
||||
}
|
||||
|
||||
// get current window, tabbrowser
|
||||
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
|
||||
var windowEnumerator = wm.getEnumerator("navigator:browser");
|
||||
var currentWindow = windowEnumerator.getNext();
|
||||
var tabbrowser = currentWindow.getBrowser();
|
||||
|
||||
/*****************
|
||||
undoCloseTab, getClosedTabCount
|
||||
*****************/
|
||||
|
||||
// get closed tab count
|
||||
var count = ss.getClosedTabCount(currentWindow);
|
||||
ok(count > -1, "getClosedTabCount returns zero or more?");
|
||||
|
||||
// create a new tab
|
||||
var newTab = tabbrowser.addTab("http://www.mozilla.org");
|
||||
|
||||
// remove tab
|
||||
tabbrowser.removeTab(newTab);
|
||||
|
||||
// getClosedTabCount
|
||||
var newcount = ss.getClosedTabCount(currentWindow);
|
||||
todo(newcount > count, "After closing a tab, getClosedTabCount has been incremented? " + newcount + " > " + count);
|
||||
|
||||
// undoCloseTab
|
||||
var undid = ss.undoCloseTab(currentWindow, null);
|
||||
ok(undid != -1, "undoCloseTab throws?");
|
||||
|
||||
// clean up
|
||||
tabbrowser.removeAllTabsBut(tabbrowser.selectedTab);
|
||||
|
||||
/*****************
|
||||
setWindowValue
|
||||
*****************/
|
||||
var key = "key1";
|
||||
var value = "value1";
|
||||
|
||||
// create a new tab
|
||||
var newTab = tabbrowser.addTab("http://www.mozilla.org");
|
||||
|
||||
// test adding
|
||||
ok(ss.setWindowValue(currentWindow, key, value) != -1, "Able to set a window value?");
|
||||
|
||||
// test retrieving
|
||||
var storedValue = ss.getWindowValue(currentWindow, key);
|
||||
is(value, storedValue, "Stored window value matches original?");
|
||||
|
||||
// test deleting
|
||||
ok(ss.deleteWindowValue(currentWindow, key) != -1, "Delete window value?");
|
||||
|
||||
// value should not exist post-delete
|
||||
is(ss.getWindowValue(currentWindow, key), "", "Fetching deleted window value fails?");
|
||||
|
||||
// clean up
|
||||
tabbrowser.removeTab(newTab);
|
||||
|
||||
/*********************
|
||||
tabValues
|
||||
*********************/
|
||||
key = "key1";
|
||||
value = "value1";
|
||||
|
||||
// create a new tab
|
||||
newTab = tabbrowser.addTab("http://www.mozilla.org");
|
||||
|
||||
// test adding
|
||||
ok(ss.setTabValue(newTab, key, value) != -1, "Able to store a tab value?");
|
||||
|
||||
// test retrieving
|
||||
var storedValue = ss.getTabValue(newTab, key);
|
||||
ok(value==storedValue, "Stored tab value match original?");
|
||||
|
||||
// test deleting
|
||||
ok(ss.deleteTabValue(newTab, key) != -1, "Able to delete a tab value?");
|
||||
// value should not exist post-delete
|
||||
ok(ss.getTabValue(newTab, key) == "", "Unable to retrieve deleted tab value?");
|
||||
|
||||
// clean up
|
||||
tabbrowser.removeTab(newTab);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
</window>
|
|
@ -1,101 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=393716
|
||||
-->
|
||||
<window title="Mozilla Bug 393716"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<title>Test for Bug 393716</title>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=393716">Mozilla Bug 393716</a>
|
||||
|
||||
<p id="display"></p>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
// set up the basics (SessionStore service, tabbrowser)
|
||||
try {
|
||||
var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||
} catch (ex) {
|
||||
ok(false, "SessionStore service available?");
|
||||
}
|
||||
try {
|
||||
var windowEnumerator = Cc["@mozilla.org/appshell/window-mediator;1"].
|
||||
getService(Ci.nsIWindowMediator).
|
||||
getEnumerator("navigator:browser");
|
||||
var currentWindow = windowEnumerator.getNext();
|
||||
var tabbrowser = currentWindow.getBrowser();
|
||||
} catch (ex) {
|
||||
ok(false, "tabbrowser available?");
|
||||
}
|
||||
|
||||
/**************
|
||||
* getTabState
|
||||
**************/
|
||||
var key = "key1", value = "value1";
|
||||
|
||||
// create a new tab
|
||||
var newTab = tabbrowser.addTab();
|
||||
ss.setTabValue(newTab, key, value);
|
||||
|
||||
// get the tab's state
|
||||
var state = ss.getTabState(newTab);
|
||||
ok(state, "Able to get the tab's state?");
|
||||
|
||||
// verify the tab state's integrity
|
||||
state = eval("(" + state + ")");
|
||||
ok(state instanceof Object && state.entries instanceof Array && state.entries.length > 0,
|
||||
"Got a valid state object?");
|
||||
ok(state.entries.length == 1 && state.entries[0].url == "about:blank",
|
||||
"Got the expected state object (test URL)?");
|
||||
ok(state.extData && state.extData[key] == value,
|
||||
"Got the expected state object (test manually set tab value)?");
|
||||
|
||||
// clean up
|
||||
tabbrowser.removeTab(newTab);
|
||||
|
||||
/*****************************
|
||||
* setTabState / duplicateTab
|
||||
*****************************/
|
||||
key = "key2";
|
||||
value = "value2";
|
||||
state = { entries: [{ url: "about:blank" }], extData: { key2: value } };
|
||||
|
||||
// create a new tab
|
||||
newTab = tabbrowser.addTab();
|
||||
|
||||
// set the tab's state
|
||||
ss.setTabState(newTab, state.toSource());
|
||||
|
||||
// verify the correctness of the restored tab
|
||||
ok(ss.getTabValue(newTab, key) == value, "Correctly restored the tab's state?");
|
||||
|
||||
// duplicate the tab
|
||||
var duplicateTab = ss.duplicateTab(currentWindow, newTab);
|
||||
|
||||
// verify the correctness of the duplicated tab
|
||||
ok(ss.getTabValue(duplicateTab, key) == value, "Correctly duplicated the tab's state?");
|
||||
|
||||
// clean up
|
||||
tabbrowser.removeTab(newTab);
|
||||
tabbrowser.removeTab(duplicateTab);
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
</window>
|
|
@ -1 +1 @@
|
|||
3.1a2
|
||||
3.1b1pre
|
||||
|
|
|
@ -90,6 +90,7 @@ bin/components/dom_canvas.xpt
|
|||
bin/components/dom_core.xpt
|
||||
bin/components/dom_css.xpt
|
||||
bin/components/dom_events.xpt
|
||||
bin/components/dom_geolocation.xpt
|
||||
bin/components/dom_html.xpt
|
||||
bin/components/dom_offline.xpt
|
||||
bin/components/dom_json.xpt
|
||||
|
@ -240,6 +241,7 @@ bin/components/nsHandlerService.js
|
|||
bin/components/nsWebHandlerApp.js
|
||||
bin/components/libdbusservice.so
|
||||
bin/components/aboutRobots.js
|
||||
bin/components/nsBadCertHandler.js
|
||||
|
||||
; Modules
|
||||
bin/modules/*
|
||||
|
|
|
@ -97,6 +97,7 @@ bin\components\dom_canvas.xpt
|
|||
bin\components\dom_core.xpt
|
||||
bin\components\dom_css.xpt
|
||||
bin\components\dom_events.xpt
|
||||
bin\components\dom_geolocation.xpt
|
||||
bin\components\dom_html.xpt
|
||||
bin\components\dom_offline.xpt
|
||||
bin\components\dom_json.xpt
|
||||
|
@ -246,6 +247,7 @@ bin\components\nsContentDispatchChooser.js
|
|||
bin\components\nsHandlerService.js
|
||||
bin\components\nsWebHandlerApp.js
|
||||
bin\components\aboutRobots.js
|
||||
bin\components\nsBadCertHandler.js
|
||||
|
||||
; Modules
|
||||
bin\modules\*
|
||||
|
|
|
@ -319,3 +319,23 @@ ifdef MOZ_CRASHREPORTER
|
|||
libs:: $(addprefix $(LOCALE_SRCDIR)/,crashreporter/crashreporter-override.ini)
|
||||
$(SYSINSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)
|
||||
endif
|
||||
|
||||
# This variable is to allow the wget-en-US target to know which ftp server to download from
|
||||
ifndef EN_US_BINARY_URL
|
||||
EN_US_BINARY_URL = $(error You must set EN_US_BINARY_URL)
|
||||
endif
|
||||
|
||||
# This make target allows us to wget the latest en-US binary from a specified website
|
||||
# The make installers-% target needs the en-US binary in dist/
|
||||
# and for the windows repackages we need the .installer.exe in dist/sea
|
||||
wget-en-US:
|
||||
ifndef WGET
|
||||
$(error Wget not installed)
|
||||
endif
|
||||
@$(WGET) -nv --output-document $(_ABS_DIST)/$(PACKAGE) $(EN_US_BINARY_URL)/$(PACKAGE)
|
||||
@echo "Downloaded $(EN_US_BINARY_URL)/$(PACKAGE) to $(_ABS_DIST)/$(PACKAGE)"
|
||||
ifeq ($(OS_ARCH), WINNT)
|
||||
$(NSINSTALL) -D $(_ABS_DIST)/install/sea
|
||||
@$(WGET) -nv --output-document $(_ABS_DIST)/install/sea/$(PKG_BASENAME).installer.exe $(EN_US_BINARY_URL)/$(PKG_BASENAME).installer.exe
|
||||
@echo "Downloaded $(EN_US_BINARY_URL)/$(PKG_BASENAME).installer.exe to $(_ABS_DIST)/install/sea/$(PKG_BASENAME)"
|
||||
endif
|
||||
|
|
|
@ -152,6 +152,3 @@ AC_DEFUN([MOZ_READ_MOZCONFIG],
|
|||
# See the mozconfig2configure script for more details.
|
||||
_AUTOCONF_TOOLS_DIR=`dirname [$]0`/[$1]/build/autoconf
|
||||
. $_AUTOCONF_TOOLS_DIR/mozconfig2configure])
|
||||
|
||||
dnl This gets inserted at the top of the configure script
|
||||
MOZ_READ_MOZCONFIG(MOZ_TOPSRCDIR)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/expect
|
||||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
|
@ -11,14 +12,16 @@
|
|||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is Mozilla Seamonkey bootstrap code.
|
||||
# The Original Code is Mozilla Corporation Code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Benjamin Smedberg <bsmedberg@covad.net>
|
||||
# Portions created by the Initial Developer are Copyright (C) 2004
|
||||
# Clint Talbert.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Armen Zambrano Gasparnian <armenzg@mozilla.com>
|
||||
# Axel Hecht <l10n@mozilla.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -33,14 +36,9 @@
|
|||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = public
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
spawn hdiutil attach -readonly -mountroot /tmp -private -noautoopen $argv
|
||||
expect {
|
||||
"byte" {send "G"; exp_continue}
|
||||
"END" {send "\r"; exp_continue}
|
||||
"Y/N?" {send "Y\r"; exp_continue}
|
||||
}
|
|
@ -279,6 +279,7 @@ user_pref("accessibility.typeaheadfind.autostart", false);
|
|||
user_pref("javascript.options.showInConsole", true);
|
||||
user_pref("layout.debug.enable_data_xbl", true);
|
||||
user_pref("browser.EULA.override", true);
|
||||
user_pref("javascript.options.jit.content", false);
|
||||
|
||||
user_pref("camino.warn_when_closing", false); // Camino-only, harmless to others
|
||||
"""
|
||||
|
|
|
@ -73,6 +73,7 @@ CPPSRCS = \
|
|||
nsPrincipal.cpp \
|
||||
nsSystemPrincipal.cpp \
|
||||
nsNullPrincipal.cpp \
|
||||
nsNullPrincipalURI.cpp \
|
||||
nsJSPrincipals.cpp \
|
||||
nsScriptSecurityManager.cpp \
|
||||
nsSecurityManagerFactory.cpp \
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
*/
|
||||
|
||||
#include "nsNullPrincipal.h"
|
||||
#include "nsNullPrincipalURI.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsIUUIDGenerator.h"
|
||||
#include "nsID.h"
|
||||
|
@ -52,8 +53,6 @@
|
|||
#include "nsDOMError.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
|
||||
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE2_CI(nsNullPrincipal,
|
||||
nsIPrincipal,
|
||||
nsISerializable)
|
||||
|
@ -119,22 +118,14 @@ nsNullPrincipal::Init()
|
|||
|
||||
str.Append(NS_NULLPRINCIPAL_PREFIX);
|
||||
str.Append(chars);
|
||||
|
||||
|
||||
if (str.Length() != prefixLen + suffixLen) {
|
||||
NS_WARNING("Out of memory allocating null-principal URI");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Use CID so we're sure we get the impl we want. Note that creating the URI
|
||||
// directly is ok because we have our own private URI scheme. In effect,
|
||||
// we're being a protocol handler.
|
||||
mURI = do_CreateInstance(kSimpleURICID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mURI->SetSpec(str);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_TryToSetImmutable(mURI);
|
||||
mURI = new nsNullPrincipalURI(str);
|
||||
NS_ENSURE_TRUE(mURI, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return mJSPrincipals.Init(this, str);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 expandtab
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsNullPrincipalURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// nsNullPrincipalURI
|
||||
|
||||
nsNullPrincipalURI::nsNullPrincipalURI(const nsCString &aSpec)
|
||||
{
|
||||
PRInt32 dividerPosition = aSpec.FindChar(':');
|
||||
NS_ASSERTION(dividerPosition != -1, "Malformed URI!");
|
||||
|
||||
PRInt32 n = aSpec.Left(mScheme, dividerPosition);
|
||||
NS_ASSERTION(n == dividerPosition, "Storing the scheme failed!");
|
||||
|
||||
PRInt32 count = aSpec.Length() - dividerPosition - 1;
|
||||
n = aSpec.Mid(mPath, dividerPosition + 1, count);
|
||||
NS_ASSERTION(n == count, "Storing the path failed!");
|
||||
|
||||
ToLowerCase(mScheme);
|
||||
}
|
||||
|
||||
static NS_DEFINE_CID(kNullPrincipalURIImplementationCID,
|
||||
NS_NULLPRINCIPALURI_IMPLEMENTATION_CID);
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsNullPrincipalURI)
|
||||
NS_IMPL_THREADSAFE_RELEASE(nsNullPrincipalURI)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsNullPrincipalURI)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
if (aIID.Equals(kNullPrincipalURIImplementationCID))
|
||||
foundInterface = static_cast<nsIURI *>(this);
|
||||
else
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURI)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// nsIURI
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetAsciiHost(nsACString &_host)
|
||||
{
|
||||
_host.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetAsciiSpec(nsACString &_spec)
|
||||
{
|
||||
nsCAutoString buffer;
|
||||
(void)GetSpec(buffer);
|
||||
NS_EscapeURL(buffer, esc_OnlyNonASCII | esc_AlwaysCopy, _spec);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetHost(nsACString &_host)
|
||||
{
|
||||
_host.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetHost(const nsACString &aHost)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetHostPort(nsACString &_host)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetHostPort(const nsACString &aHost)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetOriginCharset(nsACString &_charset)
|
||||
{
|
||||
_charset.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetPassword(nsACString &_password)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetPassword(const nsACString &aPassword)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetPath(nsACString &_path)
|
||||
{
|
||||
// We want to give a full copy of the string and not share a string buffer
|
||||
_path = nsDependentCString(mPath);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetPath(const nsACString &aPath)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetPrePath(nsACString &_prePath)
|
||||
{
|
||||
_prePath = mScheme + NS_LITERAL_CSTRING(":");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetPort(PRInt32 *_port)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetPort(PRInt32 aPort)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetScheme(nsACString &_scheme)
|
||||
{
|
||||
// We want to give a full copy of the string and not share a string buffer
|
||||
_scheme = nsDependentCString(mScheme);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetScheme(const nsACString &aScheme)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetSpec(nsACString &_spec)
|
||||
{
|
||||
_spec = mScheme + NS_LITERAL_CSTRING(":") + mPath;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetSpec(const nsACString &aSpec)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetUsername(nsACString &_username)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetUsername(const nsACString &aUsername)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetUserPass(nsACString &_userPass)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetUserPass(const nsACString &aUserPass)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::Clone(nsIURI **_newURI)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri =
|
||||
new nsNullPrincipalURI(mScheme + NS_LITERAL_CSTRING(":") + mPath);
|
||||
NS_ENSURE_TRUE(uri, NS_ERROR_OUT_OF_MEMORY);
|
||||
uri.forget(_newURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::Equals(nsIURI *aOther, PRBool *_equals)
|
||||
{
|
||||
*_equals = PR_FALSE;
|
||||
nsNullPrincipalURI *otherURI;
|
||||
nsresult rv = aOther->QueryInterface(kNullPrincipalURIImplementationCID,
|
||||
(void **)&otherURI);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*_equals = (0 == strcmp(mScheme.get(), otherURI->mScheme.get()) &&
|
||||
0 == strcmp(mPath.get(), otherURI->mPath.get()));
|
||||
NS_RELEASE(otherURI);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::Resolve(const nsACString &aRelativePath,
|
||||
nsACString &_resolvedURI)
|
||||
{
|
||||
_resolvedURI = aRelativePath;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SchemeIs(const char *aScheme, PRBool *_schemeIs)
|
||||
{
|
||||
*_schemeIs = (0 == nsCRT::strcasecmp(mScheme.get(), aScheme));
|
||||
return NS_OK;
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 sts=2 expandtab
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
|
@ -13,12 +15,13 @@
|
|||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Christopher Blizzard <blizzard@mozilla.org>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* The Initial Developer of the Original Code is the
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Shawn Wilsher <me@shawnwilsher.com> (Original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -34,22 +37,33 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <nsIURIContentListener.h>
|
||||
#include <nsIInterfaceRequestor.h>
|
||||
#include <nsCOMPtr.h>
|
||||
/**
|
||||
* This wraps nsSimpleURI so that all calls to it are done on the main thread.
|
||||
*/
|
||||
|
||||
class XRemoteContentListener : public nsIURIContentListener,
|
||||
public nsIInterfaceRequestor
|
||||
#ifndef __nsNullPrincipalURI_h__
|
||||
#define __nsNullPrincipalURI_h__
|
||||
|
||||
#include "nsIURI.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
|
||||
// {51fcd543-3b52-41f7-b91b-6b54102236e6}
|
||||
#define NS_NULLPRINCIPALURI_IMPLEMENTATION_CID \
|
||||
{0x51fcd543, 0x3b52, 0x41f7, \
|
||||
{0xb9, 0x1b, 0x6b, 0x54, 0x10, 0x22, 0x36, 0xe6} }
|
||||
|
||||
class nsNullPrincipalURI : public nsIURI
|
||||
{
|
||||
public:
|
||||
XRemoteContentListener();
|
||||
virtual ~XRemoteContentListener();
|
||||
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIURICONTENTLISTENER
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
NS_DECL_NSIURI
|
||||
|
||||
private:
|
||||
nsNullPrincipalURI(const nsCString &aSpec);
|
||||
|
||||
nsCOMPtr<nsISupports> mLoadCookie;
|
||||
private:
|
||||
nsCString mScheme;
|
||||
nsCString mPath;
|
||||
};
|
||||
|
||||
#endif // __nsNullPrincipalURI_h__
|
|
@ -316,118 +316,7 @@ PRBool
|
|||
nsScriptSecurityManager::SecurityCompareURIs(nsIURI* aSourceURI,
|
||||
nsIURI* aTargetURI)
|
||||
{
|
||||
// Note that this is not an Equals() test on purpose -- for URIs that don't
|
||||
// support host/port, we want equality to basically be object identity, for
|
||||
// security purposes. Otherwise, for example, two javascript: URIs that
|
||||
// are otherwise unrelated could end up "same origin", which would be
|
||||
// unfortunate.
|
||||
if (aSourceURI && aSourceURI == aTargetURI)
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (!aTargetURI || !aSourceURI)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// If either URI is a nested URI, get the base URI
|
||||
nsCOMPtr<nsIURI> sourceBaseURI = NS_GetInnermostURI(aSourceURI);
|
||||
nsCOMPtr<nsIURI> targetBaseURI = NS_GetInnermostURI(aTargetURI);
|
||||
|
||||
if (!sourceBaseURI || !targetBaseURI)
|
||||
return PR_FALSE;
|
||||
|
||||
// Compare schemes
|
||||
nsCAutoString targetScheme;
|
||||
PRBool sameScheme = PR_FALSE;
|
||||
if (NS_FAILED( targetBaseURI->GetScheme(targetScheme) ) ||
|
||||
NS_FAILED( sourceBaseURI->SchemeIs(targetScheme.get(), &sameScheme) ) ||
|
||||
!sameScheme)
|
||||
{
|
||||
// Not same-origin if schemes differ
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// special handling for file: URIs
|
||||
if (targetScheme.EqualsLiteral("file"))
|
||||
{
|
||||
// in traditional unsafe behavior all files are the same origin
|
||||
if (!sStrictFileOriginPolicy)
|
||||
return PR_TRUE;
|
||||
|
||||
nsCOMPtr<nsIFileURL> sourceFileURL(do_QueryInterface(sourceBaseURI));
|
||||
nsCOMPtr<nsIFileURL> targetFileURL(do_QueryInterface(targetBaseURI));
|
||||
|
||||
if (!sourceFileURL || !targetFileURL)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIFile> sourceFile, targetFile;
|
||||
|
||||
sourceFileURL->GetFile(getter_AddRefs(sourceFile));
|
||||
targetFileURL->GetFile(getter_AddRefs(targetFile));
|
||||
|
||||
if (!sourceFile || !targetFile)
|
||||
return PR_FALSE;
|
||||
|
||||
// Otherwise they had better match
|
||||
PRBool filesAreEqual = PR_FALSE;
|
||||
nsresult rv = sourceFile->Equals(targetFile, &filesAreEqual);
|
||||
return NS_SUCCEEDED(rv) && filesAreEqual;
|
||||
}
|
||||
|
||||
// Special handling for mailnews schemes
|
||||
if (targetScheme.EqualsLiteral("imap") ||
|
||||
targetScheme.EqualsLiteral("mailbox") ||
|
||||
targetScheme.EqualsLiteral("news"))
|
||||
{
|
||||
// Each message is a distinct trust domain; use the
|
||||
// whole spec for comparison
|
||||
nsCAutoString targetSpec;
|
||||
nsCAutoString sourceSpec;
|
||||
return ( NS_SUCCEEDED( targetBaseURI->GetSpec(targetSpec) ) &&
|
||||
NS_SUCCEEDED( sourceBaseURI->GetSpec(sourceSpec) ) &&
|
||||
targetSpec.Equals(sourceSpec) );
|
||||
}
|
||||
|
||||
// Compare hosts
|
||||
nsCAutoString targetHost;
|
||||
nsCAutoString sourceHost;
|
||||
if (NS_FAILED( targetBaseURI->GetHost(targetHost) ) ||
|
||||
NS_FAILED( sourceBaseURI->GetHost(sourceHost) ) ||
|
||||
!targetHost.Equals(sourceHost, nsCaseInsensitiveCStringComparator()))
|
||||
{
|
||||
// Not same-origin if hosts differ
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// Compare ports
|
||||
PRInt32 targetPort;
|
||||
nsresult rv = targetBaseURI->GetPort(&targetPort);
|
||||
PRInt32 sourcePort;
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = sourceBaseURI->GetPort(&sourcePort);
|
||||
PRBool result = NS_SUCCEEDED(rv) && targetPort == sourcePort;
|
||||
// If the port comparison failed, see if either URL has a
|
||||
// port of -1. If so, replace -1 with the default port
|
||||
// for that scheme.
|
||||
if (NS_SUCCEEDED(rv) && !result &&
|
||||
(sourcePort == -1 || targetPort == -1))
|
||||
{
|
||||
NS_ENSURE_TRUE(sIOService, PR_FALSE);
|
||||
|
||||
PRInt32 defaultPort = NS_GetDefaultPort(targetScheme.get());
|
||||
if (defaultPort == -1)
|
||||
return PR_FALSE; // No default port for this scheme
|
||||
|
||||
if (sourcePort == -1)
|
||||
sourcePort = defaultPort;
|
||||
else if (targetPort == -1)
|
||||
targetPort = defaultPort;
|
||||
result = targetPort == sourcePort;
|
||||
}
|
||||
|
||||
return result;
|
||||
return NS_SecurityCompareURIs(aSourceURI, aTargetURI, sStrictFileOriginPolicy);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
24
client.mk
24
client.mk
|
@ -89,11 +89,9 @@ endif
|
|||
TOPSRCDIR = $(CWD)
|
||||
endif
|
||||
|
||||
ifeq (Darwin,$(shell uname -s))
|
||||
AUTOCONF ?= autoconf213
|
||||
else
|
||||
AUTOCONF ?= $(shell which autoconf-2.13 autoconf2.13 autoconf213 | head -1)
|
||||
endif
|
||||
# try to find autoconf 2.13 - discard errors from 'which'
|
||||
# MacOS X 10.4 sends "no autoconf*" errors to stdout, discard those via grep
|
||||
AUTOCONF ?= $(shell which autoconf-2.13 autoconf2.13 autoconf213 2>/dev/null | grep -v '^no autoconf' | head -1)
|
||||
|
||||
MKDIR := mkdir
|
||||
SH := /bin/sh
|
||||
|
@ -164,6 +162,7 @@ endif
|
|||
|
||||
endif # MOZ_BUILD_PROJECTS
|
||||
|
||||
# 'configure' scripts generated by autoconf.
|
||||
CONFIGURES := $(TOPSRCDIR)/configure
|
||||
CONFIGURES += $(TOPSRCDIR)/nsprpub/configure
|
||||
|
||||
|
@ -276,20 +275,15 @@ EXTRA_CONFIG_DEPS := \
|
|||
$(wildcard $(TOPSRCDIR)/build/autoconf/*.m4) \
|
||||
$(NULL)
|
||||
|
||||
$(TOPSRCDIR)/configure: $(TOPSRCDIR)/configure.in $(EXTRA_CONFIG_DEPS)
|
||||
$(CONFIGURES): %: %.in $(EXTRA_CONFIG_DEPS)
|
||||
@echo Generating $@ using autoconf
|
||||
cd $(TOPSRCDIR); $(AUTOCONF)
|
||||
|
||||
$(TOPSRCDIR)/nsprpub/configure: $(TOPSRCDIR)/nsprpub/configure.in $(EXTRA_CONFIG_DEPS)
|
||||
@echo Generating $@ using autoconf
|
||||
cd $(TOPSRCDIR)/nsprpub; $(AUTOCONF)
|
||||
cd $(@D); $(AUTOCONF)
|
||||
endif
|
||||
|
||||
CONFIG_STATUS_DEPS := \
|
||||
$(TOPSRCDIR)/configure \
|
||||
$(wildcard $(CONFIGURES)) \
|
||||
$(TOPSRCDIR)/allmakefiles.sh \
|
||||
$(TOPSRCDIR)/.mozconfig.mk \
|
||||
$(wildcard $(TOPSRCDIR)/nsprpub/configure) \
|
||||
$(wildcard $(TOPSRCDIR)/directory/c-sdk/configure) \
|
||||
$(wildcard $(TOPSRCDIR)/config/milestone.txt) \
|
||||
$(wildcard $(TOPSRCDIR)/config/chrome-versions.sh) \
|
||||
|
@ -309,7 +303,9 @@ ifdef MOZ_TOOLS
|
|||
CONFIGURE = $(TOPSRCDIR)/configure
|
||||
endif
|
||||
|
||||
configure:: $(CONFIGURES)
|
||||
configure-files: $(CONFIGURES)
|
||||
|
||||
configure:: configure-files
|
||||
ifdef MOZ_BUILD_PROJECTS
|
||||
@if test ! -d $(MOZ_OBJDIR); then $(MKDIR) $(MOZ_OBJDIR); else true; fi
|
||||
endif
|
||||
|
|
|
@ -395,6 +395,7 @@ MAKE = @MAKE@
|
|||
PBBUILD_BIN = @PBBUILD@
|
||||
SDP = @SDP@
|
||||
NSINSTALL_BIN = @NSINSTALL_BIN@
|
||||
WGET = @WGET@
|
||||
|
||||
ifdef MOZ_NATIVE_JPEG
|
||||
JPEG_CFLAGS = @JPEG_CFLAGS@
|
||||
|
|
|
@ -10,4 +10,4 @@
|
|||
# hardcoded milestones in the tree from these two files.
|
||||
#--------------------------------------------------------
|
||||
|
||||
1.9.1a2
|
||||
1.9.1b1pre
|
||||
|
|
|
@ -1133,7 +1133,7 @@ ifdef IS_COMPONENT
|
|||
cp $(VMS_SYMVEC_FILE_COMP) $(VMS_SYMVEC_FILE); \
|
||||
fi
|
||||
endif
|
||||
endif
|
||||
endif # OpenVMS
|
||||
ifdef NO_LD_ARCHIVE_FLAGS
|
||||
ifdef SHARED_LIBRARY_LIBS
|
||||
@rm -f $(SUB_SHLOBJS)
|
||||
|
@ -1171,7 +1171,7 @@ endif
|
|||
done
|
||||
@rm -f $(MOZILLA_PROBE_LIBS)
|
||||
|
||||
else
|
||||
else # ! DTRACE_LIB_DEPENDENT
|
||||
$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(DTRACE_PROBE_OBJ) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
|
||||
endif # DTRACE_LIB_DEPENDENT
|
||||
|
||||
|
|
30
configure.in
30
configure.in
|
@ -1374,6 +1374,24 @@ if test "$GNU_CXX"; then
|
|||
|
||||
_DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -include $(DEPTH)/mozilla-config.h'
|
||||
_USE_CPP_INCLUDE_FLAG=1
|
||||
|
||||
AC_CACHE_CHECK(whether the compiler supports -Wno-invalid-offsetof,
|
||||
ac_has_wno_invalid_offsetof,
|
||||
[
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_CPLUSPLUS
|
||||
_SAVE_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS ${_COMPILER_PREFIX}-Wno-invalid-offsetof"
|
||||
AC_TRY_COMPILE([],
|
||||
[return(0);],
|
||||
ac_has_wno_invalid_offsetof="yes",
|
||||
ac_has_wno_invalid_offsetof="no")
|
||||
CXXFLAGS="$_SAVE_CXXFLAGS"
|
||||
AC_LANG_RESTORE
|
||||
])
|
||||
if test "$ac_has_wno_invalid_offsetof" = "yes"; then
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} ${_COMPILER_PREFIX}-Wno-invalid-offsetof"
|
||||
fi
|
||||
else
|
||||
_DEFINES_CXXFLAGS='-DMOZILLA_CLIENT -D_MOZILLA_CONFIG_H_ $(ACDEFINES)'
|
||||
fi
|
||||
|
@ -1458,7 +1476,6 @@ AC_MSG_RESULT("$ac_cv_static_assertion_macros_work")
|
|||
if test "$ac_cv_static_assertion_macros_work" = "no"; then
|
||||
AC_MSG_ERROR([Compiler cannot compile macros used in autoconf tests.])
|
||||
fi
|
||||
|
||||
fi # COMPILE_ENVIRONMENT
|
||||
|
||||
dnl ========================================================
|
||||
|
@ -4630,6 +4647,10 @@ standalone)
|
|||
|
||||
esac
|
||||
|
||||
if test -z "$MOZ_XUL_APP"; then
|
||||
AC_MSG_ERROR([builds with unsetting MOZ_XUL_APP in confvars.sh are not supported.])
|
||||
fi
|
||||
|
||||
AC_SUBST(MOZ_BUILD_APP)
|
||||
AC_SUBST(MOZ_XUL_APP)
|
||||
AC_SUBST(MOZ_PHOENIX)
|
||||
|
@ -4776,7 +4797,7 @@ cairo-mac|cairo-cocoa)
|
|||
AC_DEFINE(XP_MACOSX)
|
||||
AC_DEFINE(TARGET_CARBON)
|
||||
AC_DEFINE(TARGET_API_MAC_CARBON)
|
||||
TK_LIBS='-framework Carbon -framework CoreAudio -framework AudioToolbox -framework AudioUnit'
|
||||
TK_LIBS='-framework Carbon -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework AddressBook'
|
||||
TK_CFLAGS="-I${MACOS_SDK_DIR}/Developer/Headers/FlatCarbon"
|
||||
CFLAGS="$CFLAGS $TK_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $TK_CFLAGS"
|
||||
|
@ -5775,6 +5796,11 @@ fi
|
|||
AC_MSG_RESULT([$TAR])
|
||||
AC_SUBST(TAR)
|
||||
|
||||
AC_MSG_CHECKING([for wget])
|
||||
AC_CHECK_PROGS(WGET, wget, "")
|
||||
AC_MSG_RESULT([$WGET])
|
||||
AC_SUBST(WGET)
|
||||
|
||||
dnl ========================================================
|
||||
dnl Updater
|
||||
dnl ========================================================
|
||||
|
|
|
@ -101,6 +101,7 @@ struct JSRuntime;
|
|||
class nsICaseConversion;
|
||||
class nsIUGenCategory;
|
||||
class nsIWidget;
|
||||
class nsIDragSession;
|
||||
class nsPIDOMWindow;
|
||||
#ifdef MOZ_XTF
|
||||
class nsIXTFService;
|
||||
|
@ -1218,6 +1219,11 @@ public:
|
|||
*/
|
||||
static void HidePopupsInDocument(nsIDocument* aDocument);
|
||||
|
||||
/**
|
||||
* Retrieve the current drag session, or null if no drag is currently occuring
|
||||
*/
|
||||
static already_AddRefed<nsIDragSession> GetDragSession();
|
||||
|
||||
/**
|
||||
* Return true if aURI is a local file URI (i.e. file://).
|
||||
*/
|
||||
|
@ -1244,6 +1250,11 @@ public:
|
|||
*/
|
||||
static PRBool OfflineAppAllowed(nsIURI *aURI);
|
||||
|
||||
/**
|
||||
* Check whether an application should be allowed to use offline APIs.
|
||||
*/
|
||||
static PRBool OfflineAppAllowed(nsIPrincipal *aPrincipal);
|
||||
|
||||
/**
|
||||
* Increases the count of blockers preventing scripts from running.
|
||||
* NOTE: You might want to use nsAutoScriptBlocker rather than calling
|
||||
|
|
|
@ -97,8 +97,8 @@ class nsFrameLoader;
|
|||
|
||||
// IID for the nsIDocument interface
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x5f0203a8, 0xd926, 0x4adf, \
|
||||
{ 0xba, 0x96, 0xe6, 0xc3, 0xe6, 0xbb, 0x1b, 0xe5 } }
|
||||
{ 0xd5b1e3c5, 0x85dc, 0x403e, \
|
||||
{ 0xbb, 0x4a, 0x54, 0x66, 0xdc, 0xbe, 0x15, 0x69 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
|
@ -569,6 +569,11 @@ public:
|
|||
GetScriptHandlingObject(PRBool& aHasHadScriptHandlingObject) const = 0;
|
||||
virtual void SetScriptHandlingObject(nsIScriptGlobalObject* aScriptObject) = 0;
|
||||
|
||||
/**
|
||||
* Sets script handling object to null and marks that document has had one.
|
||||
*/
|
||||
virtual void ClearScriptHandlingObject() = 0;
|
||||
|
||||
/**
|
||||
* Get the object that is used as the scope for all of the content
|
||||
* wrappers whose owner document is this document. Unlike the script global
|
||||
|
@ -898,6 +903,14 @@ public:
|
|||
nsCompatibility GetCompatibilityMode() const {
|
||||
return mCompatMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether we've ever fired a DOMTitleChanged event for this
|
||||
* document.
|
||||
*/
|
||||
PRBool HaveFiredDOMTitleChange() const {
|
||||
return mHaveFiredTitleChange;
|
||||
}
|
||||
|
||||
/**
|
||||
* See GetXBLChildNodesFor on nsBindingManager
|
||||
|
@ -1060,6 +1073,9 @@ protected:
|
|||
// If true, whoever is creating the document has gotten it to the
|
||||
// point where it's safe to start layout on it.
|
||||
PRPackedBool mMayStartLayout;
|
||||
|
||||
// True iff we've ever fired a DOMTitleChanged event for this document
|
||||
PRPackedBool mHaveFiredTitleChange;
|
||||
|
||||
// The bidi options for this document. What this bitfield means is
|
||||
// defined in nsBidiUtils.h
|
||||
|
|
|
@ -59,6 +59,7 @@ REQUIRES = xpcom \
|
|||
js \
|
||||
webshell \
|
||||
necko \
|
||||
nkcache \
|
||||
mimetype \
|
||||
exthandler \
|
||||
chardet \
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -58,6 +58,7 @@ class nsIDocument;
|
|||
class nsIURI;
|
||||
class nsIFile;
|
||||
class nsISimpleEnumerator;
|
||||
class nsDOMDataTransfer;
|
||||
|
||||
// {1f34bc80-1bc7-11d6-a384-d705dd0746fc}
|
||||
#define NS_CONTENTAREADRAGDROP_CID \
|
||||
|
@ -76,13 +77,11 @@ class nsISimpleEnumerator;
|
|||
// RemoveChromeListeners().
|
||||
//
|
||||
class nsContentAreaDragDrop : public nsIDOMDragListener,
|
||||
public nsIDragDropHandler,
|
||||
public nsIFlavorDataProvider
|
||||
public nsIDragDropHandler
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDRAGDROPHANDLER
|
||||
NS_DECL_NSIFLAVORDATAPROVIDER
|
||||
|
||||
nsContentAreaDragDrop();
|
||||
virtual ~nsContentAreaDragDrop();
|
||||
|
@ -97,6 +96,33 @@ public:
|
|||
NS_IMETHOD DragEnd(nsIDOMEvent* aMouseEvent);
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent *event);
|
||||
|
||||
/**
|
||||
* Determine what data in the content area, if any, is being dragged.
|
||||
*
|
||||
* aWindow - the window containing the target node
|
||||
* aTarget - the mousedown event target that started the drag
|
||||
* aSelectionTargetNode - the node where the drag event should be fired
|
||||
* aIsAltKeyPressed - true if the Alt key is pressed. In some cases, this
|
||||
* will prevent the drag from occuring. For example,
|
||||
* holding down Alt over a link should select the text,
|
||||
* not drag the link.
|
||||
* aDataTransfer - the dataTransfer for the drag event.
|
||||
* aCanDrag - [out] set to true if the drag may proceed, false to stop the
|
||||
* drag entirely
|
||||
* aDragSelection - [out] set to true to indicate that a selection is being
|
||||
* dragged, rather than a specific node
|
||||
* aDragNode - [out] the link, image or area being dragged, or null if the
|
||||
* drag occured on another element.
|
||||
*/
|
||||
static nsresult GetDragData(nsIDOMWindow* aWindow,
|
||||
nsIContent* aTarget,
|
||||
nsIContent* aSelectionTargetNode,
|
||||
PRBool aIsAltKeyPressed,
|
||||
nsDOMDataTransfer* aDataTransfer,
|
||||
PRBool* aCanDrag,
|
||||
PRBool* aDragSelection,
|
||||
nsIContent** aDragNode);
|
||||
|
||||
private:
|
||||
|
||||
// Add/remove the relevant listeners
|
||||
|
@ -109,14 +135,9 @@ private:
|
|||
static void GetEventDocument(nsIDOMEvent* inEvent,
|
||||
nsIDOMDocument** outDocument);
|
||||
|
||||
static nsresult SaveURIToFile(nsAString& inSourceURIString,
|
||||
nsIFile* inDestFile);
|
||||
|
||||
void ExtractURLFromData(const nsACString & inFlavor,
|
||||
nsISupports* inDataWrapper, PRUint32 inDataLen,
|
||||
nsAString & outURL);
|
||||
nsresult GetHookEnumeratorFromEvent(nsIDOMEvent* inEvent,
|
||||
nsISimpleEnumerator** outEnumerator);
|
||||
static void ExtractURLFromData(const nsACString & inFlavor,
|
||||
nsISupports* inDataWrapper, PRUint32 inDataLen,
|
||||
nsAString & outURL);
|
||||
|
||||
PRPackedBool mListenerInstalled;
|
||||
|
||||
|
@ -128,6 +149,20 @@ private:
|
|||
|
||||
};
|
||||
|
||||
// this is used to save images to disk lazily when the image data is asked for
|
||||
// during the drop instead of when it is added to the drag data transfer. This
|
||||
// ensures that the image data is only created when an image drop is allowed.
|
||||
class nsContentAreaDragDropDataProvider : public nsIFlavorDataProvider
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIFLAVORDATAPROVIDER
|
||||
|
||||
virtual ~nsContentAreaDragDropDataProvider() {}
|
||||
|
||||
nsresult SaveURIToFile(nsAString& inSourceURIString,
|
||||
nsIFile* inDestFile);
|
||||
};
|
||||
|
||||
|
||||
#endif /* nsContentAreaDragDrop_h__ */
|
||||
|
|
|
@ -71,6 +71,9 @@
|
|||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsIOfflineCacheUpdate.h"
|
||||
#include "nsIApplicationCache.h"
|
||||
#include "nsIApplicationCacheContainer.h"
|
||||
#include "nsIApplicationCacheService.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIDOMLoadStatus.h"
|
||||
#include "nsICookieService.h"
|
||||
|
@ -94,6 +97,10 @@
|
|||
#include "nsPresShellIterator.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIDocumentLoader.h"
|
||||
#include "nsICachingChannel.h"
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
|
||||
PRLogModuleInfo* gContentSinkLogModuleInfo;
|
||||
|
||||
|
@ -845,61 +852,304 @@ nsContentSink::PrefetchHref(const nsAString &aHref,
|
|||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentSink::GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey)
|
||||
{
|
||||
aCacheKey.Truncate();
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICachingChannel> cachingChannel = do_QueryInterface(aChannel, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISupports> token;
|
||||
rv = cachingChannel->GetCacheToken(getter_AddRefs(token));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsICacheEntryDescriptor> descriptor = do_QueryInterface(token, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = descriptor->GetKey(aCacheKey);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentSink::SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache,
|
||||
nsIURI *aManifestURI,
|
||||
PRBool aIsTopDocument,
|
||||
PRBool aFetchedWithHTTPGetOrEquiv,
|
||||
CacheSelectionAction *aAction)
|
||||
{
|
||||
*aAction = CACHE_SELECTION_NONE;
|
||||
|
||||
nsCOMPtr<nsIApplicationCacheContainer> applicationCacheDocument =
|
||||
do_QueryInterface(mDocument);
|
||||
NS_ASSERTION(applicationCacheDocument,
|
||||
"mDocument must implement nsIApplicationCacheContainer.");
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// We might decide on a new application cache...
|
||||
nsCOMPtr<nsIApplicationCache> applicationCache = aLoadApplicationCache;
|
||||
|
||||
if (applicationCache) {
|
||||
nsCAutoString groupID;
|
||||
rv = applicationCache->GetGroupID(groupID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIURI> groupURI;
|
||||
rv = NS_NewURI(getter_AddRefs(groupURI), groupID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool equal = PR_FALSE;
|
||||
rv = groupURI->Equals(aManifestURI, &equal);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!equal) {
|
||||
// This is a foreign entry, mark it as such. If this is a
|
||||
// toplevel load, force a reload to avoid loading the foreign
|
||||
// entry. The next attempt will not choose this cache entry
|
||||
// (because it has been marked foreign).
|
||||
|
||||
nsCAutoString cachekey;
|
||||
rv = GetChannelCacheKey(mDocument->GetChannel(), cachekey);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = applicationCache->MarkEntry(cachekey,
|
||||
nsIApplicationCache::ITEM_FOREIGN);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aIsTopDocument) {
|
||||
*aAction = CACHE_SELECTION_RELOAD;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aIsTopDocument) {
|
||||
// This is a top level document and the http manifest attribute
|
||||
// URI is equal to the manifest URI of the cache the document
|
||||
// was loaded from - associate the document with that cache and
|
||||
// invoke the cache update process.
|
||||
rv = applicationCacheDocument->SetApplicationCache(applicationCache);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aAction = CACHE_SELECTION_UPDATE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The document was not loaded from an application cache
|
||||
// Here we know the manifest has the same origin as the
|
||||
// document. There is call to CheckMayLoad() on it above.
|
||||
|
||||
if (!aFetchedWithHTTPGetOrEquiv) {
|
||||
// The document was not loaded using HTTP GET or equivalent
|
||||
// method. The spec says to run the cache selection algorithm w/o
|
||||
// the manifest specified but we can just do return NS_OK here.
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If there is an existing application cache for this manifest,
|
||||
// associate it with the document.
|
||||
nsCAutoString manifestURISpec;
|
||||
rv = aManifestURI->GetAsciiSpec(manifestURISpec);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIApplicationCacheService> appCacheService =
|
||||
do_GetService(NS_APPLICATIONCACHESERVICE_CONTRACTID);
|
||||
if (!appCacheService) {
|
||||
// No application cache service, nothing to do here.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rv = appCacheService->GetActiveCache(manifestURISpec,
|
||||
getter_AddRefs(applicationCache));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (applicationCache) {
|
||||
rv = applicationCacheDocument->SetApplicationCache(applicationCache);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
// XXX bug 443023: if there is already a scheduled update or
|
||||
// update in progress we have to add this document as
|
||||
// an implicit entry.
|
||||
}
|
||||
|
||||
// Always do an update in this case
|
||||
*aAction = CACHE_SELECTION_UPDATE;
|
||||
}
|
||||
|
||||
if (applicationCache) {
|
||||
// We are now associated with an application cache. This item
|
||||
// should be marked as an implicit entry.
|
||||
nsCAutoString cachekey;
|
||||
rv = GetChannelCacheKey(mDocument->GetChannel(), cachekey);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = applicationCache->MarkEntry(cachekey,
|
||||
nsIApplicationCache::ITEM_IMPLICIT);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsContentSink::SelectDocAppCacheNoManifest(nsIApplicationCache *aLoadApplicationCache,
|
||||
PRBool aIsTopDocument,
|
||||
nsIURI **aManifestURI,
|
||||
CacheSelectionAction *aAction)
|
||||
{
|
||||
*aManifestURI = nsnull;
|
||||
*aAction = CACHE_SELECTION_NONE;
|
||||
|
||||
if (!aIsTopDocument || !aLoadApplicationCache) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// The document was loaded from an application cache, use that
|
||||
// application cache as the document's application cache.
|
||||
nsCOMPtr<nsIApplicationCacheContainer> applicationCacheDocument =
|
||||
do_QueryInterface(mDocument);
|
||||
NS_ASSERTION(applicationCacheDocument,
|
||||
"mDocument must implement nsIApplicationCacheContainer.");
|
||||
|
||||
rv = applicationCacheDocument->SetApplicationCache(aLoadApplicationCache);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Return the uri and invoke the update process for the selected
|
||||
// application cache.
|
||||
nsCAutoString groupID;
|
||||
rv = aLoadApplicationCache->GetGroupID(groupID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = NS_NewURI(aManifestURI, groupID);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aAction = CACHE_SELECTION_UPDATE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsContentSink::ProcessOfflineManifest(nsIContent *aElement)
|
||||
{
|
||||
// Only check the manifest for root document nodes.
|
||||
if (aElement != mDocument->GetRootContent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
// Check for a manifest= attribute.
|
||||
nsAutoString manifestSpec;
|
||||
aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::manifest, manifestSpec);
|
||||
|
||||
if (manifestSpec.IsEmpty() ||
|
||||
manifestSpec.FindChar('#') != kNotFound) {
|
||||
// Grab the application cache the document was loaded from, if any.
|
||||
nsCOMPtr<nsIApplicationCache> applicationCache;
|
||||
|
||||
nsCOMPtr<nsIApplicationCacheContainer> applicationCacheChannel =
|
||||
do_QueryInterface(mDocument->GetChannel());
|
||||
if (applicationCacheChannel) {
|
||||
rv = applicationCacheChannel->GetApplicationCache(
|
||||
getter_AddRefs(applicationCache));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (manifestSpec.IsEmpty() && !applicationCache) {
|
||||
// Not loaded from an application cache, and no manifest
|
||||
// attribute. Nothing to do here.
|
||||
return;
|
||||
}
|
||||
|
||||
// We only care about manifests in toplevel windows.
|
||||
nsCOMPtr<nsPIDOMWindow> pwindow =
|
||||
do_QueryInterface(mDocument->GetScriptGlobalObject());
|
||||
if (!pwindow) {
|
||||
// The manifest attribute is handled differently if the document is
|
||||
// not toplevel.
|
||||
nsCOMPtr<nsIDOMWindow> window = mDocument->GetWindow();
|
||||
if (!window)
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> window =
|
||||
do_QueryInterface(pwindow->GetOuterWindow());
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> parent;
|
||||
window->GetParent(getter_AddRefs(parent));
|
||||
if (parent.get() != window.get()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only update if the document has permission to use offline APIs.
|
||||
if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) {
|
||||
return;
|
||||
}
|
||||
PRBool isTop = (parent == window);
|
||||
|
||||
CacheSelectionAction action = CACHE_SELECTION_NONE;
|
||||
nsCOMPtr<nsIURI> manifestURI;
|
||||
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(manifestURI),
|
||||
manifestSpec, mDocument,
|
||||
mDocumentURI);
|
||||
if (!manifestURI) {
|
||||
return;
|
||||
|
||||
if (manifestSpec.IsEmpty()) {
|
||||
rv = SelectDocAppCacheNoManifest(applicationCache,
|
||||
isTop,
|
||||
getter_AddRefs(manifestURI),
|
||||
&action);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(manifestURI),
|
||||
manifestSpec, mDocument,
|
||||
mDocumentURI);
|
||||
if (!manifestURI) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Documents must list a manifest from the same origin
|
||||
rv = mDocument->NodePrincipal()->CheckMayLoad(manifestURI, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only continue if the document has permission to use offline APIs.
|
||||
if (!nsContentUtils::OfflineAppAllowed(mDocument->NodePrincipal())) {
|
||||
return;
|
||||
}
|
||||
|
||||
PRBool fetchedWithHTTPGetOrEquiv = PR_FALSE;
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mDocument->GetChannel()));
|
||||
if (httpChannel) {
|
||||
nsCAutoString method;
|
||||
rv = httpChannel->GetRequestMethod(method);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
fetchedWithHTTPGetOrEquiv = method.Equals("GET");
|
||||
}
|
||||
|
||||
rv = SelectDocAppCache(applicationCache, manifestURI, isTop,
|
||||
fetchedWithHTTPGetOrEquiv, &action);
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Documents must list a manifest from the same origin
|
||||
nsresult rv = mDocument->NodePrincipal()->CheckMayLoad(manifestURI, PR_TRUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
switch (action)
|
||||
{
|
||||
case CACHE_SELECTION_NONE:
|
||||
return;
|
||||
}
|
||||
case CACHE_SELECTION_UPDATE: {
|
||||
nsCOMPtr<nsIOfflineCacheUpdateService> updateService =
|
||||
do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID);
|
||||
|
||||
// Start the update
|
||||
nsCOMPtr<nsIDOMDocument> domdoc = do_QueryInterface(mDocument);
|
||||
nsCOMPtr<nsIOfflineCacheUpdateService> updateService =
|
||||
do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID);
|
||||
updateService->ScheduleOnDocumentStop(manifestURI, mDocumentURI, domdoc);
|
||||
if (updateService) {
|
||||
nsCOMPtr<nsIDOMDocument> domdoc = do_QueryInterface(mDocument);
|
||||
updateService->ScheduleOnDocumentStop(manifestURI, mDocumentURI, domdoc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CACHE_SELECTION_RELOAD: {
|
||||
// This situation occurs only for toplevel documents, see bottom
|
||||
// of SelectDocAppCache method.
|
||||
NS_ASSERTION(isTop, "Should only reload toplevel documents!");
|
||||
nsCOMPtr<nsIWebNavigation> webNav = do_QueryInterface(mDocShell);
|
||||
|
||||
webNav->Stop(nsIWebNavigation::STOP_ALL);
|
||||
webNav->Reload(nsIWebNavigation::LOAD_FLAGS_NONE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1419,6 +1669,10 @@ nsContentSink::EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType)
|
|||
void
|
||||
nsContentSink::DidBuildModelImpl(void)
|
||||
{
|
||||
if (!mDocument->HaveFiredDOMTitleChange()) {
|
||||
mDocument->NotifyPossibleTitleChange(PR_FALSE);
|
||||
}
|
||||
|
||||
// Cancel a timer if we had one out there
|
||||
if (mNotificationTimer) {
|
||||
SINK_TRACE(gContentSinkLogModuleInfo, SINK_TRACE_REFLOW,
|
||||
|
|
|
@ -76,6 +76,7 @@ class nsIContent;
|
|||
class nsIViewManager;
|
||||
class nsNodeInfoManager;
|
||||
class nsScriptLoader;
|
||||
class nsIApplicationCache;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
||||
|
@ -150,6 +151,25 @@ protected:
|
|||
nsContentSink();
|
||||
virtual ~nsContentSink();
|
||||
|
||||
enum CacheSelectionAction {
|
||||
// There is no offline cache manifest specified by the document,
|
||||
// or the document was loaded from a cache other than the one it
|
||||
// specifies via its manifest attribute and IS NOT a top-level
|
||||
// document, or an error occurred during the cache selection
|
||||
// algorithm.
|
||||
CACHE_SELECTION_NONE = 0,
|
||||
|
||||
// The offline cache manifest must be updated.
|
||||
CACHE_SELECTION_UPDATE = 1,
|
||||
|
||||
// The document was loaded from a cache other than the one it
|
||||
// specifies via its manifest attribute and IS a top-level
|
||||
// document. In this case, the document is marked as foreign in
|
||||
// the cache it was loaded from and must be reloaded from the
|
||||
// correct cache (the one it specifies).
|
||||
CACHE_SELECTION_RELOAD = 2
|
||||
};
|
||||
|
||||
nsresult Init(nsIDocument* aDoc, nsIURI* aURI,
|
||||
nsISupports* aContainer, nsIChannel* aChannel);
|
||||
|
||||
|
@ -171,6 +191,60 @@ protected:
|
|||
|
||||
void PrefetchHref(const nsAString &aHref, nsIContent *aSource,
|
||||
PRBool aExplicit);
|
||||
|
||||
// Gets the cache key (used to identify items in a cache) of the channel.
|
||||
nsresult GetChannelCacheKey(nsIChannel* aChannel, nsACString& aCacheKey);
|
||||
|
||||
// There is an offline cache manifest attribute specified and the
|
||||
// document is allowed to use the offline cache. Process the cache
|
||||
// selection algorithm for this document and the manifest. Result is
|
||||
// an action that must be taken on the manifest, see
|
||||
// CacheSelectionAction enum above.
|
||||
//
|
||||
// @param aLoadApplicationCache
|
||||
// The application cache from which the load originated, if
|
||||
// any.
|
||||
// @param aManifestURI
|
||||
// The manifest URI listed in the document.
|
||||
// @param aIsTopDocument
|
||||
// TRUE if this is a toplevel document.
|
||||
// @param aFetchedWithHTTPGetOrEquiv
|
||||
// TRUE if this was fetched using the HTTP GET method.
|
||||
// @param aAction
|
||||
// Out parameter, returns the action that should be performed
|
||||
// by the calling function.
|
||||
nsresult SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache,
|
||||
nsIURI *aManifestURI,
|
||||
PRBool aIsTopDocument,
|
||||
PRBool aFetchedWithHTTPGetOrEquiv,
|
||||
CacheSelectionAction *aAction);
|
||||
|
||||
// There is no offline cache manifest attribute specified. Process
|
||||
// the cache selection algorithm w/o the manifest. Result is an
|
||||
// action that must be taken, see CacheSelectionAction enum
|
||||
// above. In case the offline cache manifest has to be updated the
|
||||
// manifest URI is returned in aManifestURI.
|
||||
//
|
||||
// @param aLoadApplicationCache
|
||||
// The application cache from which the load originated, if
|
||||
// any.
|
||||
// @param aIsTopDocument
|
||||
// TRUE if this is a toplevel document.
|
||||
// @param aManifestURI
|
||||
// Out parameter, returns the manifest URI of the cache that
|
||||
// was selected.
|
||||
// @param aAction
|
||||
// Out parameter, returns the action that should be performed
|
||||
// by the calling function.
|
||||
nsresult SelectDocAppCacheNoManifest(nsIApplicationCache *aLoadApplicationCache,
|
||||
PRBool aIsTopDocument,
|
||||
nsIURI **aManifestURI,
|
||||
CacheSelectionAction *aAction);
|
||||
|
||||
// Searches for the offline cache manifest attribute and calls one
|
||||
// of the above defined methods to select the document's application
|
||||
// cache, let it be associated with the document and eventually
|
||||
// schedule the cache update process.
|
||||
void ProcessOfflineManifest(nsIContent *aElement);
|
||||
|
||||
// Tries to scroll to the URI's named anchor. Once we've successfully
|
||||
|
|
|
@ -154,6 +154,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
|
|||
#include "nsAttrValue.h"
|
||||
#include "nsReferencedElement.h"
|
||||
#include "nsIUGenCategory.h"
|
||||
#include "nsIDragService.h"
|
||||
|
||||
#ifdef IBMBIDI
|
||||
#include "nsIBidiKeyboard.h"
|
||||
|
@ -417,13 +418,16 @@ nsContentUtils::InitializeEventTable() {
|
|||
{ &nsGkAtoms::oncommand, { NS_XUL_COMMAND, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::onbroadcast, { NS_XUL_BROADCAST, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::oncommandupdate, { NS_XUL_COMMAND_UPDATE, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondragenter, { NS_DRAGDROP_ENTER, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondragover, { NS_DRAGDROP_OVER_SYNTH, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondragenter, { NS_DRAGDROP_ENTER, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondragover, { NS_DRAGDROP_OVER_SYNTH, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondragexit, { NS_DRAGDROP_EXIT_SYNTH, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondragdrop, { NS_DRAGDROP_DROP, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondragdrop, { NS_DRAGDROP_DRAGDROP, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondraggesture, { NS_DRAGDROP_GESTURE, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondrag, { NS_DRAGDROP_DRAG, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondragend, { NS_DRAGDROP_END, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::ondrag, { NS_DRAGDROP_DRAG, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondragend, { NS_DRAGDROP_END, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondragstart, { NS_DRAGDROP_START, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondragleave, { NS_DRAGDROP_LEAVE_SYNTH, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::ondrop, { NS_DRAGDROP_DROP, EventNameType_HTMLXUL }},
|
||||
{ &nsGkAtoms::onoverflow, { NS_SCROLLPORT_OVERFLOW, EventNameType_XUL }},
|
||||
{ &nsGkAtoms::onunderflow, { NS_SCROLLPORT_UNDERFLOW, EventNameType_XUL }}
|
||||
#ifdef MOZ_SVG
|
||||
|
@ -804,41 +808,17 @@ nsContentUtils::GetOfflineAppManifest(nsIDOMWindow *aWindow, nsIURI **aURI)
|
|||
PRBool
|
||||
nsContentUtils::OfflineAppAllowed(nsIURI *aURI)
|
||||
{
|
||||
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(aURI);
|
||||
if (!innerURI)
|
||||
return PR_FALSE;
|
||||
return NS_OfflineAppAllowed(aURI, sPrefBranch);
|
||||
}
|
||||
|
||||
// only http and https applications can use offline APIs.
|
||||
PRBool match;
|
||||
nsresult rv = innerURI->SchemeIs("http", &match);
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
/* static */
|
||||
PRBool
|
||||
nsContentUtils::OfflineAppAllowed(nsIPrincipal *aPrincipal)
|
||||
{
|
||||
nsCOMPtr<nsIURI> codebaseURI;
|
||||
aPrincipal->GetURI(getter_AddRefs(codebaseURI));
|
||||
|
||||
if (!match) {
|
||||
rv = innerURI->SchemeIs("https", &match);
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
if (!match) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPermissionManager> permissionManager =
|
||||
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
|
||||
if (!permissionManager) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRUint32 perm;
|
||||
permissionManager->TestExactPermission(innerURI, "offline-app", &perm);
|
||||
|
||||
if (perm == nsIPermissionManager::UNKNOWN_ACTION) {
|
||||
return GetBoolPref("offline-apps.allow_by_default");
|
||||
}
|
||||
|
||||
if (perm == nsIPermissionManager::DENY_ACTION) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
return OfflineAppAllowed(codebaseURI);
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -4307,6 +4287,18 @@ nsContentUtils::HidePopupsInDocument(nsIDocument* aDocument)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* static */
|
||||
already_AddRefed<nsIDragSession>
|
||||
nsContentUtils::GetDragSession()
|
||||
{
|
||||
nsIDragSession* dragSession = nsnull;
|
||||
nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||
if (dragService)
|
||||
dragService->GetCurrentSession(&dragSession);
|
||||
return dragSession;
|
||||
}
|
||||
|
||||
/* static */
|
||||
PRBool
|
||||
nsContentUtils::URIIsLocalFile(nsIURI *aURI)
|
||||
|
|
|
@ -1143,6 +1143,7 @@ NS_INTERFACE_TABLE_HEAD(nsDocument)
|
|||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIRadioGroupContainer)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIMutationObserver)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMNodeSelector)
|
||||
NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIApplicationCacheContainer)
|
||||
// nsNodeSH::PreCreate() depends on the identity pointer being the
|
||||
// same as nsINode (which nsIDocument inherits), so if you change
|
||||
// the below line, make sure nsNodeSH::PreCreate() still does the
|
||||
|
@ -1953,6 +1954,22 @@ nsDocument::SetPrincipal(nsIPrincipal *aNewPrincipal)
|
|||
mNodeInfoManager->SetDocumentPrincipal(aNewPrincipal);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetApplicationCache(nsIApplicationCache **aApplicationCache)
|
||||
{
|
||||
NS_IF_ADDREF(*aApplicationCache = mApplicationCache);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::SetApplicationCache(nsIApplicationCache *aApplicationCache)
|
||||
{
|
||||
mApplicationCache = aApplicationCache;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetContentType(nsAString& aContentType)
|
||||
{
|
||||
|
@ -3025,6 +3042,7 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
|
|||
mScriptGlobalObject = aScriptGlobalObject;
|
||||
|
||||
if (aScriptGlobalObject) {
|
||||
mScriptObject = nsnull;
|
||||
mHasHadScriptHandlingObject = PR_TRUE;
|
||||
// Go back to using the docshell for the layout history state
|
||||
mLayoutHistoryState = nsnull;
|
||||
|
@ -4462,6 +4480,7 @@ void
|
|||
nsDocument::DoNotifyPossibleTitleChange()
|
||||
{
|
||||
mPendingTitleChangeEvent.Forget();
|
||||
mHaveFiredTitleChange = PR_TRUE;
|
||||
|
||||
nsAutoString title;
|
||||
GetTitle(title);
|
||||
|
|
|
@ -93,6 +93,8 @@
|
|||
#include "nsCycleCollectionParticipant.h"
|
||||
#include "nsContentList.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIApplicationCache.h"
|
||||
#include "nsIApplicationCacheContainer.h"
|
||||
|
||||
// Put these here so all document impls get them automatically
|
||||
#include "nsHTMLStyleSheet.h"
|
||||
|
@ -408,6 +410,7 @@ class nsDocument : public nsIDocument,
|
|||
public nsIScriptObjectPrincipal,
|
||||
public nsIRadioGroupContainer,
|
||||
public nsIDOMNodeSelector,
|
||||
public nsIApplicationCacheContainer,
|
||||
public nsStubMutationObserver
|
||||
{
|
||||
public:
|
||||
|
@ -561,6 +564,12 @@ public:
|
|||
GetScriptHandlingObject(PRBool& aHasHadScriptHandlingObject) const;
|
||||
virtual void SetScriptHandlingObject(nsIScriptGlobalObject* aScriptObject);
|
||||
|
||||
virtual void ClearScriptHandlingObject()
|
||||
{
|
||||
mScriptObject = nsnull;
|
||||
mHasHadScriptHandlingObject = PR_TRUE;
|
||||
}
|
||||
|
||||
virtual nsIScriptGlobalObject* GetScopeObject();
|
||||
|
||||
/**
|
||||
|
@ -752,6 +761,9 @@ public:
|
|||
// nsIScriptObjectPrincipal
|
||||
virtual nsIPrincipal* GetPrincipal();
|
||||
|
||||
// nsIApplicationCacheContainer
|
||||
NS_DECL_NSIAPPLICATIONCACHECONTAINER
|
||||
|
||||
virtual nsresult Init();
|
||||
|
||||
virtual nsresult AddXMLEventsContent(nsIContent * aXMLEventsElement);
|
||||
|
@ -1021,6 +1033,10 @@ protected:
|
|||
// Our update nesting level
|
||||
PRUint32 mUpdateNestLevel;
|
||||
|
||||
// The application cache that this document is associated with, if
|
||||
// any. This can change during the lifetime of the document.
|
||||
nsCOMPtr<nsIApplicationCache> mApplicationCache;
|
||||
|
||||
private:
|
||||
friend class nsUnblockOnloadEvent;
|
||||
|
||||
|
|
|
@ -2791,9 +2791,11 @@ nsGenericElement::doPreHandleEvent(nsIContent* aContent,
|
|||
PRBool isAnonForEvents = aContent->IsRootOfNativeAnonymousSubtree();
|
||||
if ((aVisitor.mEvent->message == NS_MOUSE_ENTER_SYNTH ||
|
||||
aVisitor.mEvent->message == NS_MOUSE_EXIT_SYNTH) &&
|
||||
// This is an optimization - try to stop event propagation when
|
||||
// event has just possibly been retargeted.
|
||||
static_cast<nsISupports*>(aContent) == aVisitor.mEvent->target) {
|
||||
// Check if we should stop event propagation when event has just been
|
||||
// dispatched or when we're about to propagate from
|
||||
// native anonymous subtree.
|
||||
((static_cast<nsISupports*>(aContent) == aVisitor.mEvent->originalTarget &&
|
||||
!aContent->IsInNativeAnonymousSubtree()) || isAnonForEvents)) {
|
||||
nsCOMPtr<nsIContent> relatedTarget =
|
||||
do_QueryInterface(static_cast<nsMouseEvent*>
|
||||
(aVisitor.mEvent)->relatedTarget);
|
||||
|
@ -2823,19 +2825,37 @@ nsGenericElement::doPreHandleEvent(nsIContent* aContent,
|
|||
anonOwnerRelated = FindNativeAnonymousSubtreeOwner(anonOwnerRelated);
|
||||
}
|
||||
if (anonOwner == anonOwnerRelated) {
|
||||
nsCOMPtr<nsIContent> target =
|
||||
#ifdef DEBUG_smaug
|
||||
nsCOMPtr<nsIContent> originalTarget =
|
||||
do_QueryInterface(aVisitor.mEvent->originalTarget);
|
||||
// Because XBL and native anon content both do event re-targeting,
|
||||
// static_cast<nsISupports*>(aContent) == aVisitor.mEvent->target
|
||||
// optimization may not always work. So be paranoid and make
|
||||
// sure we never stop event propagation when we shouldn't!
|
||||
if (relatedTarget->FindFirstNonNativeAnonymous() ==
|
||||
target->FindFirstNonNativeAnonymous()) {
|
||||
aVisitor.mParentTarget = nsnull;
|
||||
// Event should not propagate to non-anon content.
|
||||
aVisitor.mCanHandle = isAnonForEvents;
|
||||
return NS_OK;
|
||||
nsAutoString ot, ct, rt;
|
||||
if (originalTarget) {
|
||||
originalTarget->Tag()->ToString(ot);
|
||||
}
|
||||
aContent->Tag()->ToString(ct);
|
||||
relatedTarget->Tag()->ToString(rt);
|
||||
printf("Stopping %s propagation:"
|
||||
"\n\toriginalTarget=%s \n\tcurrentTarget=%s %s"
|
||||
"\n\trelatedTarget=%s %s \n%s",
|
||||
(aVisitor.mEvent->message == NS_MOUSE_ENTER_SYNTH)
|
||||
? "mouseover" : "mouseout",
|
||||
NS_ConvertUTF16toUTF8(ot).get(),
|
||||
NS_ConvertUTF16toUTF8(ct).get(),
|
||||
isAnonForEvents
|
||||
? "(is native anonymous)"
|
||||
: (aContent->IsInNativeAnonymousSubtree()
|
||||
? "(is in native anonymous subtree)" : ""),
|
||||
NS_ConvertUTF16toUTF8(rt).get(),
|
||||
relatedTarget->IsInNativeAnonymousSubtree()
|
||||
? "(is in native anonymous subtree)" : "",
|
||||
(originalTarget && relatedTarget->FindFirstNonNativeAnonymous() ==
|
||||
originalTarget->FindFirstNonNativeAnonymous())
|
||||
? "" : "Wrong event propagation!?!\n");
|
||||
#endif
|
||||
aVisitor.mParentTarget = nsnull;
|
||||
// Event should not propagate to non-anon content.
|
||||
aVisitor.mCanHandle = isAnonForEvents;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4131,9 +4151,9 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGenericElement)
|
|||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsGenericElement, nsIContent)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS_WITH_DESTROY(nsGenericElement,
|
||||
nsIContent,
|
||||
nsNodeUtils::LastRelease(this))
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS_WITH_DESTROY(nsGenericElement,
|
||||
nsIContent,
|
||||
nsNodeUtils::LastRelease(this))
|
||||
|
||||
nsresult
|
||||
nsGenericElement::PostQueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
|
|
|
@ -404,8 +404,6 @@ public:
|
|||
|
||||
friend class nsNSElementTearoff;
|
||||
|
||||
friend class nsNSElementTearoff;
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
||||
/**
|
||||
|
|
|
@ -311,10 +311,14 @@ GK_ATOM(dragend, "dragend")
|
|||
GK_ATOM(dragenter, "dragenter")
|
||||
GK_ATOM(dragevent, "dragevent")
|
||||
GK_ATOM(dragexit, "dragexit")
|
||||
GK_ATOM(draggable, "draggable")
|
||||
GK_ATOM(draggesture, "draggesture")
|
||||
GK_ATOM(dragging, "dragging")
|
||||
GK_ATOM(dragleave, "dragleave")
|
||||
GK_ATOM(dragover, "dragover")
|
||||
GK_ATOM(dragSession, "dragSession")
|
||||
GK_ATOM(dragstart, "dragstart")
|
||||
GK_ATOM(drop, "drop")
|
||||
GK_ATOM(dropAfter, "dropAfter")
|
||||
GK_ATOM(dropBefore, "dropBefore")
|
||||
GK_ATOM(dropOn, "dropOn")
|
||||
|
|
|
@ -398,7 +398,7 @@ nsRange::ComparePoint(nsIDOMNode* aParent, PRInt32 aOffset, PRInt16* aResult)
|
|||
*aResult = cmp;
|
||||
}
|
||||
else if (nsContentUtils::ComparePoints(mEndParent, mEndOffset,
|
||||
parent, aOffset) == -1) {
|
||||
parent, aOffset) <= 0) {
|
||||
*aResult = 1;
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -885,15 +885,9 @@ nsXMLHttpRequest::ConvertBodyToText(nsAString& aOutBuffer)
|
|||
nsresult rv = NS_OK;
|
||||
|
||||
nsCAutoString dataCharset;
|
||||
nsCOMPtr<nsIDOM3Document> document(do_QueryInterface(mDocument));
|
||||
nsCOMPtr<nsIDocument> document(do_QueryInterface(mDocument));
|
||||
if (document) {
|
||||
nsAutoString inputEncoding;
|
||||
document->GetInputEncoding(inputEncoding);
|
||||
if (DOMStringIsNull(inputEncoding)) {
|
||||
dataCharset.AssignLiteral("UTF-8");
|
||||
} else {
|
||||
CopyUTF16toUTF8(inputEncoding, dataCharset);
|
||||
}
|
||||
dataCharset = document->GetDocumentCharacterSet();
|
||||
} else {
|
||||
if (NS_FAILED(DetectCharset(dataCharset)) || dataCharset.IsEmpty()) {
|
||||
// MS documentation states UTF-8 is default for responseText
|
||||
|
@ -1064,6 +1058,8 @@ nsXMLHttpRequest::Abort()
|
|||
ChangeState(XML_HTTP_REQUEST_UNINITIALIZED, PR_FALSE); // IE seems to do it
|
||||
}
|
||||
|
||||
mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1938,9 +1934,15 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
|
|||
nsCOMPtr<nsIDOMSerializer> serializer(do_CreateInstance(NS_XMLSERIALIZER_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIDocument> baseDoc(do_QueryInterface(doc));
|
||||
if (baseDoc) {
|
||||
charset = baseDoc->GetDocumentCharacterSet();
|
||||
nsCOMPtr<nsIDOM3Document> dom3doc(do_QueryInterface(doc));
|
||||
if (dom3doc) {
|
||||
nsAutoString inputEncoding;
|
||||
dom3doc->GetInputEncoding(inputEncoding);
|
||||
if (DOMStringIsNull(inputEncoding)) {
|
||||
charset.AssignLiteral("UTF-8");
|
||||
} else {
|
||||
CopyUTF16toUTF8(inputEncoding, charset);
|
||||
}
|
||||
}
|
||||
|
||||
// Serialize to a stream so that the encoding used will
|
||||
|
@ -2342,8 +2344,6 @@ nsXMLHttpRequest::Abort(nsIDOMEvent* aEvent)
|
|||
{
|
||||
Abort();
|
||||
|
||||
mState &= ~XML_HTTP_REQUEST_SYNCLOOPING;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -184,12 +184,14 @@ _TEST_FILES = test_bug5141.html \
|
|||
file_bug428847-1.xhtml \
|
||||
file_bug428847-2.xhtml \
|
||||
test_bug425201.html \
|
||||
test_bug431701.html \
|
||||
test_bug431833.html \
|
||||
test_bug435425.html \
|
||||
bug435425.sjs \
|
||||
bug435425_redirect.sjs \
|
||||
test_bug438519.html \
|
||||
test_bug444722.html \
|
||||
test_bug451376.html \
|
||||
test_text_replaceWholeText.html \
|
||||
test_text_wholeText.html \
|
||||
wholeTexty-helper.xml \
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=431701
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 431701</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=431701">Mozilla Bug 431701</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<iframe id="one"></iframe>
|
||||
<iframe id="two"></iframe>
|
||||
<iframe id="three"></iframe>
|
||||
<iframe id="four"></iframe>
|
||||
<iframe id="five"></iframe>
|
||||
<iframe id="six"></iframe>
|
||||
<iframe id="seven"></iframe>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 431701 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var docSources = [
|
||||
"data:text/html,<html></html>",
|
||||
"data:text/html;charset=UTF-8,<html></html>",
|
||||
"data:text/html;charset=ISO-8859-1,<html></html>",
|
||||
"data:text/xml,<html></html>",
|
||||
"data:text/xml,<?xml version='1.0'?><html></html>",
|
||||
"data:text/xml,<?xml version='1.0' encoding='UTF-8'?><html></html>",
|
||||
"data:text/xml,<?xml version='1.0' encoding='ISO-8859-1'?><html></html>",
|
||||
];
|
||||
|
||||
for (var i = 0; i < docSources.length; ++i) {
|
||||
document.getElementsByTagName("iframe")[i].src = docSources[i];
|
||||
}
|
||||
|
||||
function frameDoc(id) {
|
||||
return function() { return $(id).contentDocument; };
|
||||
}
|
||||
|
||||
function createDoc() {
|
||||
return document.implementation.createDocument('', 'html', null);
|
||||
}
|
||||
|
||||
function xhrDoc(idx) {
|
||||
return function() {
|
||||
// Defy same-origin restrictions!
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", docSources[idx], false);
|
||||
xhr.send();
|
||||
return xhr.responseXML;
|
||||
};
|
||||
}
|
||||
|
||||
// Each row has the document getter function, then the characterSet,
|
||||
// inputEncoding, xmlEncoding expected for that document.
|
||||
|
||||
var tests = [
|
||||
[ frameDoc("one"), "ISO-8859-1", "ISO-8859-1", null ],
|
||||
[ frameDoc("two"), "UTF-8", "UTF-8", null ],
|
||||
[ frameDoc("three"), "ISO-8859-1", "ISO-8859-1", null ],
|
||||
[ frameDoc("four"), "UTF-8", "UTF-8", null ],
|
||||
[ frameDoc("five"), "UTF-8", "UTF-8", null ],
|
||||
[ frameDoc("six"), "UTF-8", "UTF-8", "UTF-8"],
|
||||
[ frameDoc("seven"), "ISO-8859-1", "ISO-8859-1", "ISO-8859-1" ],
|
||||
[ createDoc, "UTF-8", null, null ],
|
||||
[ xhrDoc(4), "UTF-8", "UTF-8", null ],
|
||||
[ xhrDoc(5), "UTF-8", "UTF-8", "UTF-8" ],
|
||||
[ xhrDoc(6), "ISO-8859-1", "ISO-8859-1", "ISO-8859-1" ],
|
||||
];
|
||||
|
||||
function doTest(idx) {
|
||||
var [docGetter, expectedCharacterSet,
|
||||
expectedInputEncoding, expectedXMLEncoding] = tests[idx];
|
||||
var doc = docGetter();
|
||||
|
||||
// Have to be careful here to catch null vs ""
|
||||
is(doc.characterSet, expectedCharacterSet, "Test " + idx + " characterSet");
|
||||
is(doc.inputEncoding, expectedInputEncoding,
|
||||
"Test " + idx + " inputEncoding");
|
||||
is(doc.xmlEncoding, expectedXMLEncoding, "Test " + idx + " xmlEncoding");
|
||||
}
|
||||
|
||||
addLoadEvent(function() {
|
||||
// sanity check
|
||||
isnot("", null, "Shouldn't be equal!");
|
||||
|
||||
for (var i = 0; i < tests.length; ++i) {
|
||||
doTest(i);
|
||||
}
|
||||
|
||||
// Now check what xhr does
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", document.location.href);
|
||||
xhr.send(createDoc());
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
is(xhr.channel.QueryInterface(Components.interfaces.nsIHttpChannel)
|
||||
.getRequestHeader("Content-Type"),
|
||||
"application/xml; charset=UTF-8", "Testing correct type on the wire");
|
||||
xhr.abort();
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -35,7 +35,8 @@ function logEvent(evt) {
|
|||
}
|
||||
ok(i != currentEvents.length, "Extra or wrong event?");
|
||||
is(evt.type, currentEvents[i].type, "Wrong event!")
|
||||
ok(evt.target instanceof currentEvents[i].target, "Wrong event target [" + evt.type + "]!");
|
||||
ok(evt.target instanceof currentEvents[i].target,
|
||||
"Wrong event target [" + evt.target + "," + evt.type + "]!");
|
||||
// If we handled non-optional event, remove all optional events before the
|
||||
// handled event and then the non-optional event from the list.
|
||||
if (!currentEvents[i].optional) {
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=451376
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 451376</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
|
||||
<body onload="doTest()">
|
||||
<a target="_blank"
|
||||
title="IAccessibleText::attributes provides incorrect info after a mis-spelled word"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=451376">Mozilla Bug 451376</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display:none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
|
||||
<div id="area"><button>btn1</button>text<button>btn2</button></div>
|
||||
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function testRange(aRangeID,
|
||||
aStartNode, aStartOffset,
|
||||
aEndNode, aEndOffset,
|
||||
aBeforeRangeNode, aBeforeRangeOffset,
|
||||
aInRangeNode, aInRangeOffset,
|
||||
aAfterRangeNode, aAfterRangeOffset)
|
||||
{
|
||||
var range = document.createRange().
|
||||
QueryInterface(Components.interfaces.nsIDOMNSRange);
|
||||
|
||||
range.setStart(aStartNode, aStartOffset);
|
||||
range.setEnd(aEndNode, aEndOffset);
|
||||
|
||||
if (aBeforeRangeNode)
|
||||
is(range.comparePoint(aBeforeRangeNode, aBeforeRangeOffset), -1,
|
||||
"Wrong result for the point before the range '" + aRangeID + "'");
|
||||
if (aInRangeNode)
|
||||
is(range.comparePoint(aInRangeNode, aInRangeOffset), 0,
|
||||
"Wrong result for the point inside the range '" + aRangeID + "'");
|
||||
if (aAfterRangeNode)
|
||||
is(range.comparePoint(aAfterRangeNode, aAfterRangeOffset), 1,
|
||||
"Wrong result for the point after the range '" + aRangeID + "'");
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var area = document.getElementById("area");
|
||||
var btn1 = area.firstChild;
|
||||
var text = btn1.nextSibling;
|
||||
var btn2 = area.lastChild;
|
||||
|
||||
testRange("range1", area, 0, area, 1,
|
||||
null, 0,
|
||||
area, 0,
|
||||
area, 1);
|
||||
|
||||
testRange("range2", text, 2, text, 4,
|
||||
text, 0,
|
||||
text, 3,
|
||||
text, 4);
|
||||
|
||||
testRange("range3", text, 4, area, 2,
|
||||
text, 0,
|
||||
text, 4,
|
||||
area, 2);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -76,6 +76,7 @@ function testDynamics() {
|
|||
testDynamic("html3", "Hello", "Appending HTML <title> element to root element", function(doc){
|
||||
var t = doc.createElement("title"); t.textContent = "Hello"; doc.documentElement.appendChild(t);
|
||||
});
|
||||
|
||||
testDynamic("xhtml3", "Hello", "Setting 'title' clears existing <title> contents", function(doc){
|
||||
doc.title = "Hello";
|
||||
}, function(doc, desc) {
|
||||
|
@ -133,26 +134,8 @@ function testDynamics() {
|
|||
setTimeout(end, 500);
|
||||
}
|
||||
|
||||
function acid() {
|
||||
var doctype = document.implementation.createDocumentType("html", "-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
|
||||
is(doctype.ownerDocument, null, "doctype's ownerDocument was wrong after creation");
|
||||
var doc = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", doctype);
|
||||
doc.documentElement.appendChild(doc.createElementNS("http://www.w3.org/1999/xhtml", "head"));
|
||||
doc.documentElement.appendChild(doc.createElementNS("http://www.w3.org/1999/xhtml", "body"));
|
||||
var t = doc.createElementNS("http://www.w3.org/1999/xhtml", "title");
|
||||
doc.documentElement.firstChild.appendChild(t);
|
||||
// ok we have a conforming XHTML1 doc in |doc| now.
|
||||
is(doctype.ownerDocument, doc, "doctype's ownerDocument didn't change when it was assigned to another document");
|
||||
is(doc.title, "", "document had unexpected title");
|
||||
t.textContent = "Sparrow";
|
||||
is(doc.title, "Sparrow", "document.title did not update dynamically");
|
||||
doc.body.appendChild(doc.createElementNS("http://www.w3.org/1999/xhtml", "form"));
|
||||
is(doc.forms.length, 1, "document.forms not updated after inserting a form");
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
testStatics();
|
||||
// acid();
|
||||
testDynamics();
|
||||
}
|
||||
|
||||
|
|
|
@ -3146,6 +3146,13 @@ nsCanvasRenderingContext2D::GetImageData()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
#include "jstypes.h"
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_ArrayToJSUint8Buffer(JSContext *cx, JSObject *obj, jsuint offset, jsuint count,
|
||||
JSUint8 *dest);
|
||||
}
|
||||
|
||||
// void putImageData (in ImageData d, in float x, in float y);
|
||||
NS_IMETHODIMP
|
||||
nsCanvasRenderingContext2D::PutImageData()
|
||||
|
@ -3216,49 +3223,75 @@ nsCanvasRenderingContext2D::PutImageData()
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
PRUint8 *imgPtr = imageBuffer.get();
|
||||
jsval vr, vg, vb, va;
|
||||
PRUint8 ir, ig, ib, ia;
|
||||
for (int32 j = 0; j < h; j++) {
|
||||
for (int32 i = 0; i < w; i++) {
|
||||
if (!JS_GetElement(ctx, dataArray, (j*w*4) + i*4 + 0, &vr) ||
|
||||
!JS_GetElement(ctx, dataArray, (j*w*4) + i*4 + 1, &vg) ||
|
||||
!JS_GetElement(ctx, dataArray, (j*w*4) + i*4 + 2, &vb) ||
|
||||
!JS_GetElement(ctx, dataArray, (j*w*4) + i*4 + 3, &va))
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
if (JSVAL_IS_INT(vr)) ir = (PRUint8) JSVAL_TO_INT(vr);
|
||||
else if (JSVAL_IS_DOUBLE(vr)) ir = (PRUint8) (*JSVAL_TO_DOUBLE(vr));
|
||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
JSBool ok = js_ArrayToJSUint8Buffer(ctx, dataArray, 0, w*h*4, imageBuffer);
|
||||
|
||||
// no fast path? go slow.
|
||||
if (!ok) {
|
||||
jsval vr, vg, vb, va;
|
||||
PRUint8 ir, ig, ib, ia;
|
||||
for (int32 j = 0; j < h; j++) {
|
||||
for (int32 i = 0; i < w; i++) {
|
||||
if (!JS_GetElement(ctx, dataArray, (j*w*4) + i*4 + 0, &vr) ||
|
||||
!JS_GetElement(ctx, dataArray, (j*w*4) + i*4 + 1, &vg) ||
|
||||
!JS_GetElement(ctx, dataArray, (j*w*4) + i*4 + 2, &vb) ||
|
||||
!JS_GetElement(ctx, dataArray, (j*w*4) + i*4 + 3, &va))
|
||||
return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
if (JSVAL_IS_INT(vg)) ig = (PRUint8) JSVAL_TO_INT(vg);
|
||||
else if (JSVAL_IS_DOUBLE(vg)) ig = (PRUint8) (*JSVAL_TO_DOUBLE(vg));
|
||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
if (JSVAL_IS_INT(vr)) ir = (PRUint8) JSVAL_TO_INT(vr);
|
||||
else if (JSVAL_IS_DOUBLE(vr)) ir = (PRUint8) (*JSVAL_TO_DOUBLE(vr));
|
||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
if (JSVAL_IS_INT(vb)) ib = (PRUint8) JSVAL_TO_INT(vb);
|
||||
else if (JSVAL_IS_DOUBLE(vb)) ib = (PRUint8) (*JSVAL_TO_DOUBLE(vb));
|
||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
if (JSVAL_IS_INT(vg)) ig = (PRUint8) JSVAL_TO_INT(vg);
|
||||
else if (JSVAL_IS_DOUBLE(vg)) ig = (PRUint8) (*JSVAL_TO_DOUBLE(vg));
|
||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
if (JSVAL_IS_INT(va)) ia = (PRUint8) JSVAL_TO_INT(va);
|
||||
else if (JSVAL_IS_DOUBLE(va)) ia = (PRUint8) (*JSVAL_TO_DOUBLE(va));
|
||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
if (JSVAL_IS_INT(vb)) ib = (PRUint8) JSVAL_TO_INT(vb);
|
||||
else if (JSVAL_IS_DOUBLE(vb)) ib = (PRUint8) (*JSVAL_TO_DOUBLE(vb));
|
||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
// Convert to premultiplied color (losslessly if the input came from getImageData)
|
||||
ir = (ir*ia + 254) / 255;
|
||||
ig = (ig*ia + 254) / 255;
|
||||
ib = (ib*ia + 254) / 255;
|
||||
if (JSVAL_IS_INT(va)) ia = (PRUint8) JSVAL_TO_INT(va);
|
||||
else if (JSVAL_IS_DOUBLE(va)) ia = (PRUint8) (*JSVAL_TO_DOUBLE(va));
|
||||
else return NS_ERROR_DOM_SYNTAX_ERR;
|
||||
|
||||
// Convert to premultiplied color (losslessly if the input came from getImageData)
|
||||
ir = (ir*ia + 254) / 255;
|
||||
ig = (ig*ia + 254) / 255;
|
||||
ib = (ib*ia + 254) / 255;
|
||||
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
*imgPtr++ = ib;
|
||||
*imgPtr++ = ig;
|
||||
*imgPtr++ = ir;
|
||||
*imgPtr++ = ia;
|
||||
*imgPtr++ = ib;
|
||||
*imgPtr++ = ig;
|
||||
*imgPtr++ = ir;
|
||||
*imgPtr++ = ia;
|
||||
#else
|
||||
*imgPtr++ = ia;
|
||||
*imgPtr++ = ir;
|
||||
*imgPtr++ = ig;
|
||||
*imgPtr++ = ib;
|
||||
*imgPtr++ = ia;
|
||||
*imgPtr++ = ir;
|
||||
*imgPtr++ = ig;
|
||||
*imgPtr++ = ib;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Walk through and premultiply and swap rgba */
|
||||
/* XXX SSE me */
|
||||
PRUint8 ir, ig, ib, ia;
|
||||
PRUint8 *ptr = imgPtr;
|
||||
for (int32 i = 0; i < w*h; i++) {
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
ir = ptr[0];
|
||||
ig = ptr[1];
|
||||
ib = ptr[2];
|
||||
ia = ptr[3];
|
||||
ptr[0] = (ib*ia + 254) / 255;
|
||||
ptr[1] = (ig*ia + 254) / 255;
|
||||
ptr[2] = (ir*ia + 254) / 255;
|
||||
#else
|
||||
ptr[0] = (ptr[0]*ptr[3] + 254) / 255;
|
||||
ptr[1] = (ptr[1]*ptr[3] + 254) / 255;
|
||||
ptr[2] = (ptr[2]*ptr[3] + 254) / 255;
|
||||
#endif
|
||||
ptr += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,8 @@ NS_NewDOMMouseEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContex
|
|||
nsresult
|
||||
NS_NewDOMMouseScrollEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsInputEvent *aEvent);
|
||||
nsresult
|
||||
NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsDragEvent *aEvent);
|
||||
nsresult
|
||||
NS_NewDOMKeyboardEvent(nsIDOMEvent** aInstancePtrResult, nsPresContext* aPresContext, class nsKeyEvent *aEvent);
|
||||
nsresult
|
||||
NS_NewDOMMutationEvent(nsIDOMEvent** aResult, nsPresContext* aPresContext, class nsMutationEvent* aEvent);
|
||||
|
|
|
@ -76,6 +76,7 @@ CPPSRCS = \
|
|||
nsDOMTextEvent.cpp \
|
||||
nsDOMMouseEvent.cpp \
|
||||
nsDOMMouseScrollEvent.cpp \
|
||||
nsDOMDragEvent.cpp \
|
||||
nsDOMMutationEvent.cpp \
|
||||
nsDOMPopupBlockedEvent.cpp \
|
||||
nsDOMBeforeUnloadEvent.cpp \
|
||||
|
@ -92,6 +93,7 @@ CPPSRCS = \
|
|||
nsIMEStateManager.cpp \
|
||||
nsQueryContentEventHandler.cpp \
|
||||
nsDOMProgressEvent.cpp \
|
||||
nsDOMDataTransfer.cpp \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
|
|
|
@ -0,0 +1,768 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Neil Deakin <enndeakin@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsDOMDataTransfer.h"
|
||||
|
||||
#include "prlog.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsDOMLists.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsIDragService.h"
|
||||
#include "nsIScriptableRegion.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_2(nsDOMDataTransfer, mDragTarget, mDragImage)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMDataTransfer)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMDataTransfer)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMDataTransfer)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMDataTransfer)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMNSDataTransfer)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMDataTransfer)
|
||||
NS_INTERFACE_MAP_ENTRY_DOM_CLASSINFO(DataTransfer)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
// the size of the array
|
||||
const char nsDOMDataTransfer::sEffects[8][9] = {
|
||||
"none", "copy", "move", "copyMove", "link", "copyLink", "linkMove", "all"
|
||||
};
|
||||
|
||||
nsDOMDataTransfer::nsDOMDataTransfer()
|
||||
: mEventType(NS_DRAGDROP_START),
|
||||
mDropEffect(nsIDragService::DRAGDROP_ACTION_NONE),
|
||||
mEffectAllowed(nsIDragService::DRAGDROP_ACTION_UNINITIALIZED),
|
||||
mReadOnly(PR_FALSE),
|
||||
mIsExternal(PR_FALSE),
|
||||
mDragImageX(0),
|
||||
mDragImageY(0)
|
||||
{
|
||||
}
|
||||
|
||||
nsDOMDataTransfer::nsDOMDataTransfer(PRUint32 aEventType, PRUint32 aAction)
|
||||
: mEventType(aEventType),
|
||||
mDropEffect(nsIDragService::DRAGDROP_ACTION_NONE),
|
||||
mReadOnly(PR_TRUE),
|
||||
mIsExternal(PR_TRUE),
|
||||
mDragImageX(0),
|
||||
mDragImageY(0)
|
||||
{
|
||||
mEffectAllowed = aAction &
|
||||
(nsIDragService::DRAGDROP_ACTION_COPY |
|
||||
nsIDragService::DRAGDROP_ACTION_LINK |
|
||||
nsIDragService::DRAGDROP_ACTION_MOVE);
|
||||
|
||||
CacheExternalFormats();
|
||||
}
|
||||
|
||||
nsDOMDataTransfer::nsDOMDataTransfer(PRUint32 aEventType,
|
||||
const PRUint32 aEffectAllowed,
|
||||
PRBool aIsExternal,
|
||||
nsTArray<nsTArray<TransferItem> >& aItems,
|
||||
nsIDOMElement* aDragImage,
|
||||
PRUint32 aDragImageX,
|
||||
PRUint32 aDragImageY)
|
||||
: mEventType(aEventType),
|
||||
mDropEffect(nsIDragService::DRAGDROP_ACTION_NONE),
|
||||
mEffectAllowed(aEffectAllowed),
|
||||
mReadOnly(PR_TRUE),
|
||||
mIsExternal(aIsExternal),
|
||||
mItems(aItems),
|
||||
mDragImage(aDragImage),
|
||||
mDragImageX(aDragImageX),
|
||||
mDragImageY(aDragImageY)
|
||||
{
|
||||
// The items are copied from aItems into mItems. There is no need to copy
|
||||
// the actual data in the items as the data transfer will be read only. The
|
||||
// draggesture and dragstart events are the only times when items are
|
||||
// modifiable, but those events should have been using the first constructor
|
||||
// above.
|
||||
NS_ASSERTION(aEventType != NS_DRAGDROP_GESTURE &&
|
||||
aEventType != NS_DRAGDROP_START,
|
||||
"invalid event type for nsDOMDataTransfer constructor");
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetDropEffect(nsAString& aDropEffect)
|
||||
{
|
||||
aDropEffect.AssignASCII(sEffects[mDropEffect]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::SetDropEffect(const nsAString& aDropEffect)
|
||||
{
|
||||
// the drop effect can only be 'none', 'copy', 'move' or 'link'.
|
||||
for (PRUint32 e = 0; e <= nsIDragService::DRAGDROP_ACTION_LINK; e++) {
|
||||
if (aDropEffect.EqualsASCII(sEffects[e])) {
|
||||
// don't allow copyMove
|
||||
if (e != (nsIDragService::DRAGDROP_ACTION_COPY |
|
||||
nsIDragService::DRAGDROP_ACTION_MOVE))
|
||||
mDropEffect = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetEffectAllowed(nsAString& aEffectAllowed)
|
||||
{
|
||||
if (mEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED)
|
||||
aEffectAllowed.AssignLiteral("uninitialized");
|
||||
else
|
||||
aEffectAllowed.AssignASCII(sEffects[mEffectAllowed]);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::SetEffectAllowed(const nsAString& aEffectAllowed)
|
||||
{
|
||||
if (aEffectAllowed.EqualsLiteral("uninitialized")) {
|
||||
mEffectAllowed = nsIDragService::DRAGDROP_ACTION_UNINITIALIZED;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PR_STATIC_ASSERT(nsIDragService::DRAGDROP_ACTION_NONE == 0);
|
||||
PR_STATIC_ASSERT(nsIDragService::DRAGDROP_ACTION_COPY == 1);
|
||||
PR_STATIC_ASSERT(nsIDragService::DRAGDROP_ACTION_MOVE == 2);
|
||||
PR_STATIC_ASSERT(nsIDragService::DRAGDROP_ACTION_LINK == 4);
|
||||
|
||||
for (PRUint32 e = 0; e < NS_ARRAY_LENGTH(sEffects); e++) {
|
||||
if (aEffectAllowed.EqualsASCII(sEffects[e])) {
|
||||
mEffectAllowed = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetDropEffectInt(PRUint32* aDropEffect)
|
||||
{
|
||||
*aDropEffect = mDropEffect;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::SetDropEffectInt(PRUint32 aDropEffect)
|
||||
{
|
||||
mDropEffect = aDropEffect;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetEffectAllowedInt(PRUint32* aEffectAllowed)
|
||||
{
|
||||
*aEffectAllowed = mEffectAllowed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::SetEffectAllowedInt(PRUint32 aEffectAllowed)
|
||||
{
|
||||
mEffectAllowed = aEffectAllowed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetTypes(nsIDOMDOMStringList** aTypes)
|
||||
{
|
||||
return MozTypesAt(0, aTypes);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetData(const nsAString& aFormat, nsAString& aData)
|
||||
{
|
||||
// return an empty string if data for the format was not found
|
||||
aData.Truncate();
|
||||
|
||||
nsCOMPtr<nsIVariant> data;
|
||||
nsresult rv = MozGetDataAt(aFormat, 0, getter_AddRefs(data));
|
||||
if (rv == NS_ERROR_DOM_INDEX_SIZE_ERR)
|
||||
return NS_OK;
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (data) {
|
||||
nsAutoString stringdata;
|
||||
data->GetAsAString(stringdata);
|
||||
|
||||
// for the URL type, parse out the first URI from the list. The URIs are
|
||||
// separated by newlines
|
||||
if (aFormat.EqualsLiteral("URL")) {
|
||||
PRInt32 lastidx = 0, idx;
|
||||
PRInt32 length = stringdata.Length();
|
||||
while (lastidx < length) {
|
||||
idx = stringdata.FindChar('\n', lastidx);
|
||||
// lines beginning with # are comments
|
||||
if (stringdata[lastidx] == '#') {
|
||||
if (idx == -1)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
if (idx == -1)
|
||||
aData.Assign(Substring(stringdata, lastidx));
|
||||
else
|
||||
aData.Assign(Substring(stringdata, lastidx, idx - lastidx));
|
||||
aData = nsContentUtils::TrimWhitespace(aData, PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
lastidx = idx + 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aData = stringdata;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::SetData(const nsAString& aFormat, const nsAString& aData)
|
||||
{
|
||||
nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID);
|
||||
NS_ENSURE_TRUE(variant, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
variant->SetAsAString(aData);
|
||||
|
||||
return MozSetDataAt(aFormat, variant, 0);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::ClearData(const nsAString& aFormat)
|
||||
{
|
||||
nsresult rv = MozClearDataAt(aFormat, 0);
|
||||
return (rv == NS_ERROR_DOM_INDEX_SIZE_ERR) ? NS_OK : rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::GetMozItemCount(PRUint32* aCount)
|
||||
{
|
||||
*aCount = mItems.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::MozTypesAt(PRUint32 aIndex, nsIDOMDOMStringList** aTypes)
|
||||
{
|
||||
*aTypes = nsnull;
|
||||
|
||||
nsRefPtr<nsDOMStringList> types = new nsDOMStringList();
|
||||
NS_ENSURE_TRUE(types, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (aIndex < mItems.Length()) {
|
||||
// note that you can retrieve the types regardless of their principal
|
||||
nsTArray<TransferItem>& item = mItems[aIndex];
|
||||
for (PRUint32 i = 0; i < item.Length(); i++)
|
||||
types->Add(item[i].mFormat);
|
||||
}
|
||||
|
||||
*aTypes = types;
|
||||
NS_ADDREF(*aTypes);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::MozGetDataAt(const nsAString& aFormat,
|
||||
PRUint32 aIndex,
|
||||
nsIVariant** aData)
|
||||
{
|
||||
*aData = nsnull;
|
||||
|
||||
if (aFormat.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
if (aIndex >= mItems.Length())
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
|
||||
nsAutoString format;
|
||||
GetRealFormat(aFormat, format);
|
||||
|
||||
nsTArray<TransferItem>& item = mItems[aIndex];
|
||||
|
||||
// allow access to any data in the drop and dragdrop events, or if the
|
||||
// UniversalBrowserRead privilege is set, otherwise only allow access to
|
||||
// data from the same principal.
|
||||
nsIPrincipal* principal = nsnull;
|
||||
if (mEventType != NS_DRAGDROP_DROP && mEventType != NS_DRAGDROP_DRAGDROP &&
|
||||
!nsContentUtils::IsCallerTrustedForCapability("UniversalBrowserRead"))
|
||||
principal = GetCurrentPrincipal();
|
||||
|
||||
PRUint32 count = item.Length();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
TransferItem& formatitem = item[i];
|
||||
if (formatitem.mFormat.Equals(format)) {
|
||||
PRBool subsumes;
|
||||
if (formatitem.mPrincipal && principal &&
|
||||
(NS_FAILED(principal->Subsumes(formatitem.mPrincipal, &subsumes)) || !subsumes))
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
if (!formatitem.mData)
|
||||
FillInExternalDragData(formatitem, aIndex);
|
||||
*aData = formatitem.mData;
|
||||
NS_IF_ADDREF(*aData);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::MozSetDataAt(const nsAString& aFormat,
|
||||
nsIVariant* aData,
|
||||
PRUint32 aIndex)
|
||||
{
|
||||
NS_ENSURE_TRUE(aData, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (aFormat.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
if (mReadOnly)
|
||||
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
|
||||
|
||||
// Specifying an index less than the current length will replace an existing
|
||||
// item. Specifying an index equal to the current length will add a new item.
|
||||
if (aIndex > mItems.Length())
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
|
||||
// don't allow non-chrome to add file data
|
||||
// XXX perhaps this should also limit any non-string type as well
|
||||
if ((aFormat.EqualsLiteral("application/x-moz-file-promise") ||
|
||||
aFormat.EqualsLiteral("application/x-moz-file")) &&
|
||||
!nsContentUtils::IsCallerChrome()) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
return SetDataWithPrincipal(aFormat, aData, aIndex, GetCurrentPrincipal());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::MozClearDataAt(const nsAString& aFormat, PRUint32 aIndex)
|
||||
{
|
||||
if (mReadOnly)
|
||||
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
|
||||
|
||||
if (aIndex >= mItems.Length())
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
|
||||
nsAutoString format;
|
||||
GetRealFormat(aFormat, format);
|
||||
|
||||
nsIPrincipal* principal = GetCurrentPrincipal();
|
||||
|
||||
// if the format is empty, clear all formats
|
||||
PRBool clearall = format.IsEmpty();
|
||||
|
||||
nsTArray<TransferItem>& item = mItems[aIndex];
|
||||
// count backwards so that the count and index don't have to be adjusted
|
||||
// after removing an element
|
||||
for (PRInt32 i = item.Length() - 1; i >= 0; i--) {
|
||||
TransferItem& formatitem = item[i];
|
||||
if (clearall || formatitem.mFormat.Equals(format)) {
|
||||
// don't allow removing data that has a stronger principal
|
||||
PRBool subsumes;
|
||||
if (formatitem.mPrincipal && principal &&
|
||||
(NS_FAILED(principal->Subsumes(formatitem.mPrincipal, &subsumes)) || !subsumes))
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
item.RemoveElementAt(i);
|
||||
|
||||
// if a format was specified, break out. Otherwise, loop around until
|
||||
// all formats have been removed
|
||||
if (!clearall)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if the last format for an item is removed, remove the entire item
|
||||
if (!item.Length())
|
||||
mItems.RemoveElementAt(aIndex);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::SetDragImage(nsIDOMElement* aImage, PRInt32 aX, PRInt32 aY)
|
||||
{
|
||||
if (mReadOnly)
|
||||
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
|
||||
|
||||
mDragImage = aImage;
|
||||
mDragImageX = aX;
|
||||
mDragImageY = aY;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDataTransfer::AddElement(nsIDOMElement* aElement)
|
||||
{
|
||||
NS_ENSURE_TRUE(aElement, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (mReadOnly)
|
||||
return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
|
||||
|
||||
mDragTarget = do_QueryInterface(aElement);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDataTransfer::Clone(PRUint32 aEventType,
|
||||
nsIDOMDataTransfer** aNewDataTransfer)
|
||||
{
|
||||
nsDOMDataTransfer* newDataTransfer =
|
||||
new nsDOMDataTransfer(aEventType, mEffectAllowed, mIsExternal,
|
||||
mItems, mDragImage, mDragImageX, mDragImageY);
|
||||
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
*aNewDataTransfer = newDataTransfer;
|
||||
NS_ADDREF(*aNewDataTransfer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMDataTransfer::GetTransferables(nsISupportsArray** aArray)
|
||||
{
|
||||
*aArray = nsnull;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> transArray =
|
||||
do_CreateInstance("@mozilla.org/supports-array;1");
|
||||
if (!transArray)
|
||||
return;
|
||||
|
||||
PRBool added = PR_FALSE;
|
||||
PRUint32 count = mItems.Length();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
|
||||
nsTArray<TransferItem>& item = mItems[i];
|
||||
PRUint32 count = item.Length();
|
||||
if (!count)
|
||||
continue;
|
||||
|
||||
nsCOMPtr<nsITransferable> transferable =
|
||||
do_CreateInstance("@mozilla.org/widget/transferable;1");
|
||||
if (!transferable)
|
||||
return;
|
||||
|
||||
for (PRUint32 f = 0; f < count; f++) {
|
||||
TransferItem& formatitem = item[f];
|
||||
if (!formatitem.mData) // skip empty items
|
||||
continue;
|
||||
|
||||
PRUint32 length;
|
||||
nsCOMPtr<nsISupports> convertedData;
|
||||
if (!ConvertFromVariant(formatitem.mData, getter_AddRefs(convertedData), &length))
|
||||
continue;
|
||||
|
||||
// the underlying drag code uses text/unicode, so use that instead of text/plain
|
||||
const char* format;
|
||||
NS_ConvertUTF16toUTF8 utf8format(formatitem.mFormat);
|
||||
if (utf8format.EqualsLiteral("text/plain"))
|
||||
format = kUnicodeMime;
|
||||
else
|
||||
format = utf8format.get();
|
||||
|
||||
// if a converter is set for a format, set the converter for the
|
||||
// transferable and don't add the item
|
||||
nsCOMPtr<nsIFormatConverter> converter = do_QueryInterface(convertedData);
|
||||
if (converter) {
|
||||
transferable->AddDataFlavor(format);
|
||||
transferable->SetConverter(converter);
|
||||
continue;
|
||||
}
|
||||
|
||||
nsresult rv = transferable->SetTransferData(format, convertedData, length);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
added = PR_TRUE;
|
||||
}
|
||||
|
||||
// only append the transferable if data was successfully added to it
|
||||
if (added)
|
||||
transArray->AppendElement(transferable);
|
||||
}
|
||||
|
||||
NS_ADDREF(*aArray = transArray);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsDOMDataTransfer::ConvertFromVariant(nsIVariant* aVariant,
|
||||
nsISupports** aSupports,
|
||||
PRUint32* aLength)
|
||||
{
|
||||
*aSupports = nsnull;
|
||||
*aLength = 0;
|
||||
|
||||
PRUint16 type;
|
||||
aVariant->GetDataType(&type);
|
||||
if (type == nsIDataType::VTYPE_INTERFACE ||
|
||||
type == nsIDataType::VTYPE_INTERFACE_IS) {
|
||||
if (NS_FAILED(aVariant->GetAsISupports(aSupports)))
|
||||
return PR_FALSE;
|
||||
|
||||
// for flavour data providers, use kFlavorHasDataProvider (which has the
|
||||
// value 0) as the length.
|
||||
nsCOMPtr<nsIFlavorDataProvider> fdp = do_QueryInterface(*aSupports);
|
||||
*aLength = fdp ? sizeof(nsISupports) : nsITransferable::kFlavorHasDataProvider;
|
||||
}
|
||||
|
||||
PRUnichar* chrs;
|
||||
nsresult rv = aVariant->GetAsWString(&chrs);
|
||||
if (NS_FAILED(rv))
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsISupportsString>
|
||||
strSupports(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID));
|
||||
if (!strSupports)
|
||||
return PR_FALSE;
|
||||
|
||||
nsAutoString str(chrs);
|
||||
strSupports->SetData(str);
|
||||
|
||||
*aSupports = strSupports;
|
||||
NS_ADDREF(*aSupports);
|
||||
|
||||
// each character is two bytes
|
||||
*aLength = str.Length() << 1;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMDataTransfer::ClearAll()
|
||||
{
|
||||
mItems.Clear();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMDataTransfer::SetDataWithPrincipal(const nsAString& aFormat,
|
||||
nsIVariant* aData,
|
||||
PRUint32 aIndex,
|
||||
nsIPrincipal* aPrincipal)
|
||||
{
|
||||
nsAutoString format;
|
||||
GetRealFormat(aFormat, format);
|
||||
|
||||
// check if the item for the format already exists. In that case,
|
||||
// just replace it.
|
||||
TransferItem* formatitem;
|
||||
if (aIndex < mItems.Length()) {
|
||||
nsTArray<TransferItem>& item = mItems[aIndex];
|
||||
PRUint32 count = item.Length();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
TransferItem& itemformat = item[i];
|
||||
if (itemformat.mFormat.Equals(format)) {
|
||||
// don't allow replacing data that has a stronger principal
|
||||
PRBool subsumes;
|
||||
if (itemformat.mPrincipal && aPrincipal &&
|
||||
(NS_FAILED(aPrincipal->Subsumes(itemformat.mPrincipal, &subsumes)) || !subsumes))
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
|
||||
itemformat.mPrincipal = aPrincipal;
|
||||
itemformat.mData = aData;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// add a new format
|
||||
formatitem = item.AppendElement();
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(aIndex == mItems.Length(), "Index out of range");
|
||||
|
||||
// add a new index
|
||||
nsTArray<TransferItem>* item = mItems.AppendElement();
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
formatitem = item->AppendElement();
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(formatitem, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
formatitem->mFormat = format;
|
||||
formatitem->mPrincipal = aPrincipal;
|
||||
formatitem->mData = aData;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
nsDOMDataTransfer::GetCurrentPrincipal()
|
||||
{
|
||||
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
||||
|
||||
nsCOMPtr<nsIPrincipal> currentPrincipal;
|
||||
ssm->GetSubjectPrincipal(getter_AddRefs(currentPrincipal));
|
||||
if (!currentPrincipal)
|
||||
ssm->GetSystemPrincipal(getter_AddRefs(currentPrincipal));
|
||||
|
||||
return currentPrincipal.get();
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMDataTransfer::GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat)
|
||||
{
|
||||
// treat text/unicode as equivalent to text/plain
|
||||
if (aInFormat.EqualsLiteral("Text") || aInFormat.EqualsLiteral("text/unicode"))
|
||||
aOutFormat.AssignLiteral("text/plain");
|
||||
else if (aInFormat.EqualsLiteral("URL"))
|
||||
aOutFormat.AssignLiteral("text/uri-list");
|
||||
else
|
||||
aOutFormat.Assign(aInFormat);
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMDataTransfer::CacheExternalFormats()
|
||||
{
|
||||
// Called during the constructor to cache the formats available from an
|
||||
// external drag. The data associated with each format will be set to null.
|
||||
// This data will instead only be retrieved in FillInExternalDragData when
|
||||
// asked for, as it may be time consuming for the source application to
|
||||
// generate it.
|
||||
|
||||
nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||
if (!dragService)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDragSession> dragSession;
|
||||
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
||||
if (!dragSession)
|
||||
return;
|
||||
|
||||
// make sure that the system principal is used for external drags
|
||||
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
|
||||
nsCOMPtr<nsIPrincipal> sysPrincipal;
|
||||
ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal));
|
||||
|
||||
// there isn't a way to get a list of the formats that might be available on
|
||||
// all platforms, so just check for the types that can actually be imported
|
||||
// XXXndeakin there are some other formats but those are platform specific.
|
||||
const char* formats[] = { kFileMime, kHTMLMime, kURLMime, kURLDataMime, kUnicodeMime };
|
||||
|
||||
PRUint32 count;
|
||||
dragSession->GetNumDropItems(&count);
|
||||
for (PRUint32 c = 0; c < count; c++) {
|
||||
for (PRUint32 f = 0; f < NS_ARRAY_LENGTH(formats); f++) {
|
||||
// IsDataFlavorSupported doesn't take an index as an argument and just
|
||||
// checks if any of the items support a particular flavor, even though
|
||||
// the GetData method does take an index. Here, we just assume that
|
||||
// every item being dragged has the same set of flavors.
|
||||
PRBool supported;
|
||||
dragSession->IsDataFlavorSupported(formats[f], &supported);
|
||||
// if the format is supported, add an item to the array with null as
|
||||
// the data. When retrieved, GetRealData will read the data.
|
||||
if (supported) {
|
||||
if (formats[f] == kUnicodeMime) {
|
||||
SetDataWithPrincipal(NS_LITERAL_STRING("text/plain"), nsnull, c, sysPrincipal);
|
||||
}
|
||||
else {
|
||||
if (formats[f] == kURLDataMime)
|
||||
SetDataWithPrincipal(NS_LITERAL_STRING("text/uri-list"), nsnull, c, sysPrincipal);
|
||||
SetDataWithPrincipal(NS_ConvertUTF8toUTF16(formats[f]), nsnull, c, sysPrincipal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMDataTransfer::FillInExternalDragData(TransferItem& aItem, PRUint32 aIndex)
|
||||
{
|
||||
NS_PRECONDITION(mIsExternal, "Not an external drag");
|
||||
|
||||
if (!aItem.mData) {
|
||||
nsCOMPtr<nsITransferable> trans =
|
||||
do_CreateInstance("@mozilla.org/widget/transferable;1");
|
||||
if (!trans)
|
||||
return;
|
||||
|
||||
NS_ConvertUTF16toUTF8 utf8format(aItem.mFormat);
|
||||
const char* format = utf8format.get();
|
||||
if (strcmp(format, "text/plain") == 0)
|
||||
format = kUnicodeMime;
|
||||
else if (strcmp(format, "text/uri-list") == 0)
|
||||
format = kURLDataMime;
|
||||
|
||||
nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||
if (!dragService)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDragSession> dragSession;
|
||||
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
||||
if (!dragSession)
|
||||
return;
|
||||
|
||||
trans->AddDataFlavor(format);
|
||||
dragSession->GetData(trans, aIndex);
|
||||
|
||||
PRUint32 length = 0;
|
||||
nsCOMPtr<nsISupports> data;
|
||||
trans->GetTransferData(format, getter_AddRefs(data), &length);
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID);
|
||||
if (!variant)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsISupportsString> supportsstr = do_QueryInterface(data);
|
||||
if (supportsstr) {
|
||||
nsAutoString str;
|
||||
supportsstr->GetData(str);
|
||||
variant->SetAsAString(str);
|
||||
}
|
||||
else {
|
||||
variant->SetAsISupports(data);
|
||||
}
|
||||
aItem.mData = variant;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Neil Deakin <enndeakin@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef nsDOMDataTransfer_h__
|
||||
#define nsDOMDataTransfer_h__
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIVariant.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIDOMDataTransfer.h"
|
||||
#include "nsIDragService.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
class nsITransferable;
|
||||
|
||||
/**
|
||||
* TransferItem is used to hold data for a particular format. Each piece of
|
||||
* data has a principal set from the caller which added it. This allows a
|
||||
* caller that wishes to retrieve the data to only be able to access the data
|
||||
* it is allowed to, yet still allow a chrome caller to retrieve any of the
|
||||
* data.
|
||||
*/
|
||||
struct TransferItem {
|
||||
nsString mFormat;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
nsCOMPtr<nsIVariant> mData;
|
||||
};
|
||||
|
||||
class nsDOMDataTransfer : public nsIDOMDataTransfer,
|
||||
public nsIDOMNSDataTransfer
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_NSIDOMDATATRANSFER
|
||||
NS_DECL_NSIDOMNSDATATRANSFER
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMDataTransfer, nsIDOMDataTransfer)
|
||||
|
||||
friend class nsDOMDragEvent;
|
||||
friend class nsEventStateManager;
|
||||
|
||||
protected:
|
||||
|
||||
// the constructors are protected so only our friends can call them
|
||||
|
||||
// default constructor used for the dragstart/draggesture event and
|
||||
// synthetic events
|
||||
nsDOMDataTransfer();
|
||||
|
||||
// this constructor must only be used to create a dataTransfer for a drag
|
||||
// that was started without using a data transfer, either an external drag,
|
||||
// that is, a drag where the source is another application, or a drag
|
||||
// started by calling the drag service directly.
|
||||
nsDOMDataTransfer(PRUint32 aEventType, PRUint32 aAction);
|
||||
|
||||
// this constructor is used only by the Clone method to copy the fields as
|
||||
// needed to a new data transfer.
|
||||
nsDOMDataTransfer(PRUint32 aEventType,
|
||||
const PRUint32 aEffectAllowed,
|
||||
PRBool aIsExternal,
|
||||
nsTArray<nsTArray<TransferItem> >& aItems,
|
||||
nsIDOMElement* aDragImage,
|
||||
PRUint32 aDragImageX,
|
||||
PRUint32 aDragImageY);
|
||||
|
||||
static const char sEffects[8][9];
|
||||
|
||||
public:
|
||||
|
||||
void GetDragTarget(nsIDOMElement** aDragTarget)
|
||||
{
|
||||
*aDragTarget = mDragTarget;
|
||||
NS_IF_ADDREF(*aDragTarget);
|
||||
}
|
||||
|
||||
// a readonly dataTransfer cannot have new data added or existing data removed.
|
||||
// Only the dropEffect and effectAllowed may be modified.
|
||||
void SetReadOnly() { mReadOnly = PR_TRUE; }
|
||||
|
||||
// converts the data into an array of nsITransferable objects to be used for
|
||||
// drag and drop or clipboard operations.
|
||||
void GetTransferables(nsISupportsArray** transferables);
|
||||
|
||||
// converts the data in the variant to an nsISupportString if possible or
|
||||
// an nsISupports or null otherwise.
|
||||
PRBool ConvertFromVariant(nsIVariant* aVariant,
|
||||
nsISupports** aSupports,
|
||||
PRUint32* aLength);
|
||||
|
||||
// clears all of the data
|
||||
void ClearAll();
|
||||
|
||||
// Similar to SetData except also specifies the principal to store.
|
||||
// aData may be null when called from CacheExternalFormats.
|
||||
nsresult SetDataWithPrincipal(const nsAString& aFormat,
|
||||
nsIVariant* aData,
|
||||
PRUint32 aIndex,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
protected:
|
||||
|
||||
// returns a weak reference to the drag image
|
||||
nsIDOMElement* GetDragImage(PRInt32* aX, PRInt32* aY)
|
||||
{
|
||||
*aX = mDragImageX;
|
||||
*aY = mDragImageY;
|
||||
return mDragImage;
|
||||
}
|
||||
|
||||
// returns a weak reference to the current principal
|
||||
nsIPrincipal* GetCurrentPrincipal();
|
||||
|
||||
// converts some formats used for compatibility in aInFormat into aOutFormat.
|
||||
// Text and text/unicode become text/plain, and URL becomes text/uri-list
|
||||
void GetRealFormat(const nsAString& aInFormat, nsAString& aOutFormat);
|
||||
|
||||
// caches the formats that exist in the drag service that were added by an
|
||||
// external drag
|
||||
void CacheExternalFormats();
|
||||
|
||||
// fills in the data field of aItem with the data from the drag service for
|
||||
// a given index.
|
||||
void FillInExternalDragData(TransferItem& aItem, PRUint32 aIndex);
|
||||
|
||||
// the event type this data transfer is for. This will correspond to an
|
||||
// event->message value.
|
||||
PRUint32 mEventType;
|
||||
|
||||
// the drop effect and effect allowed
|
||||
PRUint32 mDropEffect;
|
||||
PRUint32 mEffectAllowed;
|
||||
|
||||
// readonly data transfers may not be modified except the drop effect and
|
||||
// effect allowed.
|
||||
PRPackedBool mReadOnly;
|
||||
|
||||
// true for drags started without a data transfer, for example, those from
|
||||
// another application.
|
||||
PRPackedBool mIsExternal;
|
||||
|
||||
// array of items, each containing an array of format->data pairs
|
||||
nsTArray<nsTArray<TransferItem> > mItems;
|
||||
|
||||
// the target of the drag. The drag and dragend events will fire at this.
|
||||
nsCOMPtr<nsIDOMElement> mDragTarget;
|
||||
|
||||
// the custom drag image and coordinates within the image. If mDragImage is
|
||||
// null, the default image is created from the drag target.
|
||||
nsCOMPtr<nsIDOMElement> mDragImage;
|
||||
PRUint32 mDragImageX;
|
||||
PRUint32 mDragImageY;
|
||||
};
|
||||
|
||||
#endif // nsDOMDataTransfer_h__
|
||||
|
|
@ -0,0 +1,246 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Neil Deakin <enndeakin@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsDOMDragEvent.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsDOMDataTransfer.h"
|
||||
#include "nsIDragService.h"
|
||||
|
||||
nsDOMDragEvent::nsDOMDragEvent(nsPresContext* aPresContext,
|
||||
nsInputEvent* aEvent)
|
||||
: nsDOMMouseEvent(aPresContext, aEvent ? aEvent :
|
||||
new nsDragEvent(PR_FALSE, 0, nsnull))
|
||||
{
|
||||
if (aEvent) {
|
||||
mEventIsInternal = PR_FALSE;
|
||||
}
|
||||
else {
|
||||
mEventIsInternal = PR_TRUE;
|
||||
mEvent->time = PR_Now();
|
||||
mEvent->refPoint.x = mEvent->refPoint.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
nsDOMDragEvent::~nsDOMDragEvent()
|
||||
{
|
||||
if (mEventIsInternal) {
|
||||
if (mEvent->eventStructType == NS_DRAG_EVENT)
|
||||
delete static_cast<nsDragEvent*>(mEvent);
|
||||
mEvent = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMDragEvent, nsDOMMouseEvent)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMDragEvent, nsDOMMouseEvent)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMDragEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMDragEvent)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(DragEvent)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMMouseEvent)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDragEvent::InitDragEvent(const nsAString & aType,
|
||||
PRBool aCanBubble,
|
||||
PRBool aCancelable,
|
||||
nsIDOMAbstractView* aView,
|
||||
PRInt32 aDetail,
|
||||
nsIDOMDataTransfer* aDataTransfer)
|
||||
{
|
||||
nsresult rv = nsDOMUIEvent::InitUIEvent(aType, aCanBubble, aCancelable, aView, aDetail);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mEventIsInternal && mEvent) {
|
||||
nsDragEvent* dragEvent = static_cast<nsDragEvent*>(mEvent);
|
||||
dragEvent->dataTransfer = aDataTransfer;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDragEvent::InitDragEventNS(const nsAString & aNamespaceURIArg,
|
||||
const nsAString & aType,
|
||||
PRBool aCanBubble,
|
||||
PRBool aCancelable,
|
||||
nsIDOMAbstractView* aView,
|
||||
PRInt32 aDetail,
|
||||
nsIDOMDataTransfer* aDataTransfer)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMDragEvent::GetDataTransfer(nsIDOMDataTransfer** aDataTransfer)
|
||||
{
|
||||
*aDataTransfer = nsnull;
|
||||
|
||||
if (!mEvent || mEvent->eventStructType != NS_DRAG_EVENT) {
|
||||
NS_WARNING("Tried to get dataTransfer from non-drag event!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// the dataTransfer field of the event caches the DataTransfer associated
|
||||
// with the drag. It is initialized when an attempt is made to retrieve it
|
||||
// rather that when the event is created to avoid duplicating the data when
|
||||
// no listener ever uses it.
|
||||
nsDragEvent* dragEvent = static_cast<nsDragEvent*>(mEvent);
|
||||
if (dragEvent->dataTransfer) {
|
||||
CallQueryInterface(dragEvent->dataTransfer, aDataTransfer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// for synthetic events, just use the supplied data transfer object
|
||||
if (mEventIsInternal) {
|
||||
NS_IF_ADDREF(*aDataTransfer = dragEvent->dataTransfer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// For draggesture and dragstart events, the data transfer object is
|
||||
// created before the event fires, so it should already be set. For other
|
||||
// drag events, get the object from the drag session.
|
||||
NS_ASSERTION(mEvent->message != NS_DRAGDROP_GESTURE &&
|
||||
mEvent->message != NS_DRAGDROP_START,
|
||||
"draggesture event created without a dataTransfer");
|
||||
|
||||
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
|
||||
NS_ENSURE_TRUE(dragSession, NS_OK); // no drag in progress
|
||||
|
||||
nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
|
||||
dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
|
||||
if (!initialDataTransfer) {
|
||||
// A dataTransfer won't exist when a drag was started by some other
|
||||
// means, for instance calling the drag service directly, or a drag
|
||||
// from another application. In either case, a new dataTransfer should
|
||||
// be created that reflects the data. Pass true to the constructor for
|
||||
// the aIsExternal argument, so that only system access is allowed.
|
||||
PRUint32 action = 0;
|
||||
dragSession->GetDragAction(&action);
|
||||
initialDataTransfer =
|
||||
new nsDOMDataTransfer(mEvent->message, action);
|
||||
NS_ENSURE_TRUE(initialDataTransfer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// now set it in the drag session so we don't need to create it again
|
||||
dragSession->SetDataTransfer(initialDataTransfer);
|
||||
}
|
||||
|
||||
// each event should use a clone of the original dataTransfer.
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> initialDataTransferNS =
|
||||
do_QueryInterface(initialDataTransfer);
|
||||
NS_ENSURE_TRUE(initialDataTransferNS, NS_ERROR_FAILURE);
|
||||
initialDataTransferNS->Clone(mEvent->message,
|
||||
getter_AddRefs(dragEvent->dataTransfer));
|
||||
NS_ENSURE_TRUE(dragEvent->dataTransfer, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// for the dragenter and dragover events, initialize the drop effect
|
||||
// from the drop action, which platform specific widget code sets before
|
||||
// the event is fired based on the keyboard state.
|
||||
if (mEvent->message == NS_DRAGDROP_ENTER ||
|
||||
mEvent->message == NS_DRAGDROP_OVER) {
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> newDataTransfer =
|
||||
do_QueryInterface(dragEvent->dataTransfer);
|
||||
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 action, effectAllowed;
|
||||
dragSession->GetDragAction(&action);
|
||||
newDataTransfer->GetEffectAllowedInt(&effectAllowed);
|
||||
newDataTransfer->SetDropEffectInt(FilterDropEffect(action, effectAllowed));
|
||||
}
|
||||
else if (mEvent->message == NS_DRAGDROP_DROP ||
|
||||
mEvent->message == NS_DRAGDROP_DRAGDROP ||
|
||||
mEvent->message == NS_DRAGDROP_END) {
|
||||
// For the drop and dragend events, set the drop effect based on the
|
||||
// last value that the dropEffect had. This will have been set in
|
||||
// nsEventStateManager::PostHandleEvent for the last dragenter or
|
||||
// dragover event.
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> newDataTransfer =
|
||||
do_QueryInterface(dragEvent->dataTransfer);
|
||||
NS_ENSURE_TRUE(newDataTransfer, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 dropEffect;
|
||||
initialDataTransferNS->GetDropEffectInt(&dropEffect);
|
||||
newDataTransfer->SetDropEffectInt(dropEffect);
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aDataTransfer = dragEvent->dataTransfer);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
PRUint32
|
||||
nsDOMDragEvent::FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed)
|
||||
{
|
||||
// It is possible for the drag action to include more than one action, but
|
||||
// the widget code which sets the action from the keyboard state should only
|
||||
// be including one. If multiple actions were set, we just consider them in
|
||||
// the following order:
|
||||
// copy, link, move
|
||||
if (aAction & nsIDragService::DRAGDROP_ACTION_COPY)
|
||||
aAction = nsIDragService::DRAGDROP_ACTION_COPY;
|
||||
else if (aAction & nsIDragService::DRAGDROP_ACTION_LINK)
|
||||
aAction = nsIDragService::DRAGDROP_ACTION_LINK;
|
||||
else if (aAction & nsIDragService::DRAGDROP_ACTION_MOVE)
|
||||
aAction = nsIDragService::DRAGDROP_ACTION_MOVE;
|
||||
|
||||
// Filter the action based on the effectAllowed. If the effectAllowed
|
||||
// doesn't include the action, then that action cannot be done, so adjust
|
||||
// the action to something that is allowed. For a copy, adjust to move or
|
||||
// link. For a move, adjust to copy or link. For a link, adjust to move or
|
||||
// link. Otherwise, use none.
|
||||
if (aAction & aEffectAllowed ||
|
||||
aEffectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED)
|
||||
return aAction;
|
||||
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_MOVE)
|
||||
return nsIDragService::DRAGDROP_ACTION_MOVE;
|
||||
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_COPY)
|
||||
return nsIDragService::DRAGDROP_ACTION_COPY;
|
||||
if (aEffectAllowed & nsIDragService::DRAGDROP_ACTION_LINK)
|
||||
return nsIDragService::DRAGDROP_ACTION_LINK;
|
||||
return nsIDragService::DRAGDROP_ACTION_NONE;
|
||||
}
|
||||
|
||||
nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsDragEvent *aEvent)
|
||||
{
|
||||
nsDOMDragEvent* event = new nsDOMDragEvent(aPresContext, aEvent);
|
||||
NS_ENSURE_TRUE(event, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return CallQueryInterface(event, aInstancePtrResult);
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -13,13 +14,12 @@
|
|||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Christopher Blizzard <blizzard@mozilla.org>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* The Initial Developer of the Original Code is the Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2008
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||
* Neil Deakin <enndeakin@gmail.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
|
@ -35,27 +35,35 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#ifndef nsDOMDragEvent_h__
|
||||
#define nsDOMDragEvent_h__
|
||||
|
||||
interface nsIDOMWindow;
|
||||
#include "nsIDOMDragEvent.h"
|
||||
#include "nsDOMMouseEvent.h"
|
||||
#include "nsIDOMDataTransfer.h"
|
||||
|
||||
/**
|
||||
* Responds to incoming xremote requests for the mozilla suite.
|
||||
*/
|
||||
class nsIContent;
|
||||
class nsEvent;
|
||||
|
||||
[scriptable, uuid(52add212-2067-4575-8d26-edd5165179b1)]
|
||||
interface nsISuiteRemoteService : nsISupports
|
||||
class nsDOMDragEvent : public nsIDOMDragEvent,
|
||||
public nsDOMMouseEvent
|
||||
{
|
||||
/**
|
||||
* Parse the command given.
|
||||
*
|
||||
* @param aCommand The command string, e.g. "openURL(http://www.foo.com/)"
|
||||
* @param aContext The domwindow to target the command at. May be null, and
|
||||
* may be ignored.
|
||||
*/
|
||||
void parseCommand (in string aCommand, in nsIDOMWindow aContext);
|
||||
public:
|
||||
nsDOMDragEvent(nsPresContext* aPresContext, nsInputEvent* aEvent);
|
||||
virtual ~nsDOMDragEvent();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_DECL_NSIDOMDRAGEVENT
|
||||
|
||||
NS_FORWARD_TO_NSDOMMOUSEEVENT
|
||||
|
||||
// filters the action to fit within the effects allowed and returns it.
|
||||
static PRUint32 FilterDropEffect(PRUint32 aAction, PRUint32 aEffectAllowed);
|
||||
};
|
||||
|
||||
%{C++
|
||||
#define NS_SUITEREMOTESERVICE_CONTRACTID "@mozilla.org/browser/xremoteservice;2"
|
||||
%}
|
||||
nsresult NS_NewDOMDragEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsPresContext* aPresContext,
|
||||
nsDragEvent* aEvent);
|
||||
|
||||
#endif // nsDOMDragEvent_h__
|
|
@ -64,7 +64,7 @@ static const char* const sEventNames[] = {
|
|||
"compositionstart", "compositionend", "popupshowing", "popupshown",
|
||||
"popuphiding", "popuphidden", "close", "command", "broadcast", "commandupdate",
|
||||
"dragenter", "dragover", "dragexit", "dragdrop", "draggesture",
|
||||
"drag", "dragend", "resize",
|
||||
"drag", "dragend", "dragstart", "dragleave", "drop", "resize",
|
||||
"scroll", "overflow", "underflow", "overflowchanged",
|
||||
"DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved",
|
||||
"DOMNodeRemovedFromDocument", "DOMNodeInsertedIntoDocument",
|
||||
|
@ -172,6 +172,9 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMEvent)
|
|||
case NS_MOUSE_SCROLL_EVENT:
|
||||
static_cast<nsMouseEvent_base*>(tmp->mEvent)->relatedTarget = nsnull;
|
||||
break;
|
||||
case NS_DRAG_EVENT:
|
||||
static_cast<nsDragEvent*>(tmp->mEvent)->dataTransfer = nsnull;
|
||||
break;
|
||||
case NS_XUL_COMMAND_EVENT:
|
||||
static_cast<nsXULCommandEvent*>(tmp->mEvent)->sourceEvent = nsnull;
|
||||
break;
|
||||
|
@ -198,6 +201,10 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMEvent)
|
|||
cb.NoteXPCOMChild(
|
||||
static_cast<nsMouseEvent_base*>(tmp->mEvent)->relatedTarget);
|
||||
break;
|
||||
case NS_DRAG_EVENT:
|
||||
cb.NoteXPCOMChild(
|
||||
static_cast<nsDragEvent*>(tmp->mEvent)->dataTransfer);
|
||||
break;
|
||||
case NS_XUL_COMMAND_EVENT:
|
||||
cb.NoteXPCOMChild(
|
||||
static_cast<nsXULCommandEvent*>(tmp->mEvent)->sourceEvent);
|
||||
|
@ -468,6 +475,27 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
|
|||
} else if (mEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
|
||||
if (atom == nsGkAtoms::onDOMMouseScroll)
|
||||
mEvent->message = NS_MOUSE_SCROLL;
|
||||
} else if (mEvent->eventStructType == NS_DRAG_EVENT) {
|
||||
if (atom == nsGkAtoms::ondragstart)
|
||||
mEvent->message = NS_DRAGDROP_START;
|
||||
else if (atom == nsGkAtoms::ondraggesture)
|
||||
mEvent->message = NS_DRAGDROP_GESTURE;
|
||||
else if (atom == nsGkAtoms::ondragenter)
|
||||
mEvent->message = NS_DRAGDROP_ENTER;
|
||||
else if (atom == nsGkAtoms::ondragover)
|
||||
mEvent->message = NS_DRAGDROP_OVER_SYNTH;
|
||||
else if (atom == nsGkAtoms::ondragleave)
|
||||
mEvent->message = NS_DRAGDROP_LEAVE_SYNTH;
|
||||
else if (atom == nsGkAtoms::ondragexit)
|
||||
mEvent->message = NS_DRAGDROP_EXIT;
|
||||
else if (atom == nsGkAtoms::ondrag)
|
||||
mEvent->message = NS_DRAGDROP_DRAG;
|
||||
else if (atom == nsGkAtoms::ondrop)
|
||||
mEvent->message = NS_DRAGDROP_DROP;
|
||||
else if (atom == nsGkAtoms::ondragdrop)
|
||||
mEvent->message = NS_DRAGDROP_DRAGDROP;
|
||||
else if (atom == nsGkAtoms::ondragend)
|
||||
mEvent->message = NS_DRAGDROP_END;
|
||||
} else if (mEvent->eventStructType == NS_KEY_EVENT) {
|
||||
if (atom == nsGkAtoms::onkeydown)
|
||||
mEvent->message = NS_KEY_DOWN;
|
||||
|
@ -760,6 +788,21 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
|
|||
newEvent = mouseEvent;
|
||||
break;
|
||||
}
|
||||
case NS_DRAG_EVENT:
|
||||
{
|
||||
nsDragEvent* oldDragEvent = static_cast<nsDragEvent*>(mEvent);
|
||||
nsDragEvent* dragEvent =
|
||||
new nsDragEvent(PR_FALSE, msg, nsnull);
|
||||
NS_ENSURE_TRUE(dragEvent, NS_ERROR_OUT_OF_MEMORY);
|
||||
isInputEvent = PR_TRUE;
|
||||
dragEvent->dataTransfer = oldDragEvent->dataTransfer;
|
||||
dragEvent->clickCount = oldDragEvent->clickCount;
|
||||
dragEvent->acceptActivation = oldDragEvent->acceptActivation;
|
||||
dragEvent->relatedTarget = oldDragEvent->relatedTarget;
|
||||
dragEvent->button = oldDragEvent->button;
|
||||
newEvent = dragEvent;
|
||||
break;
|
||||
}
|
||||
case NS_MENU_EVENT:
|
||||
{
|
||||
newEvent = new nsMenuEvent(PR_FALSE, msg, nsnull);
|
||||
|
@ -1298,7 +1341,7 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
|||
return sEventNames[eDOMEvents_dragover];
|
||||
case NS_DRAGDROP_EXIT_SYNTH:
|
||||
return sEventNames[eDOMEvents_dragexit];
|
||||
case NS_DRAGDROP_DROP:
|
||||
case NS_DRAGDROP_DRAGDROP:
|
||||
return sEventNames[eDOMEvents_dragdrop];
|
||||
case NS_DRAGDROP_GESTURE:
|
||||
return sEventNames[eDOMEvents_draggesture];
|
||||
|
@ -1306,6 +1349,12 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
|||
return sEventNames[eDOMEvents_drag];
|
||||
case NS_DRAGDROP_END:
|
||||
return sEventNames[eDOMEvents_dragend];
|
||||
case NS_DRAGDROP_START:
|
||||
return sEventNames[eDOMEvents_dragstart];
|
||||
case NS_DRAGDROP_LEAVE_SYNTH:
|
||||
return sEventNames[eDOMEvents_dragleave];
|
||||
case NS_DRAGDROP_DROP:
|
||||
return sEventNames[eDOMEvents_drop];
|
||||
case NS_SCROLLPORT_OVERFLOW:
|
||||
return sEventNames[eDOMEvents_overflow];
|
||||
case NS_SCROLLPORT_UNDERFLOW:
|
||||
|
|
|
@ -103,6 +103,9 @@ public:
|
|||
eDOMEvents_draggesture,
|
||||
eDOMEvents_drag,
|
||||
eDOMEvents_dragend,
|
||||
eDOMEvents_dragstart,
|
||||
eDOMEvents_dragleave,
|
||||
eDOMEvents_drop,
|
||||
eDOMEvents_resize,
|
||||
eDOMEvents_scroll,
|
||||
eDOMEvents_overflow,
|
||||
|
|
|
@ -65,7 +65,7 @@ public:
|
|||
NS_IMETHOD GetWhich(PRUint32 *aWhich);
|
||||
};
|
||||
|
||||
#define NS_FORWARD_TO_NSDOMMOUSEEVENT \
|
||||
#define NS_FORWARD_TO_NSDOMMOUSEEVENT \
|
||||
NS_FORWARD_NSIDOMMOUSEEVENT(nsDOMMouseEvent::) \
|
||||
NS_FORWARD_TO_NSDOMUIEVENT
|
||||
|
||||
|
|
|
@ -122,11 +122,11 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMUIEvent)
|
|||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
|
||||
|
||||
nsPoint nsDOMUIEvent::GetScreenPoint() {
|
||||
if (!mEvent ||
|
||||
(mEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
mEvent->eventStructType != NS_POPUP_EVENT &&
|
||||
mEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
|
||||
!NS_IS_DRAG_EVENT(mEvent))) {
|
||||
if (!mEvent ||
|
||||
(mEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
mEvent->eventStructType != NS_POPUP_EVENT &&
|
||||
mEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
|
||||
mEvent->eventStructType != NS_DRAG_EVENT)) {
|
||||
return nsPoint(0, 0);
|
||||
}
|
||||
|
||||
|
@ -147,7 +147,7 @@ nsPoint nsDOMUIEvent::GetClientPoint() {
|
|||
(mEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
mEvent->eventStructType != NS_POPUP_EVENT &&
|
||||
mEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
|
||||
!NS_IS_DRAG_EVENT(mEvent)) ||
|
||||
mEvent->eventStructType != NS_DRAG_EVENT) ||
|
||||
!mPresContext ||
|
||||
!((nsGUIEvent*)mEvent)->widget) {
|
||||
return mClientPoint;
|
||||
|
|
|
@ -576,6 +576,9 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
|||
case NS_MOUSE_SCROLL_EVENT:
|
||||
return NS_NewDOMMouseScrollEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsInputEvent*>(aEvent));
|
||||
case NS_DRAG_EVENT:
|
||||
return NS_NewDOMDragEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsDragEvent*>(aEvent));
|
||||
case NS_POPUPBLOCKED_EVENT:
|
||||
return NS_NewDOMPopupBlockedEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsPopupBlockedEvent*>
|
||||
|
@ -622,6 +625,9 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
|||
return NS_NewDOMMouseEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("mousescrollevents"))
|
||||
return NS_NewDOMMouseScrollEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("dragevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("dragevents"))
|
||||
return NS_NewDOMDragEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("keyboardevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("keyevents"))
|
||||
return NS_NewDOMKeyboardEvent(aDOMEvent, aPresContext, nsnull);
|
||||
|
|
|
@ -262,10 +262,13 @@ static const EventDispatchData sDragEvents[] = {
|
|||
{ NS_DRAGDROP_ENTER, HANDLER(&nsIDOMDragListener::DragEnter) },
|
||||
{ NS_DRAGDROP_OVER_SYNTH, HANDLER(&nsIDOMDragListener::DragOver) },
|
||||
{ NS_DRAGDROP_EXIT_SYNTH, HANDLER(&nsIDOMDragListener::DragExit) },
|
||||
{ NS_DRAGDROP_DROP, HANDLER(&nsIDOMDragListener::DragDrop) },
|
||||
{ NS_DRAGDROP_DRAGDROP, HANDLER(&nsIDOMDragListener::DragDrop) },
|
||||
{ NS_DRAGDROP_GESTURE, HANDLER(&nsIDOMDragListener::DragGesture) },
|
||||
{ NS_DRAGDROP_DRAG, HANDLER(&nsIDOMDragListener::Drag) },
|
||||
{ NS_DRAGDROP_END, HANDLER(&nsIDOMDragListener::DragEnd) }
|
||||
{ NS_DRAGDROP_END, HANDLER(&nsIDOMDragListener::DragEnd) },
|
||||
{ NS_DRAGDROP_START, HANDLER(&nsIDOMDragListener::DragStart) },
|
||||
{ NS_DRAGDROP_LEAVE_SYNTH, HANDLER(&nsIDOMDragListener::DragLeave) },
|
||||
{ NS_DRAGDROP_DROP, HANDLER(&nsIDOMDragListener::Drop) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sXULEvents[] = {
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "nsIEditorDocShell.h"
|
||||
#include "nsIFormControl.h"
|
||||
#include "nsIComboboxControlFrame.h"
|
||||
#include "nsIDOMNSHTMLElement.h"
|
||||
#include "nsIDOMHTMLAnchorElement.h"
|
||||
#include "nsIDOMHTMLInputElement.h"
|
||||
#include "nsIDOMNSHTMLInputElement.h"
|
||||
|
@ -113,10 +114,11 @@
|
|||
#include "nsIDOMDocumentRange.h"
|
||||
#include "nsIDOMDocumentEvent.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsIDOMDragEvent.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOMDocumentView.h"
|
||||
#include "nsIDOMAbstractView.h"
|
||||
#include "nsIDOMNSUIEvent.h"
|
||||
#include "nsDOMDragEvent.h"
|
||||
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsCaret.h"
|
||||
|
@ -140,6 +142,14 @@
|
|||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
#include "nsIDragService.h"
|
||||
#include "nsIDragSession.h"
|
||||
#include "nsDOMDataTransfer.h"
|
||||
#include "nsContentAreaDragDrop.h"
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsITreeBoxObject.h"
|
||||
#endif
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include <Events.h>
|
||||
#endif
|
||||
|
@ -853,7 +863,10 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
KillClickHoldTimer();
|
||||
break;
|
||||
#endif
|
||||
case NS_DRAGDROP_DROP:
|
||||
case NS_DRAGDROP_OVER:
|
||||
// NS_DRAGDROP_DROP is fired before NS_DRAGDROP_DRAGDROP so send
|
||||
// the enter/exit events before NS_DRAGDROP_DROP.
|
||||
GenerateDragDropEnterExit(aPresContext, (nsGUIEvent*)aEvent);
|
||||
break;
|
||||
case NS_GOTFOCUS:
|
||||
|
@ -1971,18 +1984,36 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
|||
KillClickHoldTimer();
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIContent> targetContent = mGestureDownContent;
|
||||
nsRefPtr<nsDOMDataTransfer> dataTransfer = new nsDOMDataTransfer();
|
||||
if (!dataTransfer)
|
||||
return;
|
||||
|
||||
PRBool isSelection = PR_FALSE;
|
||||
nsCOMPtr<nsIContent> eventContent, targetContent;
|
||||
mCurrentTarget->GetContentForEvent(aPresContext, aEvent,
|
||||
getter_AddRefs(eventContent));
|
||||
if (eventContent)
|
||||
DetermineDragTarget(aPresContext, eventContent, dataTransfer,
|
||||
&isSelection, getter_AddRefs(targetContent));
|
||||
|
||||
// Stop tracking the drag gesture now. This should stop us from
|
||||
// reentering GenerateDragGesture inside DOM event processing.
|
||||
StopTrackingDragGesture();
|
||||
|
||||
if (!targetContent)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = mCurrentTarget->GetWindow();
|
||||
|
||||
// get the widget from the target frame
|
||||
nsMouseEvent gestureEvent(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_GESTURE,
|
||||
widget, nsMouseEvent::eReal);
|
||||
nsDragEvent startEvent(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_START, widget);
|
||||
FillInEventFromGestureDown(&startEvent);
|
||||
|
||||
nsDragEvent gestureEvent(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_GESTURE, widget);
|
||||
FillInEventFromGestureDown(&gestureEvent);
|
||||
|
||||
startEvent.dataTransfer = gestureEvent.dataTransfer = dataTransfer;
|
||||
|
||||
// Dispatch to the DOM. By setting mCurrentTarget we are faking
|
||||
// out the ESM and telling it that the current target frame is
|
||||
// actually where the mouseDown occurred, otherwise it will use
|
||||
|
@ -1998,11 +2029,28 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
|||
// Set the current target to the content for the mouse down
|
||||
mCurrentTargetContent = targetContent;
|
||||
|
||||
// Dispatch the draggesture event to the DOM
|
||||
// Dispatch both the dragstart and draggesture events to the DOM
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEventDispatcher::Dispatch(targetContent, aPresContext, &gestureEvent, nsnull,
|
||||
nsEventDispatcher::Dispatch(targetContent, aPresContext, &startEvent, nsnull,
|
||||
&status);
|
||||
|
||||
nsDragEvent* event = &startEvent;
|
||||
if (status != nsEventStatus_eConsumeNoDefault) {
|
||||
status = nsEventStatus_eIgnore;
|
||||
nsEventDispatcher::Dispatch(targetContent, aPresContext, &gestureEvent, nsnull,
|
||||
&status);
|
||||
event = &gestureEvent;
|
||||
}
|
||||
|
||||
// now that the dataTransfer has been updated in the dragstart and
|
||||
// draggesture events, make it read only so that the data doesn't
|
||||
// change during the drag.
|
||||
dataTransfer->SetReadOnly();
|
||||
|
||||
if (status != nsEventStatus_eConsumeNoDefault)
|
||||
DoDefaultDragStart(aPresContext, event, dataTransfer,
|
||||
targetContent, isSelection);
|
||||
|
||||
// Note that frame event handling doesn't care about NS_DRAGDROP_GESTURE,
|
||||
// which is just as well since we don't really know which frame to
|
||||
// send it to
|
||||
|
@ -2017,6 +2065,230 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
|||
}
|
||||
} // GenerateDragGesture
|
||||
|
||||
void
|
||||
nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
|
||||
nsIContent* aSelectionTarget,
|
||||
nsDOMDataTransfer* aDataTransfer,
|
||||
PRBool* aIsSelection,
|
||||
nsIContent** aTargetNode)
|
||||
{
|
||||
*aTargetNode = nsnull;
|
||||
|
||||
nsCOMPtr<nsISupports> container = aPresContext->GetContainer();
|
||||
nsCOMPtr<nsIDOMWindow> window = do_GetInterface(container);
|
||||
|
||||
// GetDragData determines if a selection, link or image in the content
|
||||
// should be dragged, and places the data associated with the drag in the
|
||||
// data transfer. Skip this check for chrome shells.
|
||||
PRBool canDrag;
|
||||
nsCOMPtr<nsIContent> dragDataNode;
|
||||
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(container);
|
||||
if (dsti) {
|
||||
PRInt32 type = -1;
|
||||
if (NS_SUCCEEDED(dsti->GetItemType(&type)) &&
|
||||
type != nsIDocShellTreeItem::typeChrome) {
|
||||
// mGestureDownContent is the node where the mousedown event for the drag
|
||||
// occured, and aSelectionTarget is the node to use when a selection is used
|
||||
nsresult rv =
|
||||
nsContentAreaDragDrop::GetDragData(window, mGestureDownContent,
|
||||
aSelectionTarget, mGestureDownAlt,
|
||||
aDataTransfer, &canDrag, aIsSelection,
|
||||
getter_AddRefs(dragDataNode));
|
||||
if (NS_FAILED(rv) || !canDrag)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// if GetDragData returned a node, use that as the node being dragged.
|
||||
// Otherwise, if a selection is being dragged, use the node within the
|
||||
// selection that was dragged. Otherwise, just use the mousedown target.
|
||||
nsIContent* dragContent = mGestureDownContent;
|
||||
if (dragDataNode)
|
||||
dragContent = dragDataNode;
|
||||
else if (*aIsSelection)
|
||||
dragContent = aSelectionTarget;
|
||||
|
||||
nsIContent* originalDragContent = dragContent;
|
||||
|
||||
// If a selection isn't being dragged, look for an ancestor with the
|
||||
// draggable property set. If one is found, use that as the target of the
|
||||
// drag instead of the node that was clicked on. If a draggable node wasn't
|
||||
// found, just use the clicked node.
|
||||
if (!*aIsSelection) {
|
||||
while (dragContent) {
|
||||
nsCOMPtr<nsIDOMNSHTMLElement> htmlElement = do_QueryInterface(dragContent);
|
||||
if (htmlElement) {
|
||||
PRBool draggable = PR_FALSE;
|
||||
htmlElement->GetDraggable(&draggable);
|
||||
if (draggable)
|
||||
break;
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDOMXULElement> xulElement = do_QueryInterface(dragContent);
|
||||
if (xulElement) {
|
||||
// All XUL elements are draggable, so if a XUL element is
|
||||
// encountered, stop looking for draggable nodes and just use the
|
||||
// original clicked node instead.
|
||||
// XXXndeakin
|
||||
// In the future, we will want to improve this so that XUL has a
|
||||
// better way to specify whether something is draggable than just
|
||||
// on/off.
|
||||
dragContent = mGestureDownContent;
|
||||
break;
|
||||
}
|
||||
// otherwise, it's not an HTML or XUL element, so just keep looking
|
||||
}
|
||||
dragContent = dragContent->GetParent();
|
||||
}
|
||||
}
|
||||
|
||||
// if no node in the hierarchy was found to drag, but the GetDragData method
|
||||
// returned a node, use that returned node. Otherwise, just use the original
|
||||
// node that was clicked.
|
||||
if (!dragContent) {
|
||||
if (dragDataNode)
|
||||
dragContent = originalDragContent;
|
||||
else
|
||||
dragContent = mGestureDownContent;
|
||||
}
|
||||
|
||||
if (dragContent) {
|
||||
// if an ancestor node was used instead, clear the drag data
|
||||
// XXXndeakin rework this a bit. Find a way to just not call GetDragData if we don't need to.
|
||||
if (dragContent != originalDragContent)
|
||||
aDataTransfer->ClearAll();
|
||||
*aTargetNode = dragContent;
|
||||
NS_ADDREF(*aTargetNode);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
|
||||
nsDragEvent* aDragEvent,
|
||||
nsDOMDataTransfer* aDataTransfer,
|
||||
nsIContent* aDragTarget,
|
||||
PRBool aIsSelection)
|
||||
{
|
||||
nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||
if (!dragService)
|
||||
return;
|
||||
|
||||
// Default handling for the draggesture/dragstart event.
|
||||
//
|
||||
// First, check if a drag session already exists. This means that the drag
|
||||
// service was called directly within a draggesture handler. In this case,
|
||||
// don't do anything more, as it is assumed that the handler is managing
|
||||
// drag and drop manually.
|
||||
nsCOMPtr<nsIDragSession> dragSession;
|
||||
dragService->GetCurrentSession(getter_AddRefs(dragSession));
|
||||
if (dragSession)
|
||||
return; // already a drag in progress
|
||||
|
||||
// No drag session is currently active, so check if a handler added
|
||||
// any items to be dragged. If not, there isn't anything to drag.
|
||||
PRUint32 count = 0;
|
||||
if (aDataTransfer)
|
||||
aDataTransfer->GetMozItemCount(&count);
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
// Get the target being dragged, which may not be the same as the
|
||||
// target of the mouse event. If one wasn't set in the
|
||||
// aDataTransfer during the event handler, just use the original
|
||||
// target instead.
|
||||
nsCOMPtr<nsIDOMNode> dragTarget;
|
||||
nsCOMPtr<nsIDOMElement> dragTargetElement;
|
||||
aDataTransfer->GetDragTarget(getter_AddRefs(dragTargetElement));
|
||||
dragTarget = do_QueryInterface(dragTargetElement);
|
||||
if (!dragTarget) {
|
||||
dragTarget = do_QueryInterface(aDragTarget);
|
||||
if (!dragTarget)
|
||||
return;
|
||||
}
|
||||
|
||||
// check which drag effect should initially be used
|
||||
PRUint32 effectAllowed;
|
||||
aDataTransfer->GetEffectAllowedInt(&effectAllowed);
|
||||
|
||||
PRInt32 action = 0;
|
||||
if (effectAllowed != nsIDragService::DRAGDROP_ACTION_UNINITIALIZED)
|
||||
action = effectAllowed;
|
||||
|
||||
// get any custom drag image that was set
|
||||
PRInt32 imageX, imageY;
|
||||
nsIDOMElement* dragImage = aDataTransfer->GetDragImage(&imageX, &imageY);
|
||||
|
||||
// If a selection is being dragged, and no custom drag image was
|
||||
// set, get the selection so that the drag region can be created
|
||||
// from the selection area. If a custom image was set, it doesn't
|
||||
// matter what the selection is since the image will be used instead.
|
||||
nsISelection* selection = nsnull;
|
||||
if (aIsSelection && !dragImage) {
|
||||
nsIDocument* doc = aDragTarget->GetCurrentDoc();
|
||||
if (doc) {
|
||||
nsIPresShell* presShell = doc->GetPrimaryShell();
|
||||
if (presShell) {
|
||||
selection = presShell->GetCurrentSelection(
|
||||
nsISelectionController::SELECTION_NORMAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsArray> transArray;
|
||||
aDataTransfer->GetTransferables(getter_AddRefs(transArray));
|
||||
if (!transArray)
|
||||
return;
|
||||
|
||||
// XXXndeakin don't really want to create a new drag DOM event
|
||||
// here, but we need something to pass to the InvokeDragSession
|
||||
// methods.
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
NS_NewDOMDragEvent(getter_AddRefs(domEvent), aPresContext, aDragEvent);
|
||||
|
||||
nsCOMPtr<nsIDOMDragEvent> domDragEvent = do_QueryInterface(domEvent);
|
||||
// if creating a drag event failed, starting a drag session will
|
||||
// just fail.
|
||||
if (selection) {
|
||||
dragService->InvokeDragSessionWithSelection(selection, transArray,
|
||||
action, domDragEvent,
|
||||
aDataTransfer);
|
||||
}
|
||||
else {
|
||||
// if dragging within a XUL tree and no custom drag image was
|
||||
// set, the region argument to InvokeDragSessionWithImage needs
|
||||
// to be set to the area encompassing the selected rows of the
|
||||
// tree to ensure that the drag feedback gets clipped to those
|
||||
// rows. For other content, region should be null.
|
||||
nsCOMPtr<nsIScriptableRegion> region;
|
||||
#ifdef MOZ_XUL
|
||||
if (dragTarget && !dragImage) {
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(dragTarget);
|
||||
if (content->NodeInfo()->Equals(nsGkAtoms::treechildren,
|
||||
kNameSpaceID_XUL)) {
|
||||
nsIDocument* doc = content->GetCurrentDoc();
|
||||
if (doc) {
|
||||
nsIPresShell* presShell = doc->GetPrimaryShell();
|
||||
if (presShell) {
|
||||
nsIFrame* frame = presShell->GetPrimaryFrameFor(content);
|
||||
if (frame) {
|
||||
nsITreeBoxObject* treeBoxObject;
|
||||
CallQueryInterface(frame, &treeBoxObject);
|
||||
treeBoxObject->GetSelectionRegion(getter_AddRefs(region));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
dragService->InvokeDragSessionWithImage(dragTarget, transArray,
|
||||
region, action, dragImage,
|
||||
imageX, imageY, domDragEvent,
|
||||
aDataTransfer);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEventStateManager::GetMarkupDocumentViewer(nsIMarkupDocumentViewer** aMv)
|
||||
{
|
||||
|
@ -2539,10 +2811,124 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
|||
|
||||
break;
|
||||
|
||||
case NS_DRAGDROP_ENTER:
|
||||
case NS_DRAGDROP_OVER:
|
||||
{
|
||||
NS_ASSERTION(aEvent->eventStructType == NS_DRAG_EVENT, "Expected a drag event");
|
||||
|
||||
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
|
||||
if (!dragSession)
|
||||
break;
|
||||
|
||||
// the initial dataTransfer is the one from the dragstart event that
|
||||
// was set on the dragSession when the drag began.
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> dataTransfer;
|
||||
nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
|
||||
dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
|
||||
|
||||
nsCOMPtr<nsIDOMNSDataTransfer> initialDataTransferNS =
|
||||
do_QueryInterface(initialDataTransfer);
|
||||
|
||||
// cancelling a dragenter or dragover event means that a drop should be
|
||||
// allowed, so update the dropEffect and the canDrop state to indicate
|
||||
// that a drag is allowed. If the event isn't cancelled, a drop won't be
|
||||
// allowed. Essentially, to allow a drop somewhere, specify the effects
|
||||
// using the effectAllowed and dropEffect properties in a dragenter or
|
||||
// dragover event and cancel the event. To not allow a drop somewhere,
|
||||
// don't cancel the event or set the effectAllowed or dropEffect to
|
||||
// "none". This way, if the event is just ignored, no drop will be
|
||||
// allowed.
|
||||
PRUint32 dropEffect = nsIDragService::DRAGDROP_ACTION_NONE;
|
||||
if (nsEventStatus_eConsumeNoDefault == *aStatus) {
|
||||
// if the event has a dataTransfer set, use it.
|
||||
nsDragEvent *dragEvent = (nsDragEvent*)aEvent;
|
||||
if (dragEvent->dataTransfer) {
|
||||
// get the dataTransfer and the dropEffect that was set on it
|
||||
dataTransfer = do_QueryInterface(dragEvent->dataTransfer);
|
||||
dataTransfer->GetDropEffectInt(&dropEffect);
|
||||
}
|
||||
else {
|
||||
// if dragEvent->dataTransfer is null, it means that no attempt was
|
||||
// made to access the dataTransfer during the event, yet the event
|
||||
// was cancelled. Instead, use the initial data transfer available
|
||||
// from the drag session. The drop effect would not have been
|
||||
// initialized (which is done in nsDOMDragEvent::GetDataTransfer),
|
||||
// so set it from the drag action. We'll still want to filter it
|
||||
// based on the effectAllowed below.
|
||||
dataTransfer = initialDataTransferNS;
|
||||
|
||||
PRUint32 action;
|
||||
dragSession->GetDragAction(&action);
|
||||
|
||||
// filter the drop effect based on the action. Use UNINITIALIZED as
|
||||
// any effect is allowed.
|
||||
dropEffect = nsDOMDragEvent::FilterDropEffect(action,
|
||||
nsIDragService::DRAGDROP_ACTION_UNINITIALIZED);
|
||||
}
|
||||
|
||||
// At this point, if the dataTransfer is null, it means that the
|
||||
// drag was originally started by directly calling the drag service.
|
||||
// Just assume that all effects are allowed.
|
||||
PRUint32 effectAllowed = nsIDragService::DRAGDROP_ACTION_UNINITIALIZED;
|
||||
if (dataTransfer)
|
||||
dataTransfer->GetEffectAllowedInt(&effectAllowed);
|
||||
|
||||
// set the drag action based on the drop effect and effect allowed.
|
||||
// The drop effect field on the drag transfer object specifies the
|
||||
// desired current drop effect. However, it cannot be used if the
|
||||
// effectAllowed state doesn't include that type of action. If the
|
||||
// dropEffect is "none", then the action will be 'none' so a drop will
|
||||
// not be allowed.
|
||||
PRUint32 action = nsIDragService::DRAGDROP_ACTION_NONE;
|
||||
if (effectAllowed == nsIDragService::DRAGDROP_ACTION_UNINITIALIZED ||
|
||||
dropEffect & effectAllowed)
|
||||
action = dropEffect;
|
||||
|
||||
if (action == nsIDragService::DRAGDROP_ACTION_NONE)
|
||||
dropEffect = nsIDragService::DRAGDROP_ACTION_NONE;
|
||||
|
||||
// inform the drag session that a drop is allowed on this node.
|
||||
dragSession->SetDragAction(action);
|
||||
dragSession->SetCanDrop(action != nsIDragService::DRAGDROP_ACTION_NONE);
|
||||
}
|
||||
|
||||
// now set the drop effect in the initial dataTransfer. This ensures
|
||||
// that we can get the desired drop effect in the drop event.
|
||||
if (initialDataTransferNS)
|
||||
initialDataTransferNS->SetDropEffectInt(dropEffect);
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_DRAGDROP_DROP:
|
||||
{
|
||||
// now fire the dragdrop event, for compatibility with XUL
|
||||
if (mCurrentTarget && nsEventStatus_eConsumeNoDefault != *aStatus) {
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
mCurrentTarget->GetContentForEvent(presContext, aEvent,
|
||||
getter_AddRefs(targetContent));
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = mCurrentTarget->GetWindow();
|
||||
nsDragEvent event(NS_IS_TRUSTED_EVENT(aEvent), NS_DRAGDROP_DRAGDROP, widget);
|
||||
|
||||
nsMouseEvent* mouseEvent = static_cast<nsMouseEvent*>(aEvent);
|
||||
event.refPoint = mouseEvent->refPoint;
|
||||
event.isShift = mouseEvent->isShift;
|
||||
event.isControl = mouseEvent->isControl;
|
||||
event.isAlt = mouseEvent->isAlt;
|
||||
event.isMeta = mouseEvent->isMeta;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
|
||||
if (presShell) {
|
||||
presShell->HandleEventWithTarget(&event, mCurrentTarget,
|
||||
targetContent, &status);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NS_DRAGDROP_EXIT:
|
||||
// clean up after ourselves. make sure we do this _after_ the event, else we'll
|
||||
// clean up too early!
|
||||
// make sure to fire the enter and exit_synth events after the
|
||||
// NS_DRAGDROP_EXIT event, otherwise we'll clean up too early
|
||||
GenerateDragDropEnterExit(presContext, (nsGUIEvent*)aEvent);
|
||||
break;
|
||||
|
||||
|
@ -3176,6 +3562,8 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
|
|||
//The frame has changed but the content may not have. Check before dispatching to content
|
||||
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
|
||||
|
||||
FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_LEAVE_SYNTH,
|
||||
targetContent, lastContent, mLastDragOverFrame);
|
||||
FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_EXIT_SYNTH,
|
||||
targetContent, lastContent, mLastDragOverFrame);
|
||||
}
|
||||
|
@ -3196,6 +3584,8 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
|
|||
nsCOMPtr<nsIContent> lastContent;
|
||||
mLastDragOverFrame->GetContentForEvent(aPresContext, aEvent, getter_AddRefs(lastContent));
|
||||
|
||||
FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_LEAVE_SYNTH,
|
||||
nsnull, lastContent, mLastDragOverFrame);
|
||||
FireDragEnterOrExit(aPresContext, aEvent, NS_DRAGDROP_EXIT_SYNTH,
|
||||
nsnull, lastContent, mLastDragOverFrame);
|
||||
|
||||
|
@ -3221,8 +3611,7 @@ nsEventStateManager::FireDragEnterOrExit(nsPresContext* aPresContext,
|
|||
nsWeakFrame& aTargetFrame)
|
||||
{
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent), aMsg,
|
||||
aEvent->widget, nsMouseEvent::eReal);
|
||||
nsDragEvent event(NS_IS_TRUSTED_EVENT(aEvent), aMsg, aEvent->widget);
|
||||
event.refPoint = aEvent->refPoint;
|
||||
event.isShift = ((nsMouseEvent*)aEvent)->isShift;
|
||||
event.isControl = ((nsMouseEvent*)aEvent)->isControl;
|
||||
|
|
|
@ -60,6 +60,7 @@ class nsIDocShellTreeNode;
|
|||
class nsIDocShellTreeItem;
|
||||
class nsIFocusController;
|
||||
class imgIContainer;
|
||||
class nsDOMDataTransfer;
|
||||
|
||||
// mac uses click-hold context menus, a holdover from 4.x
|
||||
#ifdef XP_MACOSX
|
||||
|
@ -257,7 +258,7 @@ protected:
|
|||
* that recursively called us in it's Up phase. The initial caller
|
||||
* passes |nsnull| here. This is to avoid an infinite loop.
|
||||
* @param aAccessKeyState Normal, Down or Up processing phase (see enums
|
||||
* above). The initial event reciever uses 'normal', then 'down' when
|
||||
* above). The initial event receiver uses 'normal', then 'down' when
|
||||
* processing children and Up when recursively calling its ancestor.
|
||||
* @param aModifierMask modifier mask for the key event
|
||||
*/
|
||||
|
@ -318,6 +319,38 @@ protected:
|
|||
nsIFrame* inDownFrame ) ;
|
||||
void StopTrackingDragGesture ( ) ;
|
||||
void GenerateDragGesture ( nsPresContext* aPresContext, nsMouseEvent *aEvent ) ;
|
||||
|
||||
/**
|
||||
* Determine which node the drag should be targeted at.
|
||||
* This is either the node clicked when there is a selection, or, for HTML,
|
||||
* the element with a draggable property set to true.
|
||||
*
|
||||
* aSelectionTarget - target to check for selection
|
||||
* aDataTransfer - data transfer object that will contain the data to drag
|
||||
* aIsSelection - [out] set to true if a selection is being dragged
|
||||
* aTargetNode - [out] the draggable node, or null if there isn't one
|
||||
*/
|
||||
void DetermineDragTarget(nsPresContext* aPresContext,
|
||||
nsIContent* aSelectionTarget,
|
||||
nsDOMDataTransfer* aDataTransfer,
|
||||
PRBool* aIsSelection,
|
||||
nsIContent** aTargetNode);
|
||||
|
||||
/*
|
||||
* Perform the default handling for the dragstart/draggesture event and set up a
|
||||
* drag for aDataTransfer if it contains any data.
|
||||
*
|
||||
* aDragEvent - the dragstart/draggesture event
|
||||
* aDataTransfer - the data transfer that holds the data to be dragged
|
||||
* aDragTarget - the target of the drag
|
||||
* aIsSelection - true if a selection is being dragged
|
||||
*/
|
||||
void DoDefaultDragStart(nsPresContext* aPresContext,
|
||||
nsDragEvent* aDragEvent,
|
||||
nsDOMDataTransfer* aDataTransfer,
|
||||
nsIContent* aDragTarget,
|
||||
PRBool aIsSelection);
|
||||
|
||||
PRBool IsTrackingDragGesture ( ) const { return mGestureDownContent != nsnull; }
|
||||
/**
|
||||
* Set the fields of aEvent to reflect the mouse position and modifier keys
|
||||
|
|
|
@ -61,6 +61,8 @@ _TEST_FILES = \
|
|||
test_bug412567.html \
|
||||
test_bug443985.html \
|
||||
test_bug447736.html \
|
||||
test_draggableprop.html \
|
||||
test_dragstart.html \
|
||||
$(NULL)
|
||||
|
||||
_CHROME_FILES = \
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче