mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-26 06:38:36 +00:00
merge fx-team to m-c
This commit is contained in:
commit
3bf1f57058
@ -43,7 +43,7 @@
|
||||
|
||||
interface nsIEditor;
|
||||
|
||||
[scriptable, uuid(52837507-202d-4e72-a482-5f068a1fd720)]
|
||||
[scriptable, uuid(e242d495-5cde-4b1c-8c84-2525b14939f5)]
|
||||
interface nsIAccessibleEditableText : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -103,19 +103,4 @@ interface nsIAccessibleEditableText : nsISupports
|
||||
* clipboard into the text represented by this object.
|
||||
*/
|
||||
void pasteText (in long position);
|
||||
|
||||
/**
|
||||
* Returns an editor associated with the accessible.
|
||||
*/
|
||||
[noscript] readonly attribute nsIEditor associatedEditor;
|
||||
};
|
||||
|
||||
/*
|
||||
Assumptions:
|
||||
|
||||
selectAttributes method takes an nsISupports parameter.
|
||||
'set' methods throw exception on failure.
|
||||
'wstring' inputs are potentially multibyte (UTF-16 for
|
||||
instance); 'string' and UTF-8 may be a better choice.
|
||||
|
||||
*/
|
||||
|
@ -696,6 +696,16 @@ nsApplicationAccessibleWrap::Unload()
|
||||
// }
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationAccessibleWrap::GetName(nsAString& aName)
|
||||
{
|
||||
// ATK doesn't provide a way to obtain an application name (for example,
|
||||
// Firefox or Thunderbird) like IA2 does. Thus let's return an application
|
||||
// name as accessible name that was used to get a branding name (for example,
|
||||
// Minefield aka nightly Firefox or Daily aka nightly Thunderbird).
|
||||
return GetAppName(aName);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationAccessibleWrap::GetNativeInterface(void **aOutAccessible)
|
||||
{
|
||||
|
@ -57,6 +57,8 @@ public:
|
||||
virtual bool Init();
|
||||
|
||||
// nsAccessible
|
||||
NS_IMETHOD GetName(nsAString &aName);
|
||||
|
||||
virtual bool AppendChild(nsAccessible* aChild);
|
||||
virtual bool RemoveChild(nsAccessible* aChild);
|
||||
|
||||
|
@ -680,8 +680,7 @@ NotificationController::CreateTextChangeEventFor(AccMutationEvent* aEvent)
|
||||
|
||||
// Don't fire event for the first html:br in an editor.
|
||||
if (aEvent->mAccessible->Role() == roles::WHITESPACE) {
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
textAccessible->GetAssociatedEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIEditor> editor = textAccessible->GetEditor();
|
||||
if (editor) {
|
||||
bool isEmpty = false;
|
||||
editor->GetDocumentIsEmpty(&isEmpty);
|
||||
|
@ -969,10 +969,8 @@ void nsAccessible::GetBoundsRect(nsRect& aTotalBounds, nsIFrame** aBoundingFrame
|
||||
*aBoundingFrame = ancestorFrame;
|
||||
// If any other frame type, we only need to deal with the primary frame
|
||||
// Otherwise, there may be more frames attached to the same content node
|
||||
if (!nsCoreUtils::IsCorrectFrameType(ancestorFrame,
|
||||
nsGkAtoms::inlineFrame) &&
|
||||
!nsCoreUtils::IsCorrectFrameType(ancestorFrame,
|
||||
nsGkAtoms::textFrame))
|
||||
if (ancestorFrame->GetType() != nsGkAtoms::inlineFrame &&
|
||||
ancestorFrame->GetType() != nsGkAtoms::textFrame)
|
||||
break;
|
||||
ancestorFrame = ancestorFrame->GetParent();
|
||||
}
|
||||
@ -996,8 +994,7 @@ void nsAccessible::GetBoundsRect(nsRect& aTotalBounds, nsIFrame** aBoundingFrame
|
||||
|
||||
nsIFrame *iterNextFrame = nsnull;
|
||||
|
||||
if (nsCoreUtils::IsCorrectFrameType(iterFrame,
|
||||
nsGkAtoms::inlineFrame)) {
|
||||
if (iterFrame->GetType() == nsGkAtoms::inlineFrame) {
|
||||
// Only do deeper bounds search if we're on an inline frame
|
||||
// Inline frames can contain larger frames inside of them
|
||||
iterNextFrame = iterFrame->GetFirstPrincipalChild();
|
||||
|
@ -214,6 +214,11 @@ public:
|
||||
*/
|
||||
virtual PRUint64 NativeState();
|
||||
|
||||
/**
|
||||
* Return bit set of invisible and offscreen states.
|
||||
*/
|
||||
PRUint64 VisibilityState();
|
||||
|
||||
/**
|
||||
* Returns attributes for accessible without explicitly setted ARIA
|
||||
* attributes.
|
||||
@ -702,8 +707,6 @@ protected:
|
||||
virtual nsIFrame* GetBoundsFrame();
|
||||
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
|
||||
|
||||
PRUint64 VisibilityState();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Name helpers
|
||||
|
||||
|
@ -503,17 +503,6 @@ nsCoreUtils::IsErrorPage(nsIDocument *aDocument)
|
||||
return StringBeginsWith(path, neterror) || StringBeginsWith(path, certerror);
|
||||
}
|
||||
|
||||
bool
|
||||
nsCoreUtils::IsCorrectFrameType(nsIFrame *aFrame, nsIAtom *aAtom)
|
||||
{
|
||||
NS_ASSERTION(aFrame != nsnull,
|
||||
"aFrame is null in call to IsCorrectFrameType!");
|
||||
NS_ASSERTION(aAtom != nsnull,
|
||||
"aAtom is null in call to IsCorrectFrameType!");
|
||||
|
||||
return aFrame->GetType() == aAtom;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMNode>
|
||||
nsCoreUtils::GetDOMNodeForContainer(nsIDocShellTreeItem *aContainer)
|
||||
{
|
||||
|
@ -241,14 +241,6 @@ public:
|
||||
*/
|
||||
static bool IsErrorPage(nsIDocument *aDocument);
|
||||
|
||||
/**
|
||||
* Retrun true if the type of given frame equals to the given frame type.
|
||||
*
|
||||
* @param aFrame the frame
|
||||
* @param aAtom the frame type
|
||||
*/
|
||||
static bool IsCorrectFrameType(nsIFrame* aFrame, nsIAtom* aAtom);
|
||||
|
||||
/**
|
||||
* Return presShell for the document containing the given DOM node.
|
||||
*/
|
||||
|
@ -333,8 +333,7 @@ nsDocAccessible::NativeState()
|
||||
state |= states::INVISIBLE | states::OFFSCREEN;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
state |= editor ? states::EDITABLE : states::READONLY;
|
||||
|
||||
return state;
|
||||
@ -553,37 +552,32 @@ nsDocAccessible::GetVirtualCursor(nsIAccessiblePivot** aVirtualCursor)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIAccessibleHyperText method
|
||||
NS_IMETHODIMP nsDocAccessible::GetAssociatedEditor(nsIEditor **aEditor)
|
||||
// nsHyperTextAccessible method
|
||||
already_AddRefed<nsIEditor>
|
||||
nsDocAccessible::GetEditor() const
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEditor);
|
||||
*aEditor = nsnull;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Check if document is editable (designMode="on" case). Otherwise check if
|
||||
// the html:body (for HTML document case) or document element is editable.
|
||||
if (!mDocument->HasFlag(NODE_IS_EDITABLE) &&
|
||||
!mContent->HasFlag(NODE_IS_EDITABLE))
|
||||
return NS_OK;
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsISupports> container = mDocument->GetContainer();
|
||||
nsCOMPtr<nsIEditingSession> editingSession(do_GetInterface(container));
|
||||
if (!editingSession)
|
||||
return NS_OK; // No editing session interface
|
||||
return nsnull; // No editing session interface
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
editingSession->GetEditorForWindow(mDocument->GetWindow(), getter_AddRefs(editor));
|
||||
if (!editor) {
|
||||
return NS_OK;
|
||||
}
|
||||
bool isEditable;
|
||||
if (!editor)
|
||||
return nsnull;
|
||||
|
||||
bool isEditable = false;
|
||||
editor->GetIsDocumentEditable(&isEditable);
|
||||
if (isEditable) {
|
||||
NS_ADDREF(*aEditor = editor);
|
||||
}
|
||||
return NS_OK;
|
||||
if (isEditable)
|
||||
return editor.forget();
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// nsDocAccessible public method
|
||||
|
@ -133,8 +133,8 @@ public:
|
||||
virtual nsresult HandleAccEvent(AccEvent* aAccEvent);
|
||||
#endif
|
||||
|
||||
// nsIAccessibleText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
// nsHyperTextAccessible
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() const;
|
||||
|
||||
// nsDocAccessible
|
||||
|
||||
|
@ -544,11 +544,12 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::DoAction(PRUint8 index)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor)
|
||||
already_AddRefed<nsIEditor>
|
||||
nsHTMLTextFieldAccessible::GetEditor() const
|
||||
{
|
||||
*aEditor = nsnull;
|
||||
nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(mContent));
|
||||
NS_ENSURE_TRUE(editableElt, NS_ERROR_FAILURE);
|
||||
if (!editableElt)
|
||||
return nsnull;
|
||||
|
||||
// nsGenericHTMLElement::GetEditor has a security check.
|
||||
// Make sure we're not restricted by the permissions of
|
||||
@ -558,7 +559,7 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor
|
||||
bool pushed = stack && NS_SUCCEEDED(stack->Push(nsnull));
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
nsresult rv = editableElt->GetEditor(aEditor);
|
||||
editableElt->GetEditor(getter_AddRefs(editor));
|
||||
|
||||
if (pushed) {
|
||||
JSContext* cx;
|
||||
@ -566,7 +567,7 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor
|
||||
NS_ASSERTION(!cx, "context should be null");
|
||||
}
|
||||
|
||||
return rv;
|
||||
return editor.forget();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -138,8 +138,8 @@ public:
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
|
||||
// nsIAccessibleEditableText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
// nsHyperTextAccessible
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() const;
|
||||
|
||||
// nsAccessible
|
||||
virtual void ApplyARIAState(PRUint64* aState);
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "States.h"
|
||||
|
||||
#include "nsIClipboard.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsIDOMCharacterData.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
@ -165,8 +166,7 @@ nsHyperTextAccessible::NativeState()
|
||||
{
|
||||
PRUint64 states = nsAccessibleWrap::NativeState();
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
if (editor) {
|
||||
PRUint32 flags;
|
||||
editor->GetFlags(&flags);
|
||||
@ -710,8 +710,7 @@ nsHyperTextAccessible::HypertextOffsetsToDOMRange(PRInt32 aStartHTOffset,
|
||||
// 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));
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
if (editor) {
|
||||
bool isEmpty = false;
|
||||
editor->GetDocumentIsEmpty(&isEmpty);
|
||||
@ -1153,15 +1152,14 @@ nsHyperTextAccessible::GetTextAttributes(bool aIncludeDefAttrs,
|
||||
// Compute spelling attributes on text accessible only.
|
||||
nsIFrame *offsetFrame = accAtOffset->GetFrame();
|
||||
if (offsetFrame && offsetFrame->GetType() == nsGkAtoms::textFrame) {
|
||||
nsCOMPtr<nsIDOMNode> node = accAtOffset->DOMNode();
|
||||
|
||||
PRInt32 nodeOffset = 0;
|
||||
nsresult rv = RenderedToContentOffset(offsetFrame, offsetInAcc,
|
||||
&nodeOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set 'misspelled' text attribute.
|
||||
rv = GetSpellTextAttribute(node, nodeOffset, &startOffset, &endOffset,
|
||||
rv = GetSpellTextAttribute(accAtOffset->GetNode(), nodeOffset,
|
||||
&startOffset, &endOffset,
|
||||
aAttributes ? *aAttributes : nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
@ -1455,8 +1453,10 @@ NS_IMETHODIMP nsHyperTextAccessible::SetTextContents(const nsAString &aText)
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::InsertText(const nsAString &aText, PRInt32 aPosition)
|
||||
{
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
|
||||
nsCOMPtr<nsIPlaintextEditor> peditor(do_QueryInterface(editor));
|
||||
NS_ENSURE_STATE(peditor);
|
||||
@ -1470,8 +1470,10 @@ nsHyperTextAccessible::InsertText(const nsAString &aText, PRInt32 aPosition)
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::CopyText(PRInt32 aStartPos, PRInt32 aEndPos)
|
||||
{
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
NS_ENSURE_STATE(editor);
|
||||
|
||||
nsresult rv = SetSelectionRange(aStartPos, aEndPos);
|
||||
@ -1483,8 +1485,10 @@ nsHyperTextAccessible::CopyText(PRInt32 aStartPos, PRInt32 aEndPos)
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::CutText(PRInt32 aStartPos, PRInt32 aEndPos)
|
||||
{
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
NS_ENSURE_STATE(editor);
|
||||
|
||||
nsresult rv = SetSelectionRange(aStartPos, aEndPos);
|
||||
@ -1496,8 +1500,10 @@ nsHyperTextAccessible::CutText(PRInt32 aStartPos, PRInt32 aEndPos)
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::DeleteText(PRInt32 aStartPos, PRInt32 aEndPos)
|
||||
{
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
NS_ENSURE_STATE(editor);
|
||||
|
||||
nsresult rv = SetSelectionRange(aStartPos, aEndPos);
|
||||
@ -1509,8 +1515,10 @@ nsHyperTextAccessible::DeleteText(PRInt32 aStartPos, PRInt32 aEndPos)
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::PasteText(PRInt32 aPosition)
|
||||
{
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
NS_ENSURE_STATE(editor);
|
||||
|
||||
nsresult rv = SetSelectionRange(aPosition, aPosition);
|
||||
@ -1519,44 +1527,37 @@ nsHyperTextAccessible::PasteText(PRInt32 aPosition)
|
||||
return editor->Paste(nsIClipboard::kGlobalClipboard);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHyperTextAccessible::GetAssociatedEditor(nsIEditor **aEditor)
|
||||
already_AddRefed<nsIEditor>
|
||||
nsHyperTextAccessible::GetEditor() const
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEditor);
|
||||
*aEditor = nsnull;
|
||||
|
||||
if (IsDefunct())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!mContent->HasFlag(NODE_IS_EDITABLE)) {
|
||||
// If we're inside an editable container, then return that container's editor
|
||||
nsCOMPtr<nsIAccessible> ancestor, current = this;
|
||||
while (NS_SUCCEEDED(current->GetParent(getter_AddRefs(ancestor))) && ancestor) {
|
||||
nsRefPtr<nsHyperTextAccessible> ancestorTextAccessible;
|
||||
ancestor->QueryInterface(NS_GET_IID(nsHyperTextAccessible),
|
||||
getter_AddRefs(ancestorTextAccessible));
|
||||
if (ancestorTextAccessible) {
|
||||
nsAccessible* ancestor = Parent();
|
||||
while (ancestor) {
|
||||
nsHyperTextAccessible* hyperText = ancestor->AsHyperText();
|
||||
if (hyperText) {
|
||||
// Recursion will stop at container doc because it has its own impl
|
||||
// of GetAssociatedEditor()
|
||||
return ancestorTextAccessible->GetAssociatedEditor(aEditor);
|
||||
// of GetEditor()
|
||||
return hyperText->GetEditor();
|
||||
}
|
||||
current = ancestor;
|
||||
|
||||
ancestor = ancestor->Parent();
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
|
||||
nsCoreUtils::GetDocShellTreeItemFor(mContent);
|
||||
nsCOMPtr<nsIEditingSession> editingSession(do_GetInterface(docShellTreeItem));
|
||||
if (!editingSession)
|
||||
return NS_OK; // No editing session interface
|
||||
|
||||
NS_ENSURE_TRUE(mDoc, NS_ERROR_FAILURE);
|
||||
nsIDocument* docNode = mDoc->GetDocumentNode();
|
||||
NS_ENSURE_TRUE(docNode, NS_ERROR_FAILURE);
|
||||
return nsnull; // No editing session interface
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
return editingSession->GetEditorForWindow(docNode->GetWindow(), aEditor);
|
||||
nsIDocument* docNode = mDoc->GetDocumentNode();
|
||||
editingSession->GetEditorForWindow(docNode->GetWindow(),
|
||||
getter_AddRefs(editor));
|
||||
return editor.forget();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1770,8 +1771,7 @@ nsHyperTextAccessible::GetSelectionDOMRanges(PRInt16 aType,
|
||||
|
||||
nsCOMPtr<nsINode> startNode = GetNode();
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
if (editor) {
|
||||
nsCOMPtr<nsIDOMElement> editorRoot;
|
||||
editor->GetRootElement(getter_AddRefs(editorRoot));
|
||||
@ -1789,13 +1789,11 @@ nsHyperTextAccessible::GetSelectionDOMRanges(PRInt16 aType,
|
||||
|
||||
// Remove collapsed ranges
|
||||
PRUint32 numRanges = aRanges->Length();
|
||||
for (PRUint32 count = 0; count < numRanges; count ++) {
|
||||
bool isCollapsed = false;
|
||||
(*aRanges)[count]->GetCollapsed(&isCollapsed);
|
||||
if (isCollapsed) {
|
||||
aRanges->RemoveElementAt(count);
|
||||
for (PRUint32 idx = 0; idx < numRanges; idx ++) {
|
||||
if ((*aRanges)[idx]->Collapsed()) {
|
||||
aRanges->RemoveElementAt(idx);
|
||||
--numRanges;
|
||||
--count;
|
||||
--idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1837,29 +1835,19 @@ nsHyperTextAccessible::GetSelectionBounds(PRInt32 aSelectionNum,
|
||||
|
||||
nsRange* range = ranges[aSelectionNum];
|
||||
|
||||
// Get start point
|
||||
nsCOMPtr<nsIDOMNode> startDOMNode;
|
||||
range->GetStartContainer(getter_AddRefs(startDOMNode));
|
||||
nsCOMPtr<nsINode> startNode(do_QueryInterface(startDOMNode));
|
||||
PRInt32 startOffset = 0;
|
||||
range->GetStartOffset(&startOffset);
|
||||
// Get start and end points.
|
||||
nsINode* startNode = range->GetStartParent();
|
||||
nsINode* endNode = range->GetEndParent();
|
||||
PRInt32 startOffset = range->StartOffset(), endOffset = range->EndOffset();
|
||||
|
||||
// Get end point
|
||||
nsCOMPtr<nsIDOMNode> endDOMNode;
|
||||
range->GetEndContainer(getter_AddRefs(endDOMNode));
|
||||
nsCOMPtr<nsINode> endNode(do_QueryInterface(endDOMNode));
|
||||
PRInt32 endOffset = 0;
|
||||
range->GetEndOffset(&endOffset);
|
||||
|
||||
PRInt16 rangeCompareResult = 0;
|
||||
nsresult rv = range->CompareBoundaryPoints(nsIDOMRange::START_TO_END, range,
|
||||
&rangeCompareResult);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (rangeCompareResult < 0) {
|
||||
// Make sure start is before end, by swapping offsets
|
||||
// This occurs when the user selects backwards in the text
|
||||
startNode.swap(endNode);
|
||||
// Make sure start is before end, by swapping DOM points. This occurs when
|
||||
// the user selects backwards in the text.
|
||||
PRInt32 rangeCompare = nsContentUtils::ComparePoints(endNode, endOffset,
|
||||
startNode, startOffset);
|
||||
if (rangeCompare < 0) {
|
||||
nsINode* tempNode = startNode;
|
||||
startNode = endNode;
|
||||
endNode = tempNode;
|
||||
PRInt32 tempOffset = startOffset;
|
||||
startOffset = endOffset;
|
||||
endOffset = tempOffset;
|
||||
@ -2324,25 +2312,17 @@ nsHyperTextAccessible::RangeBoundToHypertextOffset(nsRange *aRange,
|
||||
bool aIsStartHTOffset,
|
||||
PRInt32 *aHTOffset)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> DOMNode;
|
||||
nsINode* node = nsnull;
|
||||
PRInt32 nodeOffset = 0;
|
||||
|
||||
nsresult rv;
|
||||
if (aIsStartBound) {
|
||||
rv = aRange->GetStartContainer(getter_AddRefs(DOMNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aRange->GetStartOffset(&nodeOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
node = aRange->GetStartParent();
|
||||
nodeOffset = aRange->StartOffset();
|
||||
} else {
|
||||
rv = aRange->GetEndContainer(getter_AddRefs(DOMNode));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = aRange->GetEndOffset(&nodeOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
node = aRange->GetEndParent();
|
||||
nodeOffset = aRange->EndOffset();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> node(do_QueryInterface(DOMNode));
|
||||
nsAccessible *startAcc =
|
||||
DOMPointToHypertextOffset(node, nodeOffset, aHTOffset);
|
||||
|
||||
@ -2354,7 +2334,7 @@ nsHyperTextAccessible::RangeBoundToHypertextOffset(nsRange *aRange,
|
||||
|
||||
// nsHyperTextAccessible
|
||||
nsresult
|
||||
nsHyperTextAccessible::GetSpellTextAttribute(nsIDOMNode *aNode,
|
||||
nsHyperTextAccessible::GetSpellTextAttribute(nsINode* aNode,
|
||||
PRInt32 aNodeOffset,
|
||||
PRInt32 *aHTStartOffset,
|
||||
PRInt32 *aHTEndOffset,
|
||||
@ -2367,25 +2347,19 @@ nsHyperTextAccessible::GetSpellTextAttribute(nsIDOMNode *aNode,
|
||||
if (!rangeCount)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> DOMNode = do_QueryInterface(aNode);
|
||||
for (PRUint32 index = 0; index < rangeCount; index++) {
|
||||
nsRange* range = ranges[index];
|
||||
|
||||
PRInt16 result;
|
||||
nsresult rv = range->ComparePoint(aNode, aNodeOffset, &result);
|
||||
nsresult rv = range->ComparePoint(DOMNode, aNodeOffset, &result);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// ComparePoint checks boundary points, but we need to check that
|
||||
// text at aNodeOffset is inside the range.
|
||||
// See also bug 460690.
|
||||
if (result == 0) {
|
||||
nsCOMPtr<nsIDOMNode> end;
|
||||
rv = range->GetEndContainer(getter_AddRefs(end));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRInt32 endOffset;
|
||||
rv = range->GetEndOffset(&endOffset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (aNode == end && aNodeOffset == endOffset) {
|
||||
if (aNode == range->GetEndParent() && aNodeOffset == range->EndOffset())
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (result == 1) { // range is before point
|
||||
|
@ -264,6 +264,14 @@ public:
|
||||
return GetChildAt(GetChildIndexAtOffset(aOffset));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// EditableTextAccessible
|
||||
|
||||
/**
|
||||
* Return the editor associated with the accessible.
|
||||
*/
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() const;
|
||||
|
||||
protected:
|
||||
// nsHyperTextAccessible
|
||||
|
||||
@ -409,7 +417,7 @@ protected:
|
||||
* @param aEndOffset [in, out] the end offset
|
||||
* @param aAttributes [out, optional] result attributes
|
||||
*/
|
||||
nsresult GetSpellTextAttribute(nsIDOMNode *aNode, PRInt32 aNodeOffset,
|
||||
nsresult GetSpellTextAttribute(nsINode* aNode, PRInt32 aNodeOffset,
|
||||
PRInt32 *aStartOffset,
|
||||
PRInt32 *aEndOffset,
|
||||
nsIPersistentProperties *aAttributes);
|
||||
|
@ -273,8 +273,7 @@ nsXFormsEditableAccessible::NativeState()
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
GetAssociatedEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIEditor> editor = GetEditor();
|
||||
NS_ENSURE_TRUE(editor, state);
|
||||
PRUint32 flags;
|
||||
editor->GetFlags(&flags);
|
||||
@ -286,11 +285,14 @@ nsXFormsEditableAccessible::NativeState()
|
||||
return state;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXFormsEditableAccessible::GetAssociatedEditor(nsIEditor **aEditor)
|
||||
already_AddRefed<nsIEditor>
|
||||
nsXFormsEditableAccessible::GetEditor() const
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
|
||||
return sXFormsService->GetEditor(DOMNode, aEditor);
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
sXFormsService->GetEditor(DOMNode, getter_AddRefs(editor));
|
||||
return editor.forget();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -144,8 +144,8 @@ class nsXFormsEditableAccessible : public nsXFormsAccessible
|
||||
public:
|
||||
nsXFormsEditableAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
|
||||
|
||||
// nsIAccessibleEditableText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
// nsHyperTextAccessible
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() const;
|
||||
|
||||
// nsAccessible
|
||||
virtual PRUint64 NativeState();
|
||||
|
@ -850,14 +850,17 @@ nsXULTextFieldAccessible::CanHaveAnonChildren()
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsXULTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor)
|
||||
already_AddRefed<nsIEditor>
|
||||
nsXULTextFieldAccessible::GetEditor() const
|
||||
{
|
||||
*aEditor = nsnull;
|
||||
|
||||
nsCOMPtr<nsIContent> inputField = GetInputField();
|
||||
nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(inputField));
|
||||
NS_ENSURE_TRUE(editableElt, NS_ERROR_FAILURE);
|
||||
return editableElt->GetEditor(aEditor);
|
||||
if (!editableElt)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
editableElt->GetEditor(getter_AddRefs(editor));
|
||||
return editor.forget();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -260,8 +260,8 @@ public:
|
||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||
NS_IMETHOD DoAction(PRUint8 index);
|
||||
|
||||
// nsIAccessibleEditableText
|
||||
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor);
|
||||
// nsHyperTextAccessible
|
||||
virtual already_AddRefed<nsIEditor> GetEditor() const;
|
||||
|
||||
// nsAccessible
|
||||
virtual void ApplyARIAState(PRUint64* aState);
|
||||
|
@ -613,9 +613,9 @@ function getNodePrettyName(aNode)
|
||||
function getObjAddress(aObj)
|
||||
{
|
||||
var exp = /native\s*@\s*(0x[a-f0-9]+)/g;
|
||||
var match = exp.exec(aObj.valueOf());
|
||||
var match = exp.exec(aObj.toString());
|
||||
if (match)
|
||||
return match[1];
|
||||
|
||||
return aObj.valueOf();
|
||||
return aObj.toString();
|
||||
}
|
||||
|
@ -15,41 +15,46 @@
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
var accessible = getApplicationAccessible();
|
||||
if (!accessible) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
var accessible = getApplicationAccessible();
|
||||
if (!accessible) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// nsIAccessible::name
|
||||
var bundleServ = Components.classes["@mozilla.org/intl/stringbundle;1"]
|
||||
.getService(Components.interfaces.nsIStringBundleService);
|
||||
var bundle = bundleServ.createBundle("chrome://branding/locale/brand.properties");
|
||||
var bundleServ =
|
||||
Components.classes["@mozilla.org/intl/stringbundle;1"].
|
||||
getService(Components.interfaces.nsIStringBundleService);
|
||||
var brandBundle =
|
||||
bundleServ.createBundle("chrome://branding/locale/brand.properties");
|
||||
|
||||
var applicationName = "";
|
||||
var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].
|
||||
getService(Components.interfaces.nsIXULAppInfo);
|
||||
|
||||
// nsIAccessible::name
|
||||
var applicationName = "";
|
||||
if (LINUX || SOLARIS) {
|
||||
applicationName = appInfo.name;
|
||||
} else {
|
||||
try {
|
||||
applicationName = bundle.GetStringFromName("brandShortName");
|
||||
} catch(e) {
|
||||
applicationName = brandBundle.GetStringFromName("brandShortName");
|
||||
} catch(e) {
|
||||
}
|
||||
|
||||
if (applicationName == "")
|
||||
applicationName = "Gecko based application";
|
||||
applicationName = "Gecko based application";
|
||||
}
|
||||
is (accessible.name, applicationName, "wrong application accessible name");
|
||||
|
||||
is (accessible.name, applicationName, "wrong application accessible name");
|
||||
// nsIAccessibleApplication
|
||||
is(accessible.appName, appInfo.name, "Wrong application name");
|
||||
is(accessible.appVersion, appInfo.version, "Wrong application version");
|
||||
is(accessible.platformName, "Gecko", "Wrong platform name");
|
||||
is(accessible.platformVersion, appInfo.platformVersion,
|
||||
"Wrong platform version");
|
||||
|
||||
// nsIAccessibleApplication
|
||||
var appInfo = Components.classes["@mozilla.org/xre/app-info;1"].
|
||||
getService(Components.interfaces.nsIXULAppInfo);
|
||||
|
||||
is(accessible.appName, appInfo.name, "Wrong application name");
|
||||
is(accessible.appVersion, appInfo.version, "Wrong application version");
|
||||
is(accessible.platformName, "Gecko", "Wrong platform name");
|
||||
is(accessible.platformVersion, appInfo.platformVersion,
|
||||
"Wrong platform version");
|
||||
|
||||
SimpleTest.finish();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
|
@ -304,12 +304,20 @@ function eventQueue(aEventType)
|
||||
// Start processing of next invoker.
|
||||
invoker = this.getNextInvoker();
|
||||
|
||||
this.setEventHandler(invoker);
|
||||
|
||||
if (gLogger.isEnabled()) {
|
||||
gLogger.logToConsole("Event queue: \n invoke: " + invoker.getID());
|
||||
gLogger.logToDOM("EQ: invoke: " + invoker.getID(), true);
|
||||
}
|
||||
|
||||
this.setEventHandler(invoker);
|
||||
var infoText = "Invoke the '" + invoker.getID() + "' test { ";
|
||||
for (var idx = 0; idx < this.mEventSeq.length; idx++) {
|
||||
infoText += this.isEventUnexpected(idx) ? "un" : "";
|
||||
infoText += "expected '" + this.getEventTypeAsString(idx) + "' event; ";
|
||||
}
|
||||
infoText += " }";
|
||||
info(infoText);
|
||||
|
||||
if (invoker.invoke() == INVOKER_ACTION_FAILED) {
|
||||
// Invoker failed to prepare action, fail and finish tests.
|
||||
|
@ -384,14 +384,11 @@
|
||||
{
|
||||
if (SEAMONKEY) {
|
||||
todo(false, "Skipping this test on SeaMonkey ftb. (Bug 718237)");
|
||||
shutdownAutoComplete();
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// register 'test-a11y-search' autocomplete search
|
||||
initAutoComplete([ "hello", "hi" ],
|
||||
[ "Beep beep'm beep beep yeah", "Baby you can drive my car" ]);
|
||||
|
||||
gInitQueue = new eventQueue();
|
||||
gInitQueue.push(new loadFormAutoComplete("iframe"));
|
||||
gInitQueue.push(new initFormAutoCompleteBy("iframe", "hello"));
|
||||
@ -461,6 +458,12 @@
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Register 'test-a11y-search' autocomplete search.
|
||||
// XPFE AutoComplete needs to register early.
|
||||
initAutoComplete([ "hello", "hi" ],
|
||||
[ "Beep beep'm beep beep yeah", "Baby you can drive my car" ]);
|
||||
|
||||
addA11yLoadEvent(initTests);
|
||||
]]>
|
||||
</script>
|
||||
|
@ -35,10 +35,6 @@
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
// register 'test-a11y-search' autocomplete search
|
||||
initAutoComplete([ "hello", "hi" ],
|
||||
[ "Beep beep'm beep beep yeah", "Baby you can drive my car" ]);
|
||||
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new openCombobox("menulist"));
|
||||
@ -73,6 +69,12 @@
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// Register 'test-a11y-search' autocomplete search.
|
||||
// XPFE AutoComplete needs to register early.
|
||||
initAutoComplete([ "hello", "hi" ],
|
||||
[ "Beep beep'm beep beep yeah", "Baby you can drive my car" ]);
|
||||
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
@ -181,7 +181,11 @@ const ContentPanning = {
|
||||
case 'click':
|
||||
evt.stopPropagation();
|
||||
evt.preventDefault();
|
||||
evt.target.removeEventListener('click', this, true);
|
||||
|
||||
let target = evt.target;
|
||||
let view = target.ownerDocument ? target.ownerDocument.defaultView
|
||||
: target;
|
||||
view.removeEventListener('click', this, true, true);
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -190,16 +194,24 @@ const ContentPanning = {
|
||||
|
||||
onTouchStart: function cp_onTouchStart(evt) {
|
||||
this.dragging = true;
|
||||
this.panning = false;
|
||||
|
||||
let oldTarget = this.target;
|
||||
[this.target, this.scrollCallback] = this.getPannable(evt.target);
|
||||
|
||||
// If there is a pan animation running (from a previous pan gesture) and
|
||||
// the user touch back the screen, stop this animation immediatly and
|
||||
// prevent the possible click action.
|
||||
// prevent the possible click action if the touch happens on the same
|
||||
// target.
|
||||
this.preventNextClick = false;
|
||||
if (KineticPanning.active) {
|
||||
KineticPanning.stop();
|
||||
this.preventNextClick = true;
|
||||
|
||||
if (oldTarget && oldTarget == this.target)
|
||||
this.preventNextClick = true;
|
||||
}
|
||||
|
||||
this.scrollCallback = this.getPannable(evt.originalTarget);
|
||||
|
||||
this.position.set(evt.screenX, evt.screenY);
|
||||
KineticPanning.record(new Point(0, 0), evt.timeStamp);
|
||||
},
|
||||
@ -211,14 +223,15 @@ const ContentPanning = {
|
||||
|
||||
this.onTouchMove(evt);
|
||||
|
||||
let pan = KineticPanning.isPan();
|
||||
let click = evt.detail;
|
||||
if (click && (pan || this.preventNextClick))
|
||||
evt.target.addEventListener('click', this, true);
|
||||
if (this.target && click && (this.panning || this.preventNextClick)) {
|
||||
let target = this.target;
|
||||
let view = target.ownerDocument ? target.ownerDocument.defaultView
|
||||
: target;
|
||||
view.addEventListener('click', this, true, true);
|
||||
}
|
||||
|
||||
this.preventNextClick = false;
|
||||
|
||||
if (pan)
|
||||
if (this.panning)
|
||||
KineticPanning.start(this);
|
||||
},
|
||||
|
||||
@ -232,6 +245,13 @@ const ContentPanning = {
|
||||
|
||||
KineticPanning.record(delta, evt.timeStamp);
|
||||
this.scrollCallback(delta.scale(-1));
|
||||
|
||||
// If a pan action happens, cancel the active state of the
|
||||
// current target.
|
||||
if (!this.panning && KineticPanning.isPan()) {
|
||||
this.panning = true;
|
||||
this._resetActive();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -249,7 +269,7 @@ const ContentPanning = {
|
||||
|
||||
getPannable: function cp_getPannable(node) {
|
||||
if (!(node instanceof Ci.nsIDOMHTMLElement) || node.tagName == 'HTML')
|
||||
return null;
|
||||
return [null, null];
|
||||
|
||||
let content = node.ownerDocument.defaultView;
|
||||
while (!(node instanceof Ci.nsIDOMHTMLBodyElement)) {
|
||||
@ -266,12 +286,12 @@ const ContentPanning = {
|
||||
|
||||
let isScroll = (overflow.indexOf('scroll') != -1);
|
||||
if (isScroll || isAuto)
|
||||
return this._generateCallback(node);
|
||||
return [node, this._generateCallback(node)];
|
||||
|
||||
node = node.parentNode;
|
||||
}
|
||||
|
||||
return this._generateCallback(content);
|
||||
return [content, this._generateCallback(content)];
|
||||
},
|
||||
|
||||
_generateCallback: function cp_generateCallback(content) {
|
||||
@ -290,6 +310,19 @@ const ContentPanning = {
|
||||
}
|
||||
}
|
||||
return scroll;
|
||||
},
|
||||
|
||||
get _domUtils() {
|
||||
delete this._domUtils;
|
||||
return this._domUtils = Cc['@mozilla.org/inspector/dom-utils;1']
|
||||
.getService(Ci.inIDOMUtils);
|
||||
},
|
||||
|
||||
_resetActive: function cp_resetActive() {
|
||||
let root = this.target.ownerDocument || this.target.document;
|
||||
|
||||
const kStateActive = 0x00000001;
|
||||
this._domUtils.setContentState(root.documentElement, kStateActive);
|
||||
}
|
||||
};
|
||||
|
||||
@ -370,6 +403,7 @@ const KineticPanning = {
|
||||
return;
|
||||
|
||||
this.momentums = [];
|
||||
this.distance.set(0, 0);
|
||||
|
||||
this.target.onKineticEnd();
|
||||
this.target = null;
|
||||
@ -378,23 +412,24 @@ const KineticPanning = {
|
||||
momentums: [],
|
||||
record: function kp_record(delta, timestamp) {
|
||||
this.momentums.push({ 'time': timestamp, 'dx' : delta.x, 'dy' : delta.y });
|
||||
this.distance.add(delta.x, delta.y);
|
||||
},
|
||||
|
||||
isPan: function cp_isPan() {
|
||||
get threshold() {
|
||||
let dpi = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils)
|
||||
.displayDPI;
|
||||
|
||||
let threshold = Services.prefs.getIntPref('ui.dragThresholdX') / 240 * dpi;
|
||||
|
||||
let deltaX = 0;
|
||||
let deltaY = 0;
|
||||
let start = this.momentums[0].time;
|
||||
return this.momentums.slice(1).some(function(momentum) {
|
||||
deltaX += momentum.dx;
|
||||
deltaY += momentum.dy;
|
||||
return (Math.abs(deltaX) > threshold) || (Math.abs(deltaY) > threshold);
|
||||
});
|
||||
delete this.threshold;
|
||||
return this.threshold = threshold;
|
||||
},
|
||||
|
||||
distance: new Point(0, 0),
|
||||
isPan: function cp_isPan() {
|
||||
return (Math.abs(this.distance.x) > this.threshold ||
|
||||
Math.abs(this.distance.y) > this.threshold);
|
||||
},
|
||||
|
||||
_startAnimation: function kp_startAnimation() {
|
||||
|
@ -1563,49 +1563,6 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
|
||||
gHomeButton.updateTooltip(homeButton);
|
||||
gHomeButton.updatePersonalToolbarStyle(homeButton);
|
||||
|
||||
#ifdef HAVE_SHELL_SERVICE
|
||||
// Perform default browser checking (after window opens).
|
||||
var shell = getShellService();
|
||||
if (shell) {
|
||||
#ifdef DEBUG
|
||||
var shouldCheck = false;
|
||||
#else
|
||||
var shouldCheck = shell.shouldCheckDefaultBrowser;
|
||||
#endif
|
||||
var willRecoverSession = false;
|
||||
try {
|
||||
var ss = Cc["@mozilla.org/browser/sessionstartup;1"].
|
||||
getService(Ci.nsISessionStartup);
|
||||
willRecoverSession =
|
||||
(ss.sessionType == Ci.nsISessionStartup.RECOVER_SESSION);
|
||||
}
|
||||
catch (ex) { /* never mind; suppose SessionStore is broken */ }
|
||||
if (shouldCheck && !shell.isDefaultBrowser(true) && !willRecoverSession) {
|
||||
// Delay the set-default-browser prompt so it doesn't block
|
||||
// initialisation of the session store service.
|
||||
setTimeout(function () {
|
||||
var brandBundle = document.getElementById("bundle_brand");
|
||||
var shellBundle = document.getElementById("bundle_shell");
|
||||
|
||||
var brandShortName = brandBundle.getString("brandShortName");
|
||||
var promptTitle = shellBundle.getString("setDefaultBrowserTitle");
|
||||
var promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage",
|
||||
[brandShortName]);
|
||||
var checkboxLabel = shellBundle.getFormattedString("setDefaultBrowserDontAsk",
|
||||
[brandShortName]);
|
||||
var checkEveryTime = { value: shouldCheck };
|
||||
var ps = Services.prompt;
|
||||
var rv = ps.confirmEx(window, promptTitle, promptMessage,
|
||||
ps.STD_YES_NO_BUTTONS,
|
||||
null, null, null, checkboxLabel, checkEveryTime);
|
||||
if (rv == 0)
|
||||
shell.setDefaultBrowser(true, false);
|
||||
shell.shouldCheckDefaultBrowser = checkEveryTime.value;
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// BiDi UI
|
||||
gBidiUI = isBidiEnabled();
|
||||
if (gBidiUI) {
|
||||
@ -3989,10 +3946,22 @@ var FullScreen = {
|
||||
}
|
||||
},
|
||||
|
||||
exitDomFullScreen : function(e) {
|
||||
exitDomFullScreen : function() {
|
||||
document.mozCancelFullScreen();
|
||||
},
|
||||
|
||||
handleEvent: function (event) {
|
||||
switch (event.type) {
|
||||
case "deactivate":
|
||||
// We must call exitDomFullScreen asynchronously, since "deactivate" is
|
||||
// dispatched in the middle of the focus manager's window lowering code,
|
||||
// and the focus manager gets confused if we exit fullscreen mode in the
|
||||
// middle of window lowering. See bug 729872.
|
||||
setTimeout(this.exitDomFullScreen.bind(this), 0);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
enterDomFullScreen : function(event) {
|
||||
if (!document.mozFullScreen) {
|
||||
return;
|
||||
@ -4039,7 +4008,7 @@ var FullScreen = {
|
||||
|
||||
// Exit DOM full-screen mode when the browser window loses focus (ALT+TAB, etc).
|
||||
if (gPrefService.getBoolPref("full-screen-api.exit-on-deactivate")) {
|
||||
window.addEventListener("deactivate", this.exitDomFullScreen, true);
|
||||
window.addEventListener("deactivate", this);
|
||||
}
|
||||
|
||||
// Cancel any "hide the toolbar" animation which is in progress, and make
|
||||
@ -4074,7 +4043,7 @@ var FullScreen = {
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", this.exitDomFullScreen);
|
||||
gBrowser.tabContainer.removeEventListener("TabClose", this.exitDomFullScreen);
|
||||
gBrowser.tabContainer.removeEventListener("TabSelect", this.exitDomFullScreen);
|
||||
window.removeEventListener("deactivate", this.exitDomFullScreen, true);
|
||||
window.removeEventListener("deactivate", this);
|
||||
}
|
||||
},
|
||||
|
||||
@ -5362,6 +5331,7 @@ function setToolbarVisibility(toolbar, isVisible) {
|
||||
|
||||
var TabsOnTop = {
|
||||
init: function TabsOnTop_init() {
|
||||
this._initialized = true;
|
||||
this.syncUI();
|
||||
Services.prefs.addObserver(this._prefName, this, false);
|
||||
},
|
||||
@ -5375,6 +5345,9 @@ var TabsOnTop = {
|
||||
},
|
||||
|
||||
syncUI: function () {
|
||||
if (!this._initialized)
|
||||
return;
|
||||
|
||||
let userEnabled = Services.prefs.getBoolPref(this._prefName);
|
||||
let enabled = userEnabled && gBrowser.tabContainer.visible;
|
||||
|
||||
@ -6121,103 +6094,114 @@ function charsetLoadListener(event) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Begin Page Style Functions */
|
||||
function getAllStyleSheets(frameset) {
|
||||
var styleSheetsArray = Array.slice(frameset.document.styleSheets);
|
||||
for (let i = 0; i < frameset.frames.length; i++) {
|
||||
let frameSheets = getAllStyleSheets(frameset.frames[i]);
|
||||
styleSheetsArray = styleSheetsArray.concat(frameSheets);
|
||||
}
|
||||
return styleSheetsArray;
|
||||
}
|
||||
|
||||
function stylesheetFillPopup(menuPopup) {
|
||||
var noStyle = menuPopup.firstChild;
|
||||
var persistentOnly = noStyle.nextSibling;
|
||||
var sep = persistentOnly.nextSibling;
|
||||
while (sep.nextSibling)
|
||||
menuPopup.removeChild(sep.nextSibling);
|
||||
var gPageStyleMenu = {
|
||||
|
||||
var styleSheets = getAllStyleSheets(window.content);
|
||||
var currentStyleSheets = {};
|
||||
var styleDisabled = getMarkupDocumentViewer().authorStyleDisabled;
|
||||
var haveAltSheets = false;
|
||||
var altStyleSelected = false;
|
||||
getAllStyleSheets: function (frameset) {
|
||||
var styleSheetsArray = Array.slice(frameset.document.styleSheets);
|
||||
for (let i = 0; i < frameset.frames.length; i++) {
|
||||
let frameSheets = this.getAllStyleSheets(frameset.frames[i]);
|
||||
styleSheetsArray = styleSheetsArray.concat(frameSheets);
|
||||
}
|
||||
return styleSheetsArray;
|
||||
},
|
||||
|
||||
for (let i = 0; i < styleSheets.length; ++i) {
|
||||
let currentStyleSheet = styleSheets[i];
|
||||
stylesheetFillPopup: function (menuPopup) {
|
||||
var noStyle = menuPopup.firstChild;
|
||||
var persistentOnly = noStyle.nextSibling;
|
||||
var sep = persistentOnly.nextSibling;
|
||||
while (sep.nextSibling)
|
||||
menuPopup.removeChild(sep.nextSibling);
|
||||
|
||||
if (!currentStyleSheet.title)
|
||||
continue;
|
||||
var styleSheets = this.getAllStyleSheets(window.content);
|
||||
var currentStyleSheets = {};
|
||||
var styleDisabled = getMarkupDocumentViewer().authorStyleDisabled;
|
||||
var haveAltSheets = false;
|
||||
var altStyleSelected = false;
|
||||
|
||||
// Skip any stylesheets whose media attribute doesn't match.
|
||||
if (currentStyleSheet.media.length > 0) {
|
||||
let mediaQueryList = currentStyleSheet.media.mediaText;
|
||||
if (!window.content.matchMedia(mediaQueryList).matches)
|
||||
for (let i = 0; i < styleSheets.length; ++i) {
|
||||
let currentStyleSheet = styleSheets[i];
|
||||
|
||||
if (!currentStyleSheet.title)
|
||||
continue;
|
||||
|
||||
// Skip any stylesheets whose media attribute doesn't match.
|
||||
if (currentStyleSheet.media.length > 0) {
|
||||
let mediaQueryList = currentStyleSheet.media.mediaText;
|
||||
if (!window.content.matchMedia(mediaQueryList).matches)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!currentStyleSheet.disabled)
|
||||
altStyleSelected = true;
|
||||
|
||||
haveAltSheets = true;
|
||||
|
||||
let lastWithSameTitle = null;
|
||||
if (currentStyleSheet.title in currentStyleSheets)
|
||||
lastWithSameTitle = currentStyleSheets[currentStyleSheet.title];
|
||||
|
||||
if (!lastWithSameTitle) {
|
||||
let menuItem = document.createElement("menuitem");
|
||||
menuItem.setAttribute("type", "radio");
|
||||
menuItem.setAttribute("label", currentStyleSheet.title);
|
||||
menuItem.setAttribute("data", currentStyleSheet.title);
|
||||
menuItem.setAttribute("checked", !currentStyleSheet.disabled && !styleDisabled);
|
||||
menuPopup.appendChild(menuItem);
|
||||
currentStyleSheets[currentStyleSheet.title] = menuItem;
|
||||
} else if (currentStyleSheet.disabled) {
|
||||
lastWithSameTitle.removeAttribute("checked");
|
||||
}
|
||||
}
|
||||
|
||||
if (!currentStyleSheet.disabled)
|
||||
altStyleSelected = true;
|
||||
noStyle.setAttribute("checked", styleDisabled);
|
||||
persistentOnly.setAttribute("checked", !altStyleSelected && !styleDisabled);
|
||||
persistentOnly.hidden = (window.content.document.preferredStyleSheetSet) ? haveAltSheets : false;
|
||||
sep.hidden = (noStyle.hidden && persistentOnly.hidden) || !haveAltSheets;
|
||||
return true;
|
||||
},
|
||||
|
||||
haveAltSheets = true;
|
||||
stylesheetInFrame: function (frame, title) {
|
||||
return Array.some(frame.document.styleSheets,
|
||||
function (stylesheet) stylesheet.title == title);
|
||||
},
|
||||
|
||||
let lastWithSameTitle = null;
|
||||
if (currentStyleSheet.title in currentStyleSheets)
|
||||
lastWithSameTitle = currentStyleSheets[currentStyleSheet.title];
|
||||
stylesheetSwitchFrame: function (frame, title) {
|
||||
var docStyleSheets = frame.document.styleSheets;
|
||||
|
||||
if (!lastWithSameTitle) {
|
||||
let menuItem = document.createElement("menuitem");
|
||||
menuItem.setAttribute("type", "radio");
|
||||
menuItem.setAttribute("label", currentStyleSheet.title);
|
||||
menuItem.setAttribute("data", currentStyleSheet.title);
|
||||
menuItem.setAttribute("checked", !currentStyleSheet.disabled && !styleDisabled);
|
||||
menuPopup.appendChild(menuItem);
|
||||
currentStyleSheets[currentStyleSheet.title] = menuItem;
|
||||
} else if (currentStyleSheet.disabled) {
|
||||
lastWithSameTitle.removeAttribute("checked");
|
||||
for (let i = 0; i < docStyleSheets.length; ++i) {
|
||||
let docStyleSheet = docStyleSheets[i];
|
||||
|
||||
if (title == "_nostyle")
|
||||
docStyleSheet.disabled = true;
|
||||
else if (docStyleSheet.title)
|
||||
docStyleSheet.disabled = (docStyleSheet.title != title);
|
||||
else if (docStyleSheet.disabled)
|
||||
docStyleSheet.disabled = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
noStyle.setAttribute("checked", styleDisabled);
|
||||
persistentOnly.setAttribute("checked", !altStyleSelected && !styleDisabled);
|
||||
persistentOnly.hidden = (window.content.document.preferredStyleSheetSet) ? haveAltSheets : false;
|
||||
sep.hidden = (noStyle.hidden && persistentOnly.hidden) || !haveAltSheets;
|
||||
return true;
|
||||
}
|
||||
stylesheetSwitchAll: function (frameset, title) {
|
||||
if (!title || title == "_nostyle" || this.stylesheetInFrame(frameset, title))
|
||||
this.stylesheetSwitchFrame(frameset, title);
|
||||
|
||||
function stylesheetInFrame(frame, title) {
|
||||
return Array.some(frame.document.styleSheets,
|
||||
function (stylesheet) stylesheet.title == title);
|
||||
}
|
||||
for (let i = 0; i < frameset.frames.length; i++)
|
||||
this.stylesheetSwitchAll(frameset.frames[i], title);
|
||||
},
|
||||
|
||||
function stylesheetSwitchFrame(frame, title) {
|
||||
var docStyleSheets = frame.document.styleSheets;
|
||||
setStyleDisabled: function (disabled) {
|
||||
getMarkupDocumentViewer().authorStyleDisabled = disabled;
|
||||
},
|
||||
};
|
||||
|
||||
for (let i = 0; i < docStyleSheets.length; ++i) {
|
||||
let docStyleSheet = docStyleSheets[i];
|
||||
/* Legacy global page-style functions */
|
||||
var getAllStyleSheets = gPageStyleMenu.getAllStyleSheets;
|
||||
var stylesheetFillPopup = gPageStyleMenu.stylesheetFillPopup;
|
||||
var stylesheetInFrame = gPageStyleMenu.stylesheetInFrame;
|
||||
var stylesheetSwitchFrame = gPageStyleMenu.stylesheetSwitchFrame;
|
||||
var stylesheetSwitchAll = gPageStyleMenu.stylesheetSwitchAll;
|
||||
var setStyleDisabled = gPageStyleMenu.setStyleDisabled;
|
||||
|
||||
if (title == "_nostyle")
|
||||
docStyleSheet.disabled = true;
|
||||
else if (docStyleSheet.title)
|
||||
docStyleSheet.disabled = (docStyleSheet.title != title);
|
||||
else if (docStyleSheet.disabled)
|
||||
docStyleSheet.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
function stylesheetSwitchAll(frameset, title) {
|
||||
if (!title || title == "_nostyle" || stylesheetInFrame(frameset, title))
|
||||
stylesheetSwitchFrame(frameset, title);
|
||||
|
||||
for (let i = 0; i < frameset.frames.length; i++)
|
||||
stylesheetSwitchAll(frameset.frames[i], title);
|
||||
}
|
||||
|
||||
function setStyleDisabled(disabled) {
|
||||
getMarkupDocumentViewer().authorStyleDisabled = disabled;
|
||||
}
|
||||
/* End of the Page Style functions */
|
||||
|
||||
var BrowserOffline = {
|
||||
_inited: false,
|
||||
|
@ -3,7 +3,6 @@
|
||||
*/
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://services-sync/main.js");
|
||||
|
||||
let gTests = [ {
|
||||
|
@ -428,6 +428,49 @@ BrowserGlue.prototype = {
|
||||
|
||||
let keywordURLUserSet = Services.prefs.prefHasUserValue("keyword.URL");
|
||||
Services.telemetry.getHistogramById("FX_KEYWORD_URL_USERSET").add(keywordURLUserSet);
|
||||
|
||||
// Perform default browser checking.
|
||||
var shell;
|
||||
try {
|
||||
shell = Components.classes["@mozilla.org/browser/shell-service;1"]
|
||||
.getService(Components.interfaces.nsIShellService);
|
||||
} catch (e) { }
|
||||
if (shell) {
|
||||
#ifdef DEBUG
|
||||
var shouldCheck = false;
|
||||
#else
|
||||
var shouldCheck = shell.shouldCheckDefaultBrowser;
|
||||
#endif
|
||||
var willRecoverSession = false;
|
||||
try {
|
||||
var ss = Cc["@mozilla.org/browser/sessionstartup;1"].
|
||||
getService(Ci.nsISessionStartup);
|
||||
willRecoverSession =
|
||||
(ss.sessionType == Ci.nsISessionStartup.RECOVER_SESSION);
|
||||
}
|
||||
catch (ex) { /* never mind; suppose SessionStore is broken */ }
|
||||
if (shouldCheck && !shell.isDefaultBrowser(true) && !willRecoverSession) {
|
||||
Services.tm.mainThread.dispatch(function() {
|
||||
var brandBundle = win.document.getElementById("bundle_brand");
|
||||
var shellBundle = win.document.getElementById("bundle_shell");
|
||||
|
||||
var brandShortName = brandBundle.getString("brandShortName");
|
||||
var promptTitle = shellBundle.getString("setDefaultBrowserTitle");
|
||||
var promptMessage = shellBundle.getFormattedString("setDefaultBrowserMessage",
|
||||
[brandShortName]);
|
||||
var checkboxLabel = shellBundle.getFormattedString("setDefaultBrowserDontAsk",
|
||||
[brandShortName]);
|
||||
var checkEveryTime = { value: shouldCheck };
|
||||
var ps = Services.prompt;
|
||||
var rv = ps.confirmEx(win, promptTitle, promptMessage,
|
||||
ps.STD_YES_NO_BUTTONS,
|
||||
null, null, null, checkboxLabel, checkEveryTime);
|
||||
if (rv == 0)
|
||||
shell.setDefaultBrowser(true, false);
|
||||
shell.shouldCheckDefaultBrowser = checkEveryTime.value;
|
||||
}, Ci.nsIThread.DISPATCH_NORMAL);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
_onQuitRequest: function BG__onQuitRequest(aCancelQuit, aQuitType) {
|
||||
|
@ -167,73 +167,33 @@ PlacesViewBase.prototype = {
|
||||
},
|
||||
|
||||
_cleanPopup: function PVB_cleanPopup(aPopup) {
|
||||
// Remove places popup children and update markers to keep track of
|
||||
// their indices.
|
||||
let start = aPopup._startMarker != -1 ? aPopup._startMarker + 1 : 0;
|
||||
let end = aPopup._endMarker != -1 ? aPopup._endMarker :
|
||||
aPopup.childNodes.length;
|
||||
let items = [];
|
||||
|
||||
// Automatically adjust the start and the end markers.
|
||||
let firstNonStaticNodeFound = false;
|
||||
for (let i = start; i < end; ++i) {
|
||||
let item = aPopup.childNodes[i];
|
||||
if (item.getAttribute("builder") == "end") {
|
||||
// we need to do this for menus that have static content at the end but
|
||||
// are initially empty, eg. the history menu, we need to know where to
|
||||
// start inserting new items.
|
||||
aPopup._endMarker = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (item._placesNode) {
|
||||
items.push(item);
|
||||
firstNonStaticNodeFound = true;
|
||||
}
|
||||
else {
|
||||
// This is static content.
|
||||
if (!firstNonStaticNodeFound) {
|
||||
// We are at the beginning of the popup, in static content.
|
||||
// The markers are initialized in menu.xml, in the base binding.
|
||||
aPopup._startMarker++;
|
||||
}
|
||||
else {
|
||||
// We are at the end of the popup, after places nodes
|
||||
aPopup._endMarker = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < items.length; ++i) {
|
||||
aPopup.removeChild(items[i]);
|
||||
if (aPopup._endMarker != -1)
|
||||
aPopup._endMarker--;
|
||||
// Remove Places nodes from the popup.
|
||||
let child = aPopup._startMarker;
|
||||
while (child.nextSibling != aPopup._endMarker) {
|
||||
if (child.nextSibling._placesNode)
|
||||
aPopup.removeChild(child.nextSibling);
|
||||
else
|
||||
child = child.nextSibling;
|
||||
}
|
||||
},
|
||||
|
||||
_rebuildPopup: function PVB__rebuildPopup(aPopup) {
|
||||
this._cleanPopup(aPopup);
|
||||
|
||||
let resultNode = aPopup._placesNode;
|
||||
if (!resultNode.containerOpen)
|
||||
return;
|
||||
|
||||
if (resultNode._feedURI) {
|
||||
aPopup.removeAttribute("emptyplacesresult");
|
||||
if (aPopup._emptyMenuItem) {
|
||||
aPopup._emptyMenuItem.hidden = true;
|
||||
}
|
||||
this._setEmptyPopupStatus(aPopup, false);
|
||||
aPopup._built = true;
|
||||
this._populateLivemarkPopup(aPopup);
|
||||
return;
|
||||
}
|
||||
|
||||
this._cleanPopup(aPopup);
|
||||
|
||||
let cc = resultNode.childCount;
|
||||
if (cc > 0) {
|
||||
aPopup.removeAttribute("emptyplacesresult");
|
||||
if (aPopup._emptyMenuItem)
|
||||
aPopup._emptyMenuItem.hidden = true;
|
||||
this._setEmptyPopupStatus(aPopup, false);
|
||||
|
||||
for (let i = 0; i < cc; ++i) {
|
||||
let child = resultNode.getChild(i);
|
||||
@ -241,11 +201,7 @@ PlacesViewBase.prototype = {
|
||||
}
|
||||
}
|
||||
else {
|
||||
aPopup.setAttribute("emptyplacesresult", "true");
|
||||
// This menu is empty. If there is no static content, add
|
||||
// an element to show it is empty.
|
||||
if (aPopup._startMarker == -1 && aPopup._endMarker == -1)
|
||||
this._showEmptyMenuItem(aPopup);
|
||||
this._setEmptyPopupStatus(aPopup, true);
|
||||
}
|
||||
aPopup._built = true;
|
||||
},
|
||||
@ -260,17 +216,28 @@ PlacesViewBase.prototype = {
|
||||
aChild.parentNode.removeChild(aChild);
|
||||
},
|
||||
|
||||
_showEmptyMenuItem: function PVB__showEmptyMenuItem(aPopup) {
|
||||
if (aPopup._emptyMenuItem) {
|
||||
aPopup._emptyMenuItem.hidden = false;
|
||||
return;
|
||||
_setEmptyPopupStatus:
|
||||
function PVB__setEmptyPopupStatus(aPopup, aEmpty) {
|
||||
if (!aPopup._emptyMenuitem) {
|
||||
let label = PlacesUIUtils.getString("bookmarksMenuEmptyFolder");
|
||||
aPopup._emptyMenuitem = document.createElement("menuitem");
|
||||
aPopup._emptyMenuitem.setAttribute("label", label);
|
||||
aPopup._emptyMenuitem.setAttribute("disabled", true);
|
||||
}
|
||||
|
||||
let label = PlacesUIUtils.getString("bookmarksMenuEmptyFolder");
|
||||
aPopup._emptyMenuItem = document.createElement("menuitem");
|
||||
aPopup._emptyMenuItem.setAttribute("label", label);
|
||||
aPopup._emptyMenuItem.setAttribute("disabled", true);
|
||||
aPopup.appendChild(aPopup._emptyMenuItem);
|
||||
if (aEmpty) {
|
||||
aPopup.setAttribute("emptyplacesresult", "true");
|
||||
// Don't add the menuitem if there is static content.
|
||||
if (!aPopup._startMarker.previousSibling &&
|
||||
!aPopup._endMarker.nextSibling)
|
||||
aPopup.insertBefore(aPopup._emptyMenuitem, aPopup._endMarker);
|
||||
}
|
||||
else {
|
||||
aPopup.removeAttribute("emptyplacesresult");
|
||||
try {
|
||||
aPopup.removeChild(aPopup._emptyMenuitem);
|
||||
} catch (ex) {}
|
||||
}
|
||||
},
|
||||
|
||||
_createMenuItemForPlacesNode:
|
||||
@ -308,6 +275,12 @@ PlacesViewBase.prototype = {
|
||||
function (aStatus, aLivemark) {
|
||||
if (Components.isSuccessCode(aStatus)) {
|
||||
element.setAttribute("livemark", "true");
|
||||
#ifdef XP_MACOSX
|
||||
// OS X native menubar doesn't track list-style-images since
|
||||
// it doesn't have a frame (bug 733415). Thus enforce updating.
|
||||
element.setAttribute("image", "");
|
||||
element.removeAttribute("image");
|
||||
#endif
|
||||
// Set an expando on the node, controller will use it to build
|
||||
// its metadata.
|
||||
aPlacesNode._feedURI = aLivemark.feedURI;
|
||||
@ -319,12 +292,11 @@ PlacesViewBase.prototype = {
|
||||
|
||||
let popup = document.createElement("menupopup");
|
||||
popup._placesNode = PlacesUtils.asContainer(aPlacesNode);
|
||||
if (this._nativeView) {
|
||||
popup._startMarker = -1;
|
||||
popup._endMarker = -1;
|
||||
}
|
||||
else
|
||||
|
||||
if (!this._nativeView) {
|
||||
popup.setAttribute("placespopup", "true");
|
||||
}
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// No context menu on mac.
|
||||
popup.setAttribute("context", "placesContext");
|
||||
@ -354,26 +326,8 @@ PlacesViewBase.prototype = {
|
||||
_insertNewItemToPopup:
|
||||
function PVB__insertNewItemToPopup(aNewChild, aPopup, aBefore) {
|
||||
let element = this._createMenuItemForPlacesNode(aNewChild);
|
||||
|
||||
if (aBefore) {
|
||||
aPopup.insertBefore(element, aBefore);
|
||||
}
|
||||
else {
|
||||
// Add the new element to the menu. If there is static content at
|
||||
// the end of the menu, add the element before that. Otherwise,
|
||||
// just add to the end.
|
||||
if (aPopup._endMarker != -1) {
|
||||
let lastElt = aPopup.childNodes[aPopup._endMarker];
|
||||
aPopup.insertBefore(element, lastElt);
|
||||
}
|
||||
else {
|
||||
aPopup.appendChild(element);
|
||||
}
|
||||
}
|
||||
|
||||
if (aPopup._endMarker != -1)
|
||||
aPopup._endMarker++;
|
||||
|
||||
let before = aBefore || aPopup._endMarker;
|
||||
aPopup.insertBefore(element, before);
|
||||
return element;
|
||||
},
|
||||
|
||||
@ -384,10 +338,8 @@ PlacesViewBase.prototype = {
|
||||
if (!siteUrl && aPopup._siteURIMenuitem) {
|
||||
aPopup.removeChild(aPopup._siteURIMenuitem);
|
||||
aPopup._siteURIMenuitem = null;
|
||||
aPopup._startMarker--;
|
||||
aPopup.removeChild(aPopup._siteURIMenuseparator);
|
||||
aPopup._siteURIMenuseparator = null;
|
||||
aPopup._startMarker--;
|
||||
}
|
||||
else if (siteUrl && !aPopup._siteURIMenuitem) {
|
||||
// Add "Open (Feed Name)" menuitem.
|
||||
@ -407,14 +359,10 @@ PlacesViewBase.prototype = {
|
||||
PlacesUIUtils.getFormattedString("menuOpenLivemarkOrigin.label",
|
||||
[aPopup.parentNode.getAttribute("label")])
|
||||
aPopup._siteURIMenuitem.setAttribute("label", label);
|
||||
aPopup.insertBefore(aPopup._siteURIMenuitem,
|
||||
aPopup.childNodes.item(aPopup._startMarker + 1));
|
||||
aPopup._startMarker++;
|
||||
aPopup.insertBefore(aPopup._siteURIMenuitem, aPopup._startMarker);
|
||||
|
||||
aPopup._siteURIMenuseparator = document.createElement("menuseparator");
|
||||
aPopup.insertBefore(aPopup._siteURIMenuseparator,
|
||||
aPopup.childNodes.item(aPopup._startMarker + 1));
|
||||
aPopup._startMarker++;
|
||||
aPopup.insertBefore(aPopup._siteURIMenuseparator, aPopup._startMarker);
|
||||
}
|
||||
},
|
||||
|
||||
@ -427,7 +375,6 @@ PlacesViewBase.prototype = {
|
||||
*/
|
||||
_setLivemarkStatusMenuItem:
|
||||
function PVB_setLivemarkStatusMenuItem(aPopup, aStatus) {
|
||||
let itemId = aPopup._placesNode.itemId;
|
||||
let statusMenuitem = aPopup._statusMenuitem;
|
||||
let stringId = "";
|
||||
if (aStatus == Ci.mozILivemark.STATUS_LOADING)
|
||||
@ -439,12 +386,11 @@ PlacesViewBase.prototype = {
|
||||
// Create the status menuitem and cache it in the popup object.
|
||||
statusMenuitem = document.createElement("menuitem");
|
||||
statusMenuitem.setAttribute("livemarkStatus", stringId);
|
||||
statusMenuitem.className = "livemarkstatus-menuitem";
|
||||
statusMenuitem.setAttribute("label", PlacesUIUtils.getString(stringId));
|
||||
statusMenuitem.setAttribute("disabled", true);
|
||||
aPopup.insertBefore(statusMenuitem,
|
||||
aPopup.childNodes.item(aPopup._startMarker + 1));
|
||||
aPopup.insertBefore(statusMenuitem, aPopup._startMarker.nextSibling);
|
||||
aPopup._statusMenuitem = statusMenuitem;
|
||||
aPopup._startMarker++;
|
||||
}
|
||||
else if (stringId &&
|
||||
statusMenuitem.getAttribute("livemarkStatus") != stringId) {
|
||||
@ -455,7 +401,6 @@ PlacesViewBase.prototype = {
|
||||
// The livemark has finished loading.
|
||||
aPopup.removeChild(aPopup._statusMenuitem);
|
||||
aPopup._statusMenuitem = null;
|
||||
aPopup._startMarker--;
|
||||
}
|
||||
},
|
||||
|
||||
@ -517,6 +462,12 @@ PlacesViewBase.prototype = {
|
||||
let menu = elt.parentNode;
|
||||
if (!menu.hasAttribute("livemark")) {
|
||||
menu.setAttribute("livemark", "true");
|
||||
#ifdef XP_MACOSX
|
||||
// OS X native menubar doesn't track list-style-images since
|
||||
// it doesn't have a frame (bug 733415). Thus enforce updating.
|
||||
menu.setAttribute("image", "");
|
||||
menu.removeAttribute("image");
|
||||
#endif
|
||||
}
|
||||
|
||||
PlacesUtils.livemarks.getLivemark(
|
||||
@ -580,13 +531,8 @@ PlacesViewBase.prototype = {
|
||||
// Figure out if we need to show the "<Empty>" menu-item.
|
||||
// TODO Bug 517701: This doesn't seem to handle the case of an empty
|
||||
// root.
|
||||
if (!parentElt.hasChildNodes() ||
|
||||
(parentElt.childNodes.length == 1 &&
|
||||
parentElt.firstChild == parentElt._emptyMenuItem))
|
||||
this._showEmptyMenuItem(parentElt);
|
||||
|
||||
if (parentElt._endMarker != -1)
|
||||
parentElt._endMarker--;
|
||||
if (parentElt._startMarker.nextSibling == parentElt._endMarker)
|
||||
this._setEmptyPopupStatus(parentElt, true);
|
||||
}
|
||||
},
|
||||
|
||||
@ -620,8 +566,9 @@ PlacesViewBase.prototype = {
|
||||
if (aPlacesNode.parent && aPlacesNode.parent._feedURI) {
|
||||
// Find the node in the parent.
|
||||
let popup = aPlacesNode.parent._DOMElement;
|
||||
for (let i = popup._startMarker; i < popup.childNodes.length; i++) {
|
||||
let child = popup.childNodes[i];
|
||||
for (let child = popup._startMarker.nextSibling;
|
||||
child != popup._endMarker;
|
||||
child = child.nextSibling) {
|
||||
if (child._placesNode && child._placesNode.uri == aPlacesNode.uri) {
|
||||
if (aCount)
|
||||
child.setAttribute("visited", "true");
|
||||
@ -649,11 +596,11 @@ PlacesViewBase.prototype = {
|
||||
if (!parentElt._built)
|
||||
return;
|
||||
|
||||
let index = parentElt._startMarker + 1 + aIndex;
|
||||
let index = Array.indexOf(parentElt.childNodes, parentElt._startMarker) +
|
||||
aIndex + 1;
|
||||
this._insertNewItemToPopup(aPlacesNode, parentElt,
|
||||
parentElt.childNodes[index]);
|
||||
if (parentElt._emptyMenuItem)
|
||||
parentElt._emptyMenuItem.hidden = true;
|
||||
this._setEmptyPopupStatus(parentElt, false);
|
||||
},
|
||||
|
||||
nodeMoved:
|
||||
@ -684,7 +631,8 @@ PlacesViewBase.prototype = {
|
||||
if (parentElt._built) {
|
||||
// Move the node.
|
||||
parentElt.removeChild(elt);
|
||||
let index = parentElt._startMarker + 1 + aNewIndex;
|
||||
let index = Array.indexOf(parentElt.childNodes, parentElt._startMarker) +
|
||||
aNewIndex + 1;
|
||||
parentElt.insertBefore(elt, parentElt.childNodes[index]);
|
||||
}
|
||||
},
|
||||
@ -821,11 +769,9 @@ PlacesViewBase.prototype = {
|
||||
if (aPopup._endOptOpenAllInTabs) {
|
||||
aPopup.removeChild(aPopup._endOptOpenAllInTabs);
|
||||
aPopup._endOptOpenAllInTabs = null;
|
||||
aPopup._endMarker--;
|
||||
|
||||
aPopup.removeChild(aPopup._endOptSeparator);
|
||||
aPopup._endOptSeparator = null;
|
||||
aPopup._endMarker--;
|
||||
}
|
||||
}
|
||||
else if (!aPopup._endOptOpenAllInTabs) {
|
||||
@ -833,7 +779,6 @@ PlacesViewBase.prototype = {
|
||||
aPopup._endOptSeparator = document.createElement("menuseparator");
|
||||
aPopup._endOptSeparator.className = "bookmarks-actions-menuseparator";
|
||||
aPopup.appendChild(aPopup._endOptSeparator);
|
||||
aPopup._endMarker++;
|
||||
|
||||
// Add the "Open All in Tabs" menuitem.
|
||||
aPopup._endOptOpenAllInTabs = document.createElement("menuitem");
|
||||
@ -846,13 +791,51 @@ PlacesViewBase.prototype = {
|
||||
aPopup._endOptOpenAllInTabs.setAttribute("label",
|
||||
gNavigatorBundle.getString("menuOpenAllInTabs.label"));
|
||||
aPopup.appendChild(aPopup._endOptOpenAllInTabs);
|
||||
aPopup._endMarker++;
|
||||
}
|
||||
},
|
||||
|
||||
_ensureMarkers: function PVB__ensureMarkers(aPopup) {
|
||||
if (aPopup._startMarker)
|
||||
return;
|
||||
|
||||
// _startMarker is an hidden menuseparator that lives before places nodes.
|
||||
aPopup._startMarker = document.createElement("menuseparator");
|
||||
aPopup._startMarker.hidden = true;
|
||||
aPopup.insertBefore(aPopup._startMarker, aPopup.firstChild);
|
||||
|
||||
// _endMarker is an hidden menuseparator that lives after places nodes.
|
||||
aPopup._endMarker = document.createElement("menuseparator");
|
||||
aPopup._endMarker.hidden = true;
|
||||
aPopup.appendChild(aPopup._endMarker);
|
||||
|
||||
// Move the markers to the right position.
|
||||
let firstNonStaticNodeFound = false;
|
||||
for (let i = 0; i < aPopup.childNodes.length; i++) {
|
||||
let child = aPopup.childNodes[i];
|
||||
// Menus that have static content at the end, but are initially empty,
|
||||
// use a special "builder" attribute to figure out where to start
|
||||
// inserting places nodes.
|
||||
if (child.getAttribute("builder") == "end") {
|
||||
aPopup.insertBefore(aPopup._endMarker, child);
|
||||
break;
|
||||
}
|
||||
|
||||
if (child._placesNode && !firstNonStaticNodeFound) {
|
||||
firstNonStaticNodeFound = true;
|
||||
aPopup.insertBefore(aPopup._startMarker, child);
|
||||
}
|
||||
}
|
||||
if (!firstNonStaticNodeFound) {
|
||||
aPopup.insertBefore(aPopup._startMarker, aPopup._endMarker);
|
||||
}
|
||||
},
|
||||
|
||||
_onPopupShowing: function PVB__onPopupShowing(aEvent) {
|
||||
// Avoid handling popupshowing of inner views.
|
||||
let popup = aEvent.originalTarget;
|
||||
|
||||
this._ensureMarkers(popup);
|
||||
|
||||
if (popup._placesNode && PlacesUIUtils.getViewForNode(popup) == this) {
|
||||
if (!popup._placesNode.containerOpen)
|
||||
popup._placesNode.containerOpen = true;
|
||||
@ -1808,8 +1791,6 @@ function PlacesMenu(aPopupShowingEvent, aPlace) {
|
||||
#ifdef XP_MACOSX
|
||||
if (this._viewElt.parentNode.localName == "menubar") {
|
||||
this._nativeView = true;
|
||||
this._rootElt._startMarker = -1;
|
||||
this._rootElt._endMarker = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1829,8 +1810,6 @@ PlacesMenu.prototype = {
|
||||
|
||||
_removeChild: function PM_removeChild(aChild) {
|
||||
PlacesViewBase.prototype._removeChild.apply(this, arguments);
|
||||
if (this._endMarker != -1)
|
||||
this._endMarker--;
|
||||
},
|
||||
|
||||
uninit: function PM_uninit() {
|
||||
|
@ -72,10 +72,6 @@
|
||||
"popup-internal-box");
|
||||
</field>
|
||||
|
||||
<!-- markers for start and end of valid places items -->
|
||||
<field name="_startMarker">-1</field>
|
||||
<field name="_endMarker">-1</field>
|
||||
|
||||
<!-- This is the view that manage the popup -->
|
||||
<field name="_rootView">PlacesUIUtils.getViewForNode(this);</field>
|
||||
|
||||
@ -83,17 +79,16 @@
|
||||
<method name="_hideDropIndicator">
|
||||
<parameter name="aEvent"/>
|
||||
<body><![CDATA[
|
||||
var target = aEvent.target;
|
||||
let target = aEvent.target;
|
||||
|
||||
// in some view we have _startMarker and _endMarker, we should not
|
||||
// draw the drop indicator outside of them
|
||||
var betweenMarkers = true;
|
||||
if (this._startMarker != -1 &&
|
||||
target.boxObject.y <= this.childNodes[this._startMarker].boxObject.y)
|
||||
betweenMarkers = false;
|
||||
if (this._endMarker != -1 &&
|
||||
target.boxObject.y >= this.childNodes[this._endMarker].boxObject.y)
|
||||
betweenMarkers = false;
|
||||
// Don't draw the drop indicator outside of markers.
|
||||
// The markers are hidden, since otherwise sometimes popups acquire
|
||||
// scrollboxes on OS X, so we can't use them directly.
|
||||
let firstChildTop = this._startMarker.nextSibling.boxObject.y;
|
||||
let lastChildBottom = this._endMarker.previousSibling.boxObject.y +
|
||||
this._endMarker.previousSibling.boxObject.height;
|
||||
let betweenMarkers = target.boxObject.y >= firstChildTop ||
|
||||
target.boxObject.y <= lastChildBottom;
|
||||
|
||||
// Hide the dropmarker if current node is not a Places node.
|
||||
return !(target && target._placesNode && betweenMarkers);
|
||||
|
@ -42,7 +42,7 @@ let test_bookmarks = {
|
||||
menu: [
|
||||
{ title: "Mozilla Firefox",
|
||||
children: [
|
||||
{ title: "Help and Tutorials",
|
||||
{ title: "Help and Tutorials",
|
||||
url: "http://en-us.www.mozilla.com/en-US/firefox/help/",
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="
|
||||
},
|
||||
@ -57,8 +57,8 @@ let test_bookmarks = {
|
||||
{ title: "About Us",
|
||||
url: "http://en-us.www.mozilla.com/en-US/about/",
|
||||
icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg=="
|
||||
},
|
||||
],
|
||||
}
|
||||
]
|
||||
},
|
||||
{ title: "test",
|
||||
description: "folder test comment",
|
||||
@ -72,10 +72,10 @@ let test_bookmarks = {
|
||||
keyword: "test",
|
||||
sidebar: true,
|
||||
postData: "hidden1%3Dbar&text1%3D%25s",
|
||||
charset: "ISO-8859-1",
|
||||
},
|
||||
charset: "ISO-8859-1"
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
],
|
||||
toolbar: [
|
||||
{ title: "Getting Started",
|
||||
@ -84,14 +84,14 @@ let test_bookmarks = {
|
||||
},
|
||||
{ title: "Latest Headlines",
|
||||
url: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
|
||||
feedUrl: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
|
||||
feedUrl: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml"
|
||||
}
|
||||
],
|
||||
unfiled: [
|
||||
{ title: "Example.tld",
|
||||
url: "http://example.tld/",
|
||||
},
|
||||
],
|
||||
url: "http://example.tld/"
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
// Pre-Places bookmarks.html file pointer.
|
||||
@ -303,6 +303,8 @@ add_test(function test_import_ontop()
|
||||
function testImportedBookmarks()
|
||||
{
|
||||
for (let group in test_bookmarks) {
|
||||
do_print("[testImportedBookmarks()] Checking group '" + group + "'");
|
||||
|
||||
let root;
|
||||
switch (group) {
|
||||
case "menu":
|
||||
@ -335,6 +337,7 @@ function testImportedBookmarksToFolder(aFolder)
|
||||
|
||||
for (let i = 0; i < root.childCount; i++) {
|
||||
let child = root.getChild(i);
|
||||
// This check depends on all "menu" bookmarks being listed first in the imported file :-|
|
||||
if (i < rootFolderCount) {
|
||||
checkItem(test_bookmarks.menu[i], child);
|
||||
}
|
||||
@ -343,9 +346,8 @@ function testImportedBookmarksToFolder(aFolder)
|
||||
let group = /Toolbar/.test(container.title) ? test_bookmarks.toolbar
|
||||
: test_bookmarks.unfiled;
|
||||
container.containerOpen = true;
|
||||
print(container.title);
|
||||
do_print("[testImportedBookmarksToFolder()] Checking container '" + container.title + "'");
|
||||
for (let t = 0; t < container.childCount; t++) {
|
||||
print(group[t].title + " " + container.getChild(t).title);
|
||||
checkItem(group[t], container.getChild(t));
|
||||
}
|
||||
container.containerOpen = false;
|
||||
|
@ -199,7 +199,7 @@ menuitem.bookmark-item {
|
||||
}
|
||||
|
||||
/* Bookmark items */
|
||||
.bookmark-item:not([container]) {
|
||||
.bookmark-item {
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
|
@ -229,15 +229,20 @@ toolbarbutton.bookmark-item > menupopup {
|
||||
list-style-image: url("chrome://global/skin/tree/folder.png");
|
||||
}
|
||||
|
||||
.query-item[container] {
|
||||
list-style-image: url("chrome://browser/skin/places/history.png");
|
||||
}
|
||||
|
||||
.bookmark-item[livemark] {
|
||||
.bookmark-item[container][livemark] {
|
||||
list-style-image: url("chrome://browser/skin/page-livemarks.png");
|
||||
}
|
||||
|
||||
.bookmark-item[query] {
|
||||
.bookmark-item[container][livemark] .bookmark-item {
|
||||
list-style-image: url("chrome://browser/skin/places/livemark-item.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
}
|
||||
|
||||
.bookmark-item[container][livemark] .bookmark-item[visited] {
|
||||
-moz-image-region: rect(0px, 32px, 16px, 16px);
|
||||
}
|
||||
|
||||
.bookmark-item[container][query] {
|
||||
list-style-image: url("chrome://browser/skin/places/query.png");
|
||||
}
|
||||
|
||||
@ -257,20 +262,23 @@ toolbarbutton.bookmark-item > menupopup {
|
||||
list-style-image: url("chrome://global/skin/tree/folder.png");
|
||||
}
|
||||
|
||||
.bookmark-item[livemark] .menuitem-iconic {
|
||||
list-style-image: url("chrome://browser/skin/places/livemark-item.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
}
|
||||
|
||||
.bookmark-item[livemark] .menuitem-iconic[visited] {
|
||||
-moz-image-region: rect(0px, 32px, 16px, 16px);
|
||||
}
|
||||
|
||||
.bookmark-item menuitem[openInTabs],
|
||||
.bookmark-item menuitem[siteURI] {
|
||||
/* Workaround for native menubar inheritance */
|
||||
.openintabs-menuitem,
|
||||
.openlivemarksite-menuitem,
|
||||
.livemarkstatus-menuitem {
|
||||
list-style-image: none;
|
||||
}
|
||||
|
||||
.bookmark-item[cutting] > .toolbarbutton-icon,
|
||||
.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-icon {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.bookmark-item[cutting] > .toolbarbutton-text,
|
||||
.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-text {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
#wrapper-personal-bookmarks[place="palette"] > .toolbarpaletteitem-box {
|
||||
background: url("chrome://browser/skin/places/bookmarksToolbar.png") no-repeat center;
|
||||
}
|
||||
@ -287,16 +295,6 @@ toolbarbutton.bookmark-item > menupopup {
|
||||
height: 16px;
|
||||
}
|
||||
|
||||
.bookmark-item[cutting] > .toolbarbutton-icon,
|
||||
.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-icon {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.bookmark-item[cutting] > .toolbarbutton-text,
|
||||
.bookmark-item[cutting] > .menu-iconic-left > .menu-iconic-text {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
#bookmarksToolbarFolderMenu,
|
||||
#BMB_bookmarksToolbar {
|
||||
list-style-image: url("chrome://browser/skin/places/bookmarksToolbar.png");
|
||||
|
@ -1224,7 +1224,7 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
||||
padding: 0;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid ThreeDShadow;
|
||||
border-radius: 2.5px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
#urlbar {
|
||||
|
@ -74,6 +74,6 @@
|
||||
-moz-padding-start: 4px;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid rgba(0,0,0,.32);
|
||||
border-radius: 2.5px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
|
@ -738,8 +738,11 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
||||
|
||||
def killAndGetStack(self, proc, utilityPath, debuggerInfo):
|
||||
"""Kill the process, preferrably in a way that gets us a stack trace."""
|
||||
if not debuggerInfo and not self.haveDumpedScreen:
|
||||
self.dumpScreen(utilityPath)
|
||||
if not debuggerInfo:
|
||||
if self.haveDumpedScreen:
|
||||
self.log.info("Not taking screenshot here: see the one that was previously logged")
|
||||
else:
|
||||
self.dumpScreen(utilityPath)
|
||||
|
||||
if self.CRASHREPORTER and not debuggerInfo:
|
||||
if self.UNIXISH:
|
||||
@ -796,8 +799,11 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
||||
if stackFixerFunction:
|
||||
line = stackFixerFunction(line)
|
||||
self.log.info(line.rstrip().decode("UTF-8", "ignore"))
|
||||
if not debuggerInfo and not self.haveDumpedScreen and "TEST-UNEXPECTED-FAIL" in line and "Test timed out" in line:
|
||||
self.dumpScreen(utilityPath)
|
||||
if not debuggerInfo and "TEST-UNEXPECTED-FAIL" in line and "Test timed out" in line:
|
||||
if self.haveDumpedScreen:
|
||||
self.log.info("Not taking screenshot here: see the one that was previously logged")
|
||||
else:
|
||||
self.dumpScreen(utilityPath)
|
||||
|
||||
(line, didTimeout) = self.readWithTimeout(logsource, timeout)
|
||||
if not hitMaxTime and maxTime and datetime.now() - startTime > timedelta(seconds = maxTime):
|
||||
|
@ -459,7 +459,7 @@ class ShutdownLeakLogger(object):
|
||||
DOM windows (that are still around after test suite shutdown, despite running
|
||||
the GC) to the tests that created them and prints leak statistics.
|
||||
"""
|
||||
MAX_LEAK_COUNT = 130
|
||||
MAX_LEAK_COUNT = 123
|
||||
|
||||
def __init__(self, logger):
|
||||
self.logger = logger
|
||||
|
@ -77,5 +77,5 @@ public interface Driver {
|
||||
* @return A 2-D array of pixels (indexed by y, then x). The pixels
|
||||
* are in ARGB-8888 format.
|
||||
*/
|
||||
int[][] getPaintedSurface();
|
||||
PaintedSurface getPaintedSurface();
|
||||
}
|
||||
|
@ -48,6 +48,8 @@ import java.io.IOException;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
|
||||
import java.lang.Class;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -291,7 +293,7 @@ public class FennecNativeDriver implements Driver {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int[][] getPaintedSurface() {
|
||||
public PaintedSurface getPaintedSurface() {
|
||||
GLSurfaceView view = getSurfaceView();
|
||||
if (view == null) {
|
||||
return null;
|
||||
@ -309,14 +311,34 @@ public class FennecNativeDriver implements Driver {
|
||||
int w = view.getWidth();
|
||||
int h = view.getHeight();
|
||||
pixelBuffer.position(0);
|
||||
int[][] pixels = new int[h][w];
|
||||
for (int y = h - 1; y >= 0; y--) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
int agbr = pixelBuffer.get();
|
||||
pixels[y][x] = (agbr & 0xFF00FF00) | ((agbr >> 16) & 0x000000FF) | ((agbr << 16) & 0x00FF0000);
|
||||
String mapFile = "/mnt/sdcard/pixels.map";
|
||||
|
||||
FileOutputStream fos = null;
|
||||
DataOutputStream dos = null;
|
||||
try {
|
||||
fos = new FileOutputStream(mapFile);
|
||||
dos = new DataOutputStream(fos);
|
||||
|
||||
for (int y = h - 1; y >= 0; y--) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
int agbr = pixelBuffer.get();
|
||||
dos.writeInt((agbr & 0xFF00FF00) | ((agbr >> 16) & 0x000000FF) | ((agbr << 16) & 0x00FF0000));
|
||||
}
|
||||
}
|
||||
return new PaintedSurface(mapFile, w, h);
|
||||
} catch (IOException e) {
|
||||
throw new RoboCopException("exception with pixel writer on file: " + mapFile);
|
||||
} finally {
|
||||
try {
|
||||
if (dos != null && fos != null) {
|
||||
dos.flush();
|
||||
dos.close();
|
||||
fos.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RoboCopException("exception closing pixel writer on file: " + mapFile);
|
||||
}
|
||||
}
|
||||
return pixels;
|
||||
}
|
||||
|
||||
public int mHeight=0;
|
||||
|
@ -61,11 +61,15 @@ _JAVA_HARNESS = \
|
||||
FennecNativeDriver.java \
|
||||
FennecNativeElement.java \
|
||||
RoboCopException.java \
|
||||
PaintedSurface.java \
|
||||
$(NULL)
|
||||
|
||||
_JAVA_TESTS = $(patsubst $(TESTPATH)/%.in,%,$(wildcard $(TESTPATH)/*.java.in))
|
||||
|
||||
_TEST_FILES = $(wildcard $(TESTPATH)/*.html)
|
||||
_TEST_FILES = \
|
||||
$(wildcard $(TESTPATH)/*.html) \
|
||||
$(wildcard $(TESTPATH)/*.sjs) \
|
||||
$(NULL)
|
||||
|
||||
_ROBOCOP_TOOLS = \
|
||||
$(TESTPATH)/robocop.ini \
|
||||
|
62
build/mobile/robocop/PaintedSurface.java.in
Normal file
62
build/mobile/robocop/PaintedSurface.java.in
Normal file
@ -0,0 +1,62 @@
|
||||
#filter substitution
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package @ANDROID_PACKAGE_NAME@;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
public class PaintedSurface {
|
||||
private String mFileName = null;
|
||||
private int mWidth = -1;
|
||||
private int mHeight = -1;
|
||||
private MappedByteBuffer mPixelBuffer = null;
|
||||
|
||||
public PaintedSurface(String filename, int width, int height) {
|
||||
mFileName = filename;
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
|
||||
try {
|
||||
File f = new File(filename);
|
||||
int pixelSize = (int)f.length();
|
||||
|
||||
FileInputStream pixelFile = new FileInputStream(filename);
|
||||
mPixelBuffer = pixelFile.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, pixelSize);
|
||||
} catch (java.io.FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (java.io.IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public final int getPixelAt(int x, int y) {
|
||||
if (mPixelBuffer == null) {
|
||||
throw new RoboCopException("Trying to access PaintedSurface with no active PixelBuffer");
|
||||
}
|
||||
|
||||
if (x >= mWidth || x < 0) {
|
||||
throw new RoboCopException("Trying to access PaintedSurface with invalid x value");
|
||||
}
|
||||
|
||||
if (y >= mHeight || y < 0) {
|
||||
throw new RoboCopException("Trying to access PaintedSurface with invalid y value");
|
||||
}
|
||||
|
||||
// The rows are reversed so row 0 is at the end and we start with the last row.
|
||||
// This is why we do mHeight-y;
|
||||
int index = (x + ((mHeight - y - 1) * mWidth)) * 4;
|
||||
int b1 = mPixelBuffer.get(index) & 0xFF;
|
||||
int b2 = mPixelBuffer.get(index + 1) & 0xFF;
|
||||
int b3 = mPixelBuffer.get(index + 2) & 0xFF;
|
||||
int b4 = mPixelBuffer.get(index + 3) & 0xFF;
|
||||
int value = (b1 << 24) + (b2 << 16) + (b3 << 8) + (b4 << 0);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
@ -67,11 +67,12 @@ NS_IMPL_THREADSAFE_ADDREF(nsNullPrincipalURI)
|
||||
NS_IMPL_THREADSAFE_RELEASE(nsNullPrincipalURI)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsNullPrincipalURI)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIURI)
|
||||
if (aIID.Equals(kNullPrincipalURIImplementationCID))
|
||||
foundInterface = static_cast<nsIURI *>(this);
|
||||
else
|
||||
NS_INTERFACE_MAP_ENTRY(nsIURI)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISizeOf)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -299,3 +300,19 @@ nsNullPrincipalURI::SchemeIs(const char *aScheme, bool *_schemeIs)
|
||||
*_schemeIs = (0 == nsCRT::strcasecmp(mScheme.get(), aScheme));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// nsISizeOf
|
||||
|
||||
size_t
|
||||
nsNullPrincipalURI::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
|
||||
{
|
||||
return mScheme.SizeOfExcludingThisIfUnshared(aMallocSizeOf) +
|
||||
mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
}
|
||||
|
||||
size_t
|
||||
nsNullPrincipalURI::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
|
||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define __nsNullPrincipalURI_h__
|
||||
|
||||
#include "nsIURI.h"
|
||||
#include "nsISizeOf.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
|
||||
@ -54,11 +55,16 @@
|
||||
{0xb9, 0x1b, 0x6b, 0x54, 0x10, 0x22, 0x36, 0xe6} }
|
||||
|
||||
class nsNullPrincipalURI : public nsIURI
|
||||
, public nsISizeOf
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIURI
|
||||
|
||||
// nsISizeOf
|
||||
virtual size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
|
||||
virtual size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
|
||||
|
||||
nsNullPrincipalURI(const nsCString &aSpec);
|
||||
|
||||
private:
|
||||
|
@ -301,6 +301,10 @@ MOZ_NATIVE_NSS = @MOZ_NATIVE_NSS@
|
||||
MOZ_B2G_RIL = @MOZ_B2G_RIL@
|
||||
MOZ_B2G_BT = @MOZ_B2G_BT@
|
||||
|
||||
MOZ_ASAN = @MOZ_ASAN@
|
||||
MOZ_CFLAGS_NSS = @MOZ_CFLAGS_NSS@
|
||||
MOZ_NO_WLZDEFS = @MOZ_NO_WLZDEFS@
|
||||
|
||||
BUILD_CTYPES = @BUILD_CTYPES@
|
||||
|
||||
COMPILE_ENVIRONMENT = @COMPILE_ENVIRONMENT@
|
||||
|
@ -148,6 +148,9 @@ xpcshell-tests:
|
||||
$(testxpcsrcdir)/runxpcshelltests.py \
|
||||
--symbols-path=$(DIST)/crashreporter-symbols \
|
||||
--build-info-json=$(DEPTH)/mozinfo.json \
|
||||
--tests-root-dir=$(testxpcobjdir) \
|
||||
--xunit-file=$(testxpcobjdir)/$(relativesrcdir)/results.xml \
|
||||
--xunit-suite-name=xpcshell \
|
||||
$(EXTRA_TEST_ARGS) \
|
||||
$(LIBXUL_DIST)/bin/xpcshell \
|
||||
$(foreach dir,$(XPCSHELL_TESTS),$(testxpcobjdir)/$(relativesrcdir)/$(dir))
|
||||
|
41
configure.in
41
configure.in
@ -628,9 +628,10 @@ if test "$GXX" = "yes"; then
|
||||
GNU_CXX=1
|
||||
CXX_VERSION=`$CXX -v 2>&1 | grep 'gcc version'`
|
||||
fi
|
||||
if test "`echo | $AS -v 2>&1 | grep -c GNU`" != "0"; then
|
||||
if test "`echo | $AS -o conftest.out -v 2>&1 | grep -c GNU`" != "0"; then
|
||||
GNU_AS=1
|
||||
fi
|
||||
rm -f conftest.out
|
||||
if test "`echo | $LD -v 2>&1 | grep -c GNU`" != "0"; then
|
||||
GNU_LD=1
|
||||
fi
|
||||
@ -1836,6 +1837,33 @@ if test -n "$CLANG_CXX"; then
|
||||
_WARNINGS_CXXFLAGS="-Qunused-arguments ${_WARNINGS_CXXFLAGS}"
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Use Address Sanitizer
|
||||
dnl ========================================================
|
||||
MOZ_ARG_ENABLE_BOOL(address-sanitizer,
|
||||
[ --enable-address-sanitizer Enable Address Sanitizer (default=no)],
|
||||
MOZ_ASAN=1,
|
||||
MOZ_ASAN= )
|
||||
if test -n "$MOZ_ASAN"; then
|
||||
MOZ_LLVM_HACKS=1
|
||||
AC_DEFINE(MOZ_ASAN)
|
||||
fi
|
||||
AC_SUBST(MOZ_ASAN)
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Enable hacks required for LLVM instrumentations
|
||||
dnl ========================================================
|
||||
MOZ_ARG_ENABLE_BOOL(llvm-hacks,
|
||||
[ --enable-llvm-hacks Enable workarounds required for several LLVM instrumentations (default=no)],
|
||||
MOZ_LLVM_HACKS=1,
|
||||
MOZ_LLVM_HACKS= )
|
||||
if test -n "$MOZ_LLVM_HACKS"; then
|
||||
MOZ_NO_WLZDEFS=1
|
||||
MOZ_CFLAGS_NSS=1
|
||||
fi
|
||||
AC_SUBST(MOZ_NO_WLZDEFS)
|
||||
AC_SUBST(MOZ_CFLAGS_NSS)
|
||||
|
||||
dnl ========================================================
|
||||
dnl GNU specific defaults
|
||||
dnl ========================================================
|
||||
@ -1846,8 +1874,13 @@ if test "$GNU_CC"; then
|
||||
MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$@ -o $@'
|
||||
DSO_LDOPTS='-shared'
|
||||
if test "$GCC_USE_GNU_LD"; then
|
||||
# Don't allow undefined symbols in libraries
|
||||
DSO_LDOPTS="$DSO_LDOPTS -Wl,-z,defs"
|
||||
# Some tools like ASan use a runtime library that is only
|
||||
# linked against executables, so we must allow undefined
|
||||
# symbols for shared objects in some cases.
|
||||
if test -z "$MOZ_NO_WLZDEFS"; then
|
||||
# Don't allow undefined symbols in libraries
|
||||
DSO_LDOPTS="$DSO_LDOPTS -Wl,-z,defs"
|
||||
fi
|
||||
fi
|
||||
WARNINGS_AS_ERRORS='-Werror -Wno-error=uninitialized'
|
||||
DSO_CFLAGS=''
|
||||
@ -9212,7 +9245,7 @@ if test -z "$MOZ_NATIVE_NSPR"; then
|
||||
fi
|
||||
if test "$MOZ_OPTIMIZE" = "1"; then
|
||||
ac_configure_args="$ac_configure_args --enable-optimize"
|
||||
else
|
||||
elif test -z "$MOZ_OPTIMIZE"; then
|
||||
ac_configure_args="$ac_configure_args --disable-optimize"
|
||||
fi
|
||||
if test -n "$HAVE_64BIT_OS"; then
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include "nsEventStates.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsISizeOf.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsEscape.h"
|
||||
@ -531,5 +532,24 @@ Link::SetHrefAttribute(nsIURI *aURI)
|
||||
NS_ConvertUTF8toUTF16(href), true);
|
||||
}
|
||||
|
||||
size_t
|
||||
Link::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
if (mCachedURI) {
|
||||
nsCOMPtr<nsISizeOf> iface = do_QueryInterface(mCachedURI);
|
||||
if (iface) {
|
||||
n += iface->SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
}
|
||||
|
||||
// The following members don't need to be measured:
|
||||
// - mElement, because it is a pointer-to-self used to avoid QIs
|
||||
// - mHistory, because it is non-owning
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -131,6 +131,9 @@ public:
|
||||
*/
|
||||
virtual bool HasDeferredDNSPrefetchRequest() { return true; }
|
||||
|
||||
virtual size_t
|
||||
SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
|
||||
|
||||
protected:
|
||||
virtual ~Link();
|
||||
|
||||
|
@ -44,7 +44,6 @@
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsParserCIID.h"
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsIStreamConverterService.h"
|
||||
#include "nsStringStream.h"
|
||||
|
@ -43,7 +43,6 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsICharsetDetector.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsIConverterInputStream.h"
|
||||
|
@ -42,7 +42,7 @@
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsCharsetAlias.h"
|
||||
#include "nsICharsetDetector.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsIConverterInputStream.h"
|
||||
@ -495,10 +495,7 @@ nsDOMFileReader::GetAsText(const nsACString &aCharset,
|
||||
}
|
||||
|
||||
nsCAutoString charset;
|
||||
nsCOMPtr<nsICharsetAlias> alias = do_GetService(NS_CHARSETALIAS_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = alias->GetPreferred(charsetGuess, charset);
|
||||
rv = nsCharsetAlias::GetPreferred(charsetGuess, charset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = ConvertStream(aFileData, aDataLen, charset.get(), aResult);
|
||||
|
@ -147,7 +147,7 @@
|
||||
#include "nsILink.h"
|
||||
#include "nsBlobProtocolHandler.h"
|
||||
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsCharsetAlias.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsIContentSink.h"
|
||||
|
||||
@ -3012,13 +3012,10 @@ nsDocument::SetDocumentCharacterSet(const nsACString& aCharSetID)
|
||||
mCharacterSet = aCharSetID;
|
||||
|
||||
#ifdef DEBUG
|
||||
nsCOMPtr<nsICharsetAlias> calias(do_GetService(NS_CHARSETALIAS_CONTRACTID));
|
||||
if (calias) {
|
||||
nsCAutoString canonicalName;
|
||||
calias->GetPreferred(aCharSetID, canonicalName);
|
||||
NS_ASSERTION(canonicalName.Equals(aCharSetID),
|
||||
"charset name must be canonical");
|
||||
}
|
||||
nsCAutoString canonicalName;
|
||||
nsCharsetAlias::GetPreferred(aCharSetID, canonicalName);
|
||||
NS_ASSERTION(canonicalName.Equals(aCharSetID),
|
||||
"charset name must be canonical");
|
||||
#endif
|
||||
|
||||
PRInt32 n = mCharSetObservers.Length();
|
||||
@ -3172,16 +3169,10 @@ nsDocument::TryChannelCharset(nsIChannel *aChannel,
|
||||
nsCAutoString charsetVal;
|
||||
nsresult rv = aChannel->GetContentCharset(charsetVal);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsICharsetAlias> calias(do_GetService(NS_CHARSETALIAS_CONTRACTID));
|
||||
if (calias) {
|
||||
nsCAutoString preferred;
|
||||
rv = calias->GetPreferred(charsetVal,
|
||||
preferred);
|
||||
if(NS_SUCCEEDED(rv)) {
|
||||
aCharset = preferred;
|
||||
aCharsetSource = kCharsetFromChannel;
|
||||
return true;
|
||||
}
|
||||
rv = nsCharsetAlias::GetPreferred(charsetVal, aCharset);
|
||||
if(NS_SUCCEEDED(rv)) {
|
||||
aCharsetSource = kCharsetFromChannel;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -882,9 +882,7 @@ nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope)
|
||||
JS_SetContextPrivate(cx, aScope);
|
||||
|
||||
nsresult rv =
|
||||
xpc->InitClassesWithNewWrappedGlobal(cx, aScope,
|
||||
NS_GET_IID(nsISupports),
|
||||
mPrincipal, nsnull,
|
||||
xpc->InitClassesWithNewWrappedGlobal(cx, aScope, mPrincipal,
|
||||
flags, getter_AddRefs(mGlobal));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
|
@ -597,29 +597,10 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
|
||||
if (aCx && wrapper) {
|
||||
nsIXPConnect *xpc = nsContentUtils::XPConnect();
|
||||
if (xpc) {
|
||||
JSObject *preservedWrapper = nsnull;
|
||||
|
||||
// If reparenting moves us to a new compartment, preserving causes
|
||||
// problems. In that case, we release ourselves and re-preserve after
|
||||
// reparenting so we're sure to have the right JS object preserved.
|
||||
// We use a JSObject stack copy of the wrapper to protect it from GC
|
||||
// under ReparentWrappedNativeIfFound.
|
||||
if (aNode->PreservingWrapper()) {
|
||||
preservedWrapper = wrapper;
|
||||
nsContentUtils::ReleaseWrapper(aNode, aNode);
|
||||
NS_ASSERTION(aNode->GetWrapper(),
|
||||
"ReleaseWrapper cleared our wrapper, this code needs to "
|
||||
"be changed to deal with that!");
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIXPConnectJSObjectHolder> oldWrapper;
|
||||
rv = xpc->ReparentWrappedNativeIfFound(aCx, wrapper, aNewScope, aNode,
|
||||
getter_AddRefs(oldWrapper));
|
||||
|
||||
if (preservedWrapper) {
|
||||
nsContentUtils::PreserveWrapper(aNode, aNode);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
aNode->mNodeInfo.swap(nodeInfo);
|
||||
|
||||
|
@ -602,7 +602,7 @@ nsWebSocket::Initialize(nsISupports* aOwner,
|
||||
if (JSVAL_IS_OBJECT(aArgv[1]) &&
|
||||
(jsobj = JSVAL_TO_OBJECT(aArgv[1])) &&
|
||||
JS_IsArrayObject(aContext, jsobj)) {
|
||||
jsuint len;
|
||||
uint32_t len;
|
||||
JS_GetArrayLength(aContext, jsobj, &len);
|
||||
|
||||
for (PRUint32 index = 0; index < len; ++index) {
|
||||
|
@ -61,7 +61,7 @@
|
||||
#include "nsIJSContextStack.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsCharsetAlias.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsIDOMElement.h"
|
||||
@ -812,11 +812,7 @@ nsXMLHttpRequest::DetectCharset()
|
||||
nsresult rv = channel ? channel->GetContentCharset(charsetVal) :
|
||||
NS_ERROR_FAILURE;
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsICharsetAlias> calias =
|
||||
do_GetService(NS_CHARSETALIAS_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && calias) {
|
||||
rv = calias->GetPreferred(charsetVal, mResponseCharset);
|
||||
}
|
||||
rv = nsCharsetAlias::GetPreferred(charsetVal, mResponseCharset);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv) || mResponseCharset.IsEmpty()) {
|
||||
|
@ -122,7 +122,7 @@ JSValToMatrixElts(JSContext* cx, const jsval& val,
|
||||
double* (&elts)[N], nsresult* rv)
|
||||
{
|
||||
JSObject* obj;
|
||||
jsuint length;
|
||||
uint32_t length;
|
||||
|
||||
if (JSVAL_IS_PRIMITIVE(val) ||
|
||||
!(obj = JSVAL_TO_OBJECT(val)) ||
|
||||
|
@ -146,11 +146,11 @@ JSValToDashArray(JSContext* cx, const jsval& patternArray,
|
||||
{
|
||||
// The cap is pretty arbitrary. 16k should be enough for
|
||||
// anybody...
|
||||
static const jsuint MAX_NUM_DASHES = 1 << 14;
|
||||
static const uint32_t MAX_NUM_DASHES = 1 << 14;
|
||||
|
||||
if (!JSVAL_IS_PRIMITIVE(patternArray)) {
|
||||
JSObject* obj = JSVAL_TO_OBJECT(patternArray);
|
||||
jsuint length;
|
||||
uint32_t length;
|
||||
if (!JS_GetArrayLength(cx, obj, &length)) {
|
||||
// Not an array-like thing
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
@ -754,7 +754,7 @@ protected:
|
||||
WebGL_MOZ_WEBGL_lose_context,
|
||||
WebGLExtensionID_Max
|
||||
};
|
||||
nsCOMPtr<WebGLExtension> mEnabledExtensions[WebGLExtensionID_Max];
|
||||
nsRefPtr<WebGLExtension> mEnabledExtensions[WebGLExtensionID_Max];
|
||||
bool IsExtensionEnabled(WebGLExtensionID ext) const {
|
||||
NS_ABORT_IF_FALSE(ext >= 0 && ext < WebGLExtensionID_Max, "bogus index!");
|
||||
return mEnabledExtensions[ext] != nsnull;
|
||||
|
@ -377,7 +377,7 @@ function start() {
|
||||
default:
|
||||
throw 'unhandled';
|
||||
break;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
var getURLOptions = function(obj) {
|
||||
@ -404,27 +404,12 @@ function start() {
|
||||
|
||||
// try to create a dummy WebGL context, just to catch context creation failures once here,
|
||||
// rather than having them result in 100's of failures (one in each test page)
|
||||
var canvas = document.getElementById("webglcheck-default");
|
||||
var ctx;
|
||||
try {
|
||||
ctx = canvas.getContext("experimental-webgl");
|
||||
} catch(e) {
|
||||
ok(false, "canvas.getContext() failed", e);
|
||||
}
|
||||
|
||||
if (ctx) {
|
||||
statusTextNode.textContent = 'Loading test lists...';
|
||||
var iframe = document.getElementById("testframe");
|
||||
var testHarness = new WebGLTestHarnessModule.TestHarness(
|
||||
iframe,
|
||||
'00_test_list.txt',
|
||||
function(type, msg, success) {
|
||||
return reporter.reportFunc(type, msg, success);
|
||||
},
|
||||
OPTIONS);
|
||||
testHarness.setTimeoutDelay(20000); // and make it much higher when running under valgrind.
|
||||
window.webglTestHarness = testHarness;
|
||||
} else {
|
||||
ctx = document.getElementById("webglcheck-default")
|
||||
.getContext("experimental-webgl");
|
||||
} catch(e) {}
|
||||
if (!ctx) {
|
||||
var errmsg = "Can't create a WebGL context";
|
||||
reporter.fullResultsNode.textContent = errmsg;
|
||||
// Workaround for SeaMonkey tinderboxes which don't support WebGL.
|
||||
@ -434,8 +419,22 @@ function start() {
|
||||
ok(false, errmsg);
|
||||
dump("WebGL mochitest failed: " + errmsg + "\n");
|
||||
reporter.finishedTestSuite();
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
statusTextNode.textContent = 'Loading test lists...';
|
||||
var iframe = document.getElementById("testframe");
|
||||
var testHarness = new WebGLTestHarnessModule.TestHarness(
|
||||
iframe,
|
||||
'00_test_list.txt',
|
||||
function(type, msg, success) {
|
||||
return reporter.reportFunc(type, msg, success);
|
||||
},
|
||||
OPTIONS);
|
||||
// Make timeout delay much higher when running under valgrind.
|
||||
testHarness.setTimeoutDelay(20000);
|
||||
window.webglTestHarness = testHarness;
|
||||
}
|
||||
|
||||
SimpleTest.requestLongerTimeout(3);
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsLinebreakConverter.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsCharsetAlias.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsIMultiplexInputStream.h"
|
||||
@ -782,7 +782,6 @@ GetSubmitCharset(nsGenericHTMLElement* aForm,
|
||||
{
|
||||
oCharset.AssignLiteral("UTF-8"); // default to utf-8
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsAutoString acceptCharsetValue;
|
||||
aForm->GetAttr(kNameSpaceID_None, nsGkAtoms::acceptcharset,
|
||||
acceptCharsetValue);
|
||||
@ -792,26 +791,19 @@ GetSubmitCharset(nsGenericHTMLElement* aForm,
|
||||
PRInt32 offset=0;
|
||||
PRInt32 spPos=0;
|
||||
// get charset from charsets one by one
|
||||
nsCOMPtr<nsICharsetAlias> calias(do_GetService(NS_CHARSETALIAS_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
return;
|
||||
}
|
||||
if (calias) {
|
||||
do {
|
||||
spPos = acceptCharsetValue.FindChar(PRUnichar(' '), offset);
|
||||
PRInt32 cnt = ((-1==spPos)?(charsetLen-offset):(spPos-offset));
|
||||
if (cnt > 0) {
|
||||
nsAutoString uCharset;
|
||||
acceptCharsetValue.Mid(uCharset, offset, cnt);
|
||||
do {
|
||||
spPos = acceptCharsetValue.FindChar(PRUnichar(' '), offset);
|
||||
PRInt32 cnt = ((-1==spPos)?(charsetLen-offset):(spPos-offset));
|
||||
if (cnt > 0) {
|
||||
nsAutoString uCharset;
|
||||
acceptCharsetValue.Mid(uCharset, offset, cnt);
|
||||
|
||||
if (NS_SUCCEEDED(calias->
|
||||
GetPreferred(NS_LossyConvertUTF16toASCII(uCharset),
|
||||
oCharset)))
|
||||
return;
|
||||
}
|
||||
offset = spPos + 1;
|
||||
} while (spPos != -1);
|
||||
}
|
||||
if (NS_SUCCEEDED(nsCharsetAlias::GetPreferred(NS_LossyConvertUTF16toASCII(uCharset),
|
||||
oCharset)))
|
||||
return;
|
||||
}
|
||||
offset = spPos + 1;
|
||||
} while (spPos != -1);
|
||||
}
|
||||
// if there are no accept-charset or all the charset are not supported
|
||||
// Get the charset from document
|
||||
|
@ -96,8 +96,8 @@ public:
|
||||
// nsIDOMHTMLAnchorElement
|
||||
NS_DECL_NSIDOMHTMLANCHORELEMENT
|
||||
|
||||
// TODO: nsHTMLAnchorElement::SizeOfAnchorElement should call
|
||||
// Link::SizeOfExcludingThis(). See bug 682431.
|
||||
// DOM memory reporter participant
|
||||
NS_DECL_SIZEOF_EXCLUDING_THIS
|
||||
|
||||
// nsILink
|
||||
NS_IMETHOD LinkAdded() { return NS_OK; }
|
||||
@ -520,3 +520,10 @@ nsHTMLAnchorElement::IntrinsicState() const
|
||||
return Link::LinkState() | nsGenericHTMLElement::IntrinsicState();
|
||||
}
|
||||
|
||||
size_t
|
||||
nsHTMLAnchorElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
|
||||
{
|
||||
return nsGenericHTMLElement::SizeOfExcludingThis(aMallocSizeOf) +
|
||||
Link::SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
|
@ -61,8 +61,8 @@ public:
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// TODO: nsHTMLAreaElement::SizeOfAnchorElement should call
|
||||
// Link::SizeOfExcludingThis(). See bug 682431.
|
||||
// DOM memory reporter participant
|
||||
NS_DECL_SIZEOF_EXCLUDING_THIS
|
||||
|
||||
// nsIDOMNode
|
||||
NS_FORWARD_NSIDOMNODE(nsGenericHTMLElement::)
|
||||
@ -335,3 +335,11 @@ nsHTMLAreaElement::IntrinsicState() const
|
||||
{
|
||||
return Link::LinkState() | nsGenericHTMLElement::IntrinsicState();
|
||||
}
|
||||
|
||||
size_t
|
||||
nsHTMLAreaElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
|
||||
{
|
||||
return nsGenericHTMLElement::SizeOfExcludingThis(aMallocSizeOf) +
|
||||
Link::SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
|
@ -84,8 +84,8 @@ public:
|
||||
// nsIDOMHTMLLinkElement
|
||||
NS_DECL_NSIDOMHTMLLINKELEMENT
|
||||
|
||||
// TODO: nsHTMLLinkElement::SizeOfAnchorElement should call
|
||||
// Link::SizeOfExcludingThis(). See bug 682431.
|
||||
// DOM memory reporter participant
|
||||
NS_DECL_SIZEOF_EXCLUDING_THIS
|
||||
|
||||
// nsILink
|
||||
NS_IMETHOD LinkAdded();
|
||||
@ -458,3 +458,11 @@ nsHTMLLinkElement::IntrinsicState() const
|
||||
{
|
||||
return Link::LinkState() | nsGenericHTMLElement::IntrinsicState();
|
||||
}
|
||||
|
||||
size_t
|
||||
nsHTMLLinkElement::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
|
||||
{
|
||||
return nsGenericHTMLElement::SizeOfExcludingThis(aMallocSizeOf) +
|
||||
Link::SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
|
@ -40,8 +40,6 @@
|
||||
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#include "nsICharsetAlias.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsPrintfCString.h"
|
||||
@ -102,7 +100,6 @@
|
||||
#include "nsFrameSelection.h"
|
||||
#include "nsISelectionPrivate.h"//for toStringwithformat code
|
||||
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsJSUtils.h"
|
||||
#include "nsIDocumentEncoder.h" //for outputting selection
|
||||
|
@ -2019,6 +2019,13 @@ void nsBuiltinDecoderStateMachine::AdvanceFrame()
|
||||
// duration.
|
||||
RenderVideoFrame(currentFrame, presTime);
|
||||
}
|
||||
// If we're no longer playing after dropping and reacquiring the lock,
|
||||
// playback must've been stopped on the decode thread (by a seek, for
|
||||
// example). In that case, the current frame is probably out of date.
|
||||
if (!IsPlaying()) {
|
||||
ScheduleStateMachine();
|
||||
return;
|
||||
}
|
||||
mDecoder->GetFrameStatistics().NotifyPresentedFrame();
|
||||
PRInt64 now = DurationToUsecs(TimeStamp::Now() - mPlayStartTime) + mPlayDuration;
|
||||
remainingTime = currentFrame->mEndTime - mStartTime - now;
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "nsMediaCache.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "prio.h"
|
||||
#include "nsThreadUtils.h"
|
||||
@ -545,8 +546,15 @@ nsMediaCache::Init()
|
||||
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
|
||||
NS_ASSERTION(!mFD, "Cache file already open?");
|
||||
|
||||
// In single process Gecko, store the media cache in the profile directory
|
||||
// so that multiple users can use separate media caches concurrently.
|
||||
// In multi-process Gecko, there is no profile dir, so just store it in the
|
||||
// system temp directory instead.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> tmp;
|
||||
nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmp));
|
||||
const char* dir = (XRE_GetProcessType() == GeckoProcessType_Content) ?
|
||||
NS_OS_TEMP_DIR : NS_APP_USER_PROFILE_LOCAL_50_DIR;
|
||||
rv = NS_GetSpecialDirectory(dir, getter_AddRefs(tmp));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsCOMPtr<nsILocalFile> tmpFile = do_QueryInterface(tmp);
|
||||
|
@ -428,9 +428,7 @@ nsSVGUseElement::SyncWidthOrHeight(nsIAtom* aName)
|
||||
// Our width/height attribute is now no longer explicitly set, so we
|
||||
// need to revert the clone's width/height to the width/height of the
|
||||
// content that's being cloned.
|
||||
nsSVGSVGElement* svgElement =
|
||||
static_cast<nsSVGSVGElement*>(mSource.get());
|
||||
svgElement->SyncWidthOrHeight(aName, target);
|
||||
TriggerReclone();
|
||||
return;
|
||||
}
|
||||
// Our width/height attribute is now no longer explicitly set, so we
|
||||
|
@ -41,7 +41,6 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsDoubleHashtable.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsIChannel.h"
|
||||
|
@ -59,8 +59,6 @@
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
|
@ -55,7 +55,8 @@
|
||||
|
||||
#include "txList.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsDoubleHashtable.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "nsBaseHashtable.h"
|
||||
#include "nsString.h"
|
||||
#include "txCore.h"
|
||||
#include "nsAutoPtr.h"
|
||||
@ -229,24 +230,7 @@ class NodeDefinition : public Node
|
||||
//Definition and Implementation of a Document.
|
||||
//
|
||||
|
||||
/**
|
||||
* nsDoubleHashtable definitions for IDs
|
||||
*
|
||||
* It may be possible to share the key value with the element,
|
||||
* but that may leave entries without keys, as the entries
|
||||
* are constructed from the key value and the setting of mElement
|
||||
* happens late. As pldhash.h ain't clear on this, we store the
|
||||
* key by inheriting from PLDHashStringEntry.
|
||||
*/
|
||||
class txIDEntry : public PLDHashStringEntry
|
||||
{
|
||||
public:
|
||||
txIDEntry(const void* aKey) : PLDHashStringEntry(aKey), mElement(nsnull)
|
||||
{
|
||||
}
|
||||
Element* mElement;
|
||||
};
|
||||
DECL_DHASH_WRAPPER(txIDMap, txIDEntry, nsAString&)
|
||||
typedef nsTHashtable<nsBaseHashtableET<nsStringHashKey, Element*> > txIDMap;
|
||||
|
||||
class Document : public NodeDefinition
|
||||
{
|
||||
|
@ -39,7 +39,7 @@
|
||||
#ifndef txKey_h__
|
||||
#define txKey_h__
|
||||
|
||||
#include "nsDoubleHashtable.h"
|
||||
#include "nsTHashtable.h"
|
||||
#include "txNodeSet.h"
|
||||
#include "txList.h"
|
||||
#include "txXSLTPatterns.h"
|
||||
@ -68,21 +68,31 @@ public:
|
||||
|
||||
struct txKeyValueHashEntry : public PLDHashEntryHdr
|
||||
{
|
||||
txKeyValueHashEntry(const void* aKey)
|
||||
: mKey(*static_cast<const txKeyValueHashKey*>(aKey)),
|
||||
mNodeSet(new txNodeSet(nsnull))
|
||||
{
|
||||
}
|
||||
public:
|
||||
typedef const txKeyValueHashKey& KeyType;
|
||||
typedef const txKeyValueHashKey* KeyTypePointer;
|
||||
|
||||
// @see nsDoubleHashtable.h
|
||||
bool MatchEntry(const void* aKey) const;
|
||||
static PLDHashNumber HashKey(const void* aKey);
|
||||
txKeyValueHashEntry(KeyTypePointer aKey)
|
||||
: mKey(*aKey),
|
||||
mNodeSet(new txNodeSet(nsnull)) { }
|
||||
|
||||
txKeyValueHashEntry(const txKeyValueHashEntry& entry)
|
||||
: mKey(entry.mKey),
|
||||
mNodeSet(entry.mNodeSet) { }
|
||||
|
||||
bool KeyEquals(KeyTypePointer aKey) const;
|
||||
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
|
||||
|
||||
static PLDHashNumber HashKey(KeyTypePointer aKey);
|
||||
|
||||
enum { ALLOW_MEMMOVE = true };
|
||||
|
||||
txKeyValueHashKey mKey;
|
||||
nsRefPtr<txNodeSet> mNodeSet;
|
||||
};
|
||||
|
||||
DECL_DHASH_WRAPPER(txKeyValueHash, txKeyValueHashEntry, txKeyValueHashKey&)
|
||||
typedef nsTHashtable<txKeyValueHashEntry> txKeyValueHash;
|
||||
|
||||
class txIndexedKeyHashKey
|
||||
{
|
||||
@ -100,22 +110,31 @@ public:
|
||||
|
||||
struct txIndexedKeyHashEntry : public PLDHashEntryHdr
|
||||
{
|
||||
txIndexedKeyHashEntry(const void* aKey)
|
||||
: mKey(*static_cast<const txIndexedKeyHashKey*>(aKey)),
|
||||
mIndexed(false)
|
||||
{
|
||||
}
|
||||
public:
|
||||
typedef const txIndexedKeyHashKey& KeyType;
|
||||
typedef const txIndexedKeyHashKey* KeyTypePointer;
|
||||
|
||||
// @see nsDoubleHashtable.h
|
||||
bool MatchEntry(const void* aKey) const;
|
||||
static PLDHashNumber HashKey(const void* aKey);
|
||||
txIndexedKeyHashEntry(KeyTypePointer aKey)
|
||||
: mKey(*aKey),
|
||||
mIndexed(false) { }
|
||||
|
||||
txIndexedKeyHashEntry(const txIndexedKeyHashEntry& entry)
|
||||
: mKey(entry.mKey),
|
||||
mIndexed(entry.mIndexed) { }
|
||||
|
||||
bool KeyEquals(KeyTypePointer aKey) const;
|
||||
|
||||
static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
|
||||
|
||||
static PLDHashNumber HashKey(KeyTypePointer aKey);
|
||||
|
||||
enum { ALLOW_MEMMOVE = true };
|
||||
|
||||
txIndexedKeyHashKey mKey;
|
||||
bool mIndexed;
|
||||
};
|
||||
|
||||
DECL_DHASH_WRAPPER(txIndexedKeyHash, txIndexedKeyHashEntry,
|
||||
txIndexedKeyHashKey&)
|
||||
typedef nsTHashtable<txIndexedKeyHashEntry> txIndexedKeyHash;
|
||||
|
||||
/**
|
||||
* Class holding all <xsl:key>s of a particular expanded name in the
|
||||
|
@ -152,51 +152,36 @@ txKeyFunctionCall::getNameAtom(nsIAtom** aAtom)
|
||||
* Hash functions
|
||||
*/
|
||||
|
||||
DHASH_WRAPPER(txKeyValueHash, txKeyValueHashEntry, txKeyValueHashKey&)
|
||||
DHASH_WRAPPER(txIndexedKeyHash, txIndexedKeyHashEntry, txIndexedKeyHashKey&)
|
||||
|
||||
bool
|
||||
txKeyValueHashEntry::MatchEntry(const void* aKey) const
|
||||
txKeyValueHashEntry::KeyEquals(KeyTypePointer aKey) const
|
||||
{
|
||||
const txKeyValueHashKey* key =
|
||||
static_cast<const txKeyValueHashKey*>(aKey);
|
||||
|
||||
return mKey.mKeyName == key->mKeyName &&
|
||||
mKey.mRootIdentifier == key->mRootIdentifier &&
|
||||
mKey.mKeyValue.Equals(key->mKeyValue);
|
||||
return mKey.mKeyName == aKey->mKeyName &&
|
||||
mKey.mRootIdentifier == aKey->mRootIdentifier &&
|
||||
mKey.mKeyValue.Equals(aKey->mKeyValue);
|
||||
}
|
||||
|
||||
PLDHashNumber
|
||||
txKeyValueHashEntry::HashKey(const void* aKey)
|
||||
txKeyValueHashEntry::HashKey(KeyTypePointer aKey)
|
||||
{
|
||||
const txKeyValueHashKey* key =
|
||||
static_cast<const txKeyValueHashKey*>(aKey);
|
||||
|
||||
return key->mKeyName.mNamespaceID ^
|
||||
NS_PTR_TO_INT32(key->mKeyName.mLocalName.get()) ^
|
||||
key->mRootIdentifier ^
|
||||
HashString(key->mKeyValue);
|
||||
return aKey->mKeyName.mNamespaceID ^
|
||||
NS_PTR_TO_INT32(aKey->mKeyName.mLocalName.get()) ^
|
||||
aKey->mRootIdentifier ^
|
||||
HashString(aKey->mKeyValue);
|
||||
}
|
||||
|
||||
bool
|
||||
txIndexedKeyHashEntry::MatchEntry(const void* aKey) const
|
||||
txIndexedKeyHashEntry::KeyEquals(KeyTypePointer aKey) const
|
||||
{
|
||||
const txIndexedKeyHashKey* key =
|
||||
static_cast<const txIndexedKeyHashKey*>(aKey);
|
||||
|
||||
return mKey.mKeyName == key->mKeyName &&
|
||||
mKey.mRootIdentifier == key->mRootIdentifier;
|
||||
return mKey.mKeyName == aKey->mKeyName &&
|
||||
mKey.mRootIdentifier == aKey->mRootIdentifier;
|
||||
}
|
||||
|
||||
PLDHashNumber
|
||||
txIndexedKeyHashEntry::HashKey(const void* aKey)
|
||||
txIndexedKeyHashEntry::HashKey(KeyTypePointer aKey)
|
||||
{
|
||||
const txIndexedKeyHashKey* key =
|
||||
static_cast<const txIndexedKeyHashKey*>(aKey);
|
||||
|
||||
return key->mKeyName.mNamespaceID ^
|
||||
NS_PTR_TO_INT32(key->mKeyName.mLocalName.get()) ^
|
||||
key->mRootIdentifier;
|
||||
return aKey->mKeyName.mNamespaceID ^
|
||||
NS_PTR_TO_INT32(aKey->mKeyName.mLocalName.get()) ^
|
||||
aKey->mRootIdentifier;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -211,9 +196,6 @@ txKeyHash::getKeyNodes(const txExpandedName& aKeyName,
|
||||
txExecutionState& aEs,
|
||||
txNodeSet** aResult)
|
||||
{
|
||||
NS_ENSURE_TRUE(mKeyValues.mHashTable.ops && mIndexedKeys.mHashTable.ops,
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
*aResult = nsnull;
|
||||
|
||||
PRInt32 identifier = txXPathNodeUtils::getUniqueIdentifier(aRoot);
|
||||
@ -241,7 +223,7 @@ txKeyHash::getKeyNodes(const txExpandedName& aKeyName,
|
||||
}
|
||||
|
||||
txIndexedKeyHashKey indexKey(aKeyName, identifier);
|
||||
txIndexedKeyHashEntry* indexEntry = mIndexedKeys.AddEntry(indexKey);
|
||||
txIndexedKeyHashEntry* indexEntry = mIndexedKeys.PutEntry(indexKey);
|
||||
NS_ENSURE_TRUE(indexEntry, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (indexEntry->mIndexed) {
|
||||
@ -412,7 +394,7 @@ nsresult txXSLKey::testNode(const txXPathNode& aNode,
|
||||
txXPathNodeUtils::appendNodeValue(res->get(i), val);
|
||||
|
||||
aKey.mKeyValue.Assign(val);
|
||||
txKeyValueHashEntry* entry = aKeyValueHash.AddEntry(aKey);
|
||||
txKeyValueHashEntry* entry = aKeyValueHash.PutEntry(aKey);
|
||||
NS_ENSURE_TRUE(entry && entry->mNodeSet,
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
@ -427,7 +409,7 @@ nsresult txXSLKey::testNode(const txXPathNode& aNode,
|
||||
exprResult->stringValue(val);
|
||||
|
||||
aKey.mKeyValue.Assign(val);
|
||||
txKeyValueHashEntry* entry = aKeyValueHash.AddEntry(aKey);
|
||||
txKeyValueHashEntry* entry = aKeyValueHash.PutEntry(aKey);
|
||||
NS_ENSURE_TRUE(entry && entry->mNodeSet,
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIAuthPrompt.h"
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsCharsetAlias.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
@ -282,29 +282,23 @@ txStylesheetSink::OnDataAvailable(nsIRequest *aRequest, nsISupports *aContext,
|
||||
NS_IMETHODIMP
|
||||
txStylesheetSink::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
|
||||
{
|
||||
nsCAutoString charset(NS_LITERAL_CSTRING("UTF-8"));
|
||||
PRInt32 charsetSource = kCharsetFromDocTypeDefault;
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
|
||||
// check channel's charset...
|
||||
nsCAutoString charsetVal;
|
||||
nsresult rv = channel->GetContentCharset(charsetVal);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsCOMPtr<nsICharsetAlias> calias =
|
||||
do_GetService(NS_CHARSETALIAS_CONTRACTID);
|
||||
|
||||
if (calias) {
|
||||
nsCAutoString preferred;
|
||||
rv = calias->GetPreferred(charsetVal,
|
||||
preferred);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
charset = preferred;
|
||||
charsetSource = kCharsetFromChannel;
|
||||
}
|
||||
nsCAutoString charset;
|
||||
if (NS_SUCCEEDED(channel->GetContentCharset(charsetVal))) {
|
||||
if (NS_SUCCEEDED(nsCharsetAlias::GetPreferred(charsetVal, charset))) {
|
||||
charsetSource = kCharsetFromChannel;
|
||||
}
|
||||
}
|
||||
|
||||
if (charset.IsEmpty()) {
|
||||
charset.AssignLiteral("UTF-8");
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIParser> parser = do_QueryInterface(aContext);
|
||||
parser->SetDocumentCharset(charset, charsetSource);
|
||||
|
||||
@ -318,6 +312,7 @@ txStylesheetSink::OnStartRequest(nsIRequest *aRequest, nsISupports *aContext)
|
||||
bool sniff;
|
||||
if (NS_SUCCEEDED(uri->SchemeIs("file", &sniff)) && sniff &&
|
||||
contentType.Equals(UNKNOWN_CONTENT_TYPE)) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIStreamConverterService> serv =
|
||||
do_GetService("@mozilla.org/streamConverters;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -45,7 +45,7 @@
|
||||
#include "nsIDocumentTransformer.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsCharsetAlias.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "txURIUtils.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
@ -184,11 +184,9 @@ txMozillaTextOutput::createResultDocument(nsIDOMDocument* aSourceDocument)
|
||||
if (!mOutputFormat.mEncoding.IsEmpty()) {
|
||||
NS_LossyConvertUTF16toASCII charset(mOutputFormat.mEncoding);
|
||||
nsCAutoString canonicalCharset;
|
||||
nsCOMPtr<nsICharsetAlias> calias =
|
||||
do_GetService("@mozilla.org/intl/charsetalias;1");
|
||||
|
||||
if (calias &&
|
||||
NS_SUCCEEDED(calias->GetPreferred(charset, canonicalCharset))) {
|
||||
if (NS_SUCCEEDED(nsCharsetAlias::GetPreferred(charset,
|
||||
canonicalCharset))) {
|
||||
mDocument->SetDocumentCharacterSetSource(kCharsetFromOtherComponent);
|
||||
mDocument->SetDocumentCharacterSet(canonicalCharset);
|
||||
}
|
||||
|
@ -64,7 +64,7 @@
|
||||
#include "nsIDocumentTransformer.h"
|
||||
#include "mozilla/css/Loader.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsICharsetAlias.h"
|
||||
#include "nsCharsetAlias.h"
|
||||
#include "nsIHTMLContentSink.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "txXMLUtils.h"
|
||||
@ -857,11 +857,7 @@ txMozillaXMLOutput::createResultDocument(const nsSubstring& aName, PRInt32 aNsID
|
||||
if (!mOutputFormat.mEncoding.IsEmpty()) {
|
||||
NS_LossyConvertUTF16toASCII charset(mOutputFormat.mEncoding);
|
||||
nsCAutoString canonicalCharset;
|
||||
nsCOMPtr<nsICharsetAlias> calias =
|
||||
do_GetService("@mozilla.org/intl/charsetalias;1");
|
||||
|
||||
if (calias &&
|
||||
NS_SUCCEEDED(calias->GetPreferred(charset, canonicalCharset))) {
|
||||
if (NS_SUCCEEDED(nsCharsetAlias::GetPreferred(charset, canonicalCharset))) {
|
||||
mDocument->SetDocumentCharacterSetSource(kCharsetFromOtherComponent);
|
||||
mDocument->SetDocumentCharacterSet(canonicalCharset);
|
||||
}
|
||||
|
80
dom/base/DOMRequestHelper.jsm
Normal file
80
dom/base/DOMRequestHelper.jsm
Normal file
@ -0,0 +1,80 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* helper object for APIs that deal with DOMRequest and need to release them properly
|
||||
* when the window goes out of scope
|
||||
*/
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
let EXPORTED_SYMBOLS = ["DOMRequestIpcHelper"];
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(Services, "rs", function() {
|
||||
return Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci.nsIDOMRequestService);
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
|
||||
return Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
|
||||
});
|
||||
|
||||
function DOMRequestIpcHelper() {
|
||||
}
|
||||
|
||||
DOMRequestIpcHelper.prototype = {
|
||||
getRequestId: function(aRequest) {
|
||||
let id = "id" + this._getRandomId();
|
||||
this._requests[id] = aRequest;
|
||||
return id;
|
||||
},
|
||||
|
||||
getRequest: function(aId) {
|
||||
if (this._requests[aId])
|
||||
return this._requests[aId];
|
||||
},
|
||||
|
||||
removeRequest: function(aId) {
|
||||
if (this._requests[aId])
|
||||
delete this._requests[aId];
|
||||
},
|
||||
|
||||
_getRandomId: function() {
|
||||
return Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
if (wId == this.innerWindowID) {
|
||||
Services.obs.removeObserver(this, "inner-window-destroyed");
|
||||
this._requests = [];
|
||||
this._window = null;
|
||||
this._messages.forEach((function(msgName) {
|
||||
cpmm.removeMessageListener(msgName, this);
|
||||
}).bind(this));
|
||||
if(this.uninit)
|
||||
this.uninit();
|
||||
}
|
||||
},
|
||||
|
||||
initHelper: function(aWindow, aMessages) {
|
||||
this._messages = aMessages;
|
||||
this._requests = [];
|
||||
this._window = aWindow;
|
||||
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
this.innerWindowID = util.currentInnerWindowID;
|
||||
this._id = this._getRandomId();
|
||||
Services.obs.addObserver(this, "inner-window-destroyed", false);
|
||||
this._messages.forEach((function(msgName) {
|
||||
cpmm.addMessageListener(msgName, this);
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
createRequest: function() {
|
||||
return Services.rs.createRequest(this._window);
|
||||
}
|
||||
}
|
@ -69,6 +69,9 @@ EXTRA_JS_MODULES += Webapps.jsm \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
EXTRA_JS_MODULES += DOMRequestHelper.jsm \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsIDOMDOMError.idl \
|
||||
nsIDOMDOMRequest.idl \
|
||||
|
@ -70,6 +70,8 @@
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "BatteryManager.h"
|
||||
#include "PowerManager.h"
|
||||
#include "nsIDOMWakeLock.h"
|
||||
#include "nsIPowerManagerService.h"
|
||||
#include "SmsManager.h"
|
||||
#include "nsISmsService.h"
|
||||
#include "mozilla/Hal.h"
|
||||
@ -172,7 +174,10 @@ Navigator::Invalidate()
|
||||
mBatteryManager = nsnull;
|
||||
}
|
||||
|
||||
mPowerManager = nsnull;
|
||||
if (mPowerManager) {
|
||||
mPowerManager->Shutdown();
|
||||
mPowerManager = nsnull;
|
||||
}
|
||||
|
||||
if (mSmsManager) {
|
||||
mSmsManager->Shutdown();
|
||||
@ -958,15 +963,38 @@ Navigator::GetMozBattery(nsIDOMMozBatteryManager** aBattery)
|
||||
NS_IMETHODIMP
|
||||
Navigator::GetMozPower(nsIDOMMozPowerManager** aPower)
|
||||
{
|
||||
*aPower = nsnull;
|
||||
|
||||
if (!mPowerManager) {
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_TRUE(win, NS_OK);
|
||||
|
||||
mPowerManager = new power::PowerManager();
|
||||
mPowerManager->Init(win);
|
||||
}
|
||||
|
||||
NS_ADDREF(*aPower = mPowerManager);
|
||||
nsCOMPtr<nsIDOMMozPowerManager> power =
|
||||
do_QueryInterface(NS_ISUPPORTS_CAST(nsIDOMMozPowerManager*, mPowerManager));
|
||||
power.forget(aPower);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
Navigator::RequestWakeLock(const nsAString &aTopic, nsIDOMMozWakeLock **aWakeLock)
|
||||
{
|
||||
*aWakeLock = nsnull;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_TRUE(win, NS_OK);
|
||||
|
||||
nsCOMPtr<nsIPowerManagerService> pmService =
|
||||
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(pmService, NS_OK);
|
||||
|
||||
return pmService->NewWakeLock(aTopic, win, aWakeLock);
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// Navigator::nsIDOMNavigatorSms
|
||||
//*****************************************************************************
|
||||
|
@ -1,38 +1,6 @@
|
||||
/* ***** 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 Open Web Apps.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Fabrice Desré <fabrice@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
@ -41,27 +9,31 @@ const Cr = Components.results;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(Services, "rs", function() {
|
||||
return Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci.nsIDOMRequestService);
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
|
||||
return Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
|
||||
});
|
||||
|
||||
function convertAppsArray(aApps, aWindow) {
|
||||
let apps = new Array();
|
||||
for (let i = 0; i < aApps.length; i++) {
|
||||
let app = aApps[i];
|
||||
apps.push(new WebappsApplication(aWindow, app.origin, app.manifest, app.manifestURL,
|
||||
app.receipts, app.installOrigin, app.installTime));
|
||||
}
|
||||
return apps;
|
||||
}
|
||||
|
||||
function WebappsRegistry() {
|
||||
this.messages = ["Webapps:Install:Return:OK", "Webapps:Install:Return:KO",
|
||||
"Webapps:Uninstall:Return:OK", "Webapps:Uninstall:Return:KO",
|
||||
"Webapps:Enumerate:Return:OK", "Webapps:Enumerate:Return:KO"];
|
||||
|
||||
this.mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
|
||||
|
||||
this.messages.forEach((function(msgName) {
|
||||
this.mm.addMessageListener(msgName, this);
|
||||
}).bind(this));
|
||||
|
||||
this._window = null;
|
||||
this._id = this._getRandomId();
|
||||
this._callbacks = [];
|
||||
}
|
||||
|
||||
WebappsRegistry.prototype = {
|
||||
_onerror: null,
|
||||
_oninstall: null,
|
||||
_onuninstall: null,
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
|
||||
/** from https://developer.mozilla.org/en/OpenWebApps/The_Manifest
|
||||
* only the name property is mandatory
|
||||
@ -70,7 +42,7 @@ WebappsRegistry.prototype = {
|
||||
// TODO : check for install_allowed_from
|
||||
if (aManifest.name == undefined)
|
||||
return false;
|
||||
|
||||
|
||||
if (aManifest.installs_allowed_from) {
|
||||
ok = false;
|
||||
aManifest.installs_allowed_from.forEach(function(aOrigin) {
|
||||
@ -81,97 +53,41 @@ WebappsRegistry.prototype = {
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
getCallbackId: function(aCallback) {
|
||||
let id = "id" + this._getRandomId();
|
||||
this._callbacks[id] = aCallback;
|
||||
return id;
|
||||
},
|
||||
|
||||
getCallback: function(aId) {
|
||||
return this._callbacks[aId];
|
||||
},
|
||||
|
||||
removeCallback: function(aId) {
|
||||
if (this._callbacks[aId])
|
||||
delete this._callbacks[aId];
|
||||
},
|
||||
|
||||
_getRandomId: function() {
|
||||
return Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
|
||||
},
|
||||
|
||||
_convertAppsArray: function(aApps) {
|
||||
let apps = new Array();
|
||||
for (let i = 0; i < aApps.length; i++) {
|
||||
let app = aApps[i];
|
||||
apps.push(new WebappsApplication(app.origin, app.manifest, app.receipt, app.installOrigin, app.installTime));
|
||||
}
|
||||
return apps;
|
||||
},
|
||||
|
||||
set oninstall(aCallback) {
|
||||
if (this.hasPrivileges)
|
||||
this._oninstall = aCallback;
|
||||
else
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
set onuninstall(aCallback) {
|
||||
if (this.hasPrivileges)
|
||||
this._onuninstall = aCallback;
|
||||
else
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
},
|
||||
|
||||
set onerror(aCallback) {
|
||||
this._onerror = aCallback;
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
let msg = aMessage.json;
|
||||
if (!(msg.oid == this._id || aMessage.name == "Webapps:Install:Return:OK" || aMessage.name == "Webapps:Uninstall:Return:OK"))
|
||||
if (msg.oid != this._id)
|
||||
return
|
||||
let req = this.getRequest(msg.requestID);
|
||||
if (!req)
|
||||
return;
|
||||
let app = msg.app;
|
||||
let cb;
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:Install:Return:OK":
|
||||
if (this._oninstall)
|
||||
this._oninstall.handleEvent(new WebappsApplication(app.origin, app.manifest, app.receipt,
|
||||
Services.rs.fireSuccess(req, new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
app.installOrigin, app.installTime));
|
||||
break;
|
||||
case "Webapps:Install:Return:KO":
|
||||
if (this._onerror)
|
||||
this._onerror.handleEvent(new RegistryError(Ci.mozIDOMApplicationRegistryError.DENIED));
|
||||
Services.rs.fireError(req, "DENIED");
|
||||
break;
|
||||
case "Webapps:Uninstall:Return:OK":
|
||||
if (this._onuninstall)
|
||||
this._onuninstall.handleEvent(new WebappsApplication(msg.origin, null, null, null, 0));
|
||||
break;
|
||||
case "Webapps:Uninstall:Return:KO":
|
||||
if (this._onerror)
|
||||
this._onerror.handleEvent(new RegistryError(Ci.mozIDOMApplicationRegistryError.PERMISSION_DENIED));
|
||||
break;
|
||||
case "Webapps:Enumerate:Return:OK":
|
||||
cb = this.getCallback(msg.callbackID);
|
||||
if (cb.success) {
|
||||
let apps = this._convertAppsArray(msg.apps);
|
||||
cb.success.handleEvent(apps, apps.length);
|
||||
case "Webapps:GetSelf:Return:OK":
|
||||
if (msg.apps.length) {
|
||||
app = msg.apps[0];
|
||||
Services.rs.fireSuccess(req, new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
app.installOrigin, app.installTime));
|
||||
} else {
|
||||
Services.rs.fireSuccess(req, null);
|
||||
}
|
||||
break;
|
||||
case "Webapps:Enumerate:Return:KO":
|
||||
cb = this.getCallback(msg.callbackID);
|
||||
if (cb.error)
|
||||
cb.error.handleEvent(new RegistryError(Ci.mozIDOMApplicationRegistryError.PERMISSION_DENIED));
|
||||
case "Webapps:GetInstalled:Return:OK":
|
||||
Services.rs.fireSuccess(req, convertAppsArray(msg.apps, this._window));
|
||||
break;
|
||||
case "Webapps:GetSelf:Return:KO":
|
||||
case "Webapps:GetInstalled:Return:KO":
|
||||
Services.rs.fireError(req, "ERROR");
|
||||
break;
|
||||
}
|
||||
this.removeCallback(msg.callbackID);
|
||||
},
|
||||
|
||||
_fireError: function(aCode) {
|
||||
if (!this._onerror)
|
||||
return;
|
||||
this._onerror.handleEvent(new RegistryError(aCode));
|
||||
this.removeRequest(msg.requestID);
|
||||
},
|
||||
|
||||
_getOrigin: function(aURL) {
|
||||
@ -181,7 +97,9 @@ WebappsRegistry.prototype = {
|
||||
|
||||
// mozIDOMApplicationRegistry implementation
|
||||
|
||||
install: function(aURL, aReceipt) {
|
||||
install: function(aURL, aParams) {
|
||||
let request = this.createRequest();
|
||||
let requestID = this.getRequestId(request);
|
||||
let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
|
||||
xhr.open("GET", aURL, true);
|
||||
|
||||
@ -191,90 +109,70 @@ WebappsRegistry.prototype = {
|
||||
let installOrigin = this._getOrigin(this._window.location.href);
|
||||
let manifest = JSON.parse(xhr.responseText, installOrigin);
|
||||
if (!this.checkManifest(manifest, installOrigin)) {
|
||||
this._fireError(Ci.mozIDOMApplicationRegistryError.INVALID_MANIFEST);
|
||||
Services.rs.fireError(request, "INVALID_MANIFEST");
|
||||
} else {
|
||||
this.mm.sendAsyncMessage("Webapps:Install", { app: { installOrigin: installOrigin,
|
||||
origin: this._getOrigin(aURL),
|
||||
manifest: manifest,
|
||||
receipt: aReceipt },
|
||||
from: this._window.location.href,
|
||||
oid: this._id });
|
||||
let receipts = (aParams && aParams.receipts && Array.isArray(aParams.receipts)) ? aParams.receipts : [];
|
||||
cpmm.sendAsyncMessage("Webapps:Install", { app: { installOrigin: installOrigin,
|
||||
origin: this._getOrigin(aURL),
|
||||
manifestURL: aURL,
|
||||
manifest: manifest,
|
||||
receipts: receipts },
|
||||
from: this._window.location.href,
|
||||
oid: this._id,
|
||||
requestID: requestID });
|
||||
}
|
||||
} catch(e) {
|
||||
this._fireError(Ci.mozIDOMApplicationRegistryError.MANIFEST_PARSE_ERROR);
|
||||
Services.rs.fireError(request, "MANIFEST_PARSE_ERROR");
|
||||
}
|
||||
}
|
||||
else {
|
||||
this._fireError(Ci.mozIDOMApplicationRegistryError.MANIFEST_URL_ERROR);
|
||||
Services.rs.fireError(request, "MANIFEST_URL_ERROR");
|
||||
}
|
||||
}).bind(this), false);
|
||||
|
||||
xhr.addEventListener("error", (function() {
|
||||
this._fireError(Ci.mozIDOMApplicationRegistryError.NETWORK_ERROR);
|
||||
Services.rs.fireError(request, "NETWORK_ERROR");
|
||||
}).bind(this), false);
|
||||
|
||||
xhr.send(null);
|
||||
return request;
|
||||
},
|
||||
|
||||
uninstall: function(aOrigin) {
|
||||
if (this.hasPrivileges)
|
||||
this.mm.sendAsyncMessage("Webapps:Uninstall", { from: this._window.location.href,
|
||||
origin: aOrigin,
|
||||
oid: this._id });
|
||||
else
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
getSelf: function() {
|
||||
let request = this.createRequest();
|
||||
cpmm.sendAsyncMessage("Webapps:GetSelf", { origin: this._getOrigin(this._window.location.href),
|
||||
oid: this._id,
|
||||
requestID: this.getRequestId(request) });
|
||||
return request;
|
||||
},
|
||||
|
||||
launch: function(aOrigin) {
|
||||
this.mm.sendAsyncMessage("Webapps:Launch", { origin: aOrigin,
|
||||
from: this._window.location.href});
|
||||
},
|
||||
|
||||
enumerate: function(aSuccess, aError) {
|
||||
this.mm.sendAsyncMessage("Webapps:Enumerate", { from: this._window.location.href,
|
||||
origin: this._getOrigin(this._window.location.href),
|
||||
getInstalled: function() {
|
||||
let request = this.createRequest();
|
||||
cpmm.sendAsyncMessage("Webapps:GetInstalled", { origin: this._getOrigin(this._window.location.href),
|
||||
oid: this._id,
|
||||
callbackID: this.getCallbackId({ success: aSuccess, error: aError }) });
|
||||
requestID: this.getRequestId(request) });
|
||||
return request;
|
||||
},
|
||||
|
||||
enumerateAll: function(aSuccess, aError) {
|
||||
if (this.hasPrivileges) {
|
||||
this.mm.sendAsyncMessage("Webapps:EnumerateAll", { from: this._window.location.href,
|
||||
origin: this._getOrigin(this._window.location.href),
|
||||
oid: this._id,
|
||||
callbackID: this.getCallbackId({ success: aSuccess, error: aError }) });
|
||||
} else {
|
||||
if (aError)
|
||||
aError.handleEvent(new RegistryError(Ci.mozIDOMApplicationRegistryError.PERMISSION_DENIED));
|
||||
}
|
||||
get mgmt() {
|
||||
if (!this._mgmt)
|
||||
this._mgmt = new WebappsApplicationMgmt(this._window);
|
||||
return this._mgmt;
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
if (wId == this.innerWindowID) {
|
||||
Services.obs.removeObserver(this, "inner-window-destroyed");
|
||||
this._oninstall = null;
|
||||
this._onuninstall = null;
|
||||
this._onerror = null;
|
||||
this._callbacks = [];
|
||||
this._window = null;
|
||||
}
|
||||
uninit: function() {
|
||||
this._mgmt = null;
|
||||
},
|
||||
|
||||
// nsIDOMGlobalPropertyInitializer implementation
|
||||
init: function(aWindow) {
|
||||
dump("DOMApplicationRegistry::init() " + aWindow + "\n");
|
||||
this._window = aWindow;
|
||||
this._window.appId = this._id;
|
||||
let from = Services.io.newURI(this._window.location.href, null, null);
|
||||
let perm = Services.perms.testExactPermission(from, "webapps-manage");
|
||||
|
||||
//only pages with perm set and chrome or about pages can uninstall, enumerate all set oninstall an onuninstall
|
||||
this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION || from.schemeIs("chrome") || from.schemeIs("about");
|
||||
this.initHelper(aWindow, ["Webapps:Install:Return:OK", "Webapps:Install:Return:KO",
|
||||
"Webapps:GetInstalled:Return:OK", "Webapps:GetInstalled:Return:KO",
|
||||
"Webapps:GetSelf:Return:OK", "Webapps:GetSelf:Return:KO"]);
|
||||
|
||||
Services.obs.addObserver(this, "inner-window-destroyed", false);
|
||||
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
this.innerWindowID = util.currentInnerWindowID;
|
||||
this._id = util.outerWindowID;
|
||||
},
|
||||
|
||||
classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
|
||||
@ -288,18 +186,26 @@ WebappsRegistry.prototype = {
|
||||
classDescription: "Webapps Registry"})
|
||||
}
|
||||
|
||||
function WebappsApplication(aOrigin, aManifest, aReceipt, aInstallOrigin, aInstallTime) {
|
||||
/**
|
||||
* mozIDOMApplication object
|
||||
*/
|
||||
function WebappsApplication(aWindow, aOrigin, aManifest, aManifestURL, aReceipts, aInstallOrigin, aInstallTime) {
|
||||
this._origin = aOrigin;
|
||||
this._manifest = aManifest;
|
||||
this._receipt = aReceipt;
|
||||
this._manifestURL = aManifestURL;
|
||||
this._receipts = aReceipts;
|
||||
this._installOrigin = aInstallOrigin;
|
||||
this._installTime = aInstallTime;
|
||||
|
||||
this.initHelper(aWindow, ["Webapps:Uninstall:Return:OK", "Webapps:Uninstall:Return:KO"]);
|
||||
}
|
||||
|
||||
WebappsApplication.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
_origin: null,
|
||||
_manifest: null,
|
||||
_receipt: null,
|
||||
_manifestURL: null,
|
||||
_receipts: [],
|
||||
_installOrigin: null,
|
||||
_installTime: 0,
|
||||
|
||||
@ -311,8 +217,12 @@ WebappsApplication.prototype = {
|
||||
return this._manifest;
|
||||
},
|
||||
|
||||
get receipt() {
|
||||
return this._receipt;
|
||||
get manifestURL() {
|
||||
return this._manifestURL;
|
||||
},
|
||||
|
||||
get receipts() {
|
||||
return this._receipts;
|
||||
},
|
||||
|
||||
get installOrigin() {
|
||||
@ -323,6 +233,39 @@ WebappsApplication.prototype = {
|
||||
return this._installTime;
|
||||
},
|
||||
|
||||
launch: function(aStartPoint) {
|
||||
let request = this.createRequest();
|
||||
cpmm.sendAsyncMessage("Webapps:Launch", { origin: this._origin,
|
||||
startPoint: aStartPoint,
|
||||
oid: this._id,
|
||||
requestID: this.getRequestId(request) });
|
||||
return request;
|
||||
},
|
||||
|
||||
uninstall: function() {
|
||||
let request = this.createRequest();
|
||||
cpmm.sendAsyncMessage("Webapps:Uninstall", { origin: this._origin,
|
||||
oid: this._id,
|
||||
requestID: this.getRequestId(request) });
|
||||
return request;
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
var msg = aMessage.json;
|
||||
let req = this.getRequest(msg.requestID);
|
||||
if (msg.oid != this._id || !req)
|
||||
return;
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:Uninstall:Return:OK":
|
||||
Services.rs.fireSuccess(req, msg.origin);
|
||||
break;
|
||||
case "Webapps:Uninstall:Return:KO":
|
||||
Services.rs.fireError(req, msg.origin);
|
||||
break;
|
||||
}
|
||||
this.removeRequest(msg.requestID);
|
||||
},
|
||||
|
||||
classID: Components.ID("{723ed303-7757-4fb0-b261-4f78b1f6bd22}"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplication]),
|
||||
@ -334,26 +277,131 @@ WebappsApplication.prototype = {
|
||||
classDescription: "Webapps Application"})
|
||||
}
|
||||
|
||||
function RegistryError(aCode) {
|
||||
this._code = aCode;
|
||||
/**
|
||||
* mozIDOMApplicationMgmt object
|
||||
*/
|
||||
function WebappsApplicationMgmt(aWindow) {
|
||||
let principal = aWindow.document.nodePrincipal;
|
||||
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
|
||||
|
||||
let perm = principal == secMan.getSystemPrincipal() ?
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION :
|
||||
Services.perms.testExactPermission(principal.URI, "webapps-manage");
|
||||
|
||||
//only pages with perm set can use some functions
|
||||
this.hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION;
|
||||
|
||||
this.initHelper(aWindow, ["Webapps:GetAll:Return:OK", "Webapps:GetAll:Return:KO",
|
||||
"Webapps:Install:Return:OK", "Webapps:Uninstall:Return:OK"]);
|
||||
|
||||
this._oninstall = null;
|
||||
this._onuninstall = null;
|
||||
}
|
||||
|
||||
RegistryError.prototype = {
|
||||
_code: null,
|
||||
|
||||
get code() {
|
||||
return this._code;
|
||||
WebappsApplicationMgmt.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
|
||||
uninit: function() {
|
||||
this._oninstall = null;
|
||||
this._onuninstall = null;
|
||||
},
|
||||
|
||||
classID: Components.ID("{b4937718-11a3-400b-a69f-ab442a418569}"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationRegistryError]),
|
||||
getAll: function() {
|
||||
let request = this.createRequest();
|
||||
cpmm.sendAsyncMessage("Webapps:GetAll", { oid: this._id,
|
||||
requestID: this.getRequestId(request),
|
||||
hasPrivileges: this.hasPrivileges });
|
||||
return request;
|
||||
},
|
||||
|
||||
classInfo: XPCOMUtils.generateCI({classID: Components.ID("{b4937718-11a3-400b-a69f-ab442a418569}"),
|
||||
contractID: "@mozilla.org/webapps/error;1",
|
||||
interfaces: [Ci.mozIDOMApplicationRegistryError],
|
||||
get oninstall() {
|
||||
return this._oninstall;
|
||||
},
|
||||
|
||||
get onuninstall() {
|
||||
this._onuninstall;
|
||||
},
|
||||
|
||||
set oninstall(aCallback) {
|
||||
if (this.hasPrivileges)
|
||||
this._oninstall = aCallback;
|
||||
else
|
||||
|
||||
throw new Components.exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
},
|
||||
|
||||
set onuninstall(aCallback) {
|
||||
if (this.hasPrivileges)
|
||||
this._onuninstall = aCallback;
|
||||
else
|
||||
throw new Components.exception("Denied", Cr.NS_ERROR_FAILURE);
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
var msg = aMessage.json;
|
||||
let req = this.getRequest(msg.requestID);
|
||||
// We want Webapps:Install:Return:OK and Webapps:Uninstall:Return:OK to be boradcasted
|
||||
// to all instances of mozApps.mgmt
|
||||
if (!((msg.oid == this._id && req)
|
||||
|| aMessage.name == "Webapps:Install:Return:OK" || aMessage.name == "Webapps:Uninstall:Return:OK"))
|
||||
return;
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:GetAll:Return:OK":
|
||||
Services.rs.fireSuccess(req, convertAppsArray(msg.apps, this._window));
|
||||
break;
|
||||
case "Webapps:GetAll:Return:KO":
|
||||
Services.rs.fireError(req, "DENIED");
|
||||
break;
|
||||
case "Webapps:Install:Return:OK":
|
||||
if (this._oninstall) {
|
||||
let app = msg.app;
|
||||
let event = new WebappsApplicationEvent(new WebappsApplication(this._window, app.origin, app.manifest, app.manifestURL, app.receipts,
|
||||
app.installOrigin, app.installTime));
|
||||
this._oninstall.handleEvent(event);
|
||||
}
|
||||
break;
|
||||
case "Webapps:Uninstall:Return:OK":
|
||||
if (this._onuninstall) {
|
||||
let event = new WebappsApplicationEvent(new WebappsApplication(this._window, msg.origin, null, null, null, null, 0));
|
||||
this._onuninstall.handleEvent(event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
this.removeRequest(msg.requestID);
|
||||
},
|
||||
|
||||
classID: Components.ID("{8c1bca96-266f-493a-8d57-ec7a95098c15}"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationMgmt]),
|
||||
|
||||
classInfo: XPCOMUtils.generateCI({classID: Components.ID("{8c1bca96-266f-493a-8d57-ec7a95098c15}"),
|
||||
contractID: "@mozilla.org/webapps/application-mgmt;1",
|
||||
interfaces: [Ci.mozIDOMApplicationMgmt],
|
||||
flags: Ci.nsIClassInfo.DOM_OBJECT,
|
||||
classDescription: "Webapps Registry Error"})
|
||||
classDescription: "Webapps Application Mgmt"})
|
||||
}
|
||||
|
||||
const NSGetFactory = XPCOMUtils.generateNSGetFactory([WebappsRegistry, WebappsApplication, RegistryError]);
|
||||
/**
|
||||
* mozIDOMApplicationEvent object
|
||||
*/
|
||||
function WebappsApplicationEvent(aApp) {
|
||||
this._app = aApp;
|
||||
}
|
||||
|
||||
WebappsApplicationEvent.prototype = {
|
||||
get application() {
|
||||
return this._app;
|
||||
},
|
||||
|
||||
classID: Components.ID("{5bc42b2a-9acc-49d5-a336-c353c8125e48}"),
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationEvent]),
|
||||
|
||||
classInfo: XPCOMUtils.generateCI({classID: Components.ID("{8c1bca96-266f-493a-8d57-ec7a95098c15}"),
|
||||
contractID: "@mozilla.org/webapps/application-event;1",
|
||||
interfaces: [Ci.mozIDOMApplicationEvent],
|
||||
flags: Ci.nsIClassInfo.DOM_OBJECT,
|
||||
classDescription: "Webapps Application Event"})
|
||||
}
|
||||
|
||||
const NSGetFactory = XPCOMUtils.generateNSGetFactory([WebappsRegistry, WebappsApplication]);
|
||||
|
@ -1,39 +1,6 @@
|
||||
/* ***** 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 Mobile Browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Fabrice Desré <fabrice@mozilla.com>
|
||||
* Mark Finkle <mfinkle@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
@ -50,17 +17,21 @@ XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
|
||||
return NetUtil;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
|
||||
return Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
|
||||
});
|
||||
|
||||
let DOMApplicationRegistry = {
|
||||
appsFile: null,
|
||||
webapps: { },
|
||||
|
||||
init: function() {
|
||||
this.mm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
|
||||
let messages = ["Webapps:Install", "Webapps:Uninstall",
|
||||
"Webapps:Enumerate", "Webapps:EnumerateAll", "Webapps:Launch"];
|
||||
"Webapps:GetSelf", "Webapps:GetInstalled",
|
||||
"Webapps:Launch", "Webapps:GetAll"];
|
||||
|
||||
messages.forEach((function(msgName) {
|
||||
this.mm.addMessageListener(msgName, this);
|
||||
ppmm.addMessageListener(msgName, this);
|
||||
}).bind(this));
|
||||
|
||||
let appsDir = FileUtils.getDir("ProfD", ["webapps"], true, true);
|
||||
@ -114,29 +85,29 @@ let DOMApplicationRegistry = {
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
let msg = aMessage.json;
|
||||
let from = Services.io.newURI(msg.from, null, null);
|
||||
let perm = Services.perms.testExactPermission(from, "webapps-manage");
|
||||
|
||||
//only pages with perm set and chrome or about pages can uninstall, enumerate all set oninstall an onuninstall
|
||||
let hasPrivileges = perm == Ci.nsIPermissionManager.ALLOW_ACTION || from.schemeIs("chrome") || from.schemeIs("about");
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "Webapps:Install":
|
||||
// always ask for UI to install
|
||||
Services.obs.notifyObservers(this, "webapps-ask-install", JSON.stringify(msg));
|
||||
break;
|
||||
case "Webapps:GetSelf":
|
||||
this.getSelf(msg);
|
||||
break;
|
||||
case "Webapps:Uninstall":
|
||||
if (hasPrivileges)
|
||||
this.uninstall(msg);
|
||||
this.uninstall(msg);
|
||||
break;
|
||||
case "Webapps:Launch":
|
||||
Services.obs.notifyObservers(this, "webapps-launch", JSON.stringify(msg));
|
||||
break;
|
||||
case "Webapps:Enumerate":
|
||||
this.enumerate(msg);
|
||||
case "Webapps:GetInstalled":
|
||||
this.getInstalled(msg);
|
||||
break;
|
||||
case "Webapps:EnumerateAll":
|
||||
this.enumerateAll(msg);
|
||||
case "Webapps:GetAll":
|
||||
if (msg.hasPrivileges)
|
||||
this.getAll(msg);
|
||||
else
|
||||
ppmm.sendAsyncMessage("Webapps:GetAll:Return:KO", msg);
|
||||
break;
|
||||
}
|
||||
},
|
||||
@ -162,14 +133,15 @@ let DOMApplicationRegistry = {
|
||||
let clone = {
|
||||
installOrigin: aApp.installOrigin,
|
||||
origin: aApp.origin,
|
||||
receipt: aApp.receipt,
|
||||
installTime: aApp.installTime
|
||||
receipts: aApp.receipts,
|
||||
installTime: aApp.installTime,
|
||||
manifestURL: aApp.manifestURL
|
||||
};
|
||||
return clone;
|
||||
},
|
||||
|
||||
denyInstall: function(aData) {
|
||||
this.mm.sendAsyncMessage("Webapps:Install:Return:KO", aData);
|
||||
ppmm.sendAsyncMessage("Webapps:Install:Return:KO", aData);
|
||||
},
|
||||
|
||||
confirmInstall: function(aData, aFromSync) {
|
||||
@ -202,7 +174,7 @@ let DOMApplicationRegistry = {
|
||||
|
||||
if (!aFromSync)
|
||||
this._saveApps((function() {
|
||||
this.mm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
|
||||
ppmm.sendAsyncMessage("Webapps:Install:Return:OK", aData);
|
||||
Services.obs.notifyObservers(this, "webapps-sync-install", id);
|
||||
}).bind(this));
|
||||
},
|
||||
@ -244,9 +216,11 @@ let DOMApplicationRegistry = {
|
||||
},
|
||||
|
||||
uninstall: function(aData) {
|
||||
let found = false;
|
||||
for (let id in this.webapps) {
|
||||
let app = this.webapps[id];
|
||||
if (app.origin == aData.origin) {
|
||||
found = true;
|
||||
delete this.webapps[id];
|
||||
let dir = FileUtils.getDir("ProfD", ["webapps", id], true, true);
|
||||
try {
|
||||
@ -254,62 +228,53 @@ let DOMApplicationRegistry = {
|
||||
} catch (e) {
|
||||
}
|
||||
this._saveApps((function() {
|
||||
this.mm.sendAsyncMessage("Webapps:Uninstall:Return:OK", aData);
|
||||
ppmm.sendAsyncMessage("Webapps:Uninstall:Return:OK", aData);
|
||||
Services.obs.notifyObservers(this, "webapps-sync-uninstall", id);
|
||||
}).bind(this));
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
ppmm.sendAsyncMessage("Webapps:Uninstall:Return:KO", aData);
|
||||
},
|
||||
|
||||
enumerate: function(aData) {
|
||||
getSelf: function(aData) {
|
||||
aData.apps = [];
|
||||
let tmp = [];
|
||||
let selfId;
|
||||
|
||||
let id = this._appId(aData.origin);
|
||||
// if it's an app, add itself to the result
|
||||
|
||||
if (id) {
|
||||
let app = this._cloneAppObject(this.webapps[id]);
|
||||
aData.apps.push(app);
|
||||
tmp.push({ id: id });
|
||||
selfId = id;
|
||||
}
|
||||
|
||||
// check if it's a store.
|
||||
let isStore = false;
|
||||
this._readManifests(tmp, (function(aResult) {
|
||||
for (let i = 0; i < aResult.length; i++)
|
||||
aData.apps[i].manifest = aResult[i].manifest;
|
||||
ppmm.sendAsyncMessage("Webapps:GetSelf:Return:OK", aData);
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
getInstalled: function(aData) {
|
||||
aData.apps = [];
|
||||
let tmp = [];
|
||||
let id = this._appId(aData.origin);
|
||||
|
||||
for (id in this.webapps) {
|
||||
let app = this.webapps[id];
|
||||
if (app.installOrigin == aData.origin) {
|
||||
isStore = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// add all the apps from this store
|
||||
if (isStore) {
|
||||
for (id in this.webapps) {
|
||||
if (id == selfId)
|
||||
continue;
|
||||
let app = this._cloneAppObject(this.webapps[id]);
|
||||
if (app.installOrigin == aData.origin) {
|
||||
aData.apps.push(app);
|
||||
tmp.push({ id: id });
|
||||
}
|
||||
if (this.webapps[id].installOrigin == aData.origin) {
|
||||
aData.apps.push(this._cloneAppObject(this.webapps[id]));
|
||||
tmp.push({ id: id });
|
||||
}
|
||||
}
|
||||
|
||||
this._readManifests(tmp, (function(aResult) {
|
||||
for (let i = 0; i < aResult.length; i++)
|
||||
aData.apps[i].manifest = aResult[i].manifest;
|
||||
this.mm.sendAsyncMessage("Webapps:Enumerate:Return:OK", aData);
|
||||
ppmm.sendAsyncMessage("Webapps:GetInstalled:Return:OK", aData);
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
denyEnumerate: function(aData) {
|
||||
this.mm.sendAsyncMessage("Webapps:Enumerate:Return:KO", aData);
|
||||
},
|
||||
|
||||
enumerateAll: function(aData) {
|
||||
getAll: function(aData) {
|
||||
aData.apps = [];
|
||||
let tmp = [];
|
||||
|
||||
@ -322,7 +287,7 @@ let DOMApplicationRegistry = {
|
||||
this._readManifests(tmp, (function(aResult) {
|
||||
for (let i = 0; i < aResult.length; i++)
|
||||
aData.apps[i].manifest = aResult[i].manifest;
|
||||
this.mm.sendAsyncMessage("Webapps:Enumerate:Return:OK", aData);
|
||||
ppmm.sendAsyncMessage("Webapps:GetAll:Return:OK", aData);
|
||||
}).bind(this));
|
||||
},
|
||||
|
||||
@ -368,7 +333,7 @@ let DOMApplicationRegistry = {
|
||||
dir.remove(true);
|
||||
} catch (e) {
|
||||
}
|
||||
this.mm.sendAsyncMessage("Webapps:Uninstall:Return:OK", { origin: origin });
|
||||
ppmm.sendAsyncMessage("Webapps:Uninstall:Return:OK", { origin: origin });
|
||||
} else {
|
||||
if (!!this.webapps[record.id]) {
|
||||
this.webapps[record.id] = record.value;
|
||||
@ -377,7 +342,7 @@ let DOMApplicationRegistry = {
|
||||
else {
|
||||
let data = { app: record.value };
|
||||
this.confirmInstall(data, true);
|
||||
this.mm.sendAsyncMessage("Webapps:Install:Return:OK", data);
|
||||
ppmm.sendAsyncMessage("Webapps:Install:Return:OK", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,9 +2,3 @@
|
||||
component {fff440b3-fae2-45c1-bf03-3b5a2e432270} Webapps.js
|
||||
contract @mozilla.org/webapps;1 {fff440b3-fae2-45c1-bf03-3b5a2e432270}
|
||||
category JavaScript-navigator-property mozApps @mozilla.org/webapps;1
|
||||
|
||||
component {723ed303-7757-4fb0-b261-4f78b1f6bd22} Webapps.js
|
||||
contract @mozilla.org/webapps/application;1 {723ed303-7757-4fb0-b261-4f78b1f6bd22}
|
||||
|
||||
component {b4937718-11a3-400b-a69f-ab442a418569} Webapps.js
|
||||
contract @mozilla.org/webapps/error;1 {b4937718-11a3-400b-a69f-ab442a418569}
|
||||
|
@ -507,6 +507,7 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
|
||||
#include "nsIDOMBatteryManager.h"
|
||||
#include "BatteryManager.h"
|
||||
#include "nsIDOMPowerManager.h"
|
||||
#include "nsIDOMWakeLock.h"
|
||||
#include "nsIDOMSmsManager.h"
|
||||
#include "nsIDOMSmsMessage.h"
|
||||
#include "nsIDOMSmsEvent.h"
|
||||
@ -548,6 +549,7 @@ static const char kDOMStringBundleURL[] =
|
||||
nsIXPCScriptable::WANT_ENUMERATE | \
|
||||
nsIXPCScriptable::DONT_ENUM_QUERY_INTERFACE | \
|
||||
nsIXPCScriptable::USE_STUB_EQUALITY_HOOK | \
|
||||
nsIXPCScriptable::IS_GLOBAL_OBJECT | \
|
||||
nsIXPCScriptable::WANT_OUTER_OBJECT)
|
||||
|
||||
#define NODE_SCRIPTABLE_FLAGS \
|
||||
@ -1435,6 +1437,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
NS_DEFINE_CLASSINFO_DATA(MozPowerManager, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(MozWakeLock, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(MozSmsManager, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
|
||||
@ -1549,7 +1554,7 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
NS_DEFINE_CLASSINFO_DATA(AnimationEvent, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(ContentFrameMessageManager, nsEventTargetSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS | nsIXPCScriptable::IS_GLOBAL_OBJECT)
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(FormData, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
@ -1617,8 +1622,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_B2G_BT
|
||||
NS_DEFINE_CLASSINFO_DATA(BluetoothAdapter, nsDOMGenericSH,
|
||||
DOM_DEFAULT_SCRIPTABLE_FLAGS)
|
||||
NS_DEFINE_CLASSINFO_DATA(BluetoothAdapter, nsEventTargetSH,
|
||||
EVENTTARGET_SCRIPTABLE_FLAGS)
|
||||
#endif
|
||||
|
||||
NS_DEFINE_CLASSINFO_DATA(DOMError, nsDOMGenericSH,
|
||||
@ -4030,6 +4035,10 @@ nsDOMClassInfo::Init()
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozPowerManager)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(MozWakeLock, nsIDOMMozWakeLock)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozWakeLock)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
||||
DOM_CLASSINFO_MAP_BEGIN(MozSmsManager, nsIDOMMozSmsManager)
|
||||
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSmsManager)
|
||||
DOM_CLASSINFO_MAP_END
|
||||
|
@ -429,6 +429,7 @@ DOMCI_CLASS(GeoPositionError)
|
||||
DOMCI_CLASS(MozBatteryManager)
|
||||
|
||||
DOMCI_CLASS(MozPowerManager)
|
||||
DOMCI_CLASS(MozWakeLock)
|
||||
|
||||
DOMCI_CLASS(MozSmsManager)
|
||||
DOMCI_CLASS(MozSmsMessage)
|
||||
|
@ -144,7 +144,11 @@ static PRLogModuleInfo* gJSDiagnostics;
|
||||
|
||||
#define NS_CC_SKIPPABLE_DELAY 400 // ms
|
||||
|
||||
#define NS_CC_FORCED (5 * 60 * PR_USEC_PER_SEC) // 5 min
|
||||
// Force a CC after this long if there's anything in the purple buffer.
|
||||
#define NS_CC_FORCED (2 * 60 * PR_USEC_PER_SEC) // 2 min
|
||||
|
||||
// Trigger a CC if the purple buffer exceeds this size when we check it.
|
||||
#define NS_CC_PURPLE_LIMIT 250
|
||||
|
||||
#define JAVASCRIPT nsIProgrammingLanguage::JAVASCRIPT
|
||||
|
||||
@ -2227,11 +2231,9 @@ nsJSContext::CreateNativeGlobalForInner(
|
||||
|
||||
nsRefPtr<nsIXPConnectJSObjectHolder> jsholder;
|
||||
nsresult rv = xpc->
|
||||
InitClassesWithNewWrappedGlobal(mContext,
|
||||
aNewInner, NS_GET_IID(nsISupports),
|
||||
InitClassesWithNewWrappedGlobal(mContext, aNewInner,
|
||||
aIsChrome ? systemPrincipal.get() : aPrincipal,
|
||||
nsnull, flags,
|
||||
getter_AddRefs(jsholder));
|
||||
flags, getter_AddRefs(jsholder));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
@ -2324,7 +2326,7 @@ nsJSContext::SetOuterObject(JSObject* aOuterObject)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ABORT_IF_FALSE(wrapper, "bad wrapper");
|
||||
|
||||
wrapper->RefreshPrototype();
|
||||
wrapper->FinishInitForWrappedGlobal();
|
||||
JS_SetPrototype(mContext, aOuterObject, JS_GetPrototype(inner));
|
||||
|
||||
return NS_OK;
|
||||
@ -3286,46 +3288,70 @@ ShrinkGCBuffersTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
nsJSContext::ShrinkGCBuffersNow();
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
static bool
|
||||
ShouldTriggerCC(PRUint32 aSuspected)
|
||||
{
|
||||
return sNeedsFullCC ||
|
||||
aSuspected > NS_CC_PURPLE_LIMIT ||
|
||||
sLastCCEndTime + NS_CC_FORCED < PR_Now();
|
||||
}
|
||||
|
||||
static void
|
||||
TimerFireForgetSkippable(PRUint32 aSuspected, bool aRemoveChildless)
|
||||
{
|
||||
PRTime startTime = PR_Now();
|
||||
nsCycleCollector_forgetSkippable(aRemoveChildless);
|
||||
sPreviousSuspectedCount = nsCycleCollector_suspectedCount();
|
||||
sCleanupSinceLastGC = true;
|
||||
PRTime delta = PR_Now() - startTime;
|
||||
if (sMinForgetSkippableTime > delta) {
|
||||
sMinForgetSkippableTime = delta;
|
||||
}
|
||||
if (sMaxForgetSkippableTime < delta) {
|
||||
sMaxForgetSkippableTime = delta;
|
||||
}
|
||||
sTotalForgetSkippableTime += delta;
|
||||
sRemovedPurples += (aSuspected - sPreviousSuspectedCount);
|
||||
++sForgetSkippableBeforeCC;
|
||||
}
|
||||
|
||||
static void
|
||||
CCTimerFired(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
if (sDidShutdown) {
|
||||
return;
|
||||
}
|
||||
if (sCCLockedOut) {
|
||||
if (sDidShutdown || sCCLockedOut) {
|
||||
return;
|
||||
}
|
||||
++sCCTimerFireCount;
|
||||
if (sCCTimerFireCount < (NS_CC_DELAY / NS_CC_SKIPPABLE_DELAY)) {
|
||||
PRUint32 suspected = nsCycleCollector_suspectedCount();
|
||||
if ((sPreviousSuspectedCount + 100) > suspected) {
|
||||
// Just few new suspected objects, return early.
|
||||
return;
|
||||
}
|
||||
|
||||
PRTime startTime = PR_Now();
|
||||
nsCycleCollector_forgetSkippable();
|
||||
sPreviousSuspectedCount = nsCycleCollector_suspectedCount();
|
||||
sCleanupSinceLastGC = true;
|
||||
PRTime delta = PR_Now() - startTime;
|
||||
if (sMinForgetSkippableTime > delta) {
|
||||
sMinForgetSkippableTime = delta;
|
||||
}
|
||||
if (sMaxForgetSkippableTime < delta) {
|
||||
sMaxForgetSkippableTime = delta;
|
||||
}
|
||||
sTotalForgetSkippableTime += delta;
|
||||
sRemovedPurples += (suspected - sPreviousSuspectedCount);
|
||||
++sForgetSkippableBeforeCC;
|
||||
} else {
|
||||
sPreviousSuspectedCount = 0;
|
||||
nsJSContext::KillCCTimer();
|
||||
if (sNeedsFullCC ||
|
||||
nsCycleCollector_suspectedCount() > 500 ||
|
||||
sLastCCEndTime + NS_CC_FORCED < PR_Now()) {
|
||||
|
||||
// During early timer fires, we only run forgetSkippable. During the first
|
||||
// late timer fire, we decide if we are going to have a second and final
|
||||
// late timer fire, where we may run the CC.
|
||||
const PRUint32 numEarlyTimerFires = NS_CC_DELAY / NS_CC_SKIPPABLE_DELAY - 2;
|
||||
bool isLateTimerFire = sCCTimerFireCount > numEarlyTimerFires;
|
||||
PRUint32 suspected = nsCycleCollector_suspectedCount();
|
||||
if (isLateTimerFire && ShouldTriggerCC(suspected)) {
|
||||
if (sCCTimerFireCount == numEarlyTimerFires + 1) {
|
||||
TimerFireForgetSkippable(suspected, true);
|
||||
if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
|
||||
// Our efforts to avoid a CC have failed, so we return to let the
|
||||
// timer fire once more to trigger a CC.
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// We are in the final timer fire and still meet the conditions for
|
||||
// triggering a CC.
|
||||
nsJSContext::CycleCollectNow();
|
||||
}
|
||||
} else if ((sPreviousSuspectedCount + 100) <= suspected) {
|
||||
// Only do a forget skippable if there are more than a few new objects.
|
||||
TimerFireForgetSkippable(suspected, false);
|
||||
}
|
||||
|
||||
if (isLateTimerFire) {
|
||||
// We have either just run the CC or decided we don't want to run the CC
|
||||
// next time, so kill the timer.
|
||||
sPreviousSuspectedCount = 0;
|
||||
nsJSContext::KillCCTimer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,47 +16,56 @@
|
||||
#include <bluedroid/bluetooth.h>
|
||||
#endif
|
||||
|
||||
#define POWERED_EVENT_NAME NS_LITERAL_STRING("powered")
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
|
||||
class ToggleBtResultTask : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ToggleBtResultTask(bool result, nsRefPtr<BluetoothAdapter>& adapterPtr)
|
||||
ToggleBtResultTask(nsRefPtr<BluetoothAdapter>& adapterPtr, bool result)
|
||||
: mResult(result)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread()); // This should be running on the worker thread
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
mAdapterPtr.swap(adapterPtr);
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
MOZ_ASSERT(NS_IsMainThread()); // This method is supposed to run on the main thread!
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mResult) {
|
||||
//TODO:Bug-731361
|
||||
NS_WARNING("BT firmware loading fails.\n");
|
||||
}
|
||||
|
||||
//mAdapterPtr must be null before returning to prevent the background
|
||||
//thread from racing to release it during the destruction of this runnable.
|
||||
mAdapterPtr->FirePowered();
|
||||
mAdapterPtr = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
bool mResult;
|
||||
nsRefPtr<BluetoothAdapter> mAdapterPtr;
|
||||
bool mResult;
|
||||
};
|
||||
|
||||
class ToggleBtTask : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ToggleBtTask(bool onOff, BluetoothAdapter* adapterPtr)
|
||||
ToggleBtTask(bool onOff, BluetoothAdapter* adapterPtr)
|
||||
: mOnOff(onOff),
|
||||
mAdapterPtr(adapterPtr)
|
||||
mAdapterPtr(adapterPtr)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread()); // The constructor should be running on the main thread.
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
}
|
||||
|
||||
NS_IMETHOD Run() {
|
||||
bool result;
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
|
||||
MOZ_ASSERT(!NS_IsMainThread()); // This should be running on the worker thread.
|
||||
bool result;
|
||||
|
||||
//Toggle BT here
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
@ -65,13 +74,16 @@ class ToggleBtTask : public nsRunnable
|
||||
} else {
|
||||
result = bt_disable();
|
||||
}
|
||||
#else
|
||||
#else
|
||||
result = true;
|
||||
#endif
|
||||
|
||||
// Create a result thread and pass it to Main Thread,
|
||||
nsCOMPtr<nsIRunnable> resultRunnable = new ToggleBtResultTask(result, mAdapterPtr);
|
||||
NS_DispatchToMainThread(resultRunnable);
|
||||
nsCOMPtr<nsIRunnable> resultRunnable = new ToggleBtResultTask(mAdapterPtr, result);
|
||||
|
||||
if (NS_FAILED(NS_DispatchToMainThread(resultRunnable))) {
|
||||
NS_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -81,25 +93,21 @@ class ToggleBtTask : public nsRunnable
|
||||
bool mOnOff;
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
||||
DOMCI_DATA(BluetoothAdapter, mozilla::dom::bluetooth::BluetoothAdapter)
|
||||
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
DOMCI_DATA(BluetoothAdapter, BluetoothAdapter)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothAdapter)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothAdapter,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(powered)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothAdapter,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(powered)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothAdapter,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(powered)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothAdapter,
|
||||
nsDOMEventTargetHelper)
|
||||
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(powered)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothAdapter)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothAdapter)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMBluetoothAdapter)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BluetoothAdapter)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||
@ -107,18 +115,16 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
||||
NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
|
||||
|
||||
BluetoothAdapter::BluetoothAdapter() : mPower(false)
|
||||
BluetoothAdapter::BluetoothAdapter()
|
||||
: mPower(false)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BluetoothAdapter::GetPower(bool* aPower)
|
||||
{
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
*aPower = bt_is_enabled();
|
||||
#else
|
||||
*aPower = mPower;
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -128,13 +134,13 @@ BluetoothAdapter::SetPower(bool aPower)
|
||||
if (mPower != aPower) {
|
||||
mPower = aPower;
|
||||
|
||||
ToggleBluetoothAsync();
|
||||
return ToggleBluetoothAsync();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
BluetoothAdapter::ToggleBluetoothAsync()
|
||||
{
|
||||
if (!mToggleBtThread) {
|
||||
@ -143,14 +149,17 @@ BluetoothAdapter::ToggleBluetoothAsync()
|
||||
|
||||
nsCOMPtr<nsIRunnable> r = new ToggleBtTask(mPower, this);
|
||||
|
||||
mToggleBtThread->Dispatch(r, 0);
|
||||
return mToggleBtThread->Dispatch(r, NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
nsresult
|
||||
BluetoothAdapter::FirePowered()
|
||||
{
|
||||
nsRefPtr<nsDOMEvent> event = new nsDOMEvent(nsnull, nsnull);
|
||||
nsresult rv = event->InitEvent(POWERED_EVENT_NAME, false, false);
|
||||
nsresult rv = event->InitEvent(NS_LITERAL_STRING("powered"), false, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = event->SetTrusted(true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool dummy;
|
||||
|
@ -11,10 +11,12 @@
|
||||
#include "nsDOMEventTargetHelper.h"
|
||||
#include "nsIDOMBluetoothAdapter.h"
|
||||
|
||||
class nsIEventTarget;
|
||||
|
||||
BEGIN_BLUETOOTH_NAMESPACE
|
||||
|
||||
class BluetoothAdapter : public nsIDOMBluetoothAdapter
|
||||
,public nsDOMEventTargetHelper
|
||||
, public nsDOMEventTargetHelper
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -36,7 +38,7 @@ protected:
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIEventTarget> mToggleBtThread;
|
||||
void ToggleBluetoothAsync();
|
||||
nsresult ToggleBluetoothAsync();
|
||||
};
|
||||
|
||||
END_BLUETOOTH_NAMESPACE
|
||||
|
@ -17,6 +17,15 @@ const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(Services, "rs", function() {
|
||||
return Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci.nsIDOMRequestService);
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "cpmm", function() {
|
||||
return Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
|
||||
});
|
||||
|
||||
const nsIClassInfo = Ci.nsIClassInfo;
|
||||
const CONTACTPROPERTIES_CID = Components.ID("{53ed7c20-ceda-11e0-9572-0800200c9a66}");
|
||||
@ -184,6 +193,7 @@ function ContactManager()
|
||||
}
|
||||
|
||||
ContactManager.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
|
||||
save: function save(aContact) {
|
||||
let request;
|
||||
@ -222,9 +232,9 @@ ContactManager.prototype = {
|
||||
|
||||
this._setMetaData(newContact, aContact);
|
||||
debug("send: " + JSON.stringify(newContact));
|
||||
request = this._rs.createRequest(this._window);
|
||||
this._mm.sendAsyncMessage("Contact:Save", {contact: newContact,
|
||||
requestID: this.getRequestId({ request: request })});
|
||||
request = this.createRequest();
|
||||
cpmm.sendAsyncMessage("Contact:Save", {contact: newContact,
|
||||
requestID: this.getRequestId(request)});
|
||||
return request;
|
||||
} else {
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
@ -234,9 +244,9 @@ ContactManager.prototype = {
|
||||
remove: function removeContact(aRecord) {
|
||||
let request;
|
||||
if (this.hasPrivileges) {
|
||||
request = this._rs.createRequest(this._window);
|
||||
this._mm.sendAsyncMessage("Contact:Remove", {id: aRecord.id,
|
||||
requestID: this.getRequestId({ request: request })});
|
||||
request = this.createRequest();
|
||||
cpmm.sendAsyncMessage("Contact:Remove", {id: aRecord.id,
|
||||
requestID: this.getRequestId(request)});
|
||||
return request;
|
||||
} else {
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
@ -260,26 +270,6 @@ ContactManager.prototype = {
|
||||
return contacts;
|
||||
},
|
||||
|
||||
getRequestId: function(aRequest) {
|
||||
let id = "id" + this._getRandomId();
|
||||
this._requests[id] = aRequest;
|
||||
return id;
|
||||
},
|
||||
|
||||
getRequest: function(aId) {
|
||||
if (this._requests[aId])
|
||||
return this._requests[aId].request;
|
||||
},
|
||||
|
||||
removeRequest: function(aId) {
|
||||
if (this._requests[aId])
|
||||
delete this._requests[aId];
|
||||
},
|
||||
|
||||
_getRandomId: function() {
|
||||
return Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
debug("Contactmanager::receiveMessage: " + aMessage.name);
|
||||
let msg = aMessage.json;
|
||||
@ -291,7 +281,7 @@ ContactManager.prototype = {
|
||||
if (req) {
|
||||
let result = this._convertContactsArray(contacts);
|
||||
debug("result: " + JSON.stringify(result));
|
||||
this._rs.fireSuccess(req, result);
|
||||
Services.rs.fireSuccess(req, result);
|
||||
} else {
|
||||
debug("no request stored!" + msg.requestID);
|
||||
}
|
||||
@ -301,7 +291,7 @@ ContactManager.prototype = {
|
||||
case "Contact:Remove:Return:OK":
|
||||
req = this.getRequest(msg.requestID);
|
||||
if (req)
|
||||
this._rs.fireSuccess(req, 0);
|
||||
Services.rs.fireSuccess(req, null);
|
||||
break;
|
||||
case "Contacts:Find:Return:KO":
|
||||
case "Contact:Save:Return:KO":
|
||||
@ -309,7 +299,7 @@ ContactManager.prototype = {
|
||||
case "Contacts:Clear:Return:KO":
|
||||
req = this.getRequest(msg.requestID);
|
||||
if (req)
|
||||
this._rs.fireError(req, msg.errorMsg);
|
||||
Services.rs.fireError(req, msg.errorMsg);
|
||||
break;
|
||||
default:
|
||||
debug("Wrong message: " + aMessage.name);
|
||||
@ -320,9 +310,9 @@ ContactManager.prototype = {
|
||||
find: function(aOptions) {
|
||||
let request;
|
||||
if (this.hasPrivileges) {
|
||||
request = this._rs.createRequest(this._window);
|
||||
this._mm.sendAsyncMessage("Contacts:Find", {findOptions: aOptions,
|
||||
requestID: this.getRequestId({ request: request })});
|
||||
request = this.createRequest();
|
||||
cpmm.sendAsyncMessage("Contacts:Find", {findOptions: aOptions,
|
||||
requestID: this.getRequestId(request)});
|
||||
return request;
|
||||
} else {
|
||||
debug("find not allowed");
|
||||
@ -333,8 +323,8 @@ ContactManager.prototype = {
|
||||
clear: function() {
|
||||
let request;
|
||||
if (this.hasPrivileges) {
|
||||
request = this._rs.createRequest(this._window);
|
||||
this._mm.sendAsyncMessage("Contacts:Clear", {requestID: this.getRequestId({ request: request })});
|
||||
request = this.createRequest();
|
||||
cpmm.sendAsyncMessage("Contacts:Clear", {requestID: this.getRequestId(request)});
|
||||
return request;
|
||||
} else {
|
||||
debug("clear not allowed");
|
||||
@ -347,22 +337,12 @@ ContactManager.prototype = {
|
||||
if (!Services.prefs.getBoolPref("dom.mozContacts.enabled"))
|
||||
return null;
|
||||
|
||||
this._window = aWindow;
|
||||
this._messages = ["Contacts:Find:Return:OK", "Contacts:Find:Return:KO",
|
||||
this.initHelper(aWindow, ["Contacts:Find:Return:OK", "Contacts:Find:Return:KO",
|
||||
"Contacts:Clear:Return:OK", "Contacts:Clear:Return:KO",
|
||||
"Contact:Save:Return:OK", "Contact:Save:Return:KO",
|
||||
"Contact:Remove:Return:OK", "Contact:Remove:Return:KO"];
|
||||
"Contact:Remove:Return:OK", "Contact:Remove:Return:KO"]);
|
||||
|
||||
this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
|
||||
this._messages.forEach((function(msgName) {
|
||||
this._mm.addMessageListener(msgName, this);
|
||||
}).bind(this));
|
||||
|
||||
this._rs = Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci.nsIDOMRequestService);
|
||||
this._requests = [];
|
||||
Services.obs.addObserver(this, "inner-window-destroyed", false);
|
||||
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
this._innerWindowID = util.currentInnerWindowID;
|
||||
|
||||
let principal = aWindow.document.nodePrincipal;
|
||||
let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
|
||||
@ -376,21 +356,6 @@ ContactManager.prototype = {
|
||||
debug("has privileges :" + this.hasPrivileges);
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
|
||||
if (wId == this.innerWindowID) {
|
||||
Services.obs.removeObserver(this, "inner-window-destroyed");
|
||||
this._messages.forEach((function(msgName) {
|
||||
this._mm.removeMessageListener(msgName, this);
|
||||
}).bind(this));
|
||||
this._mm = null;
|
||||
this._messages = null;
|
||||
this._requests = null;
|
||||
this._window = null;
|
||||
this._innerWindowID = null;
|
||||
}
|
||||
},
|
||||
|
||||
classID : CONTACTMANAGER_CID,
|
||||
QueryInterface : XPCOMUtils.generateQI([nsIDOMContactManager, Ci.nsIDOMGlobalPropertyInitializer]),
|
||||
|
||||
|
@ -20,16 +20,18 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/ContactDB.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "ppmm", function() {
|
||||
return Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
|
||||
});
|
||||
|
||||
let myGlobal = this;
|
||||
|
||||
let DOMContactManager = {
|
||||
|
||||
init: function() {
|
||||
debug("Init");
|
||||
this._mm = Cc["@mozilla.org/parentprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager);
|
||||
this._messages = ["Contacts:Find", "Contacts:Clear", "Contact:Save", "Contact:Remove"];
|
||||
this._messages.forEach((function(msgName) {
|
||||
this._mm.addMessageListener(msgName, this);
|
||||
ppmm.addMessageListener(msgName, this);
|
||||
}).bind(this));
|
||||
|
||||
var idbManager = Components.classes["@mozilla.org/dom/indexeddb/manager;1"].getService(Ci.nsIIndexedDatabaseManager);
|
||||
@ -52,10 +54,10 @@ let DOMContactManager = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
myGlobal = null;
|
||||
this._messages.forEach((function(msgName) {
|
||||
this._mm.removeMessageListener(msgName, this);
|
||||
ppmm.removeMessageListener(msgName, this);
|
||||
}).bind(this));
|
||||
Services.obs.removeObserver(this, "profile-before-change");
|
||||
this._mm = null;
|
||||
ppmm = null;
|
||||
this._messages = null;
|
||||
if (this._db)
|
||||
this._db.close();
|
||||
@ -72,23 +74,23 @@ let DOMContactManager = {
|
||||
for (let i in contacts)
|
||||
result.push(contacts[i]);
|
||||
debug("result:" + JSON.stringify(result));
|
||||
this._mm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result});
|
||||
ppmm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result});
|
||||
}.bind(this),
|
||||
function(aErrorMsg) { this._mm.sendAsyncMessage("Contacts:Find:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }) }.bind(this),
|
||||
function(aErrorMsg) { ppmm.sendAsyncMessage("Contacts:Find:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }) }.bind(this),
|
||||
msg.findOptions);
|
||||
break;
|
||||
case "Contact:Save":
|
||||
this._db.saveContact(msg.contact, function() {this._mm.sendAsyncMessage("Contact:Save:Return:OK", { requestID: msg.requestID }); }.bind(this),
|
||||
function(aErrorMsg) { this._mm.sendAsyncMessage("Contact:Save:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this));
|
||||
this._db.saveContact(msg.contact, function() { ppmm.sendAsyncMessage("Contact:Save:Return:OK", { requestID: msg.requestID }); }.bind(this),
|
||||
function(aErrorMsg) { ppmm.sendAsyncMessage("Contact:Save:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this));
|
||||
break;
|
||||
case "Contact:Remove":
|
||||
this._db.removeContact(msg.id,
|
||||
function() {this._mm.sendAsyncMessage("Contact:Remove:Return:OK", { requestID: msg.requestID }); }.bind(this),
|
||||
function(aErrorMsg) {this._mm.sendAsyncMessage("Contact:Remove:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this));
|
||||
function() { ppmm.sendAsyncMessage("Contact:Remove:Return:OK", { requestID: msg.requestID }); }.bind(this),
|
||||
function(aErrorMsg) { ppmm.sendAsyncMessage("Contact:Remove:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this));
|
||||
break;
|
||||
case "Contacts:Clear":
|
||||
this._db.clear(function() { this._mm.sendAsyncMessage("Contacts:Clear:Return:OK", { requestID: msg.requestID }); }.bind(this),
|
||||
function(aErrorMsg) { this._mm.sendAsyncMessage("Contacts:Clear:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this));
|
||||
this._db.clear(function() { ppmm.sendAsyncMessage("Contacts:Clear:Return:OK", { requestID: msg.requestID }); }.bind(this),
|
||||
function(aErrorMsg) { ppmm.sendAsyncMessage("Contacts:Clear:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }); }.bind(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ ConvertCloneReadInfosToArrayInternal(
|
||||
}
|
||||
|
||||
if (!aReadInfos.IsEmpty()) {
|
||||
if (!JS_SetArrayLength(aCx, array, jsuint(aReadInfos.Length()))) {
|
||||
if (!JS_SetArrayLength(aCx, array, uint32_t(aReadInfos.Length()))) {
|
||||
NS_WARNING("Failed to set array length!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
@ -410,7 +410,7 @@ IDBDatabase::CreateObjectStore(const nsAString& aName,
|
||||
|
||||
JSObject* obj = JSVAL_TO_OBJECT(val);
|
||||
|
||||
jsuint length;
|
||||
uint32_t length;
|
||||
if (!JS_GetArrayLength(aCx, obj, &length)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
@ -421,7 +421,7 @@ IDBDatabase::CreateObjectStore(const nsAString& aName,
|
||||
|
||||
keyPathArray.SetCapacity(length);
|
||||
|
||||
for (jsuint index = 0; index < length; index++) {
|
||||
for (uint32_t index = 0; index < length; index++) {
|
||||
jsval val;
|
||||
JSString* jsstr;
|
||||
nsDependentJSString str;
|
||||
@ -566,7 +566,7 @@ IDBDatabase::Transaction(const jsval& aStoreNames,
|
||||
|
||||
// See if this is a JS array.
|
||||
if (JS_IsArrayObject(aCx, obj)) {
|
||||
jsuint length;
|
||||
uint32_t length;
|
||||
if (!JS_GetArrayLength(aCx, obj, &length)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
@ -577,7 +577,7 @@ IDBDatabase::Transaction(const jsval& aStoreNames,
|
||||
|
||||
storesToOpen.SetCapacity(length);
|
||||
|
||||
for (jsuint index = 0; index < length; index++) {
|
||||
for (uint32_t index = 0; index < length; index++) {
|
||||
jsval val;
|
||||
JSString* jsstr;
|
||||
nsDependentJSString str;
|
||||
|
@ -904,7 +904,7 @@ GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
|
||||
}
|
||||
|
||||
if (!keys.IsEmpty()) {
|
||||
if (!JS_SetArrayLength(aCx, array, jsuint(keys.Length()))) {
|
||||
if (!JS_SetArrayLength(aCx, array, uint32_t(keys.Length()))) {
|
||||
NS_WARNING("Failed to set array length!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
@ -618,12 +618,12 @@ IDBObjectStore::AppendIndexUpdateInfo(PRInt64 aIndexID,
|
||||
if (aMultiEntry && !JSVAL_IS_PRIMITIVE(key) &&
|
||||
JS_IsArrayObject(aCx, JSVAL_TO_OBJECT(key))) {
|
||||
JSObject* array = JSVAL_TO_OBJECT(key);
|
||||
jsuint arrayLength;
|
||||
uint32_t arrayLength;
|
||||
if (!JS_GetArrayLength(aCx, array, &arrayLength)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
for (jsuint arrayIndex = 0; arrayIndex < arrayLength; arrayIndex++) {
|
||||
for (uint32_t arrayIndex = 0; arrayIndex < arrayLength; arrayIndex++) {
|
||||
jsval arrayItem;
|
||||
if (!JS_GetElement(aCx, array, arrayIndex, &arrayItem)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
@ -1700,7 +1700,7 @@ IDBObjectStore::CreateIndex(const nsAString& aName,
|
||||
|
||||
JSObject* obj = JSVAL_TO_OBJECT(aKeyPath);
|
||||
|
||||
jsuint length;
|
||||
uint32_t length;
|
||||
if (!JS_GetArrayLength(aCx, obj, &length)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
@ -1711,7 +1711,7 @@ IDBObjectStore::CreateIndex(const nsAString& aName,
|
||||
|
||||
keyPathArray.SetCapacity(length);
|
||||
|
||||
for (jsuint index = 0; index < length; index++) {
|
||||
for (uint32_t index = 0; index < length; index++) {
|
||||
jsval val;
|
||||
JSString* jsstr;
|
||||
nsDependentJSString str;
|
||||
|
@ -170,12 +170,12 @@ Key::EncodeJSVal(JSContext* aCx, const jsval aVal, PRUint8 aTypeOffset)
|
||||
aTypeOffset < (eMaxType * MaxArrayCollapse),
|
||||
"Wrong typeoffset");
|
||||
|
||||
jsuint length;
|
||||
uint32_t length;
|
||||
if (!JS_GetArrayLength(aCx, obj, &length)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
for (jsuint index = 0; index < length; index++) {
|
||||
for (uint32_t index = 0; index < length; index++) {
|
||||
jsval val;
|
||||
if (!JS_GetElement(aCx, obj, index, &val)) {
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
@ -220,7 +220,7 @@ Key::DecodeJSVal(const unsigned char*& aPos, const unsigned char* aEnd,
|
||||
aTypeOffset = 0;
|
||||
}
|
||||
|
||||
jsuint index = 0;
|
||||
uint32_t index = 0;
|
||||
while (aPos < aEnd && *aPos - aTypeOffset != eTerminator) {
|
||||
jsval val;
|
||||
nsresult rv = DecodeJSVal(aPos, aEnd, aCx, aTypeOffset, &val);
|
||||
|
@ -36,104 +36,79 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "domstubs.idl"
|
||||
#include "nsIArray.idl"
|
||||
#include "nsIDOMEvent.idl"
|
||||
#include "nsIDOMEventTarget.idl"
|
||||
|
||||
[scriptable, uuid(e0c271cb-266b-48c9-a7e4-96590b445c26)]
|
||||
interface mozIDOMApplicationRegistryError : nsISupports
|
||||
{
|
||||
const unsigned short DENIED = 1;
|
||||
const unsigned short PERMISSION_DENIED = 2;
|
||||
const unsigned short MANIFEST_URL_ERROR = 3;
|
||||
const unsigned short NETWORK_ERROR = 4;
|
||||
const unsigned short MANIFEST_PARSE_ERROR = 5;
|
||||
const unsigned short INVALID_MANIFEST = 6;
|
||||
interface nsIDOMDOMRequest;
|
||||
|
||||
readonly attribute short code;
|
||||
};
|
||||
|
||||
[scriptable, uuid(a6856a3d-dece-43ce-89b9-72dba07f4246)]
|
||||
interface mozIDOMApplication : nsISupports
|
||||
[scriptable, uuid(b70b84f1-7ac9-4a92-bc32-8b6a7eb7879e)]
|
||||
interface mozIDOMApplication : nsISupports
|
||||
{
|
||||
readonly attribute jsval manifest;
|
||||
readonly attribute DOMString receipt;
|
||||
readonly attribute DOMString manifestURL;
|
||||
readonly attribute nsIArray receipts; /* an array of strings */
|
||||
readonly attribute DOMString origin;
|
||||
readonly attribute DOMString installOrigin;
|
||||
readonly attribute unsigned long installTime;
|
||||
|
||||
/* startPoint will be used when several launch_path exists for an app */
|
||||
nsIDOMDOMRequest launch([optional] in DOMString startPoint);
|
||||
nsIDOMDOMRequest uninstall();
|
||||
};
|
||||
|
||||
[scriptable, function, uuid(be170df5-9154-463b-9197-10a6195eba52)]
|
||||
interface mozIDOMApplicationRegistryEnumerateCallback : nsISupports
|
||||
[scriptable, uuid(870bfbdc-3e13-4042-99dd-18e25720782d)]
|
||||
interface mozIDOMApplicationEvent : nsIDOMEvent
|
||||
{
|
||||
void handleEvent([array, size_is(count)] in mozIDOMApplication apps,
|
||||
in unsigned long count);
|
||||
readonly attribute mozIDOMApplication application;
|
||||
};
|
||||
|
||||
[scriptable, function, uuid(ae0ed33d-35cf-443a-837b-a6cebf16bd49)]
|
||||
interface mozIDOMApplicationRegistryErrorCallback : nsISupports
|
||||
[scriptable, uuid(a82771f6-ba46-4073-9e6e-f1ad3f42b1f6)]
|
||||
interface mozIDOMApplicationMgmt : nsIDOMEventTarget
|
||||
{
|
||||
void handleEvent(in mozIDOMApplicationRegistryError error);
|
||||
/**
|
||||
* the request will return the all the applications installed. Only accessible
|
||||
* to privileged callers.
|
||||
*/
|
||||
nsIDOMDOMRequest getAll();
|
||||
|
||||
/**
|
||||
* event listener to get notified of application installs. Only settable by
|
||||
* privileged callers.
|
||||
* the event will be a mozIDOMApplicationEvent
|
||||
*/
|
||||
attribute nsIDOMEventListener oninstall;
|
||||
|
||||
/**
|
||||
* event listener to get notified of application uninstalls. Only settable by
|
||||
* privileged callers.
|
||||
* the event will be a mozIDOMApplicationEvent
|
||||
*/
|
||||
attribute nsIDOMEventListener onuninstall;
|
||||
};
|
||||
|
||||
[scriptable, uuid(ac63c0ba-1f33-4e3e-b9aa-6a3243a9adba)]
|
||||
[scriptable, uuid(f6929871-288b-4613-9a37-9a150760ac50)]
|
||||
interface mozIDOMApplicationRegistry : nsISupports
|
||||
{
|
||||
/**
|
||||
* Install a web app. onerror can be used to report errors,
|
||||
* and oninstall if the caller is privileged.
|
||||
*
|
||||
* @param manifestUrl : the URL of the webapps manifest
|
||||
* @param receipt : An opaque string used to track payment status
|
||||
* @param manifestUrl : the URL of the webapps manifest.
|
||||
* @param parameters : A structure with optional information.
|
||||
* { receipts: ... } will be used to specify the payment receipts for this installation.
|
||||
*/
|
||||
void install(in DOMString manifestUrl,
|
||||
[optional] in DOMString receipt);
|
||||
nsIDOMDOMRequest install(in DOMString manifestUrl, [optional] in jsval parameters);
|
||||
|
||||
/**
|
||||
* This call is only accessible to privileged callers.
|
||||
*
|
||||
* @param origin : the origin of the application to uninstall.
|
||||
* the request will return the application currently installed, or null.
|
||||
*/
|
||||
void uninstall(in DOMString origin);
|
||||
nsIDOMDOMRequest getSelf();
|
||||
|
||||
/**
|
||||
* Enumerate apps : either return itself if caller is an app, or
|
||||
* apps installed from a store if caller is a store
|
||||
*
|
||||
* @param success: the callback that will get the array of applications
|
||||
* @param error: optional error callback
|
||||
* the request will return the applications installed from this origin, or null.
|
||||
*/
|
||||
void enumerate(in mozIDOMApplicationRegistryEnumerateCallback success,
|
||||
[optional] in mozIDOMApplicationRegistryErrorCallback error);
|
||||
nsIDOMDOMRequest getInstalled();
|
||||
|
||||
/**
|
||||
* Enumerate all apps installed from all stores.
|
||||
* Only usable by privileged callers.
|
||||
*
|
||||
* @param success: the callback that will get the array of applications
|
||||
* @param error: optional error callback
|
||||
*/
|
||||
void enumerateAll(in mozIDOMApplicationRegistryEnumerateCallback success,
|
||||
[optional] in mozIDOMApplicationRegistryErrorCallback error);
|
||||
|
||||
/**
|
||||
* launch a webapp. Behavior is application dependant.
|
||||
*
|
||||
* @param origin : the origin of the application to launch
|
||||
*/
|
||||
void launch(in DOMString origin);
|
||||
|
||||
/**
|
||||
* event listener to get notified of application installs. Only settable by
|
||||
* privileged callers
|
||||
*/
|
||||
attribute nsIDOMEventListener oninstall;
|
||||
|
||||
/**
|
||||
* event listener to get notified of application uninstalls. Only settable by
|
||||
* privileged callers
|
||||
*/
|
||||
attribute nsIDOMEventListener onuninstall;
|
||||
|
||||
/**
|
||||
* event listener to get notified of errors.
|
||||
*/
|
||||
attribute nsIDOMEventListener onerror;
|
||||
readonly attribute mozIDOMApplicationMgmt mgmt;
|
||||
};
|
||||
|
@ -131,3 +131,4 @@ interface nsIDOMFontFaceList;
|
||||
|
||||
// Power
|
||||
interface nsIDOMMozPowerManager;
|
||||
interface nsIDOMMozWakeLock;
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(b1f4b1fa-49c2-4375-9ce8-bf97ecf6b428)]
|
||||
[scriptable, uuid(e610c037-db58-4cd7-8ed3-0d7f1422b4d3)]
|
||||
interface nsIDOMNavigator : nsISupports
|
||||
{
|
||||
readonly attribute DOMString appCodeName;
|
||||
@ -110,4 +110,34 @@ interface nsIDOMNavigator : nsISupports
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
void mozVibrate(in jsval aPattern);
|
||||
|
||||
/**
|
||||
* Request a wake lock for a resource.
|
||||
*
|
||||
* A page holds a wake lock to request that a resource not be turned
|
||||
* off (or otherwise made unavailable).
|
||||
*
|
||||
* The topic is the name of a resource that might be made unavailable for
|
||||
* various reasons. For example, on a mobile device the power manager might
|
||||
* decide to turn off the screen after a period of idle time to save power.
|
||||
*
|
||||
* The resource manager checks the lock state of a topic before turning off
|
||||
* the associated resource. For example, a page could hold a lock on the
|
||||
* "screen" topic to prevent the screensaver from appearing or the screen
|
||||
* from turning off.
|
||||
*
|
||||
* The resource manager defines what each topic means and sets policy. For
|
||||
* example, the resource manager might decide to ignore 'screen' wake locks
|
||||
* held by pages which are not visible.
|
||||
*
|
||||
* One topic can be locked multiple times; it is considered released only when
|
||||
* all locks on the topic have been released.
|
||||
*
|
||||
* The returned nsIDOMMozWakeLock object is a token of the lock. You can
|
||||
* unlock the lock via the object's |unlock| method. The lock is released
|
||||
* automatically when its associated window is unloaded.
|
||||
*
|
||||
* @param aTopic resource name
|
||||
*/
|
||||
nsIDOMMozWakeLock requestWakeLock(in DOMString aTopic);
|
||||
};
|
||||
|
@ -52,15 +52,19 @@ EXPORTS_NAMESPACES = mozilla/dom/power
|
||||
|
||||
EXPORTS_mozilla/dom/power = \
|
||||
PowerManagerService.h \
|
||||
Types.h \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
PowerManager.cpp \
|
||||
PowerManagerService.cpp \
|
||||
WakeLock.cpp \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsIDOMPowerManager.idl \
|
||||
nsIDOMWakeLock.idl \
|
||||
nsIDOMWakeLockListener.idl \
|
||||
nsIPowerManagerService.idl \
|
||||
$(NULL)
|
||||
|
||||
|
@ -36,9 +36,13 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "PowerManager.h"
|
||||
#include "WakeLock.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDOMClassInfoID.h"
|
||||
#include "nsIDOMWakeLockListener.h"
|
||||
#include "nsIPowerManagerService.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
DOMCI_DATA(MozPowerManager, mozilla::dom::power::PowerManager)
|
||||
@ -50,20 +54,66 @@ namespace power {
|
||||
NS_INTERFACE_MAP_BEGIN(PowerManager)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMozPowerManager)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMMozPowerManager)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMozWakeLockListener)
|
||||
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozPowerManager)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_ADDREF(PowerManager)
|
||||
NS_IMPL_RELEASE(PowerManager)
|
||||
|
||||
NS_IMETHODIMP
|
||||
PowerManager::Reboot()
|
||||
nsresult
|
||||
PowerManager::Init(nsIDOMWindow *aWindow)
|
||||
{
|
||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR);
|
||||
mWindow = do_GetWeakReference(aWindow);
|
||||
|
||||
nsCOMPtr<nsIPowerManagerService> pmService =
|
||||
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(pmService, NS_OK);
|
||||
NS_ENSURE_STATE(pmService);
|
||||
|
||||
// Add ourself to the global notification list.
|
||||
pmService->AddWakeLockListener(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PowerManager::Shutdown()
|
||||
{
|
||||
nsCOMPtr<nsIPowerManagerService> pmService =
|
||||
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
|
||||
NS_ENSURE_STATE(pmService);
|
||||
|
||||
// Remove ourself from the global notification list.
|
||||
pmService->RemoveWakeLockListener(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
PowerManager::CheckPermission()
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = do_QueryReferent(mWindow);
|
||||
NS_ENSURE_STATE(win);
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(win->GetExtantDocument());
|
||||
NS_ENSURE_STATE(doc);
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
doc->NodePrincipal()->GetURI(getter_AddRefs(uri));
|
||||
|
||||
if (!nsContentUtils::URIIsChromeOrInPref(uri, "dom.power.whitelist")) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PowerManager::Reboot()
|
||||
{
|
||||
nsresult rv = CheckPermission();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPowerManagerService> pmService =
|
||||
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
|
||||
NS_ENSURE_STATE(pmService);
|
||||
|
||||
pmService->Reboot();
|
||||
|
||||
@ -73,17 +123,74 @@ PowerManager::Reboot()
|
||||
NS_IMETHODIMP
|
||||
PowerManager::PowerOff()
|
||||
{
|
||||
NS_ENSURE_TRUE(nsContentUtils::IsCallerChrome(), NS_ERROR_DOM_SECURITY_ERR);
|
||||
nsresult rv = CheckPermission();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPowerManagerService> pmService =
|
||||
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(pmService, NS_OK);
|
||||
NS_ENSURE_STATE(pmService);
|
||||
|
||||
pmService->PowerOff();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PowerManager::AddWakeLockListener(nsIDOMMozWakeLockListener *aListener)
|
||||
{
|
||||
nsresult rv = CheckPermission();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// already added? bail out.
|
||||
if (mListeners.Contains(aListener))
|
||||
return NS_OK;
|
||||
|
||||
mListeners.AppendElement(aListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PowerManager::RemoveWakeLockListener(nsIDOMMozWakeLockListener *aListener)
|
||||
{
|
||||
nsresult rv = CheckPermission();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mListeners.RemoveElement(aListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PowerManager::GetWakeLockState(const nsAString &aTopic, nsAString &aState)
|
||||
{
|
||||
nsresult rv = CheckPermission();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPowerManagerService> pmService =
|
||||
do_GetService(POWERMANAGERSERVICE_CONTRACTID);
|
||||
NS_ENSURE_STATE(pmService);
|
||||
|
||||
return pmService->GetWakeLockState(aTopic, aState);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PowerManager::Callback(const nsAString &aTopic, const nsAString &aState)
|
||||
{
|
||||
/**
|
||||
* We maintain a local listener list instead of using the global
|
||||
* list so that when the window is destroyed we don't have to
|
||||
* cleanup the mess.
|
||||
* Copy the listeners list before we walk through the callbacks
|
||||
* because the callbacks may install new listeners. We expect no
|
||||
* more than one listener per window, so it shouldn't be too long.
|
||||
*/
|
||||
nsAutoTArray<nsCOMPtr<nsIDOMMozWakeLockListener>, 2> listeners(mListeners);
|
||||
for (PRUint32 i = 0; i < listeners.Length(); ++i) {
|
||||
listeners[i]->Callback(aTopic, aState);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // power
|
||||
} // dom
|
||||
} // mozilla
|
||||
|
@ -37,7 +37,12 @@
|
||||
#ifndef mozilla_dom_power_PowerManager_h
|
||||
#define mozilla_dom_power_PowerManager_h
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIDOMPowerManager.h"
|
||||
#include "nsIDOMWakeLockListener.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -45,13 +50,24 @@ namespace power {
|
||||
|
||||
class PowerManager
|
||||
: public nsIDOMMozPowerManager
|
||||
, public nsIDOMMozWakeLockListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIDOMMOZPOWERMANAGER
|
||||
NS_DECL_NSIDOMMOZWAKELOCKLISTENER
|
||||
|
||||
PowerManager() {};
|
||||
virtual ~PowerManager() {};
|
||||
|
||||
nsresult Init(nsIDOMWindow *aWindow);
|
||||
nsresult Shutdown();
|
||||
|
||||
private:
|
||||
nsresult CheckPermission();
|
||||
|
||||
nsWeakPtr mWindow;
|
||||
nsTArray<nsCOMPtr<nsIDOMMozWakeLockListener> > mListeners;
|
||||
};
|
||||
|
||||
} // namespace power
|
||||
|
@ -36,7 +36,12 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "mozilla/Hal.h"
|
||||
#include "mozilla/HalWakeLock.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "nsIDOMWakeLockListener.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "PowerManagerService.h"
|
||||
#include "WakeLock.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -44,14 +49,67 @@ namespace power {
|
||||
|
||||
NS_IMPL_ISUPPORTS1(PowerManagerService, nsIPowerManagerService)
|
||||
|
||||
/* static */ nsRefPtr<PowerManagerService> PowerManagerService::sSingleton;
|
||||
|
||||
/* static */ already_AddRefed<nsIPowerManagerService>
|
||||
PowerManagerService::GetInstance()
|
||||
{
|
||||
nsCOMPtr<nsIPowerManagerService> pmService;
|
||||
if (!sSingleton) {
|
||||
sSingleton = new PowerManagerService();
|
||||
sSingleton->Init();
|
||||
ClearOnShutdown(&sSingleton);
|
||||
}
|
||||
|
||||
pmService = new PowerManagerService();
|
||||
nsCOMPtr<nsIPowerManagerService> service(do_QueryInterface(sSingleton));
|
||||
return service.forget();
|
||||
}
|
||||
|
||||
return pmService.forget();
|
||||
void
|
||||
PowerManagerService::Init()
|
||||
{
|
||||
hal::RegisterWakeLockObserver(this);
|
||||
}
|
||||
|
||||
PowerManagerService::~PowerManagerService()
|
||||
{
|
||||
hal::UnregisterWakeLockObserver(this);
|
||||
}
|
||||
|
||||
void
|
||||
PowerManagerService::ComputeWakeLockState(const hal::WakeLockInformation& aWakeLockInfo,
|
||||
nsAString &aState)
|
||||
{
|
||||
hal::WakeLockState state = hal::ComputeWakeLockState(aWakeLockInfo.numLocks(),
|
||||
aWakeLockInfo.numHidden());
|
||||
switch (state) {
|
||||
case hal::WAKE_LOCK_STATE_UNLOCKED:
|
||||
aState.AssignLiteral("unlocked");
|
||||
break;
|
||||
case hal::WAKE_LOCK_STATE_HIDDEN:
|
||||
aState.AssignLiteral("locked-background");
|
||||
break;
|
||||
case hal::WAKE_LOCK_STATE_VISIBLE:
|
||||
aState.AssignLiteral("locked-foreground");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PowerManagerService::Notify(const hal::WakeLockInformation& aWakeLockInfo)
|
||||
{
|
||||
nsAutoString state;
|
||||
ComputeWakeLockState(aWakeLockInfo, state);
|
||||
|
||||
/**
|
||||
* Copy the listeners list before we walk through the callbacks
|
||||
* because the callbacks may install new listeners. We expect no
|
||||
* more than one listener per window, so it shouldn't be too long.
|
||||
*/
|
||||
nsAutoTArray<nsCOMPtr<nsIDOMMozWakeLockListener>, 2> listeners(mWakeLockListeners);
|
||||
|
||||
for (PRUint32 i = 0; i < listeners.Length(); ++i) {
|
||||
listeners[i]->Callback(aWakeLockInfo.topic(), state);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -68,6 +126,50 @@ PowerManagerService::PowerOff()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PowerManagerService::AddWakeLockListener(nsIDOMMozWakeLockListener *aListener)
|
||||
{
|
||||
if (mWakeLockListeners.Contains(aListener))
|
||||
return NS_OK;
|
||||
|
||||
mWakeLockListeners.AppendElement(aListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PowerManagerService::RemoveWakeLockListener(nsIDOMMozWakeLockListener *aListener)
|
||||
{
|
||||
mWakeLockListeners.RemoveElement(aListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PowerManagerService::GetWakeLockState(const nsAString &aTopic, nsAString &aState)
|
||||
{
|
||||
hal::WakeLockInformation info;
|
||||
hal::GetWakeLockInfo(aTopic, &info);
|
||||
|
||||
ComputeWakeLockState(info, aState);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PowerManagerService::NewWakeLock(const nsAString &aTopic,
|
||||
nsIDOMWindow *aWindow,
|
||||
nsIDOMMozWakeLock **aWakeLock)
|
||||
{
|
||||
nsRefPtr<WakeLock> wakelock = new WakeLock();
|
||||
nsresult rv = wakelock->Init(aTopic, aWindow);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIDOMMozWakeLock> wl =
|
||||
do_QueryInterface(NS_ISUPPORTS_CAST(nsIDOMMozWakeLock*, wakelock));
|
||||
wl.forget(aWakeLock);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // power
|
||||
} // dom
|
||||
} // mozilla
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user