mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 15:28:39 +09:00
Merge remote-tracking branch 'origin/master' into custom
This commit is contained in:
commit
20c6498ca1
395 changed files with 818 additions and 23422 deletions
|
|
@ -96,10 +96,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
'/accessible/windows/ia2',
|
||||
'/accessible/windows/msaa',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
|
|
@ -52,10 +52,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
'/accessible/windows/ia2',
|
||||
'/accessible/windows/msaa',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
|
|
@ -32,10 +32,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
'/accessible/windows/ia2',
|
||||
'/accessible/windows/msaa',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
|
|
@ -19,10 +19,6 @@ else:
|
|||
LOCAL_INCLUDES += [
|
||||
'/accessible/atk',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
|
|
@ -28,10 +28,6 @@ if CONFIG['ACCESSIBILITY']:
|
|||
LOCAL_INCLUDES += [
|
||||
'/accessible/atk',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef MOZILLA_A11Y_ARIAGRIDACCESSIBLEWRAP_H
|
||||
#define MOZILLA_A11Y_ARIAGRIDACCESSIBLEWRAP_H
|
||||
|
||||
#include "ARIAGridAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class ARIAGridAccessible ARIAGridAccessibleWrap;
|
||||
typedef class ARIAGridCellAccessible ARIAGridCellAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* For documentation of the accessibility architecture,
|
||||
* see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
|
||||
*/
|
||||
|
||||
#ifndef _AccessibleWrap_H_
|
||||
#define _AccessibleWrap_H_
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
#include "Accessible.h"
|
||||
#include "States.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
|
||||
#if defined(__OBJC__)
|
||||
@class mozAccessible;
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class AccessibleWrap : public Accessible
|
||||
{
|
||||
public: // construction, destruction
|
||||
AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc);
|
||||
virtual ~AccessibleWrap();
|
||||
|
||||
/**
|
||||
* Get the native Obj-C object (mozAccessible).
|
||||
*/
|
||||
virtual void GetNativeInterface(void** aOutAccessible) override;
|
||||
|
||||
/**
|
||||
* The objective-c |Class| type that this accessible's native object
|
||||
* should be instantied with. used on runtime to determine the
|
||||
* right type for this accessible's associated native object.
|
||||
*/
|
||||
virtual Class GetNativeType ();
|
||||
|
||||
virtual void Shutdown () override;
|
||||
|
||||
virtual bool InsertChildAt(uint32_t aIdx, Accessible* aChild) override;
|
||||
virtual bool RemoveChild(Accessible* aAccessible) override;
|
||||
|
||||
virtual nsresult HandleAccEvent(AccEvent* aEvent) override;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Return true if the parent doesn't have children to expose to AT.
|
||||
*/
|
||||
bool AncestorIsFlat();
|
||||
|
||||
/**
|
||||
* Get the native object. Create it if needed.
|
||||
*/
|
||||
#if defined(__OBJC__)
|
||||
mozAccessible* GetNativeObject();
|
||||
#else
|
||||
id GetNativeObject();
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Our native object. Private because its creation is done lazily.
|
||||
* Don't access it directly. Ever. Unless you are GetNativeObject() or
|
||||
* Shutdown()
|
||||
*/
|
||||
#if defined(__OBJC__)
|
||||
// if we are in Objective-C, we use the actual Obj-C class.
|
||||
mozAccessible* mNativeObject;
|
||||
#else
|
||||
id mNativeObject;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* We have created our native. This does not mean there is one.
|
||||
* This can never go back to false.
|
||||
* We need it because checking whether we need a native object cost time.
|
||||
*/
|
||||
bool mNativeInited;
|
||||
};
|
||||
|
||||
#if defined(__OBJC__)
|
||||
void FireNativeEvent(mozAccessible* aNativeAcc, uint32_t aEventType);
|
||||
#else
|
||||
void FireNativeEvent(id aNativeAcc, uint32_t aEventType);
|
||||
#endif
|
||||
|
||||
Class GetTypeFromRole(roles::Role aRole);
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -1,256 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "DocAccessible.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
#include "Accessible-inl.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "Role.h"
|
||||
|
||||
#import "mozAccessible.h"
|
||||
#import "mozActionElements.h"
|
||||
#import "mozHTMLAccessible.h"
|
||||
#import "mozTableAccessible.h"
|
||||
#import "mozTextAccessible.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
AccessibleWrap::
|
||||
AccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) :
|
||||
Accessible(aContent, aDoc), mNativeObject(nil),
|
||||
mNativeInited(false)
|
||||
{
|
||||
}
|
||||
|
||||
AccessibleWrap::~AccessibleWrap()
|
||||
{
|
||||
}
|
||||
|
||||
mozAccessible*
|
||||
AccessibleWrap::GetNativeObject()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (!mNativeInited && !mNativeObject && !IsDefunct() && !AncestorIsFlat()) {
|
||||
uintptr_t accWrap = reinterpret_cast<uintptr_t>(this);
|
||||
mNativeObject = [[GetNativeType() alloc] initWithAccessible:accWrap];
|
||||
}
|
||||
|
||||
mNativeInited = true;
|
||||
|
||||
return mNativeObject;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
void
|
||||
AccessibleWrap::GetNativeInterface(void** aOutInterface)
|
||||
{
|
||||
*aOutInterface = static_cast<void*>(GetNativeObject());
|
||||
}
|
||||
|
||||
// overridden in subclasses to create the right kind of object. by default we create a generic
|
||||
// 'mozAccessible' node.
|
||||
Class
|
||||
AccessibleWrap::GetNativeType ()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (IsXULTabpanels())
|
||||
return [mozPaneAccessible class];
|
||||
|
||||
if (IsTable())
|
||||
return [mozTableAccessible class];
|
||||
|
||||
if (IsTableRow())
|
||||
return [mozTableRowAccessible class];
|
||||
|
||||
if (IsTableCell())
|
||||
return [mozTableCellAccessible class];
|
||||
|
||||
return GetTypeFromRole(Role());
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
// this method is very important. it is fired when an accessible object "dies". after this point
|
||||
// the object might still be around (because some 3rd party still has a ref to it), but it is
|
||||
// in fact 'dead'.
|
||||
void
|
||||
AccessibleWrap::Shutdown ()
|
||||
{
|
||||
// this ensure we will not try to re-create the native object.
|
||||
mNativeInited = true;
|
||||
|
||||
// we really intend to access the member directly.
|
||||
if (mNativeObject) {
|
||||
[mNativeObject expire];
|
||||
[mNativeObject release];
|
||||
mNativeObject = nil;
|
||||
}
|
||||
|
||||
Accessible::Shutdown();
|
||||
}
|
||||
|
||||
nsresult
|
||||
AccessibleWrap::HandleAccEvent(AccEvent* aEvent)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
nsresult rv = Accessible::HandleAccEvent(aEvent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (IPCAccessibilityActive()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t eventType = aEvent->GetEventType();
|
||||
|
||||
// ignore everything but focus-changed, value-changed, caret, selection
|
||||
// and document load complete events for now.
|
||||
if (eventType != nsIAccessibleEvent::EVENT_FOCUS &&
|
||||
eventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE &&
|
||||
eventType != nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE &&
|
||||
eventType != nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED &&
|
||||
eventType != nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED &&
|
||||
eventType != nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE)
|
||||
return NS_OK;
|
||||
|
||||
Accessible* accessible = aEvent->GetAccessible();
|
||||
NS_ENSURE_STATE(accessible);
|
||||
|
||||
mozAccessible *nativeAcc = nil;
|
||||
accessible->GetNativeInterface((void**)&nativeAcc);
|
||||
if (!nativeAcc)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
FireNativeEvent(nativeAcc, eventType);
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
bool
|
||||
AccessibleWrap::InsertChildAt(uint32_t aIdx, Accessible* aAccessible)
|
||||
{
|
||||
bool inserted = Accessible::InsertChildAt(aIdx, aAccessible);
|
||||
if (inserted && mNativeObject)
|
||||
[mNativeObject appendChild:aAccessible];
|
||||
|
||||
return inserted;
|
||||
}
|
||||
|
||||
bool
|
||||
AccessibleWrap::RemoveChild(Accessible* aAccessible)
|
||||
{
|
||||
bool removed = Accessible::RemoveChild(aAccessible);
|
||||
|
||||
if (removed && mNativeObject)
|
||||
[mNativeObject invalidateChildren];
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AccessibleWrap protected
|
||||
|
||||
bool
|
||||
AccessibleWrap::AncestorIsFlat()
|
||||
{
|
||||
// We don't create a native object if we're child of a "flat" accessible;
|
||||
// for example, on OS X buttons shouldn't have any children, because that
|
||||
// makes the OS confused.
|
||||
//
|
||||
// To maintain a scripting environment where the XPCOM accessible hierarchy
|
||||
// look the same on all platforms, we still let the C++ objects be created
|
||||
// though.
|
||||
|
||||
Accessible* parent = Parent();
|
||||
while (parent) {
|
||||
if (nsAccUtils::MustPrune(parent))
|
||||
return true;
|
||||
|
||||
parent = parent->Parent();
|
||||
}
|
||||
// no parent was flat
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
a11y::FireNativeEvent(mozAccessible* aNativeAcc, uint32_t aEventType)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
switch (aEventType) {
|
||||
case nsIAccessibleEvent::EVENT_FOCUS:
|
||||
[aNativeAcc didReceiveFocus];
|
||||
break;
|
||||
case nsIAccessibleEvent::EVENT_VALUE_CHANGE:
|
||||
case nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE:
|
||||
[aNativeAcc valueDidChange];
|
||||
break;
|
||||
case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED:
|
||||
case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED:
|
||||
[aNativeAcc selectedTextDidChange];
|
||||
break;
|
||||
case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE:
|
||||
[aNativeAcc documentLoadComplete];
|
||||
break;
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
Class
|
||||
a11y::GetTypeFromRole(roles::Role aRole)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
switch (aRole) {
|
||||
case roles::COMBOBOX:
|
||||
case roles::PUSHBUTTON:
|
||||
case roles::SPLITBUTTON:
|
||||
case roles::TOGGLE_BUTTON:
|
||||
{
|
||||
return [mozButtonAccessible class];
|
||||
}
|
||||
|
||||
case roles::PAGETAB:
|
||||
return [mozButtonAccessible class];
|
||||
|
||||
case roles::CHECKBUTTON:
|
||||
return [mozCheckboxAccessible class];
|
||||
|
||||
case roles::HEADING:
|
||||
return [mozHeadingAccessible class];
|
||||
|
||||
case roles::PAGETABLIST:
|
||||
return [mozTabsAccessible class];
|
||||
|
||||
case roles::ENTRY:
|
||||
case roles::STATICTEXT:
|
||||
case roles::CAPTION:
|
||||
case roles::ACCEL_LABEL:
|
||||
case roles::PASSWORD_TEXT:
|
||||
// normal textfield (static or editable)
|
||||
return [mozTextAccessible class];
|
||||
|
||||
case roles::TEXT_LEAF:
|
||||
return [mozTextLeafAccessible class];
|
||||
|
||||
case roles::LINK:
|
||||
return [mozLinkAccessible class];
|
||||
|
||||
default:
|
||||
return [mozAccessible class];
|
||||
}
|
||||
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_a11y_ApplicationAccessibleWrap_h__
|
||||
#define mozilla_a11y_ApplicationAccessibleWrap_h__
|
||||
|
||||
#include "ApplicationAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef ApplicationAccessible ApplicationAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_a11y_DocAccessibleWrap_h__
|
||||
#define mozilla_a11y_DocAccessibleWrap_h__
|
||||
|
||||
#include "DocAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class DocAccessibleWrap : public DocAccessible
|
||||
{
|
||||
public:
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell);
|
||||
virtual ~DocAccessibleWrap();
|
||||
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "DocAccessibleWrap.h"
|
||||
|
||||
#import "mozAccessible.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
DocAccessibleWrap::
|
||||
DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell) :
|
||||
DocAccessible(aDocument, aPresShell)
|
||||
{
|
||||
}
|
||||
|
||||
DocAccessibleWrap::~DocAccessibleWrap()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_a11y_HTMLTableAccessibleWrap_h__
|
||||
#define mozilla_a11y_HTMLTableAccessibleWrap_h__
|
||||
|
||||
#include "HTMLTableAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class HTMLTableAccessible HTMLTableAccessibleWrap;
|
||||
typedef class HTMLTableCellAccessible HTMLTableCellAccessibleWrap;
|
||||
typedef class HTMLTableHeaderCellAccessible HTMLTableHeaderCellAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_a11y_HyperTextAccessibleWrap_h__
|
||||
#define mozilla_a11y_HyperTextAccessibleWrap_h__
|
||||
|
||||
#include "HyperTextAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class HyperTextAccessible HyperTextAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_a11y_ImageAccessibleWrap_h__
|
||||
#define mozilla_a11y_ImageAccessibleWrap_h__
|
||||
|
||||
#include "ImageAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class ImageAccessible ImageAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _MacUtils_H_
|
||||
#define _MacUtils_H_
|
||||
|
||||
@class NSString;
|
||||
class nsString;
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
namespace utils {
|
||||
|
||||
/**
|
||||
* Get a localized string from the string bundle.
|
||||
* Return nil if not found.
|
||||
*/
|
||||
NSString* LocalizedString(const nsString& aString);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#import "MacUtils.h"
|
||||
|
||||
#include "Accessible.h"
|
||||
|
||||
#include "nsCocoaUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
namespace utils {
|
||||
|
||||
/**
|
||||
* Get a localized string from the a11y string bundle.
|
||||
* Return nil if not found.
|
||||
*/
|
||||
NSString*
|
||||
LocalizedString(const nsString& aString)
|
||||
{
|
||||
nsString text;
|
||||
|
||||
Accessible::TranslateString(aString, text);
|
||||
|
||||
return text.IsEmpty() ? nil : nsCocoaUtils::ToNSString(text);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,174 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "Platform.h"
|
||||
#include "ProxyAccessible.h"
|
||||
#include "DocAccessibleParent.h"
|
||||
#include "mozTableAccessible.h"
|
||||
|
||||
#include "nsAppShell.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
// Mac a11y whitelisting
|
||||
static bool sA11yShouldBeEnabled = false;
|
||||
|
||||
bool
|
||||
ShouldA11yBeEnabled()
|
||||
{
|
||||
EPlatformDisabledState disabledState = PlatformDisabledState();
|
||||
return (disabledState == ePlatformIsForceEnabled) || ((disabledState == ePlatformIsEnabled) && sA11yShouldBeEnabled);
|
||||
}
|
||||
|
||||
void
|
||||
PlatformInit()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
PlatformShutdown()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProxyCreated(ProxyAccessible* aProxy, uint32_t)
|
||||
{
|
||||
// Pass in dummy state for now as retrieving proxy state requires IPC.
|
||||
// Note that we can use ProxyAccessible::IsTable* functions here because they
|
||||
// do not use IPC calls but that might change after bug 1210477.
|
||||
Class type;
|
||||
if (aProxy->IsTable())
|
||||
type = [mozTableAccessible class];
|
||||
else if (aProxy->IsTableRow())
|
||||
type = [mozTableRowAccessible class];
|
||||
else if (aProxy->IsTableCell())
|
||||
type = [mozTableCellAccessible class];
|
||||
else
|
||||
type = GetTypeFromRole(aProxy->Role());
|
||||
|
||||
uintptr_t accWrap = reinterpret_cast<uintptr_t>(aProxy) | IS_PROXY;
|
||||
mozAccessible* mozWrapper = [[type alloc] initWithAccessible:accWrap];
|
||||
aProxy->SetWrapper(reinterpret_cast<uintptr_t>(mozWrapper));
|
||||
|
||||
mozAccessible* nativeParent = nullptr;
|
||||
if (aProxy->IsDoc() && aProxy->AsDoc()->IsTopLevel()) {
|
||||
// If proxy is top level, the parent we need to invalidate the children of
|
||||
// will be a non-remote accessible.
|
||||
Accessible* outerDoc = aProxy->OuterDocOfRemoteBrowser();
|
||||
if (outerDoc) {
|
||||
nativeParent = GetNativeFromGeckoAccessible(outerDoc);
|
||||
}
|
||||
} else {
|
||||
// Non-top level proxies need proxy parents' children invalidated.
|
||||
ProxyAccessible* parent = aProxy->Parent();
|
||||
nativeParent = GetNativeFromProxy(parent);
|
||||
NS_ASSERTION(parent, "a non-top-level proxy is missing a parent?");
|
||||
}
|
||||
|
||||
if (nativeParent) {
|
||||
[nativeParent invalidateChildren];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProxyDestroyed(ProxyAccessible* aProxy)
|
||||
{
|
||||
mozAccessible* nativeParent = nil;
|
||||
if (aProxy->IsDoc() && aProxy->AsDoc()->IsTopLevel()) {
|
||||
// Invalidate native parent in parent process's children on proxy destruction
|
||||
Accessible* outerDoc = aProxy->OuterDocOfRemoteBrowser();
|
||||
if (outerDoc) {
|
||||
nativeParent = GetNativeFromGeckoAccessible(outerDoc);
|
||||
}
|
||||
} else {
|
||||
if (!aProxy->Document()->IsShutdown()) {
|
||||
// Only do if the document has not been shut down, else parent will return
|
||||
// garbage since we don't shut down children from top down.
|
||||
ProxyAccessible* parent = aProxy->Parent();
|
||||
// Invalidate proxy parent's children.
|
||||
if (parent) {
|
||||
nativeParent = GetNativeFromProxy(parent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mozAccessible* wrapper = GetNativeFromProxy(aProxy);
|
||||
[wrapper expire];
|
||||
[wrapper release];
|
||||
aProxy->SetWrapper(0);
|
||||
|
||||
if (nativeParent) {
|
||||
[nativeParent invalidateChildren];
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProxyEvent(ProxyAccessible* aProxy, uint32_t aEventType)
|
||||
{
|
||||
// ignore everything but focus-changed, value-changed, caret and selection
|
||||
// events for now.
|
||||
if (aEventType != nsIAccessibleEvent::EVENT_FOCUS &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_VALUE_CHANGE &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_TEXT_VALUE_CHANGE &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED &&
|
||||
aEventType != nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED)
|
||||
return;
|
||||
|
||||
mozAccessible* wrapper = GetNativeFromProxy(aProxy);
|
||||
if (wrapper)
|
||||
FireNativeEvent(wrapper, aEventType);
|
||||
}
|
||||
|
||||
void
|
||||
ProxyStateChangeEvent(ProxyAccessible* aProxy, uint64_t, bool)
|
||||
{
|
||||
// mac doesn't care about state change events
|
||||
}
|
||||
|
||||
void
|
||||
ProxyCaretMoveEvent(ProxyAccessible* aTarget, int32_t aOffset)
|
||||
{
|
||||
mozAccessible* wrapper = GetNativeFromProxy(aTarget);
|
||||
if (wrapper)
|
||||
[wrapper selectedTextDidChange];
|
||||
}
|
||||
|
||||
void
|
||||
ProxyTextChangeEvent(ProxyAccessible*, const nsString&, int32_t, uint32_t,
|
||||
bool, bool)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProxyShowHideEvent(ProxyAccessible*, ProxyAccessible*, bool, bool)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ProxySelectionEvent(ProxyAccessible*, ProxyAccessible*, uint32_t)
|
||||
{
|
||||
}
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
@interface GeckoNSApplication(a11y)
|
||||
-(void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute;
|
||||
@end
|
||||
|
||||
@implementation GeckoNSApplication(a11y)
|
||||
|
||||
-(void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute
|
||||
{
|
||||
if ([attribute isEqualToString:@"AXEnhancedUserInterface"])
|
||||
mozilla::a11y::sA11yShouldBeEnabled = ([value intValue] == 1);
|
||||
|
||||
return [super accessibilitySetValue:value forAttribute:attribute];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* For documentation of the accessibility architecture,
|
||||
* see http://lxr.mozilla.org/seamonkey/source/accessible/accessible-docs.html
|
||||
*/
|
||||
|
||||
#ifndef mozilla_a11y_RootAccessibleWrap_h__
|
||||
#define mozilla_a11y_RootAccessibleWrap_h__
|
||||
|
||||
#include "RootAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
class RootAccessibleWrap : public RootAccessible
|
||||
{
|
||||
public:
|
||||
RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell);
|
||||
virtual ~RootAccessibleWrap();
|
||||
|
||||
Class GetNativeType ();
|
||||
|
||||
// let's our native accessible get in touch with the
|
||||
// native cocoa view that is our accessible parent.
|
||||
void GetNativeWidget (void **aOutView);
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "RootAccessibleWrap.h"
|
||||
|
||||
#include "mozDocAccessible.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsView.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
RootAccessibleWrap::
|
||||
RootAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell) :
|
||||
RootAccessible(aDocument, aPresShell)
|
||||
{
|
||||
}
|
||||
|
||||
RootAccessibleWrap::~RootAccessibleWrap()
|
||||
{
|
||||
}
|
||||
|
||||
Class
|
||||
RootAccessibleWrap::GetNativeType()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
return [mozRootAccessible class];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
void
|
||||
RootAccessibleWrap::GetNativeWidget(void** aOutView)
|
||||
{
|
||||
nsIFrame *frame = GetFrame();
|
||||
if (frame) {
|
||||
nsView *view = frame->GetView();
|
||||
if (view) {
|
||||
nsIWidget *widget = view->GetWidget();
|
||||
if (widget) {
|
||||
*aOutView = (void**)widget->GetNativeData (NS_NATIVE_WIDGET);
|
||||
NS_ASSERTION (*aOutView,
|
||||
"Couldn't get the native NSView parent we need to connect the accessibility hierarchy!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_a11y_TextLeafAccessibleWrap_h__
|
||||
#define mozilla_a11y_TextLeafAccessibleWrap_h__
|
||||
|
||||
#include "TextLeafAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class TextLeafAccessible TextLeafAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_a11y_XULListboxAccessibleWrap_h__
|
||||
#define mozilla_a11y_XULListboxAccessibleWrap_h__
|
||||
|
||||
#include "XULListboxAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class XULListboxAccessible XULListboxAccessibleWrap;
|
||||
typedef class XULListCellAccessible XULListCellAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_a11y_XULMenuAccessibleWrap_h__
|
||||
#define mozilla_a11y_XULMenuAccessibleWrap_h__
|
||||
|
||||
#include "XULMenuAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class XULMenuitemAccessible XULMenuitemAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_a11y_XULTreeGridAccessibleWrap_h__
|
||||
#define mozilla_a11y_XULTreeGridAccessibleWrap_h__
|
||||
|
||||
#include "XULTreeGridAccessible.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
typedef class XULTreeGridAccessible XULTreeGridAccessibleWrap;
|
||||
typedef class XULTreeGridCellAccessible XULTreeGridCellAccessibleWrap;
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# 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/.
|
||||
|
||||
EXPORTS += [
|
||||
'mozAccessibleProtocol.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.a11y += [
|
||||
'AccessibleWrap.h',
|
||||
'HyperTextAccessibleWrap.h',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'AccessibleWrap.mm',
|
||||
'DocAccessibleWrap.mm',
|
||||
'MacUtils.mm',
|
||||
'mozAccessible.mm',
|
||||
'mozActionElements.mm',
|
||||
'mozDocAccessible.mm',
|
||||
'mozHTMLAccessible.mm',
|
||||
'mozTableAccessible.mm',
|
||||
'mozTextAccessible.mm',
|
||||
'Platform.mm',
|
||||
'RootAccessibleWrap.mm',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/base',
|
||||
'/accessible/generic',
|
||||
'/accessible/html',
|
||||
'/accessible/ipc',
|
||||
'/accessible/ipc/other',
|
||||
'/accessible/xul',
|
||||
'/layout/generic',
|
||||
'/layout/xul',
|
||||
'/widget',
|
||||
'/widget/cocoa',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
|
@ -1,181 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "AccessibleWrap.h"
|
||||
#include "ProxyAccessible.h"
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "mozAccessibleProtocol.h"
|
||||
|
||||
@class mozRootAccessible;
|
||||
|
||||
/**
|
||||
* All mozAccessibles are either abstract objects (that correspond to XUL
|
||||
* widgets, HTML frames, etc) or are attached to a certain view; for example
|
||||
* a document view. When we hand an object off to an AT, we always want
|
||||
* to give it the represented view, in the latter case.
|
||||
*/
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
inline id <mozAccessible>
|
||||
GetObjectOrRepresentedView(id <mozAccessible> aObject)
|
||||
{
|
||||
return [aObject hasRepresentedView] ? [aObject representedView] : aObject;
|
||||
}
|
||||
|
||||
inline mozAccessible*
|
||||
GetNativeFromGeckoAccessible(Accessible* aAccessible)
|
||||
{
|
||||
mozAccessible* native = nil;
|
||||
aAccessible->GetNativeInterface((void**)&native);
|
||||
return native;
|
||||
}
|
||||
|
||||
inline mozAccessible*
|
||||
GetNativeFromProxy(const ProxyAccessible* aProxy)
|
||||
{
|
||||
return reinterpret_cast<mozAccessible*>(aProxy->GetWrapper());
|
||||
}
|
||||
|
||||
} // a11y
|
||||
} // mozilla
|
||||
|
||||
// This is OR'd with the Accessible owner to indicate the wrap-ee is a proxy.
|
||||
static const uintptr_t IS_PROXY = 1;
|
||||
|
||||
@interface mozAccessible : NSObject <mozAccessible>
|
||||
{
|
||||
/**
|
||||
* Weak reference; it owns us.
|
||||
*/
|
||||
uintptr_t mGeckoAccessible;
|
||||
|
||||
/**
|
||||
* Strong ref to array of children
|
||||
*/
|
||||
NSMutableArray* mChildren;
|
||||
|
||||
/**
|
||||
* Weak reference to the parent
|
||||
*/
|
||||
mozAccessible* mParent;
|
||||
|
||||
/**
|
||||
* The role of our gecko accessible.
|
||||
*/
|
||||
mozilla::a11y::role mRole;
|
||||
}
|
||||
|
||||
// return the Accessible for this mozAccessible if it exists.
|
||||
- (mozilla::a11y::AccessibleWrap*)getGeckoAccessible;
|
||||
|
||||
// return the ProxyAccessible for this mozAccessible if it exists.
|
||||
- (mozilla::a11y::ProxyAccessible*)getProxyAccessible;
|
||||
|
||||
// inits with the gecko owner.
|
||||
- (id)initWithAccessible:(uintptr_t)aGeckoObj;
|
||||
|
||||
// our accessible parent (AXParent)
|
||||
- (id <mozAccessible>)parent;
|
||||
|
||||
// a lazy cache of our accessible children (AXChildren). updated
|
||||
- (NSArray*)children;
|
||||
|
||||
// returns the size of this accessible.
|
||||
- (NSValue*)size;
|
||||
|
||||
// returns the position, in cocoa coordinates.
|
||||
- (NSValue*)position;
|
||||
|
||||
// can be overridden to report another role name.
|
||||
- (NSString*)role;
|
||||
|
||||
// a subrole is a more specialized variant of the role. for example,
|
||||
// the role might be "textfield", while the subrole is "password textfield".
|
||||
- (NSString*)subrole;
|
||||
|
||||
// Return the role description, as there are a few exceptions.
|
||||
- (NSString*)roleDescription;
|
||||
|
||||
// returns the native window we're inside.
|
||||
- (NSWindow*)window;
|
||||
|
||||
// the value of this element.
|
||||
- (id)value;
|
||||
|
||||
// name that is associated with this accessible (for buttons, etc)
|
||||
- (NSString*)title;
|
||||
|
||||
// the accessible description (help text) of this particular instance.
|
||||
- (NSString*)help;
|
||||
|
||||
- (BOOL)isEnabled;
|
||||
|
||||
// information about focus.
|
||||
- (BOOL)isFocused;
|
||||
- (BOOL)canBeFocused;
|
||||
|
||||
// returns NO if for some reason we were unable to focus the element.
|
||||
- (BOOL)focus;
|
||||
|
||||
// notifications sent out to listening accessible providers.
|
||||
- (void)didReceiveFocus;
|
||||
- (void)valueDidChange;
|
||||
- (void)selectedTextDidChange;
|
||||
- (void)documentLoadComplete;
|
||||
|
||||
// internal method to retrieve a child at a given index.
|
||||
- (id)childAt:(uint32_t)i;
|
||||
|
||||
#pragma mark -
|
||||
|
||||
// invalidates and removes all our children from our cached array.
|
||||
- (void)invalidateChildren;
|
||||
|
||||
/**
|
||||
* Append a child if they are already cached.
|
||||
*/
|
||||
- (void)appendChild:(mozilla::a11y::Accessible*)aAccessible;
|
||||
|
||||
// makes ourselves "expired". after this point, we might be around if someone
|
||||
// has retained us (e.g., a third-party), but we really contain no information.
|
||||
- (void)expire;
|
||||
- (BOOL)isExpired;
|
||||
|
||||
#ifdef DEBUG
|
||||
- (void)printHierarchy;
|
||||
- (void)printHierarchyWithLevel:(unsigned)numSpaces;
|
||||
|
||||
- (void)sanityCheckChildren;
|
||||
- (void)sanityCheckChildren:(NSArray*)theChildren;
|
||||
#endif
|
||||
|
||||
// ---- NSAccessibility methods ---- //
|
||||
|
||||
// whether to skip this element when traversing the accessibility
|
||||
// hierarchy.
|
||||
- (BOOL)accessibilityIsIgnored;
|
||||
|
||||
// called by third-parties to determine the deepest child element under the mouse
|
||||
- (id)accessibilityHitTest:(NSPoint)point;
|
||||
|
||||
// returns the deepest unignored focused accessible element
|
||||
- (id)accessibilityFocusedUIElement;
|
||||
|
||||
// a mozAccessible needs to at least provide links to its parent and
|
||||
// children.
|
||||
- (NSArray*)accessibilityAttributeNames;
|
||||
|
||||
// value for the specified attribute
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute;
|
||||
|
||||
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute;
|
||||
- (void)accessibilitySetValue:(id)value forAttribute:(NSString*)attribute;
|
||||
|
||||
@end
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,69 +0,0 @@
|
|||
/* -*- Mode: Objective-C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#import "mozView.h"
|
||||
|
||||
/* This protocol's primary use is so widget/cocoa can talk back to us
|
||||
properly.
|
||||
|
||||
ChildView owns the topmost mozRootAccessible, and needs to take care of setting up
|
||||
that parent/child relationship.
|
||||
|
||||
This protocol is thus used to make sure it knows it's talking to us, and not
|
||||
just some random |id|.
|
||||
*/
|
||||
|
||||
@protocol mozAccessible
|
||||
|
||||
// returns whether this accessible is the root accessible. there is one
|
||||
// root accessible per window.
|
||||
- (BOOL)isRoot;
|
||||
|
||||
// some mozAccessibles implement accessibility support in place of another object. for example,
|
||||
// ChildView gets its support from us.
|
||||
//
|
||||
// instead of returning a mozAccessible to the OS when it wants an object, we need to pass the view we represent, so the
|
||||
// OS doesn't get confused and think we return some random object.
|
||||
- (BOOL)hasRepresentedView;
|
||||
- (id)representedView;
|
||||
|
||||
#ifdef DEBUG
|
||||
// debug utility that will print the native accessibility tree, starting
|
||||
// at this node.
|
||||
- (void)printHierarchy;
|
||||
#endif
|
||||
|
||||
/*** general ***/
|
||||
|
||||
// returns the accessible at the specified point.
|
||||
- (id)accessibilityHitTest:(NSPoint)point;
|
||||
|
||||
// whether this element is flagged as ignored.
|
||||
- (BOOL)accessibilityIsIgnored;
|
||||
|
||||
// currently focused UI element (possibly a child accessible)
|
||||
- (id)accessibilityFocusedUIElement;
|
||||
|
||||
/*** attributes ***/
|
||||
|
||||
// all supported attributes
|
||||
- (NSArray*)accessibilityAttributeNames;
|
||||
|
||||
// value for given attribute.
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute;
|
||||
|
||||
// whether a particular attribute can be modified
|
||||
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute;
|
||||
|
||||
/*** actions ***/
|
||||
|
||||
- (NSArray*)accessibilityActionNames;
|
||||
- (NSString*)accessibilityActionDescription:(NSString*)action;
|
||||
- (void)accessibilityPerformAction:(NSString*)action;
|
||||
|
||||
@end
|
||||
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "mozAccessible.h"
|
||||
|
||||
/* Simple subclasses for things like checkboxes, buttons, etc. */
|
||||
|
||||
@interface mozButtonAccessible : mozAccessible
|
||||
{
|
||||
}
|
||||
- (BOOL)hasPopup;
|
||||
- (void)click;
|
||||
- (BOOL)isTab;
|
||||
@end
|
||||
|
||||
@interface mozCheckboxAccessible : mozButtonAccessible
|
||||
// returns one of the constants defined in CheckboxValue
|
||||
- (int)isChecked;
|
||||
@end
|
||||
|
||||
/* Class for tabs - not individual tabs */
|
||||
@interface mozTabsAccessible : mozAccessible
|
||||
{
|
||||
NSMutableArray* mTabs;
|
||||
}
|
||||
-(id)tabs;
|
||||
@end
|
||||
|
||||
/**
|
||||
* Accessible for a PANE
|
||||
*/
|
||||
@interface mozPaneAccessible : mozAccessible
|
||||
|
||||
@end
|
||||
|
|
@ -1,340 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#import "mozActionElements.h"
|
||||
|
||||
#import "MacUtils.h"
|
||||
#include "Accessible-inl.h"
|
||||
#include "DocAccessible.h"
|
||||
#include "XULTabAccessible.h"
|
||||
|
||||
#include "nsDeckFrame.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
enum CheckboxValue {
|
||||
// these constants correspond to the values in the OS
|
||||
kUnchecked = 0,
|
||||
kChecked = 1,
|
||||
kMixed = 2
|
||||
};
|
||||
|
||||
@implementation mozButtonAccessible
|
||||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
static NSArray *attributes = nil;
|
||||
if (!attributes) {
|
||||
attributes = [[NSArray alloc] initWithObjects:NSAccessibilityParentAttribute, // required
|
||||
NSAccessibilityRoleAttribute, // required
|
||||
NSAccessibilityRoleDescriptionAttribute,
|
||||
NSAccessibilityPositionAttribute, // required
|
||||
NSAccessibilitySizeAttribute, // required
|
||||
NSAccessibilityWindowAttribute, // required
|
||||
NSAccessibilityPositionAttribute, // required
|
||||
NSAccessibilityTopLevelUIElementAttribute, // required
|
||||
NSAccessibilityHelpAttribute,
|
||||
NSAccessibilityEnabledAttribute, // required
|
||||
NSAccessibilityFocusedAttribute, // required
|
||||
NSAccessibilityTitleAttribute, // required
|
||||
NSAccessibilityChildrenAttribute,
|
||||
NSAccessibilityDescriptionAttribute,
|
||||
#if DEBUG
|
||||
@"AXMozDescription",
|
||||
#endif
|
||||
nil];
|
||||
}
|
||||
return attributes;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
|
||||
if ([self hasPopup])
|
||||
return [self children];
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
|
||||
if ([self isTab])
|
||||
return utils::LocalizedString(NS_LITERAL_STRING("tab"));
|
||||
|
||||
return NSAccessibilityRoleDescription([self role], nil);
|
||||
}
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
{
|
||||
return ![self getGeckoAccessible] && ![self getProxyAccessible];
|
||||
}
|
||||
|
||||
- (NSArray*)accessibilityActionNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([self isEnabled]) {
|
||||
if ([self hasPopup])
|
||||
return [NSArray arrayWithObjects:NSAccessibilityPressAction,
|
||||
NSAccessibilityShowMenuAction,
|
||||
nil];
|
||||
return [NSArray arrayWithObject:NSAccessibilityPressAction];
|
||||
}
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSString*)accessibilityActionDescription:(NSString*)action
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([action isEqualToString:NSAccessibilityPressAction]) {
|
||||
if ([self isTab])
|
||||
return utils::LocalizedString(NS_LITERAL_STRING("switch"));
|
||||
|
||||
return @"press button"; // XXX: localize this later?
|
||||
}
|
||||
|
||||
if ([self hasPopup]) {
|
||||
if ([action isEqualToString:NSAccessibilityShowMenuAction])
|
||||
return @"show menu";
|
||||
}
|
||||
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (void)accessibilityPerformAction:(NSString*)action
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if ([self isEnabled] && [action isEqualToString:NSAccessibilityPressAction]) {
|
||||
// TODO: this should bring up the menu, but currently doesn't.
|
||||
// once msaa and atk have merged better, they will implement
|
||||
// the action needed to show the menu.
|
||||
[self click];
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)click
|
||||
{
|
||||
// both buttons and checkboxes have only one action. we should really stop using arbitrary
|
||||
// arrays with actions, and define constants for these actions.
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
|
||||
accWrap->DoAction(0);
|
||||
else if (ProxyAccessible* proxy = [self getProxyAccessible])
|
||||
proxy->DoAction(0);
|
||||
}
|
||||
|
||||
- (BOOL)isTab
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
|
||||
return accWrap->Role() == roles::PAGETAB;
|
||||
|
||||
if (ProxyAccessible* proxy = [self getProxyAccessible])
|
||||
return proxy->Role() == roles::PAGETAB;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
- (BOOL)hasPopup
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
|
||||
return accWrap->NativeState() & states::HASPOPUP;
|
||||
|
||||
if (ProxyAccessible* proxy = [self getProxyAccessible])
|
||||
return proxy->NativeState() & states::HASPOPUP;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation mozCheckboxAccessible
|
||||
|
||||
- (NSString*)accessibilityActionDescription:(NSString*)action
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([action isEqualToString:NSAccessibilityPressAction]) {
|
||||
if ([self isChecked] != kUnchecked)
|
||||
return @"uncheck checkbox"; // XXX: localize this later?
|
||||
|
||||
return @"check checkbox"; // XXX: localize this later?
|
||||
}
|
||||
|
||||
return nil;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (int)isChecked
|
||||
{
|
||||
uint64_t state = 0;
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible])
|
||||
state = accWrap->NativeState();
|
||||
else if (ProxyAccessible* proxy = [self getProxyAccessible])
|
||||
state = proxy->NativeState();
|
||||
|
||||
// check if we're checked or in a mixed state
|
||||
if (state & states::CHECKED) {
|
||||
return (state & states::MIXED) ? kMixed : kChecked;
|
||||
}
|
||||
|
||||
return kUnchecked;
|
||||
}
|
||||
|
||||
- (id)value
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
return [NSNumber numberWithInt:[self isChecked]];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation mozTabsAccessible
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[mTabs release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
// standard attributes that are shared and supported by root accessible (AXMain) elements.
|
||||
static NSMutableArray* attributes = nil;
|
||||
|
||||
if (!attributes) {
|
||||
attributes = [[super accessibilityAttributeNames] mutableCopy];
|
||||
[attributes addObject:NSAccessibilityContentsAttribute];
|
||||
[attributes addObject:NSAccessibilityTabsAttribute];
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute
|
||||
{
|
||||
if ([attribute isEqualToString:NSAccessibilityContentsAttribute])
|
||||
return [super children];
|
||||
if ([attribute isEqualToString:NSAccessibilityTabsAttribute])
|
||||
return [self tabs];
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selected tab (the mozAccessible)
|
||||
*/
|
||||
- (id)value
|
||||
{
|
||||
mozAccessible* nativeAcc = nil;
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
if (Accessible* accTab = accWrap->GetSelectedItem(0)) {
|
||||
accTab->GetNativeInterface((void**)&nativeAcc);
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
if (ProxyAccessible* proxyTab = proxy->GetSelectedItem(0)) {
|
||||
nativeAcc = GetNativeFromProxy(proxyTab);
|
||||
}
|
||||
}
|
||||
|
||||
return nativeAcc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mozAccessibles that are the tabs.
|
||||
*/
|
||||
- (id)tabs
|
||||
{
|
||||
if (mTabs)
|
||||
return mTabs;
|
||||
|
||||
NSArray* children = [self children];
|
||||
NSEnumerator* enumerator = [children objectEnumerator];
|
||||
mTabs = [[NSMutableArray alloc] init];
|
||||
|
||||
id obj;
|
||||
while ((obj = [enumerator nextObject]))
|
||||
if ([obj isTab])
|
||||
[mTabs addObject:obj];
|
||||
|
||||
return mTabs;
|
||||
}
|
||||
|
||||
- (void)invalidateChildren
|
||||
{
|
||||
[super invalidateChildren];
|
||||
|
||||
[mTabs release];
|
||||
mTabs = nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation mozPaneAccessible
|
||||
|
||||
- (NSUInteger)accessibilityArrayAttributeCount:(NSString*)attribute
|
||||
{
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
if (!accWrap && !proxy)
|
||||
return 0;
|
||||
|
||||
// By default this calls -[[mozAccessible children] count].
|
||||
// Since we don't cache mChildren. This is faster.
|
||||
if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
|
||||
if (accWrap)
|
||||
return accWrap->ChildCount() ? 1 : 0;
|
||||
|
||||
return proxy->ChildrenCount() ? 1 : 0;
|
||||
}
|
||||
|
||||
return [super accessibilityArrayAttributeCount:attribute];
|
||||
}
|
||||
|
||||
- (NSArray*)children
|
||||
{
|
||||
if (![self getGeckoAccessible])
|
||||
return nil;
|
||||
|
||||
nsDeckFrame* deckFrame = do_QueryFrame([self getGeckoAccessible]->GetFrame());
|
||||
nsIFrame* selectedFrame = deckFrame ? deckFrame->GetSelectedBox() : nullptr;
|
||||
|
||||
Accessible* selectedAcc = nullptr;
|
||||
if (selectedFrame) {
|
||||
nsINode* node = selectedFrame->GetContent();
|
||||
selectedAcc = [self getGeckoAccessible]->Document()->GetAccessible(node);
|
||||
}
|
||||
|
||||
if (selectedAcc) {
|
||||
mozAccessible *curNative = GetNativeFromGeckoAccessible(selectedAcc);
|
||||
if (curNative)
|
||||
return [NSArray arrayWithObjects:GetObjectOrRepresentedView(curNative), nil];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "mozAccessible.h"
|
||||
|
||||
// our protocol that we implement (so cocoa widgets can talk to us)
|
||||
#import "mozAccessibleProtocol.h"
|
||||
|
||||
/*
|
||||
The root accessible. There is one per window.
|
||||
Created by the RootAccessibleWrap.
|
||||
*/
|
||||
@interface mozRootAccessible : mozAccessible
|
||||
{
|
||||
// the mozView that we're representing.
|
||||
// all outside communication goes through the mozView.
|
||||
// in reality, it's just piping all calls to us, and we're
|
||||
// doing its dirty work!
|
||||
//
|
||||
// whenever someone asks who we are (e.g., a child asking
|
||||
// for its parent, or our parent asking for its child), we'll
|
||||
// respond the mozView. it is absolutely necessary for third-
|
||||
// party tools that we do this!
|
||||
//
|
||||
// /hwaara
|
||||
id <mozView, mozAccessible> mParallelView; // weak ref
|
||||
}
|
||||
@end
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "RootAccessibleWrap.h"
|
||||
|
||||
#import "mozDocAccessible.h"
|
||||
|
||||
#import "mozView.h"
|
||||
|
||||
// This must be included last:
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
static id <mozAccessible, mozView>
|
||||
getNativeViewFromRootAccessible(Accessible* aAccessible)
|
||||
{
|
||||
RootAccessibleWrap* root =
|
||||
static_cast<RootAccessibleWrap*>(aAccessible->AsRoot());
|
||||
id <mozAccessible, mozView> nativeView = nil;
|
||||
root->GetNativeWidget ((void**)&nativeView);
|
||||
return nativeView;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation mozRootAccessible
|
||||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
// if we're expired, we don't support any attributes.
|
||||
if (![self getGeckoAccessible])
|
||||
return [NSArray array];
|
||||
|
||||
// standard attributes that are shared and supported by root accessible (AXMain) elements.
|
||||
static NSMutableArray* attributes = nil;
|
||||
|
||||
if (!attributes) {
|
||||
attributes = [[super accessibilityAttributeNames] mutableCopy];
|
||||
[attributes addObject:NSAccessibilityMainAttribute];
|
||||
[attributes addObject:NSAccessibilityMinimizedAttribute];
|
||||
}
|
||||
|
||||
return attributes;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityMainAttribute])
|
||||
return [NSNumber numberWithBool:[[self window] isMainWindow]];
|
||||
if ([attribute isEqualToString:NSAccessibilityMinimizedAttribute])
|
||||
return [NSNumber numberWithBool:[[self window] isMiniaturized]];
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
|
||||
// return the AXParent that our parallell NSView tells us about.
|
||||
- (id)parent
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (!mParallelView)
|
||||
mParallelView = (id<mozView, mozAccessible>)[self representedView];
|
||||
|
||||
if (mParallelView)
|
||||
return [mParallelView accessibilityAttributeValue:NSAccessibilityParentAttribute];
|
||||
|
||||
NSAssert(mParallelView, @"we're a root accessible w/o native view?");
|
||||
return [super parent];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)hasRepresentedView
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
// this will return our parallell NSView. see mozDocAccessible.h
|
||||
- (id)representedView
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if (mParallelView)
|
||||
return (id)mParallelView;
|
||||
|
||||
mParallelView = getNativeViewFromRootAccessible ([self getGeckoAccessible]);
|
||||
|
||||
NSAssert(mParallelView, @"can't return root accessible's native parallel view.");
|
||||
return mParallelView;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (BOOL)isRoot
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#import "mozAccessible.h"
|
||||
|
||||
@interface mozHeadingAccessible : mozAccessible
|
||||
|
||||
@end
|
||||
|
||||
@interface mozLinkAccessible : mozAccessible
|
||||
|
||||
@end
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#import "mozHTMLAccessible.h"
|
||||
|
||||
#import "Accessible-inl.h"
|
||||
#import "HyperTextAccessible.h"
|
||||
|
||||
#import "nsCocoaUtils.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
@implementation mozHeadingAccessible
|
||||
|
||||
- (NSString*)title
|
||||
{
|
||||
nsAutoString title;
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
mozilla::ErrorResult rv;
|
||||
// XXX use the flattening API when there are available
|
||||
// see bug 768298
|
||||
accWrap->GetContent()->GetTextContent(title, rv);
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
proxy->Title(title);
|
||||
}
|
||||
|
||||
return nsCocoaUtils::ToNSString(title);
|
||||
}
|
||||
|
||||
- (id)value
|
||||
{
|
||||
uint32_t level = 0;
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
level = accWrap->GetLevelInternal();
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
level = proxy->GetLevelInternal();
|
||||
}
|
||||
|
||||
return [NSNumber numberWithInt:level];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface mozLinkAccessible ()
|
||||
-(NSURL*)url;
|
||||
@end
|
||||
|
||||
@implementation mozLinkAccessible
|
||||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
// if we're expired, we don't support any attributes.
|
||||
if (![self getGeckoAccessible] && ![self getProxyAccessible])
|
||||
return [NSArray array];
|
||||
|
||||
static NSMutableArray* attributes = nil;
|
||||
|
||||
if (!attributes) {
|
||||
attributes = [[super accessibilityAttributeNames] mutableCopy];
|
||||
[attributes addObject:NSAccessibilityURLAttribute];
|
||||
}
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString *)attribute
|
||||
{
|
||||
if ([attribute isEqualToString:NSAccessibilityURLAttribute])
|
||||
return [self url];
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
|
||||
- (NSArray*)accessibilityActionNames
|
||||
{
|
||||
// if we're expired, we don't support any attributes.
|
||||
if (![self getGeckoAccessible] && ![self getProxyAccessible])
|
||||
return [NSArray array];
|
||||
|
||||
static NSArray* actionNames = nil;
|
||||
|
||||
if (!actionNames) {
|
||||
actionNames = [[NSArray alloc] initWithObjects:NSAccessibilityPressAction,
|
||||
nil];
|
||||
}
|
||||
|
||||
return actionNames;
|
||||
}
|
||||
|
||||
- (void)accessibilityPerformAction:(NSString*)action
|
||||
{
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
if (!accWrap && !proxy) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ([action isEqualToString:NSAccessibilityPressAction]) {
|
||||
if (accWrap) {
|
||||
accWrap->DoAction(0);
|
||||
} else if (proxy) {
|
||||
proxy->DoAction(0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
[super accessibilityPerformAction:action];
|
||||
|
||||
}
|
||||
|
||||
- (NSString*)customDescription
|
||||
{
|
||||
return @"";
|
||||
}
|
||||
|
||||
- (NSString*)value
|
||||
{
|
||||
return @"";
|
||||
}
|
||||
|
||||
- (NSURL*)url
|
||||
{
|
||||
nsAutoString value;
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
accWrap->Value(value);
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
proxy->Value(value);
|
||||
}
|
||||
|
||||
NSString* urlString = value.IsEmpty() ? nil : nsCocoaUtils::ToNSString(value);
|
||||
if (!urlString)
|
||||
return nil;
|
||||
|
||||
return [NSURL URLWithString:urlString];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#import "mozAccessible.h"
|
||||
|
||||
@interface mozTablePartAccessible : mozAccessible
|
||||
- (BOOL)isLayoutTablePart;
|
||||
- (NSString*)role;
|
||||
@end
|
||||
|
||||
@interface mozTableAccessible : mozTablePartAccessible
|
||||
- (NSArray*)additionalAccessibilityAttributeNames;
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute;
|
||||
@end
|
||||
|
||||
@interface mozTableRowAccessible : mozTablePartAccessible
|
||||
- (NSArray*)additionalAccessibilityAttributeNames;
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute;
|
||||
@end
|
||||
|
||||
@interface mozTableCellAccessible : mozTablePartAccessible
|
||||
- (NSArray*)additionalAccessibilityAttributeNames;
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute;
|
||||
@end
|
||||
|
|
@ -1,281 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:expandtab:shiftwidth=2:tabstop=2:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#import "Accessible-inl.h"
|
||||
#import "mozTableAccessible.h"
|
||||
#import "TableAccessible.h"
|
||||
#import "TableCellAccessible.h"
|
||||
#import "nsCocoaUtils.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
// convert an array of Gecko accessibles to an NSArray of native accessibles
|
||||
static inline NSMutableArray*
|
||||
ConvertToNSArray(nsTArray<Accessible*>& aArray)
|
||||
{
|
||||
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
|
||||
|
||||
// iterate through the list, and get each native accessible.
|
||||
size_t totalCount = aArray.Length();
|
||||
for (size_t i = 0; i < totalCount; i++) {
|
||||
Accessible* curAccessible = aArray.ElementAt(i);
|
||||
mozAccessible* curNative = GetNativeFromGeckoAccessible(curAccessible);
|
||||
if (curNative)
|
||||
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
|
||||
}
|
||||
|
||||
return nativeArray;
|
||||
}
|
||||
|
||||
// convert an array of Gecko proxy accessibles to an NSArray of native accessibles
|
||||
static inline NSMutableArray*
|
||||
ConvertToNSArray(nsTArray<ProxyAccessible*>& aArray)
|
||||
{
|
||||
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
|
||||
|
||||
// iterate through the list, and get each native accessible.
|
||||
size_t totalCount = aArray.Length();
|
||||
for (size_t i = 0; i < totalCount; i++) {
|
||||
ProxyAccessible* curAccessible = aArray.ElementAt(i);
|
||||
mozAccessible* curNative = GetNativeFromProxy(curAccessible);
|
||||
if (curNative)
|
||||
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
|
||||
}
|
||||
|
||||
return nativeArray;
|
||||
}
|
||||
|
||||
@implementation mozTablePartAccessible
|
||||
- (BOOL)isLayoutTablePart;
|
||||
{
|
||||
if (Accessible* accWrap = [self getGeckoAccessible]) {
|
||||
while (accWrap) {
|
||||
if (accWrap->IsTable()) {
|
||||
return accWrap->AsTable()->IsProbablyLayoutTable();
|
||||
}
|
||||
accWrap = accWrap->Parent();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
while (proxy) {
|
||||
if (proxy->IsTable()) {
|
||||
return proxy->TableIsProbablyForLayout();
|
||||
}
|
||||
proxy = proxy->Parent();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
- (NSString*)role
|
||||
{
|
||||
return [self isLayoutTablePart] ? NSAccessibilityGroupRole : [super role];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation mozTableAccessible
|
||||
- (NSArray*)additionalAccessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
|
||||
if ([self isLayoutTablePart]) {
|
||||
return additionalAttributes;
|
||||
}
|
||||
|
||||
static NSArray* tableAttrs = nil;
|
||||
if (!tableAttrs) {
|
||||
NSMutableArray* tempArray = [NSMutableArray new];
|
||||
[tempArray addObject:NSAccessibilityRowCountAttribute];
|
||||
[tempArray addObject:NSAccessibilityColumnCountAttribute];
|
||||
[tempArray addObject:NSAccessibilityRowsAttribute];
|
||||
tableAttrs = [[NSArray alloc] initWithArray:tempArray];
|
||||
[tempArray release];
|
||||
}
|
||||
|
||||
return [additionalAttributes arrayByAddingObjectsFromArray:tableAttrs];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
TableAccessible* table = accWrap->AsTable();
|
||||
if ([attribute isEqualToString:NSAccessibilityRowCountAttribute])
|
||||
return @(table->RowCount());
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnCountAttribute])
|
||||
return @(table->ColCount());
|
||||
if ([attribute isEqualToString:NSAccessibilityRowsAttribute]) {
|
||||
// Create a new array with the list of table rows.
|
||||
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
|
||||
uint32_t totalCount = accWrap->ChildCount();
|
||||
for (uint32_t i = 0; i < totalCount; i++) {
|
||||
if (accWrap->GetChildAt(i)->IsTableRow()) {
|
||||
mozAccessible* curNative =
|
||||
GetNativeFromGeckoAccessible(accWrap->GetChildAt(i));
|
||||
if (curNative)
|
||||
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
|
||||
}
|
||||
}
|
||||
return nativeArray;
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
if ([attribute isEqualToString:NSAccessibilityRowCountAttribute])
|
||||
return @(proxy->TableRowCount());
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnCountAttribute])
|
||||
return @(proxy->TableColumnCount());
|
||||
if ([attribute isEqualToString:NSAccessibilityRowsAttribute]) {
|
||||
// Create a new array with the list of table rows.
|
||||
NSMutableArray* nativeArray = [[NSMutableArray alloc] init];
|
||||
uint32_t totalCount = proxy->ChildrenCount();
|
||||
for (uint32_t i = 0; i < totalCount; i++) {
|
||||
if (proxy->ChildAt(i)->IsTableRow()) {
|
||||
mozAccessible* curNative =
|
||||
GetNativeFromProxy(proxy->ChildAt(i));
|
||||
if (curNative)
|
||||
[nativeArray addObject:GetObjectOrRepresentedView(curNative)];
|
||||
}
|
||||
}
|
||||
return nativeArray;
|
||||
}
|
||||
}
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation mozTableRowAccessible
|
||||
- (NSArray*)additionalAccessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
|
||||
if ([self isLayoutTablePart]) {
|
||||
return additionalAttributes;
|
||||
}
|
||||
|
||||
static NSArray* tableRowAttrs = nil;
|
||||
if (!tableRowAttrs) {
|
||||
NSMutableArray* tempArray = [NSMutableArray new];
|
||||
[tempArray addObject:NSAccessibilityIndexAttribute];
|
||||
tableRowAttrs = [[NSArray alloc] initWithArray:tempArray];
|
||||
[tempArray release];
|
||||
}
|
||||
|
||||
return [additionalAttributes arrayByAddingObjectsFromArray:tableRowAttrs];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
if ([attribute isEqualToString:NSAccessibilityIndexAttribute]) {
|
||||
// Count the number of rows before that one to obtain the row index.
|
||||
uint32_t index = 0;
|
||||
Accessible* parent = accWrap->Parent();
|
||||
if (parent) {
|
||||
for (int32_t i = accWrap->IndexInParent() - 1; i >= 0; i--) {
|
||||
if (parent->GetChildAt(i)->IsTableRow()) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return [NSNumber numberWithUnsignedInteger:index];
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
if ([attribute isEqualToString:NSAccessibilityIndexAttribute]) {
|
||||
// Count the number of rows before that one to obtain the row index.
|
||||
uint32_t index = 0;
|
||||
ProxyAccessible* parent = proxy->Parent();
|
||||
if (parent) {
|
||||
for (int32_t i = proxy->IndexInParent() - 1; i >= 0; i--) {
|
||||
if (parent->ChildAt(i)->IsTableRow()) {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return [NSNumber numberWithUnsignedInteger:index];
|
||||
}
|
||||
}
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation mozTableCellAccessible
|
||||
- (NSArray*)additionalAccessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
NSArray* additionalAttributes = [super additionalAccessibilityAttributeNames];
|
||||
if ([self isLayoutTablePart]) {
|
||||
return additionalAttributes;
|
||||
}
|
||||
|
||||
static NSArray* tableCellAttrs = nil;
|
||||
if (!tableCellAttrs) {
|
||||
NSMutableArray* tempArray = [NSMutableArray new];
|
||||
[tempArray addObject:NSAccessibilityRowIndexRangeAttribute];
|
||||
[tempArray addObject:NSAccessibilityColumnIndexRangeAttribute];
|
||||
[tempArray addObject:NSAccessibilityRowHeaderUIElementsAttribute];
|
||||
[tempArray addObject:NSAccessibilityColumnHeaderUIElementsAttribute];
|
||||
tableCellAttrs = [[NSArray alloc] initWithArray:tempArray];
|
||||
[tempArray release];
|
||||
}
|
||||
|
||||
return [additionalAttributes arrayByAddingObjectsFromArray:tableCellAttrs];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
TableCellAccessible* cell = accWrap->AsTableCell();
|
||||
if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
|
||||
return [NSValue valueWithRange:NSMakeRange(cell->RowIdx(),
|
||||
cell->RowExtent())];
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
|
||||
return [NSValue valueWithRange:NSMakeRange(cell->ColIdx(),
|
||||
cell->ColExtent())];
|
||||
if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
|
||||
AutoTArray<Accessible*, 10> headerCells;
|
||||
cell->RowHeaderCells(&headerCells);
|
||||
return ConvertToNSArray(headerCells);
|
||||
}
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
|
||||
AutoTArray<Accessible*, 10> headerCells;
|
||||
cell->ColHeaderCells(&headerCells);
|
||||
return ConvertToNSArray(headerCells);
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
if ([attribute isEqualToString:NSAccessibilityRowIndexRangeAttribute])
|
||||
return [NSValue valueWithRange:NSMakeRange(proxy->RowIdx(),
|
||||
proxy->RowExtent())];
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnIndexRangeAttribute])
|
||||
return [NSValue valueWithRange:NSMakeRange(proxy->ColIdx(),
|
||||
proxy->ColExtent())];
|
||||
if ([attribute isEqualToString:NSAccessibilityRowHeaderUIElementsAttribute]) {
|
||||
nsTArray<ProxyAccessible*> headerCells;
|
||||
proxy->RowHeaderCells(&headerCells);
|
||||
return ConvertToNSArray(headerCells);
|
||||
}
|
||||
if ([attribute isEqualToString:NSAccessibilityColumnHeaderUIElementsAttribute]) {
|
||||
nsTArray<ProxyAccessible*> headerCells;
|
||||
proxy->ColHeaderCells(&headerCells);
|
||||
return ConvertToNSArray(headerCells);
|
||||
}
|
||||
}
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
@end
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
#import "mozAccessible.h"
|
||||
|
||||
#import "HyperTextAccessible.h"
|
||||
|
||||
@interface mozTextAccessible : mozAccessible
|
||||
{
|
||||
}
|
||||
@end
|
||||
|
||||
@interface mozTextLeafAccessible : mozAccessible
|
||||
{
|
||||
}
|
||||
@end
|
||||
|
|
@ -1,627 +0,0 @@
|
|||
/* -*- Mode: Objective-C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "Accessible-inl.h"
|
||||
#include "HyperTextAccessible-inl.h"
|
||||
#include "TextLeafAccessible.h"
|
||||
|
||||
#include "nsCocoaUtils.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
#import "mozTextAccessible.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
inline bool
|
||||
ToNSRange(id aValue, NSRange* aRange)
|
||||
{
|
||||
NS_PRECONDITION(aRange, "aRange is nil");
|
||||
|
||||
if ([aValue isKindOfClass:[NSValue class]] &&
|
||||
strcmp([(NSValue*)aValue objCType], @encode(NSRange)) == 0) {
|
||||
*aRange = [aValue rangeValue];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline NSString*
|
||||
ToNSString(id aValue)
|
||||
{
|
||||
if ([aValue isKindOfClass:[NSString class]]) {
|
||||
return aValue;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
@interface mozTextAccessible ()
|
||||
- (NSString*)subrole;
|
||||
- (NSString*)selectedText;
|
||||
- (NSValue*)selectedTextRange;
|
||||
- (NSValue*)visibleCharacterRange;
|
||||
- (long)textLength;
|
||||
- (BOOL)isReadOnly;
|
||||
- (NSNumber*)caretLineNumber;
|
||||
- (void)setText:(NSString*)newText;
|
||||
- (NSString*)text;
|
||||
- (NSString*)stringFromRange:(NSRange*)range;
|
||||
@end
|
||||
|
||||
@implementation mozTextAccessible
|
||||
|
||||
- (BOOL)accessibilityIsIgnored
|
||||
{
|
||||
return ![self getGeckoAccessible] && ![self getProxyAccessible];
|
||||
}
|
||||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
static NSMutableArray* supportedAttributes = nil;
|
||||
if (!supportedAttributes) {
|
||||
// text-specific attributes to supplement the standard one
|
||||
supportedAttributes = [[NSMutableArray alloc] initWithObjects:
|
||||
NSAccessibilitySelectedTextAttribute, // required
|
||||
NSAccessibilitySelectedTextRangeAttribute, // required
|
||||
NSAccessibilityNumberOfCharactersAttribute, // required
|
||||
NSAccessibilityVisibleCharacterRangeAttribute, // required
|
||||
NSAccessibilityInsertionPointLineNumberAttribute,
|
||||
@"AXRequired",
|
||||
@"AXInvalid",
|
||||
nil
|
||||
];
|
||||
[supportedAttributes addObjectsFromArray:[super accessibilityAttributeNames]];
|
||||
}
|
||||
return supportedAttributes;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityNumberOfCharactersAttribute])
|
||||
return [NSNumber numberWithInt:[self textLength]];
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityInsertionPointLineNumberAttribute])
|
||||
return [self caretLineNumber];
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute])
|
||||
return [self selectedTextRange];
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute])
|
||||
return [self selectedText];
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
|
||||
return @"";
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
|
||||
// Apple's SpeechSynthesisServer expects AXValue to return an AXStaticText
|
||||
// object's AXSelectedText attribute. See bug 674612 for details.
|
||||
// Also if there is no selected text, we return the full text.
|
||||
// See bug 369710 for details.
|
||||
if ([[self role] isEqualToString:NSAccessibilityStaticTextRole]) {
|
||||
NSString* selectedText = [self selectedText];
|
||||
return (selectedText && [selectedText length]) ? selectedText : [self text];
|
||||
}
|
||||
|
||||
return [self text];
|
||||
}
|
||||
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
if ([attribute isEqualToString:@"AXRequired"]) {
|
||||
return [NSNumber numberWithBool:!!(accWrap->State() & states::REQUIRED)];
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:@"AXInvalid"]) {
|
||||
return [NSNumber numberWithBool:!!(accWrap->State() & states::INVALID)];
|
||||
}
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
if ([attribute isEqualToString:@"AXRequired"]) {
|
||||
return [NSNumber numberWithBool:!!(proxy->State() & states::REQUIRED)];
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:@"AXInvalid"]) {
|
||||
return [NSNumber numberWithBool:!!(proxy->State() & states::INVALID)];
|
||||
}
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute])
|
||||
return [self visibleCharacterRange];
|
||||
|
||||
// let mozAccessible handle all other attributes
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSArray*)accessibilityParameterizedAttributeNames
|
||||
{
|
||||
static NSArray* supportedParametrizedAttributes = nil;
|
||||
// text specific parametrized attributes
|
||||
if (!supportedParametrizedAttributes) {
|
||||
supportedParametrizedAttributes = [[NSArray alloc] initWithObjects:
|
||||
NSAccessibilityStringForRangeParameterizedAttribute,
|
||||
NSAccessibilityLineForIndexParameterizedAttribute,
|
||||
NSAccessibilityRangeForLineParameterizedAttribute,
|
||||
NSAccessibilityAttributedStringForRangeParameterizedAttribute,
|
||||
NSAccessibilityBoundsForRangeParameterizedAttribute,
|
||||
#if DEBUG
|
||||
NSAccessibilityRangeForPositionParameterizedAttribute,
|
||||
NSAccessibilityRangeForIndexParameterizedAttribute,
|
||||
NSAccessibilityRTFForRangeParameterizedAttribute,
|
||||
NSAccessibilityStyleRangeForIndexParameterizedAttribute,
|
||||
#endif
|
||||
nil
|
||||
];
|
||||
}
|
||||
return supportedParametrizedAttributes;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute forParameter:(id)parameter
|
||||
{
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return nil;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityStringForRangeParameterizedAttribute]) {
|
||||
NSRange range;
|
||||
if (!ToNSRange(parameter, &range)) {
|
||||
#if DEBUG
|
||||
NSLog(@"%@: range not set", attribute);
|
||||
#endif
|
||||
return @"";
|
||||
}
|
||||
|
||||
return [self stringFromRange:&range];
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityRangeForLineParameterizedAttribute]) {
|
||||
// XXX: actually get the integer value for the line #
|
||||
return [NSValue valueWithRange:NSMakeRange(0, [self textLength])];
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityAttributedStringForRangeParameterizedAttribute]) {
|
||||
NSRange range;
|
||||
if (!ToNSRange(parameter, &range)) {
|
||||
#if DEBUG
|
||||
NSLog(@"%@: range not set", attribute);
|
||||
#endif
|
||||
return @"";
|
||||
}
|
||||
|
||||
return [[[NSAttributedString alloc] initWithString:[self stringFromRange:&range]] autorelease];
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityLineForIndexParameterizedAttribute]) {
|
||||
// XXX: actually return the line #
|
||||
return [NSNumber numberWithInt:0];
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityBoundsForRangeParameterizedAttribute]) {
|
||||
NSRange range;
|
||||
if (!ToNSRange(parameter, &range)) {
|
||||
#if DEBUG
|
||||
NSLog(@"%@:no range", attribute);
|
||||
#endif
|
||||
return nil;
|
||||
}
|
||||
|
||||
int32_t start = range.location;
|
||||
int32_t end = start + range.length;
|
||||
DesktopIntRect bounds;
|
||||
if (textAcc) {
|
||||
bounds =
|
||||
DesktopIntRect::FromUnknownRect(textAcc->TextBounds(start, end));
|
||||
} else if (proxy) {
|
||||
bounds =
|
||||
DesktopIntRect::FromUnknownRect(proxy->TextBounds(start, end));
|
||||
}
|
||||
|
||||
return [NSValue valueWithRect:nsCocoaUtils::GeckoRectToCocoaRect(bounds)];
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
NSLog(@"unhandled attribute:%@ forParameter:%@", attribute, parameter);
|
||||
#endif
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)accessibilityIsAttributeSettable:(NSString*)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
|
||||
return ![self isReadOnly];
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute] ||
|
||||
[attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute] ||
|
||||
[attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute])
|
||||
return YES;
|
||||
|
||||
return [super accessibilityIsAttributeSettable:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
|
||||
}
|
||||
|
||||
- (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return;
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
|
||||
[self setText:ToNSString(value)];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilitySelectedTextAttribute]) {
|
||||
NSString* stringValue = ToNSString(value);
|
||||
if (!stringValue)
|
||||
return;
|
||||
|
||||
int32_t start = 0, end = 0;
|
||||
nsString text;
|
||||
if (textAcc) {
|
||||
textAcc->SelectionBoundsAt(0, &start, &end);
|
||||
textAcc->DeleteText(start, end - start);
|
||||
nsCocoaUtils::GetStringForNSString(stringValue, text);
|
||||
textAcc->InsertText(text, start);
|
||||
} else if (proxy) {
|
||||
nsString data;
|
||||
proxy->SelectionBoundsAt(0, data, &start, &end);
|
||||
proxy->DeleteText(start, end - start);
|
||||
nsCocoaUtils::GetStringForNSString(stringValue, text);
|
||||
proxy->InsertText(text, start);
|
||||
}
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilitySelectedTextRangeAttribute]) {
|
||||
NSRange range;
|
||||
if (!ToNSRange(value, &range))
|
||||
return;
|
||||
|
||||
if (textAcc) {
|
||||
textAcc->SetSelectionBoundsAt(0, range.location,
|
||||
range.location + range.length);
|
||||
} else if (proxy) {
|
||||
proxy->SetSelectionBoundsAt(0, range.location,
|
||||
range.location + range.length);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityVisibleCharacterRangeAttribute]) {
|
||||
NSRange range;
|
||||
if (!ToNSRange(value, &range))
|
||||
return;
|
||||
|
||||
if (textAcc) {
|
||||
textAcc->ScrollSubstringTo(range.location, range.location + range.length,
|
||||
nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE);
|
||||
} else if (proxy) {
|
||||
proxy->ScrollSubstringTo(range.location, range.location + range.length,
|
||||
nsIAccessibleScrollType::SCROLL_TYPE_TOP_EDGE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
[super accessibilitySetValue:value forAttribute:attribute];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (NSString*)subrole
|
||||
{
|
||||
if(mRole == roles::PASSWORD_TEXT)
|
||||
return NSAccessibilitySecureTextFieldSubrole;
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (BOOL)isReadOnly
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
if ([[self role] isEqualToString:NSAccessibilityStaticTextRole])
|
||||
return YES;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (textAcc)
|
||||
return (accWrap->State() & states::READONLY) == 0;
|
||||
|
||||
if (ProxyAccessible* proxy = [self getProxyAccessible])
|
||||
return (proxy->State() & states::READONLY) == 0;
|
||||
|
||||
return NO;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
|
||||
}
|
||||
|
||||
- (NSNumber*)caretLineNumber
|
||||
{
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
|
||||
int32_t lineNumber = -1;
|
||||
if (textAcc) {
|
||||
lineNumber = textAcc->CaretLineNumber() - 1;
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
lineNumber = proxy->CaretLineNumber() - 1;
|
||||
}
|
||||
|
||||
return (lineNumber >= 0) ? [NSNumber numberWithInt:lineNumber] : nil;
|
||||
}
|
||||
|
||||
- (void)setText:(NSString*)aNewString
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
|
||||
nsString text;
|
||||
nsCocoaUtils::GetStringForNSString(aNewString, text);
|
||||
if (textAcc) {
|
||||
textAcc->ReplaceText(text);
|
||||
} else if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
proxy->ReplaceText(text);
|
||||
}
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (NSString*)text
|
||||
{
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return nil;
|
||||
|
||||
// A password text field returns an empty value
|
||||
if (mRole == roles::PASSWORD_TEXT)
|
||||
return @"";
|
||||
|
||||
nsAutoString text;
|
||||
if (textAcc) {
|
||||
textAcc->TextSubstring(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT, text);
|
||||
} else if (proxy) {
|
||||
proxy->TextSubstring(0, nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT, text);
|
||||
}
|
||||
|
||||
return nsCocoaUtils::ToNSString(text);
|
||||
}
|
||||
|
||||
- (long)textLength
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return 0;
|
||||
|
||||
return textAcc ? textAcc->CharacterCount() : proxy->CharacterCount();
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
|
||||
}
|
||||
|
||||
- (long)selectedTextLength
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return 0;
|
||||
|
||||
int32_t start = 0, end = 0;
|
||||
if (textAcc) {
|
||||
textAcc->SelectionBoundsAt(0, &start, &end);
|
||||
} else if (proxy) {
|
||||
nsString data;
|
||||
proxy->SelectionBoundsAt(0, data, &start, &end);
|
||||
}
|
||||
return (end - start);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
|
||||
}
|
||||
|
||||
- (NSString*)selectedText
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return nil;
|
||||
|
||||
int32_t start = 0, end = 0;
|
||||
nsAutoString selText;
|
||||
if (textAcc) {
|
||||
textAcc->SelectionBoundsAt(0, &start, &end);
|
||||
if (start != end) {
|
||||
textAcc->TextSubstring(start, end, selText);
|
||||
}
|
||||
} else if (proxy) {
|
||||
proxy->SelectionBoundsAt(0, selText, &start, &end);
|
||||
}
|
||||
|
||||
return nsCocoaUtils::ToNSString(selText);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSValue*)selectedTextRange
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
|
||||
int32_t start = 0;
|
||||
int32_t end = 0;
|
||||
int32_t count = 0;
|
||||
if (textAcc) {
|
||||
count = textAcc->SelectionCount();
|
||||
if (count) {
|
||||
textAcc->SelectionBoundsAt(0, &start, &end);
|
||||
return [NSValue valueWithRange:NSMakeRange(start, end - start)];
|
||||
}
|
||||
|
||||
start = textAcc->CaretOffset();
|
||||
return [NSValue valueWithRange:NSMakeRange(start != -1 ? start : 0, 0)];
|
||||
}
|
||||
|
||||
if (proxy) {
|
||||
count = proxy->SelectionCount();
|
||||
if (count) {
|
||||
nsString data;
|
||||
proxy->SelectionBoundsAt(0, data, &start, &end);
|
||||
return [NSValue valueWithRange:NSMakeRange(start, end - start)];
|
||||
}
|
||||
|
||||
start = proxy->CaretOffset();
|
||||
return [NSValue valueWithRange:NSMakeRange(start != -1 ? start : 0, 0)];
|
||||
}
|
||||
|
||||
return [NSValue valueWithRange:NSMakeRange(0, 0)];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||
}
|
||||
|
||||
- (NSValue*)visibleCharacterRange
|
||||
{
|
||||
// XXX this won't work with Textarea and such as we actually don't give
|
||||
// the visible character range.
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return 0;
|
||||
|
||||
return [NSValue valueWithRange:
|
||||
NSMakeRange(0, textAcc ?
|
||||
textAcc->CharacterCount() : proxy->CharacterCount())];
|
||||
}
|
||||
|
||||
- (void)valueDidChange
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
|
||||
NSAccessibilityValueChangedNotification);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
||||
- (void)selectedTextDidChange
|
||||
{
|
||||
NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
|
||||
NSAccessibilitySelectedTextChangedNotification);
|
||||
}
|
||||
|
||||
- (NSString*)stringFromRange:(NSRange*)range
|
||||
{
|
||||
NS_PRECONDITION(range, "no range");
|
||||
|
||||
AccessibleWrap* accWrap = [self getGeckoAccessible];
|
||||
ProxyAccessible* proxy = [self getProxyAccessible];
|
||||
HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
|
||||
if (!textAcc && !proxy)
|
||||
return nil;
|
||||
|
||||
nsAutoString text;
|
||||
if (textAcc) {
|
||||
textAcc->TextSubstring(range->location,
|
||||
range->location + range->length, text);
|
||||
} else if (proxy) {
|
||||
proxy->TextSubstring(range->location,
|
||||
range->location + range->length, text);
|
||||
}
|
||||
|
||||
return nsCocoaUtils::ToNSString(text);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation mozTextLeafAccessible
|
||||
|
||||
- (NSArray*)accessibilityAttributeNames
|
||||
{
|
||||
static NSMutableArray* supportedAttributes = nil;
|
||||
if (!supportedAttributes) {
|
||||
supportedAttributes = [[super accessibilityAttributeNames] mutableCopy];
|
||||
[supportedAttributes removeObject:NSAccessibilityChildrenAttribute];
|
||||
}
|
||||
|
||||
return supportedAttributes;
|
||||
}
|
||||
|
||||
- (id)accessibilityAttributeValue:(NSString*)attribute
|
||||
{
|
||||
if ([attribute isEqualToString:NSAccessibilityTitleAttribute])
|
||||
return @"";
|
||||
|
||||
if ([attribute isEqualToString:NSAccessibilityValueAttribute])
|
||||
return [self text];
|
||||
|
||||
return [super accessibilityAttributeValue:attribute];
|
||||
}
|
||||
|
||||
- (NSString*)text
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
return nsCocoaUtils::ToNSString(accWrap->AsTextLeaf()->Text());
|
||||
}
|
||||
|
||||
if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
nsString text;
|
||||
proxy->Text(&text);
|
||||
return nsCocoaUtils::ToNSString(text);
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (long)textLength
|
||||
{
|
||||
if (AccessibleWrap* accWrap = [self getGeckoAccessible]) {
|
||||
return accWrap->AsTextLeaf()->Text().Length();
|
||||
}
|
||||
|
||||
if (ProxyAccessible* proxy = [self getProxyAccessible]) {
|
||||
nsString text;
|
||||
proxy->Text(&text);
|
||||
return text.Length();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
@ -9,8 +9,6 @@ if 'gtk' in toolkit:
|
|||
DIRS += ['atk']
|
||||
elif toolkit == 'windows':
|
||||
DIRS += ['windows']
|
||||
elif toolkit == 'cocoa':
|
||||
DIRS += ['mac']
|
||||
else:
|
||||
DIRS += ['other']
|
||||
|
||||
|
|
|
|||
|
|
@ -42,10 +42,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
LOCAL_INCLUDES += [
|
||||
'/accessible/windows/msaa',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
|
|
@ -37,10 +37,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
'/accessible/windows/ia2',
|
||||
'/accessible/windows/msaa',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/mac',
|
||||
]
|
||||
else:
|
||||
LOCAL_INCLUDES += [
|
||||
'/accessible/other',
|
||||
|
|
|
|||
|
|
@ -16,9 +16,6 @@ SOURCES += [
|
|||
'nsXULStub.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
FINAL_TARGET = 'dist/XUL.framework/Versions/%(MOZILLA_VERSION)s' % CONFIG
|
||||
|
||||
DEFINES['XPCOM_GLUE'] = True
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
|
|
@ -44,7 +41,3 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
|||
]
|
||||
|
||||
DISABLE_STL_WRAPPING = True
|
||||
|
||||
# Need to link with CoreFoundation on Mac
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
OS_LIBS += CONFIG['TK_LIBS']
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@ flavors = {
|
|||
'WINNT': 'win',
|
||||
'Android': 'android',
|
||||
'Linux': 'linux',
|
||||
'Darwin': 'mac' if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa' else 'ios',
|
||||
'SunOS': 'solaris',
|
||||
'GNU/kFreeBSD': 'freebsd',
|
||||
'DragonFly': 'dragonfly',
|
||||
|
|
|
|||
|
|
@ -10,4 +10,4 @@
|
|||
# hardcoded milestones in the tree from these two files.
|
||||
#--------------------------------------------------------
|
||||
|
||||
4.8.0
|
||||
4.8.2
|
||||
|
|
|
|||
|
|
@ -45,10 +45,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
DEFINES['SQLITE_WIN32_GETVERSIONEX'] = 0
|
||||
DEFINES['SQLITE_ALLOW_URI_AUTHORITY'] = 1
|
||||
|
||||
# -DSQLITE_ENABLE_LOCKING_STYLE=1 to help with AFP folders
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
DEFINES['SQLITE_ENABLE_LOCKING_STYLE'] = 1
|
||||
|
||||
# sqlite defaults this to on on __APPLE_ but it breaks on newer iOS SDKs
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'uikit':
|
||||
DEFINES['SQLITE_ENABLE_LOCKING_STYLE'] = 0
|
||||
|
|
|
|||
|
|
@ -1,304 +1,376 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/ResizeObserver.h"
|
||||
|
||||
#include "mozilla/dom/DOMRect.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ResizeObserver)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ResizeObserver)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ResizeObserver)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(ResizeObserver)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ResizeObserver)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ResizeObserver)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mObservationMap)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ResizeObserver)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObservationMap)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
already_AddRefed<ResizeObserver>
|
||||
ResizeObserver::Constructor(const GlobalObject& aGlobal,
|
||||
ResizeObserverCallback& aCb,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindowInner> window =
|
||||
do_QueryInterface(aGlobal.GetAsSupports());
|
||||
|
||||
if (!window) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> document = window->GetExtantDoc();
|
||||
|
||||
if (!document) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ResizeObserver> observer = new ResizeObserver(window.forget(), aCb);
|
||||
document->AddResizeObserver(observer);
|
||||
|
||||
return observer.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ResizeObserver::Observe(Element* aTarget,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!aTarget) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<ResizeObservation> observation;
|
||||
|
||||
if (!mObservationMap.Get(aTarget, getter_AddRefs(observation))) {
|
||||
observation = new ResizeObservation(this, aTarget);
|
||||
|
||||
mObservationMap.Put(aTarget, observation);
|
||||
mObservationList.insertBack(observation);
|
||||
|
||||
// Per the spec, we need to trigger notification in event loop that
|
||||
// contains ResizeObserver observe call even when resize/reflow does
|
||||
// not happen.
|
||||
aTarget->OwnerDoc()->ScheduleResizeObserversNotification();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ResizeObserver::Unobserve(Element* aTarget,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!aTarget) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<ResizeObservation> observation;
|
||||
|
||||
if (mObservationMap.Get(aTarget, getter_AddRefs(observation))) {
|
||||
mObservationMap.Remove(aTarget);
|
||||
|
||||
MOZ_ASSERT(!mObservationList.isEmpty(),
|
||||
"If ResizeObservation found for an element, observation list "
|
||||
"must be not empty.");
|
||||
|
||||
observation->remove();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ResizeObserver::Disconnect()
|
||||
{
|
||||
mObservationMap.Clear();
|
||||
mObservationList.clear();
|
||||
mActiveTargets.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
ResizeObserver::GatherActiveObservations(uint32_t aDepth)
|
||||
{
|
||||
mActiveTargets.Clear();
|
||||
mHasSkippedTargets = false;
|
||||
|
||||
for (auto observation : mObservationList) {
|
||||
if (observation->IsActive()) {
|
||||
uint32_t targetDepth =
|
||||
nsContentUtils::GetNodeDepth(observation->Target());
|
||||
|
||||
if (targetDepth > aDepth) {
|
||||
mActiveTargets.AppendElement(observation);
|
||||
} else {
|
||||
mHasSkippedTargets = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ResizeObserver::HasActiveObservations() const
|
||||
{
|
||||
return !mActiveTargets.IsEmpty();
|
||||
}
|
||||
|
||||
bool
|
||||
ResizeObserver::HasSkippedObservations() const
|
||||
{
|
||||
return mHasSkippedTargets;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ResizeObserver::BroadcastActiveObservations()
|
||||
{
|
||||
uint32_t shallowestTargetDepth = UINT32_MAX;
|
||||
|
||||
if (HasActiveObservations()) {
|
||||
Sequence<OwningNonNull<ResizeObserverEntry>> entries;
|
||||
|
||||
for (auto observation : mActiveTargets) {
|
||||
RefPtr<ResizeObserverEntry> entry =
|
||||
new ResizeObserverEntry(this, observation->Target());
|
||||
|
||||
nsRect rect = observation->GetTargetRect();
|
||||
entry->SetContentRect(rect);
|
||||
|
||||
if (!entries.AppendElement(entry.forget(), fallible)) {
|
||||
// Out of memory.
|
||||
break;
|
||||
}
|
||||
|
||||
// Sync the broadcast size of observation so the next size inspection
|
||||
// will be based on the updated size from last delivered observations.
|
||||
observation->UpdateBroadcastSize(rect);
|
||||
|
||||
uint32_t targetDepth =
|
||||
nsContentUtils::GetNodeDepth(observation->Target());
|
||||
|
||||
if (targetDepth < shallowestTargetDepth) {
|
||||
shallowestTargetDepth = targetDepth;
|
||||
}
|
||||
}
|
||||
|
||||
mCallback->Call(this, entries, *this);
|
||||
mActiveTargets.Clear();
|
||||
mHasSkippedTargets = false;
|
||||
}
|
||||
|
||||
return shallowestTargetDepth;
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ResizeObserverEntry)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ResizeObserverEntry)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ResizeObserverEntry)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ResizeObserverEntry,
|
||||
mTarget, mContentRect,
|
||||
mOwner)
|
||||
|
||||
already_AddRefed<ResizeObserverEntry>
|
||||
ResizeObserverEntry::Constructor(const GlobalObject& aGlobal,
|
||||
Element* aTarget,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<ResizeObserverEntry> observerEntry =
|
||||
new ResizeObserverEntry(aGlobal.GetAsSupports(), aTarget);
|
||||
return observerEntry.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ResizeObserverEntry::SetContentRect(nsRect aRect)
|
||||
{
|
||||
RefPtr<DOMRect> contentRect = new DOMRect(mTarget);
|
||||
nsIFrame* frame = mTarget->GetPrimaryFrame();
|
||||
|
||||
if (frame) {
|
||||
nsMargin padding = frame->GetUsedPadding();
|
||||
|
||||
// Per the spec, we need to include padding in contentRect of
|
||||
// ResizeObserverEntry.
|
||||
aRect.x = padding.left;
|
||||
aRect.y = padding.top;
|
||||
}
|
||||
|
||||
contentRect->SetLayoutRect(aRect);
|
||||
mContentRect = contentRect.forget();
|
||||
}
|
||||
|
||||
ResizeObserverEntry::~ResizeObserverEntry()
|
||||
{
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ResizeObservation)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ResizeObservation)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ResizeObservation)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ResizeObservation,
|
||||
mTarget, mOwner)
|
||||
|
||||
already_AddRefed<ResizeObservation>
|
||||
ResizeObservation::Constructor(const GlobalObject& aGlobal,
|
||||
Element* aTarget,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<ResizeObservation> observation =
|
||||
new ResizeObservation(aGlobal.GetAsSupports(), aTarget);
|
||||
return observation.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
ResizeObservation::IsActive() const
|
||||
{
|
||||
nsRect rect = GetTargetRect();
|
||||
return (rect.width != mBroadcastWidth || rect.height != mBroadcastHeight);
|
||||
}
|
||||
|
||||
void
|
||||
ResizeObservation::UpdateBroadcastSize(nsRect aRect)
|
||||
{
|
||||
mBroadcastWidth = aRect.width;
|
||||
mBroadcastHeight = aRect.height;
|
||||
}
|
||||
|
||||
nsRect
|
||||
ResizeObservation::GetTargetRect() const
|
||||
{
|
||||
nsRect rect;
|
||||
nsIFrame* frame = mTarget->GetPrimaryFrame();
|
||||
|
||||
if (frame) {
|
||||
if (mTarget->IsSVGElement()) {
|
||||
gfxRect bbox = nsSVGUtils::GetBBox(frame);
|
||||
rect.width = NSFloatPixelsToAppUnits(bbox.width, AppUnitsPerCSSPixel());
|
||||
rect.height = NSFloatPixelsToAppUnits(bbox.height, AppUnitsPerCSSPixel());
|
||||
} else {
|
||||
// Per the spec, non-replaced inline Elements will always have an empty
|
||||
// content rect.
|
||||
if (frame->IsFrameOfType(nsIFrame::eReplaced) ||
|
||||
!frame->IsFrameOfType(nsIFrame::eLineParticipant)) {
|
||||
rect = frame->GetContentRectRelativeToSelf();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
ResizeObservation::~ResizeObservation()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/ResizeObserver.h"
|
||||
|
||||
#include "mozilla/dom/DOMRect.h"
|
||||
#include "nsIContentInlines.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsSVGUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/**
|
||||
* Returns the length of the parent-traversal path (in terms of the number of
|
||||
* nodes) to an unparented/root node from aNode. An unparented/root node is
|
||||
* considered to have a depth of 1, its children have a depth of 2, etc.
|
||||
* aNode is expected to be non-null.
|
||||
* Note: The shadow root is not part of the calculation because the caller,
|
||||
* ResizeObserver, doesn't observe the shadow root, and only needs relative
|
||||
* depths among all the observed targets. In other words, we calculate the
|
||||
* depth of the flattened tree.
|
||||
*
|
||||
* Note: these is a spec issue about how to handle shadow DOM case. We
|
||||
* may need to update this function later.
|
||||
*
|
||||
*
|
||||
* https://drafts.csswg.org/resize-observer/#calculate-depth-for-node-h
|
||||
*/
|
||||
static uint32_t
|
||||
GetNodeDepth(nsINode* aNode) {
|
||||
uint32_t depth = 1;
|
||||
|
||||
MOZ_ASSERT(aNode, "Node shouldn't be null");
|
||||
|
||||
// Use GetFlattenedTreeParentNode to bypass the shadow root and cross the
|
||||
// shadow boundary to calculate the node depth without the shadow root.
|
||||
while ((aNode = aNode->GetFlattenedTreeParentNode())) {
|
||||
++depth;
|
||||
}
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns |aTarget|'s size in the form of an nsSize.
|
||||
* If the target is an SVG, width and height are determined from the bounding box.
|
||||
*/
|
||||
static nsSize
|
||||
GetTargetSize(Element* aTarget, ResizeObserverBoxOptions aBox) {
|
||||
nsSize size;
|
||||
nsIFrame* frame = aTarget->GetPrimaryFrame();
|
||||
|
||||
if (!frame) {
|
||||
return size;
|
||||
}
|
||||
|
||||
if (aTarget->IsSVGElement()) {
|
||||
// Per the spec, an SVG size is always its bounding box size, no matter what
|
||||
// box option you choose, because SVG elements do not use the standard CSS box
|
||||
// model.
|
||||
gfxRect bbox = nsSVGUtils::GetBBox(frame);
|
||||
size.width = NSFloatPixelsToAppUnits(bbox.width, AppUnitsPerCSSPixel());
|
||||
size.height = NSFloatPixelsToAppUnits(bbox.height, AppUnitsPerCSSPixel());
|
||||
} else {
|
||||
// Per the spec, non-replaced inline Elements will always have an empty
|
||||
// content rect. We therefore always use the same empty size for
|
||||
// non-replaced inline elements here, and their IsActive() will
|
||||
// always return false. (So its observation won't be fired.)
|
||||
if (!frame->IsFrameOfType(nsIFrame::eReplaced) &&
|
||||
frame->IsFrameOfType(nsIFrame::eLineParticipant)) {
|
||||
return size;
|
||||
}
|
||||
|
||||
switch (aBox) {
|
||||
case ResizeObserverBoxOptions::Border_box:
|
||||
// GetSize() includes the content area, borders, and padding.
|
||||
size = frame->GetSize();
|
||||
break;
|
||||
case ResizeObserverBoxOptions::Content_box:
|
||||
default:
|
||||
size = frame->GetContentRectRelativeToSelf().Size();
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ResizeObserver)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ResizeObserver)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ResizeObserver)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(ResizeObserver)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ResizeObserver)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ResizeObserver)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mObservationMap)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ResizeObserver)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mObservationMap)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
already_AddRefed<ResizeObserver>
|
||||
ResizeObserver::Constructor(const GlobalObject& aGlobal,
|
||||
ResizeObserverCallback& aCb,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindowInner> window =
|
||||
do_QueryInterface(aGlobal.GetAsSupports());
|
||||
|
||||
if (!window) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> document = window->GetExtantDoc();
|
||||
|
||||
if (!document) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<ResizeObserver> observer = new ResizeObserver(window.forget(), aCb);
|
||||
document->AddResizeObserver(observer);
|
||||
|
||||
return observer.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ResizeObserver::Observe(Element* aTarget,
|
||||
const ResizeObserverOptions& aOptions,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!aTarget) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<ResizeObservation> observation;
|
||||
|
||||
if (!mObservationMap.Get(aTarget, getter_AddRefs(observation))) {
|
||||
nsIFrame* frame = aTarget->GetPrimaryFrame();
|
||||
WritingMode wm = frame ? frame->GetWritingMode() : WritingMode();
|
||||
observation = new ResizeObservation(aTarget->OwnerDoc(), aTarget, aOptions.mBox, wm);
|
||||
|
||||
mObservationMap.Put(aTarget, observation);
|
||||
mObservationList.insertBack(observation);
|
||||
|
||||
// Per the spec, we need to trigger notification in event loop that
|
||||
// contains ResizeObserver observe call even when resize/reflow does
|
||||
// not happen.
|
||||
aTarget->OwnerDoc()->ScheduleResizeObserversNotification();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ResizeObserver::Unobserve(Element* aTarget,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!aTarget) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<ResizeObservation> observation;
|
||||
|
||||
if (mObservationMap.Get(aTarget, getter_AddRefs(observation))) {
|
||||
mObservationMap.Remove(aTarget);
|
||||
|
||||
MOZ_ASSERT(!mObservationList.isEmpty(),
|
||||
"If ResizeObservation found for an element, observation list "
|
||||
"must be not empty.");
|
||||
|
||||
observation->remove();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ResizeObserver::Disconnect()
|
||||
{
|
||||
mObservationMap.Clear();
|
||||
mObservationList.clear();
|
||||
mActiveTargets.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
ResizeObserver::GatherActiveObservations(uint32_t aDepth)
|
||||
{
|
||||
mActiveTargets.Clear();
|
||||
mHasSkippedTargets = false;
|
||||
|
||||
for (auto observation : mObservationList) {
|
||||
if (observation->IsActive()) {
|
||||
uint32_t targetDepth = GetNodeDepth(observation->Target());
|
||||
|
||||
if (targetDepth > aDepth) {
|
||||
mActiveTargets.AppendElement(observation);
|
||||
} else {
|
||||
mHasSkippedTargets = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ResizeObserver::HasActiveObservations() const
|
||||
{
|
||||
return !mActiveTargets.IsEmpty();
|
||||
}
|
||||
|
||||
bool
|
||||
ResizeObserver::HasSkippedObservations() const
|
||||
{
|
||||
return mHasSkippedTargets;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ResizeObserver::BroadcastActiveObservations()
|
||||
{
|
||||
uint32_t shallowestTargetDepth = UINT32_MAX;
|
||||
|
||||
if (HasActiveObservations()) {
|
||||
Sequence<OwningNonNull<ResizeObserverEntry>> entries;
|
||||
|
||||
for (auto observation : mActiveTargets) {
|
||||
Element* target = observation->Target();
|
||||
RefPtr<ResizeObserverEntry> entry = new ResizeObserverEntry(this, target);
|
||||
|
||||
nsSize borderBoxSize = GetTargetSize(target, ResizeObserverBoxOptions::Border_box);
|
||||
entry->SetBorderBoxSize(borderBoxSize);
|
||||
|
||||
nsSize contentBoxSize = GetTargetSize(target, ResizeObserverBoxOptions::Content_box);
|
||||
entry->SetContentRectAndSize(contentBoxSize);
|
||||
|
||||
if (!entries.AppendElement(entry.forget(), fallible)) {
|
||||
// Out of memory.
|
||||
break;
|
||||
}
|
||||
|
||||
// Sync the broadcast size of observation so the next size inspection
|
||||
// will be based on the updated size from last delivered observations.
|
||||
switch (observation->BoxOptions()) {
|
||||
case ResizeObserverBoxOptions::Border_box:
|
||||
observation->UpdateLastReportedSize(borderBoxSize);
|
||||
break;
|
||||
case ResizeObserverBoxOptions::Content_box:
|
||||
default:
|
||||
observation->UpdateLastReportedSize(contentBoxSize);
|
||||
}
|
||||
|
||||
uint32_t targetDepth = GetNodeDepth(observation->Target());
|
||||
|
||||
if (targetDepth < shallowestTargetDepth) {
|
||||
shallowestTargetDepth = targetDepth;
|
||||
}
|
||||
}
|
||||
|
||||
mCallback->Call(this, entries, *this);
|
||||
mActiveTargets.Clear();
|
||||
mHasSkippedTargets = false;
|
||||
}
|
||||
|
||||
return shallowestTargetDepth;
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ResizeObserverEntry)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ResizeObserverEntry)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ResizeObserverEntry)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ResizeObserverEntry,
|
||||
mOwner,
|
||||
mTarget,
|
||||
mContentRect,
|
||||
mBorderBoxSize,
|
||||
mContentBoxSize)
|
||||
|
||||
already_AddRefed<ResizeObserverEntry>
|
||||
ResizeObserverEntry::Constructor(const GlobalObject& aGlobal,
|
||||
Element* aTarget,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
RefPtr<ResizeObserverEntry> observerEntry =
|
||||
new ResizeObserverEntry(aGlobal.GetAsSupports(), aTarget);
|
||||
return observerEntry.forget();
|
||||
}
|
||||
|
||||
void
|
||||
ResizeObserverEntry::SetBorderBoxSize(const nsSize& aSize) {
|
||||
nsIFrame* frame = mTarget->GetPrimaryFrame();
|
||||
WritingMode wm = frame ? frame->GetWritingMode() : WritingMode();
|
||||
mBorderBoxSize = new ResizeObserverSize(this, aSize, wm);
|
||||
}
|
||||
|
||||
void
|
||||
ResizeObserverEntry::SetContentRectAndSize(const nsSize& aSize) {
|
||||
nsIFrame* frame = mTarget->GetPrimaryFrame();
|
||||
|
||||
// Update mContentRect.
|
||||
nsMargin padding = frame ? frame->GetUsedPadding(): nsMargin();
|
||||
// Per the spec, we need to use the top-left padding offset as the origin of
|
||||
// our contentRect.
|
||||
nsRect rect(nsPoint(padding.left, padding.top), aSize);
|
||||
RefPtr<DOMRect> contentRect = new DOMRect(mTarget);
|
||||
contentRect->SetLayoutRect(rect);
|
||||
mContentRect = contentRect.forget();
|
||||
|
||||
// Update mContentBoxSize.
|
||||
WritingMode wm = frame ? frame->GetWritingMode() : WritingMode();
|
||||
mContentBoxSize = new ResizeObserverSize(this, aSize, wm);
|
||||
}
|
||||
|
||||
ResizeObserverEntry::~ResizeObserverEntry()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ResizeObserverSize, mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ResizeObserverSize)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ResizeObserverSize)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ResizeObserverSize)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ResizeObservation)
|
||||
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(ResizeObservation)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(ResizeObservation)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ResizeObservation,
|
||||
mTarget, mOwner)
|
||||
|
||||
bool
|
||||
ResizeObservation::IsActive() const
|
||||
{
|
||||
nsIFrame* frame = mTarget->GetPrimaryFrame();
|
||||
WritingMode wm = frame ? frame->GetWritingMode() : WritingMode();
|
||||
LogicalSize size(wm, GetTargetSize(mTarget, mObservedBox));
|
||||
return mLastReportedSize.ISize(mLastReportedWM) != size.ISize(wm) ||
|
||||
mLastReportedSize.BSize(mLastReportedWM) != size.BSize(wm);
|
||||
}
|
||||
|
||||
void
|
||||
ResizeObservation::UpdateLastReportedSize(const nsSize& aSize) {
|
||||
nsIFrame* frame = mTarget->GetPrimaryFrame();
|
||||
mLastReportedWM = frame ? frame->GetWritingMode() : WritingMode();
|
||||
mLastReportedSize = LogicalSize(mLastReportedWM, aSize);
|
||||
}
|
||||
|
||||
ResizeObservation::~ResizeObservation()
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
|||
|
|
@ -1,254 +1,312 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_ResizeObserver_h
|
||||
#define mozilla_dom_ResizeObserver_h
|
||||
|
||||
#include "mozilla/dom/ResizeObserverBinding.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/**
|
||||
* ResizeObserver interfaces and algorithms are based on
|
||||
* https://wicg.github.io/ResizeObserver/#api
|
||||
*/
|
||||
class ResizeObserver final
|
||||
: public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ResizeObserver)
|
||||
|
||||
ResizeObserver(already_AddRefed<nsPIDOMWindowInner>&& aOwner,
|
||||
ResizeObserverCallback& aCb)
|
||||
: mOwner(aOwner)
|
||||
, mCallback(&aCb)
|
||||
{
|
||||
MOZ_ASSERT(mOwner, "Need a non-null owner window");
|
||||
}
|
||||
|
||||
static already_AddRefed<ResizeObserver>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
ResizeObserverCallback& aCb,
|
||||
ErrorResult& aRv);
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override
|
||||
{
|
||||
return ResizeObserverBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
void Observe(Element* aTarget, ErrorResult& aRv);
|
||||
|
||||
void Unobserve(Element* aTarget, ErrorResult& aRv);
|
||||
|
||||
void Disconnect();
|
||||
|
||||
/*
|
||||
* Gather all observations which have an observed target with size changed
|
||||
* since last BroadcastActiveObservations() in this ResizeObserver.
|
||||
* An observation will be skipped if the depth of its observed target is less
|
||||
* or equal than aDepth. All gathered observations will be added to
|
||||
* mActiveTargets.
|
||||
*/
|
||||
void GatherActiveObservations(uint32_t aDepth);
|
||||
|
||||
/*
|
||||
* Returns whether this ResizeObserver has any active observations
|
||||
* since last GatherActiveObservations().
|
||||
*/
|
||||
bool HasActiveObservations() const;
|
||||
|
||||
/*
|
||||
* Returns whether this ResizeObserver has any skipped observations
|
||||
* since last GatherActiveObservations().
|
||||
*/
|
||||
bool HasSkippedObservations() const;
|
||||
|
||||
/*
|
||||
* Deliver the callback function in JavaScript for all active observations
|
||||
* and pass the sequence of ResizeObserverEntry so JavaScript can access them.
|
||||
* The broadcast size of observations will be updated and mActiveTargets will
|
||||
* be cleared. It also returns the shallowest depth of elements from active
|
||||
* observations or UINT32_MAX if there is no any active observations.
|
||||
*/
|
||||
uint32_t BroadcastActiveObservations();
|
||||
|
||||
protected:
|
||||
~ResizeObserver()
|
||||
{
|
||||
mObservationList.clear();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> mOwner;
|
||||
RefPtr<ResizeObserverCallback> mCallback;
|
||||
nsTArray<RefPtr<ResizeObservation>> mActiveTargets;
|
||||
bool mHasSkippedTargets;
|
||||
|
||||
// Combination of HashTable and LinkedList so we can iterate through
|
||||
// the elements of HashTable in order of insertion time.
|
||||
// Will be nice if we have our own data structure for this in the future.
|
||||
nsRefPtrHashtable<nsPtrHashKey<Element>, ResizeObservation> mObservationMap;
|
||||
LinkedList<ResizeObservation> mObservationList;
|
||||
};
|
||||
|
||||
/**
|
||||
* ResizeObserverEntry is the entry that contains the information for observed
|
||||
* elements. This object is the one that visible to JavaScript in callback
|
||||
* function that is fired by ResizeObserver.
|
||||
*/
|
||||
class ResizeObserverEntry final
|
||||
: public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ResizeObserverEntry)
|
||||
|
||||
ResizeObserverEntry(nsISupports* aOwner, Element* aTarget)
|
||||
: mOwner(aOwner)
|
||||
, mTarget(aTarget)
|
||||
{
|
||||
MOZ_ASSERT(mOwner, "Need a non-null owner");
|
||||
MOZ_ASSERT(mTarget, "Need a non-null target element");
|
||||
}
|
||||
|
||||
static already_AddRefed<ResizeObserverEntry>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
Element* aTarget,
|
||||
ErrorResult& aRv);
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override
|
||||
{
|
||||
return ResizeObserverEntryBinding::Wrap(aCx, this,
|
||||
aGivenProto);
|
||||
}
|
||||
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
Element* Target() const
|
||||
{
|
||||
return mTarget;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the DOMRectReadOnly of target's content rect so it can be
|
||||
* accessed from JavaScript in callback function of ResizeObserver.
|
||||
*/
|
||||
DOMRectReadOnly* GetContentRect() const
|
||||
{
|
||||
return mContentRect;
|
||||
}
|
||||
|
||||
void SetContentRect(nsRect aRect);
|
||||
|
||||
protected:
|
||||
~ResizeObserverEntry();
|
||||
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsCOMPtr<Element> mTarget;
|
||||
RefPtr<DOMRectReadOnly> mContentRect;
|
||||
};
|
||||
|
||||
/**
|
||||
* We use ResizeObservation to store and sync the size information of one
|
||||
* observed element so we can decide whether an observation should be fired
|
||||
* or not.
|
||||
*/
|
||||
class ResizeObservation final
|
||||
: public nsISupports
|
||||
, public nsWrapperCache
|
||||
, public LinkedListElement<ResizeObservation>
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ResizeObservation)
|
||||
|
||||
ResizeObservation(nsISupports* aOwner, Element* aTarget)
|
||||
: mOwner(aOwner)
|
||||
, mTarget(aTarget)
|
||||
, mBroadcastWidth(0)
|
||||
, mBroadcastHeight(0)
|
||||
{
|
||||
MOZ_ASSERT(mOwner, "Need a non-null owner");
|
||||
MOZ_ASSERT(mTarget, "Need a non-null target element");
|
||||
}
|
||||
|
||||
static already_AddRefed<ResizeObservation>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
Element* aTarget,
|
||||
ErrorResult& aRv);
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override
|
||||
{
|
||||
return ResizeObservationBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
Element* Target() const
|
||||
{
|
||||
return mTarget;
|
||||
}
|
||||
|
||||
nscoord BroadcastWidth() const
|
||||
{
|
||||
return mBroadcastWidth;
|
||||
}
|
||||
|
||||
nscoord BroadcastHeight() const
|
||||
{
|
||||
return mBroadcastHeight;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns whether the observed target element size differs from current
|
||||
* BroadcastWidth and BroadcastHeight
|
||||
*/
|
||||
bool IsActive() const;
|
||||
|
||||
/*
|
||||
* Update current BroadcastWidth and BroadcastHeight with size from aRect.
|
||||
*/
|
||||
void UpdateBroadcastSize(nsRect aRect);
|
||||
|
||||
/*
|
||||
* Returns the target's rect in the form of nsRect.
|
||||
* If the target is SVG, width and height are determined from bounding box.
|
||||
*/
|
||||
nsRect GetTargetRect() const;
|
||||
|
||||
protected:
|
||||
~ResizeObservation();
|
||||
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsCOMPtr<Element> mTarget;
|
||||
|
||||
// Broadcast width and broadcast height are the latest recorded size
|
||||
// of observed target.
|
||||
nscoord mBroadcastWidth;
|
||||
nscoord mBroadcastHeight;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_ResizeObserver_h
|
||||
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_ResizeObserver_h
|
||||
#define mozilla_dom_ResizeObserver_h
|
||||
|
||||
#include "mozilla/AppUnits.h"
|
||||
#include "mozilla/WritingModes.h"
|
||||
#include "mozilla/dom/ResizeObserverBinding.h"
|
||||
#include "nsCoord.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
/**
|
||||
* ResizeObserver interfaces and algorithms are based on
|
||||
* https://wicg.github.io/ResizeObserver/#api
|
||||
*/
|
||||
class ResizeObserver final
|
||||
: public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ResizeObserver)
|
||||
|
||||
ResizeObserver(already_AddRefed<nsPIDOMWindowInner>&& aOwner,
|
||||
ResizeObserverCallback& aCb)
|
||||
: mOwner(aOwner)
|
||||
, mCallback(&aCb)
|
||||
{
|
||||
MOZ_ASSERT(mOwner, "Need a non-null owner window");
|
||||
}
|
||||
|
||||
static already_AddRefed<ResizeObserver>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
ResizeObserverCallback& aCb,
|
||||
ErrorResult& aRv);
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override
|
||||
{
|
||||
return ResizeObserverBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
void Observe(Element* aTarget, const ResizeObserverOptions& aOptions, ErrorResult& aRv);
|
||||
|
||||
void Unobserve(Element* aTarget, ErrorResult& aRv);
|
||||
|
||||
void Disconnect();
|
||||
|
||||
/*
|
||||
* Gather all observations which have an observed target with size changed
|
||||
* since last BroadcastActiveObservations() in this ResizeObserver.
|
||||
* An observation will be skipped if the depth of its observed target is less
|
||||
* or equal than aDepth. All gathered observations will be added to
|
||||
* mActiveTargets.
|
||||
*/
|
||||
void GatherActiveObservations(uint32_t aDepth);
|
||||
|
||||
/*
|
||||
* Returns whether this ResizeObserver has any active observations
|
||||
* since last GatherActiveObservations().
|
||||
*/
|
||||
bool HasActiveObservations() const;
|
||||
|
||||
/*
|
||||
* Returns whether this ResizeObserver has any skipped observations
|
||||
* since last GatherActiveObservations().
|
||||
*/
|
||||
bool HasSkippedObservations() const;
|
||||
|
||||
/*
|
||||
* Deliver the callback function in JavaScript for all active observations
|
||||
* and pass the sequence of ResizeObserverEntry so JavaScript can access them.
|
||||
* The active observations' mLastReportedSize fields will be updated, and
|
||||
* mActiveTargets will be cleared. It also returns the shallowest depth of
|
||||
* elements from active observations or numeric_limits<uint32_t>::max() if
|
||||
* there are not any active observations.
|
||||
*/
|
||||
uint32_t BroadcastActiveObservations();
|
||||
|
||||
protected:
|
||||
~ResizeObserver()
|
||||
{
|
||||
mObservationList.clear();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindowInner> mOwner;
|
||||
RefPtr<ResizeObserverCallback> mCallback;
|
||||
nsTArray<RefPtr<ResizeObservation>> mActiveTargets;
|
||||
// The spec uses a list to store the skipped targets. However, it seems what
|
||||
// we want is to check if there are any skipped targets (i.e. existence).
|
||||
// Therefore, we use a boolean value to represent the existence of skipped
|
||||
// targets.
|
||||
bool mHasSkippedTargets;
|
||||
|
||||
// Combination of HashTable and LinkedList so we can iterate through
|
||||
// the elements of HashTable in order of insertion time.
|
||||
// Will be nice if we have our own data structure for this in the future.
|
||||
nsRefPtrHashtable<nsPtrHashKey<Element>, ResizeObservation> mObservationMap;
|
||||
LinkedList<ResizeObservation> mObservationList;
|
||||
};
|
||||
|
||||
/**
|
||||
* ResizeObserverEntry is the entry that contains the information for observed
|
||||
* elements. This object is the one that visible to JavaScript in callback
|
||||
* function that is fired by ResizeObserver.
|
||||
*/
|
||||
class ResizeObserverEntry final
|
||||
: public nsISupports
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ResizeObserverEntry)
|
||||
|
||||
ResizeObserverEntry(nsISupports* aOwner, Element* aTarget)
|
||||
: mOwner(aOwner)
|
||||
, mTarget(aTarget)
|
||||
{
|
||||
MOZ_ASSERT(mOwner, "Need a non-null owner");
|
||||
MOZ_ASSERT(mTarget, "Need a non-null target element");
|
||||
}
|
||||
|
||||
static already_AddRefed<ResizeObserverEntry>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
Element* aTarget,
|
||||
ErrorResult& aRv);
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override
|
||||
{
|
||||
return ResizeObserverEntryBinding::Wrap(aCx, this,
|
||||
aGivenProto);
|
||||
}
|
||||
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
Element* Target() const
|
||||
{
|
||||
return mTarget;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the DOMRectReadOnly of target's content rect so it can be
|
||||
* accessed from JavaScript in callback function of ResizeObserver.
|
||||
*/
|
||||
DOMRectReadOnly* GetContentRect() const
|
||||
{
|
||||
return mContentRect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns target's logical border-box size and content-box size as
|
||||
* ResizeObserverSize.
|
||||
*/
|
||||
ResizeObserverSize* BorderBoxSize() const {
|
||||
return mBorderBoxSize;
|
||||
}
|
||||
ResizeObserverSize* ContentBoxSize() const {
|
||||
return mContentBoxSize;
|
||||
}
|
||||
|
||||
// Set borderBoxSize.
|
||||
void SetBorderBoxSize(const nsSize& aSize);
|
||||
// Set contentRect and contentBoxSize.
|
||||
void SetContentRectAndSize(const nsSize& aSize);
|
||||
|
||||
protected:
|
||||
~ResizeObserverEntry();
|
||||
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsCOMPtr<Element> mTarget;
|
||||
|
||||
RefPtr<DOMRectReadOnly> mContentRect;
|
||||
RefPtr<ResizeObserverSize> mBorderBoxSize;
|
||||
RefPtr<ResizeObserverSize> mContentBoxSize;
|
||||
};
|
||||
|
||||
class ResizeObserverSize final : public nsISupports, public nsWrapperCache {
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ResizeObserverSize)
|
||||
|
||||
// Note: the unit of |aSize| is app unit, and we convert it into css pixel in
|
||||
// the public JS APIs.
|
||||
ResizeObserverSize(nsISupports* aOwner, const nsSize& aSize,
|
||||
const WritingMode aWM)
|
||||
: mOwner(aOwner), mSize(aWM, aSize), mWM(aWM) {
|
||||
MOZ_ASSERT(mOwner, "Need a non-null owner");
|
||||
}
|
||||
|
||||
nsISupports* GetParentObject() const { return mOwner; }
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override {
|
||||
return ResizeObserverSizeBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
double InlineSize() const {
|
||||
return NSAppUnitsToDoublePixels(mSize.ISize(mWM), AppUnitsPerCSSPixel());
|
||||
}
|
||||
|
||||
double BlockSize() const {
|
||||
return NSAppUnitsToDoublePixels(mSize.BSize(mWM), AppUnitsPerCSSPixel());
|
||||
}
|
||||
|
||||
protected:
|
||||
~ResizeObserverSize() = default;
|
||||
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
const LogicalSize mSize;
|
||||
const WritingMode mWM;
|
||||
};
|
||||
|
||||
/**
|
||||
* We use ResizeObservation to store and sync the size information of one
|
||||
* observed element so we can decide whether an observation should be fired
|
||||
* or not.
|
||||
*/
|
||||
class ResizeObservation final
|
||||
: public nsISupports
|
||||
, public nsWrapperCache
|
||||
, public LinkedListElement<ResizeObservation>
|
||||
{
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ResizeObservation)
|
||||
|
||||
ResizeObservation(nsISupports* aOwner,
|
||||
Element* aTarget,
|
||||
ResizeObserverBoxOptions aBox,
|
||||
const WritingMode aWM)
|
||||
: mOwner(aOwner)
|
||||
, mTarget(aTarget)
|
||||
, mObservedBox(aBox)
|
||||
, mLastReportedSize(aWM)
|
||||
, mLastReportedWM(aWM)
|
||||
{
|
||||
MOZ_ASSERT(mOwner, "Need a non-null owner");
|
||||
MOZ_ASSERT(mTarget, "Need a non-null target element");
|
||||
}
|
||||
|
||||
static already_AddRefed<ResizeObservation>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
Element* aTarget,
|
||||
ErrorResult& aRv);
|
||||
|
||||
JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override
|
||||
{
|
||||
return ResizeObservationBinding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return mOwner;
|
||||
}
|
||||
|
||||
Element* Target() const
|
||||
{
|
||||
return mTarget;
|
||||
}
|
||||
|
||||
ResizeObserverBoxOptions BoxOptions() const
|
||||
{
|
||||
return mObservedBox;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns whether the observed target element size differs from the saved
|
||||
* mLastReportedSize.
|
||||
*/
|
||||
bool IsActive() const;
|
||||
|
||||
/*
|
||||
* Update current mLastReportedSize with size from aSize.
|
||||
*/
|
||||
void UpdateLastReportedSize(const nsSize& aSize);
|
||||
|
||||
protected:
|
||||
~ResizeObservation();
|
||||
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsCOMPtr<Element> mTarget;
|
||||
|
||||
const ResizeObserverBoxOptions mObservedBox;
|
||||
|
||||
// The latest recorded size of observed target.
|
||||
// Per the spec, observation.lastReportedSize should be entry.borderBoxSize
|
||||
// or entry.contentBoxSize (i.e. logical size), instead of entry.contentRect
|
||||
// (i.e. physical rect), so we store this as LogicalSize.
|
||||
LogicalSize mLastReportedSize;
|
||||
WritingMode mLastReportedWM;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_ResizeObserver_h
|
||||
|
||||
|
|
|
|||
|
|
@ -41,9 +41,9 @@ public:
|
|||
|
||||
void Disconnect();
|
||||
|
||||
bool IsRegistered() const { return mRegistered; }
|
||||
|
||||
void DetachFromOwner() { mOwner = nullptr; }
|
||||
bool IsRegistered() const { return mRegistered; }
|
||||
|
||||
void DetachFromOwner() { mOwner = nullptr; }
|
||||
|
||||
protected:
|
||||
virtual ~ResizeObserverNotificationHelper();
|
||||
|
|
|
|||
|
|
@ -9781,17 +9781,3 @@ nsContentUtils::GetClosestNonNativeAnonymousAncestor(Element* aElement)
|
|||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
/* static */ uint32_t
|
||||
nsContentUtils::GetNodeDepth(nsINode* aNode)
|
||||
{
|
||||
uint32_t depth = 1;
|
||||
|
||||
MOZ_ASSERT(aNode, "Node shouldn't be null");
|
||||
|
||||
while ((aNode = aNode->GetParentNode())) {
|
||||
++depth;
|
||||
}
|
||||
|
||||
return depth;
|
||||
}
|
||||
|
|
@ -2756,14 +2756,6 @@ public:
|
|||
static bool
|
||||
IsCustomElementsEnabled() { return sIsCustomElementsEnabled; }
|
||||
|
||||
/**
|
||||
* Returns the length of the parent-traversal path (in terms of the number of
|
||||
* nodes) to an unparented/root node from aNode. An unparented/root node is
|
||||
* considered to have a depth of 1, its children have a depth of 2, etc.
|
||||
* aNode is expected to be non-null.
|
||||
*/
|
||||
static uint32_t GetNodeDepth(nsINode* aNode);
|
||||
|
||||
private:
|
||||
static bool InitializeEventTable();
|
||||
|
||||
|
|
|
|||
|
|
@ -2267,6 +2267,7 @@ GK_ATOM(windows_theme_generic, "windows-theme-generic")
|
|||
|
||||
// And the same again, as media query keywords.
|
||||
GK_ATOM(_moz_color_picker_available, "-moz-color-picker-available")
|
||||
GK_ATOM(_moz_dark_theme, "-moz-dark-theme")
|
||||
GK_ATOM(_moz_scrollbar_start_backward, "-moz-scrollbar-start-backward")
|
||||
GK_ATOM(_moz_scrollbar_start_forward, "-moz-scrollbar-start-forward")
|
||||
GK_ATOM(_moz_scrollbar_end_backward, "-moz-scrollbar-end-backward")
|
||||
|
|
|
|||
|
|
@ -736,6 +736,11 @@ DOMInterfaces = {
|
|||
'headerFile': 'mozilla/dom/ResizeObserver.h',
|
||||
},
|
||||
|
||||
'ResizeObserverSize': {
|
||||
'nativeType': 'mozilla::dom::ResizeObserverSize',
|
||||
'headerFile': 'mozilla/dom/ResizeObserver.h',
|
||||
},
|
||||
|
||||
'Response': {
|
||||
'binaryNames': { 'headers': 'headers_' },
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,12 +7,21 @@
|
|||
* https://wicg.github.io/ResizeObserver/
|
||||
*/
|
||||
|
||||
enum ResizeObserverBoxOptions {
|
||||
"border-box",
|
||||
"content-box"
|
||||
};
|
||||
|
||||
dictionary ResizeObserverOptions {
|
||||
ResizeObserverBoxOptions box = "content-box";
|
||||
};
|
||||
|
||||
[Constructor(ResizeObserverCallback callback),
|
||||
Exposed=Window,
|
||||
Pref="layout.css.resizeobserver.enabled"]
|
||||
interface ResizeObserver {
|
||||
[Throws]
|
||||
void observe(Element? target);
|
||||
void observe(Element? target, optional ResizeObserverOptions options);
|
||||
[Throws]
|
||||
void unobserve(Element? target);
|
||||
void disconnect();
|
||||
|
|
@ -21,19 +30,23 @@ interface ResizeObserver {
|
|||
callback ResizeObserverCallback = void (sequence<ResizeObserverEntry> entries, ResizeObserver observer);
|
||||
|
||||
[Constructor(Element? target),
|
||||
ChromeOnly,
|
||||
Pref="layout.css.resizeobserver.enabled"]
|
||||
interface ResizeObserverEntry {
|
||||
readonly attribute Element target;
|
||||
readonly attribute DOMRectReadOnly? contentRect;
|
||||
readonly attribute ResizeObserverSize borderBoxSize;
|
||||
readonly attribute ResizeObserverSize contentBoxSize;
|
||||
};
|
||||
|
||||
[Constructor(Element? target),
|
||||
ChromeOnly,
|
||||
[Pref="layout.css.resizeobserver.enabled"]
|
||||
interface ResizeObserverSize {
|
||||
readonly attribute unrestricted double inlineSize;
|
||||
readonly attribute unrestricted double blockSize;
|
||||
};
|
||||
|
||||
[ChromeOnly,
|
||||
Pref="layout.css.resizeobserver.enabled"]
|
||||
interface ResizeObservation {
|
||||
readonly attribute Element target;
|
||||
readonly attribute long broadcastWidth;
|
||||
readonly attribute long broadcastHeight;
|
||||
boolean isActive();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,11 +22,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
LOCAL_INCLUDES += [
|
||||
'../printingui/win',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
DEFINES['PROXY_PRINTING'] = 1
|
||||
LOCAL_INCLUDES += [
|
||||
'../printingui/mac',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_PDF_PRINTING']:
|
||||
DEFINES['PROXY_PRINTING'] = 1
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# 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/.
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'nsPrintProgress.cpp',
|
||||
'nsPrintProgressParams.cpp',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'nsPrintingPromptServiceX.mm',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
|
@ -1,213 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsPrintProgress.h"
|
||||
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
NS_IMPL_ADDREF(nsPrintProgress)
|
||||
NS_IMPL_RELEASE(nsPrintProgress)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsPrintProgress)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintStatusFeedback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPrintProgress)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPrintStatusFeedback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
|
||||
NS_INTERFACE_MAP_END_THREADSAFE
|
||||
|
||||
|
||||
nsPrintProgress::nsPrintProgress()
|
||||
{
|
||||
m_closeProgress = false;
|
||||
m_processCanceled = false;
|
||||
m_pendingStateFlags = -1;
|
||||
m_pendingStateValue = NS_OK;
|
||||
}
|
||||
|
||||
nsPrintProgress::~nsPrintProgress()
|
||||
{
|
||||
(void)ReleaseListeners();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OpenProgressDialog(mozIDOMWindowProxy *parent,
|
||||
const char *dialogURL,
|
||||
nsISupports *parameters,
|
||||
nsIObserver *openDialogObserver,
|
||||
bool *notifyOnOpen)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("The nsPrintingPromptService::ShowProgress "
|
||||
"implementation for OS X returns "
|
||||
"NS_ERROR_NOT_IMPLEMENTED, so we should never get "
|
||||
"here.");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::CloseProgressDialog(bool forceClose)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("The nsPrintingPromptService::ShowProgress "
|
||||
"implementation for OS X returns "
|
||||
"NS_ERROR_NOT_IMPLEMENTED, so we should never get "
|
||||
"here.");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::GetPrompter(nsIPrompt **_retval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
*_retval = nullptr;
|
||||
|
||||
if (! m_closeProgress && m_dialog) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(m_dialog);
|
||||
MOZ_ASSERT(window);
|
||||
return window->GetPrompter(_retval);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::GetProcessCanceledByUser(bool *aProcessCanceledByUser)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aProcessCanceledByUser);
|
||||
*aProcessCanceledByUser = m_processCanceled;
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP nsPrintProgress::SetProcessCanceledByUser(bool aProcessCanceledByUser)
|
||||
{
|
||||
m_processCanceled = aProcessCanceledByUser;
|
||||
OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP, NS_OK);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::RegisterListener(nsIWebProgressListener * listener)
|
||||
{
|
||||
if (!listener) //Nothing to do with a null listener!
|
||||
return NS_OK;
|
||||
|
||||
m_listenerList.AppendObject(listener);
|
||||
if (m_closeProgress || m_processCanceled)
|
||||
listener->OnStateChange(nullptr, nullptr,
|
||||
nsIWebProgressListener::STATE_STOP, NS_OK);
|
||||
else
|
||||
{
|
||||
listener->OnStatusChange(nullptr, nullptr, NS_OK, m_pendingStatus.get());
|
||||
if (m_pendingStateFlags != -1)
|
||||
listener->OnStateChange(nullptr, nullptr, m_pendingStateFlags, m_pendingStateValue);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::UnregisterListener(nsIWebProgressListener *listener)
|
||||
{
|
||||
if (listener)
|
||||
m_listenerList.RemoveObject(listener);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::DoneIniting()
|
||||
{
|
||||
if (m_observer) {
|
||||
m_observer->Observe(nullptr, nullptr, nullptr);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
|
||||
{
|
||||
m_pendingStateFlags = aStateFlags;
|
||||
m_pendingStateValue = aStatus;
|
||||
|
||||
uint32_t count = m_listenerList.Count();
|
||||
for (uint32_t i = count - 1; i < count; i --)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
|
||||
if (progressListener)
|
||||
progressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
|
||||
{
|
||||
uint32_t count = m_listenerList.Count();
|
||||
for (uint32_t i = count - 1; i < count; i --)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
|
||||
if (progressListener)
|
||||
progressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage)
|
||||
{
|
||||
if (aMessage && *aMessage)
|
||||
m_pendingStatus = aMessage;
|
||||
|
||||
uint32_t count = m_listenerList.Count();
|
||||
for (uint32_t i = count - 1; i < count; i --)
|
||||
{
|
||||
nsCOMPtr<nsIWebProgressListener> progressListener = m_listenerList.SafeObjectAt(i);
|
||||
if (progressListener)
|
||||
progressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPrintProgress::ReleaseListeners()
|
||||
{
|
||||
m_listenerList.Clear();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::ShowStatusString(const char16_t *status)
|
||||
{
|
||||
return OnStatusChange(nullptr, nullptr, NS_OK, status);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::StartMeteors()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::StopMeteors()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::ShowProgress(int32_t percent)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::SetDocShell(nsIDocShell *shell,
|
||||
mozIDOMWindowProxy *window)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgress::CloseWindow()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsPrintProgress_h
|
||||
#define __nsPrintProgress_h
|
||||
|
||||
#include "nsIPrintProgress.h"
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPrintStatusFeedback.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsPrintProgress : public nsIPrintProgress, public nsIPrintStatusFeedback
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIPRINTPROGRESS
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_DECL_NSIPRINTSTATUSFEEDBACK
|
||||
|
||||
nsPrintProgress();
|
||||
|
||||
protected:
|
||||
virtual ~nsPrintProgress();
|
||||
|
||||
private:
|
||||
nsresult ReleaseListeners();
|
||||
|
||||
bool m_closeProgress;
|
||||
bool m_processCanceled;
|
||||
nsString m_pendingStatus;
|
||||
int32_t m_pendingStateFlags;
|
||||
nsresult m_pendingStateValue;
|
||||
// XXX This member is read-only.
|
||||
nsCOMPtr<mozIDOMWindowProxy> m_dialog;
|
||||
nsCOMArray<nsIWebProgressListener> m_listenerList;
|
||||
nsCOMPtr<nsIObserver> m_observer;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsPrintProgressParams.h"
|
||||
#include "nsReadableUtils.h"
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPrintProgressParams, nsIPrintProgressParams)
|
||||
|
||||
nsPrintProgressParams::nsPrintProgressParams()
|
||||
{
|
||||
}
|
||||
|
||||
nsPrintProgressParams::~nsPrintProgressParams()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::GetDocTitle(char16_t * *aDocTitle)
|
||||
{
|
||||
NS_ENSURE_ARG(aDocTitle);
|
||||
|
||||
*aDocTitle = ToNewUnicode(mDocTitle);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::SetDocTitle(const char16_t * aDocTitle)
|
||||
{
|
||||
mDocTitle = aDocTitle;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::GetDocURL(char16_t * *aDocURL)
|
||||
{
|
||||
NS_ENSURE_ARG(aDocURL);
|
||||
|
||||
*aDocURL = ToNewUnicode(mDocURL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPrintProgressParams::SetDocURL(const char16_t * aDocURL)
|
||||
{
|
||||
mDocURL = aDocURL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsPrintProgressParams_h
|
||||
#define __nsPrintProgressParams_h
|
||||
|
||||
#include "nsIPrintProgressParams.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsPrintProgressParams : public nsIPrintProgressParams
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPRINTPROGRESSPARAMS
|
||||
|
||||
nsPrintProgressParams();
|
||||
|
||||
protected:
|
||||
virtual ~nsPrintProgressParams();
|
||||
|
||||
private:
|
||||
nsString mDocTitle;
|
||||
nsString mDocURL;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsPrintingPromptService_h
|
||||
#define __nsPrintingPromptService_h
|
||||
|
||||
// {E042570C-62DE-4bb6-A6E0-798E3C07B4DF}
|
||||
#define NS_PRINTINGPROMPTSERVICE_CID \
|
||||
{0xe042570c, 0x62de, 0x4bb6, { 0xa6, 0xe0, 0x79, 0x8e, 0x3c, 0x7, 0xb4, 0xdf}}
|
||||
#define NS_PRINTINGPROMPTSERVICE_CONTRACTID \
|
||||
"@mozilla.org/embedcomp/printingprompt-service;1"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "nsPIPromptService.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
|
||||
// Printing Progress Includes
|
||||
#include "nsPrintProgress.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
|
||||
class nsPrintingPromptService: public nsIPrintingPromptService,
|
||||
public nsIWebProgressListener
|
||||
{
|
||||
public:
|
||||
nsPrintingPromptService();
|
||||
|
||||
nsresult Init();
|
||||
|
||||
NS_DECL_NSIPRINTINGPROMPTSERVICE
|
||||
NS_DECL_NSIWEBPROGRESSLISTENER
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
protected:
|
||||
virtual ~nsPrintingPromptService();
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIPrintProgress> mPrintProgress;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsPrintingPromptService.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "nsIPrintDialogService.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
//*****************************************************************************
|
||||
// nsPrintingPromptService
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener)
|
||||
|
||||
nsPrintingPromptService::nsPrintingPromptService()
|
||||
{
|
||||
}
|
||||
|
||||
nsPrintingPromptService::~nsPrintingPromptService()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult nsPrintingPromptService::Init()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// nsPrintingPromptService::nsIPrintingPromptService
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
|
||||
NS_PRINTDIALOGSERVICE_CONTRACTID));
|
||||
if (dlgPrint) {
|
||||
return dlgPrint->Show(nsPIDOMWindowOuter::From(parent), printSettings,
|
||||
webBrowserPrint);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowProgress(mozIDOMWindowProxy* parent,
|
||||
nsIWebBrowserPrint* webBrowserPrint, // ok to be null
|
||||
nsIPrintSettings* printSettings, // ok to be null
|
||||
nsIObserver* openDialogObserver, // ok to be null
|
||||
bool isForPrinting,
|
||||
nsIWebProgressListener** webProgressListener,
|
||||
nsIPrintProgressParams** printProgressParams,
|
||||
bool* notifyOnOpen)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowPageSetup(mozIDOMWindowProxy *parent, nsIPrintSettings *printSettings, nsIObserver *aObs)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
|
||||
NS_PRINTDIALOGSERVICE_CONTRACTID));
|
||||
if (dlgPrint) {
|
||||
return dlgPrint->ShowPageSetup(nsPIDOMWindowOuter::From(parent), printSettings);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::ShowPrinterProperties(mozIDOMWindowProxy *parent, const char16_t *printerName, nsIPrintSettings *printSettings)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// nsPrintingPromptService::nsIWebProgressListener
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location, in unsigned long aFlags); */
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -10,7 +10,5 @@ DIRS += ['ipc']
|
|||
if CONFIG['NS_PRINTING']:
|
||||
if toolkit == 'windows':
|
||||
DIRS += ['win']
|
||||
elif toolkit == 'cocoa':
|
||||
DIRS += ['mac']
|
||||
elif CONFIG['MOZ_PDF_PRINTING']:
|
||||
DIRS += ['unixshared']
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ EXPORTS.cairo += [
|
|||
'pixman-rename.h',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] not in ('cocoa', 'uikit'):
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] not in ('uikit'):
|
||||
EXPORTS.cairo += [
|
||||
'cairo-pdf.h',
|
||||
]
|
||||
|
|
@ -56,7 +56,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
]
|
||||
else:
|
||||
DEFINES['CAIRO_OMIT_WIN32_PRINTING'] = True
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] in {'cocoa', 'uikit'}:
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] in {'uikit'}:
|
||||
EXPORTS.cairo += [
|
||||
'cairo-quartz-image.h',
|
||||
'cairo-quartz.h',
|
||||
|
|
|
|||
|
|
@ -1,107 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "MacIOSurfaceTextureHostBasic.h"
|
||||
#include "mozilla/gfx/MacIOSurface.h"
|
||||
#include "MacIOSurfaceHelpers.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
MacIOSurfaceTextureSourceBasic::MacIOSurfaceTextureSourceBasic(
|
||||
BasicCompositor* aCompositor,
|
||||
MacIOSurface* aSurface)
|
||||
: mCompositor(aCompositor)
|
||||
, mSurface(aSurface)
|
||||
{
|
||||
MOZ_COUNT_CTOR(MacIOSurfaceTextureSourceBasic);
|
||||
}
|
||||
|
||||
MacIOSurfaceTextureSourceBasic::~MacIOSurfaceTextureSourceBasic()
|
||||
{
|
||||
MOZ_COUNT_DTOR(MacIOSurfaceTextureSourceBasic);
|
||||
}
|
||||
|
||||
gfx::IntSize
|
||||
MacIOSurfaceTextureSourceBasic::GetSize() const
|
||||
{
|
||||
return gfx::IntSize(mSurface->GetDevicePixelWidth(),
|
||||
mSurface->GetDevicePixelHeight());
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
MacIOSurfaceTextureSourceBasic::GetFormat() const
|
||||
{
|
||||
// Set the format the same way as CreateSourceSurfaceFromMacIOSurface.
|
||||
return mSurface->GetFormat() == gfx::SurfaceFormat::NV12
|
||||
? gfx::SurfaceFormat::B8G8R8X8 : gfx::SurfaceFormat::B8G8R8A8;
|
||||
}
|
||||
|
||||
MacIOSurfaceTextureHostBasic::MacIOSurfaceTextureHostBasic(
|
||||
TextureFlags aFlags,
|
||||
const SurfaceDescriptorMacIOSurface& aDescriptor
|
||||
)
|
||||
: TextureHost(aFlags)
|
||||
{
|
||||
mSurface = MacIOSurface::LookupSurface(aDescriptor.surfaceId(),
|
||||
aDescriptor.scaleFactor(),
|
||||
!aDescriptor.isOpaque());
|
||||
}
|
||||
|
||||
gfx::SourceSurface*
|
||||
MacIOSurfaceTextureSourceBasic::GetSurface(gfx::DrawTarget* aTarget)
|
||||
{
|
||||
if (!mSourceSurface) {
|
||||
mSourceSurface = CreateSourceSurfaceFromMacIOSurface(mSurface);
|
||||
}
|
||||
return mSourceSurface;
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureSourceBasic::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
mCompositor = AssertBasicCompositor(aCompositor);
|
||||
}
|
||||
|
||||
bool
|
||||
MacIOSurfaceTextureHostBasic::Lock()
|
||||
{
|
||||
if (!mCompositor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mTextureSource) {
|
||||
mTextureSource = new MacIOSurfaceTextureSourceBasic(mCompositor, mSurface);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureHostBasic::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
BasicCompositor* compositor = AssertBasicCompositor(aCompositor);
|
||||
if (!compositor) {
|
||||
mTextureSource = nullptr;
|
||||
return;
|
||||
}
|
||||
mCompositor = compositor;
|
||||
if (mTextureSource) {
|
||||
mTextureSource->SetCompositor(compositor);
|
||||
}
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
MacIOSurfaceTextureHostBasic::GetFormat() const {
|
||||
return mSurface->HasAlpha() ? gfx::SurfaceFormat::R8G8B8A8 : gfx::SurfaceFormat::B8G8R8X8;
|
||||
}
|
||||
|
||||
gfx::IntSize
|
||||
MacIOSurfaceTextureHostBasic::GetSize() const {
|
||||
return gfx::IntSize(mSurface->GetDevicePixelWidth(),
|
||||
mSurface->GetDevicePixelHeight());
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_MACIOSURFACETEXTUREHOST_BASIC_H
|
||||
#define MOZILLA_GFX_MACIOSURFACETEXTUREHOST_BASIC_H
|
||||
|
||||
#include "mozilla/layers/BasicCompositor.h"
|
||||
#include "mozilla/layers/TextureHostBasic.h"
|
||||
|
||||
class MacIOSurface;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class BasicCompositor;
|
||||
|
||||
/**
|
||||
* A texture source meant for use with BasicCompositor.
|
||||
*
|
||||
* It does not own any GL texture, and attaches its shared handle to one of
|
||||
* the compositor's temporary textures when binding.
|
||||
*/
|
||||
class MacIOSurfaceTextureSourceBasic
|
||||
: public TextureSourceBasic,
|
||||
public TextureSource
|
||||
{
|
||||
public:
|
||||
MacIOSurfaceTextureSourceBasic(BasicCompositor* aCompositor,
|
||||
MacIOSurface* aSurface);
|
||||
virtual ~MacIOSurfaceTextureSourceBasic();
|
||||
|
||||
virtual const char* Name() const override { return "MacIOSurfaceTextureSourceBasic"; }
|
||||
|
||||
virtual TextureSourceBasic* AsSourceBasic() override { return this; }
|
||||
|
||||
virtual gfx::IntSize GetSize() const override;
|
||||
virtual gfx::SurfaceFormat GetFormat() const override;
|
||||
virtual gfx::SourceSurface* GetSurface(gfx::DrawTarget* aTarget) override;
|
||||
|
||||
virtual void DeallocateDeviceData() override { }
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
protected:
|
||||
RefPtr<BasicCompositor> mCompositor;
|
||||
RefPtr<MacIOSurface> mSurface;
|
||||
RefPtr<gfx::SourceSurface> mSourceSurface;
|
||||
};
|
||||
|
||||
/**
|
||||
* A TextureHost for shared MacIOSurface
|
||||
*
|
||||
* Most of the logic actually happens in MacIOSurfaceTextureSourceBasic.
|
||||
*/
|
||||
class MacIOSurfaceTextureHostBasic : public TextureHost
|
||||
{
|
||||
public:
|
||||
MacIOSurfaceTextureHostBasic(TextureFlags aFlags,
|
||||
const SurfaceDescriptorMacIOSurface& aDescriptor);
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override { return mCompositor; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override;
|
||||
|
||||
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override
|
||||
{
|
||||
aTexture = mTextureSource;
|
||||
return !!aTexture;
|
||||
}
|
||||
|
||||
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
|
||||
{
|
||||
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
|
||||
}
|
||||
|
||||
virtual gfx::IntSize GetSize() const override;
|
||||
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
virtual const char* Name() override { return "MacIOSurfaceTextureHostBasic"; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
RefPtr<BasicCompositor> mCompositor;
|
||||
RefPtr<MacIOSurfaceTextureSourceBasic> mTextureSource;
|
||||
RefPtr<MacIOSurface> mSurface;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_GFX_MACIOSURFACETEXTUREHOSTOGL_BASIC_H
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=8 et :
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/gfx/Point.h"
|
||||
#include "mozilla/layers/PLayerTransaction.h"
|
||||
#include "mozilla/layers/ShadowLayers.h"
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
#include "mozilla/layers/CompositorTypes.h"
|
||||
|
||||
#include "gfx2DGlue.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
using namespace mozilla::gl;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
/*static*/ void
|
||||
ShadowLayerForwarder::PlatformSyncBeforeUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
LayerManagerComposite::PlatformSyncBeforeReplyUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
/*static*/ bool
|
||||
LayerManagerComposite::SupportsDirectTexturing()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
@ -117,7 +117,6 @@ EXPORTS.mozilla.layers += [
|
|||
'AxisPhysicsModel.h',
|
||||
'AxisPhysicsMSDModel.h',
|
||||
'basic/BasicCompositor.h',
|
||||
'basic/MacIOSurfaceTextureHostBasic.h',
|
||||
'basic/TextureHostBasic.h',
|
||||
'BSPTree.h',
|
||||
'BufferTexture.h',
|
||||
|
|
@ -186,8 +185,6 @@ EXPORTS.mozilla.layers += [
|
|||
'LayersTypes.h',
|
||||
'opengl/CompositingRenderTargetOGL.h',
|
||||
'opengl/CompositorOGL.h',
|
||||
'opengl/MacIOSurfaceTextureClientOGL.h',
|
||||
'opengl/MacIOSurfaceTextureHostOGL.h',
|
||||
'opengl/TextureClientOGL.h',
|
||||
'opengl/TextureHostOGL.h',
|
||||
'PersistentBufferProvider.h',
|
||||
|
|
@ -213,21 +210,6 @@ if CONFIG['MOZ_X11']:
|
|||
'opengl/X11TextureSourceOGL.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
EXPORTS.mozilla.layers += [
|
||||
'opengl/GLManager.h',
|
||||
]
|
||||
EXPORTS += [
|
||||
'MacIOSurfaceHelpers.h',
|
||||
'MacIOSurfaceImage.h',
|
||||
]
|
||||
SOURCES += [
|
||||
'ipc/ShadowLayerUtilsMac.cpp',
|
||||
'MacIOSurfaceHelpers.cpp',
|
||||
'MacIOSurfaceImage.cpp',
|
||||
'opengl/GLManager.cpp',
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
'apz/public/IAPZCTreeManager.cpp',
|
||||
'apz/src/APZCTreeManager.cpp',
|
||||
|
|
@ -379,13 +361,6 @@ if CONFIG['_MSC_VER'] and CONFIG['CPU_ARCH'] == 'x86_64':
|
|||
]:
|
||||
SOURCES[src].no_pgo = True
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
SOURCES += [
|
||||
'basic/MacIOSurfaceTextureHostBasic.cpp',
|
||||
'opengl/MacIOSurfaceTextureClientOGL.cpp',
|
||||
'opengl/MacIOSurfaceTextureHostOGL.cpp',
|
||||
]
|
||||
|
||||
IPDL_SOURCES = [
|
||||
'ipc/LayersMessages.ipdlh',
|
||||
'ipc/LayersSurfaces.ipdlh',
|
||||
|
|
|
|||
|
|
@ -1,70 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GLManager.h"
|
||||
#include "CompositorOGL.h" // for CompositorOGL
|
||||
#include "GLContext.h" // for GLContext
|
||||
#include "mozilla/Attributes.h" // for override
|
||||
#include "mozilla/RefPtr.h" // for RefPtr
|
||||
#include "mozilla/layers/Compositor.h" // for Compositor
|
||||
#include "mozilla/layers/LayerManagerComposite.h"
|
||||
#include "mozilla/layers/LayersTypes.h"
|
||||
#include "mozilla/mozalloc.h" // for operator new, etc
|
||||
|
||||
using namespace mozilla::gl;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class GLManagerCompositor : public GLManager
|
||||
{
|
||||
public:
|
||||
explicit GLManagerCompositor(CompositorOGL* aCompositor)
|
||||
: mImpl(aCompositor)
|
||||
{}
|
||||
|
||||
virtual GLContext* gl() const override
|
||||
{
|
||||
return mImpl->gl();
|
||||
}
|
||||
|
||||
virtual void ActivateProgram(ShaderProgramOGL *aProg) override
|
||||
{
|
||||
mImpl->ActivateProgram(aProg);
|
||||
}
|
||||
|
||||
virtual ShaderProgramOGL* GetProgram(GLenum aTarget, gfx::SurfaceFormat aFormat) override
|
||||
{
|
||||
ShaderConfigOGL config = ShaderConfigFromTargetAndFormat(aTarget, aFormat);
|
||||
return mImpl->GetShaderProgramFor(config);
|
||||
}
|
||||
|
||||
virtual const gfx::Matrix4x4& GetProjMatrix() const override
|
||||
{
|
||||
return mImpl->GetProjMatrix();
|
||||
}
|
||||
|
||||
virtual void BindAndDrawQuad(ShaderProgramOGL *aProg,
|
||||
const gfx::Rect& aLayerRect,
|
||||
const gfx::Rect& aTextureRect) override
|
||||
{
|
||||
mImpl->BindAndDrawQuad(aProg, aLayerRect, aTextureRect);
|
||||
}
|
||||
|
||||
private:
|
||||
RefPtr<CompositorOGL> mImpl;
|
||||
};
|
||||
|
||||
/* static */ GLManager*
|
||||
GLManager::CreateGLManager(LayerManagerComposite* aManager)
|
||||
{
|
||||
if (aManager && aManager->GetCompositor()->GetBackendType() == LayersBackend::LAYERS_OPENGL) {
|
||||
return new GLManagerCompositor(aManager->GetCompositor()->AsCompositorOGL());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_GLMANAGER_H
|
||||
#define MOZILLA_GFX_GLMANAGER_H
|
||||
|
||||
#include "mozilla/gfx/Types.h" // for SurfaceFormat
|
||||
#include "OGLShaderProgram.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gl {
|
||||
class GLContext;
|
||||
} // namespace gl
|
||||
|
||||
namespace layers {
|
||||
|
||||
class LayerManagerComposite;
|
||||
|
||||
/**
|
||||
* Minimal interface to allow widgets to draw using OpenGL. Abstracts
|
||||
* CompositorOGL. Call CreateGLManager with a LayerManagerComposite
|
||||
* backed by a CompositorOGL.
|
||||
*/
|
||||
class GLManager
|
||||
{
|
||||
public:
|
||||
static GLManager* CreateGLManager(LayerManagerComposite* aManager);
|
||||
|
||||
virtual ~GLManager() {}
|
||||
|
||||
virtual gl::GLContext* gl() const = 0;
|
||||
virtual ShaderProgramOGL* GetProgram(GLenum aTarget, gfx::SurfaceFormat aFormat) = 0;
|
||||
virtual void ActivateProgram(ShaderProgramOGL* aPrg) = 0;
|
||||
virtual const gfx::Matrix4x4& GetProjMatrix() const = 0;
|
||||
virtual void BindAndDrawQuad(ShaderProgramOGL *aProg, const gfx::Rect& aLayerRect,
|
||||
const gfx::Rect& aTextureRect) = 0;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "MacIOSurfaceTextureClientOGL.h"
|
||||
#include "mozilla/gfx/MacIOSurface.h"
|
||||
#include "MacIOSurfaceHelpers.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
MacIOSurfaceTextureData::MacIOSurfaceTextureData(MacIOSurface* aSurface,
|
||||
BackendType aBackend)
|
||||
: mSurface(aSurface)
|
||||
, mBackend(aBackend)
|
||||
{
|
||||
MOZ_ASSERT(mSurface);
|
||||
}
|
||||
|
||||
MacIOSurfaceTextureData::~MacIOSurfaceTextureData()
|
||||
{}
|
||||
|
||||
// static
|
||||
MacIOSurfaceTextureData*
|
||||
MacIOSurfaceTextureData::Create(MacIOSurface* aSurface, BackendType aBackend)
|
||||
{
|
||||
MOZ_ASSERT(aSurface);
|
||||
if (!aSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
return new MacIOSurfaceTextureData(aSurface, aBackend);
|
||||
}
|
||||
|
||||
MacIOSurfaceTextureData*
|
||||
MacIOSurfaceTextureData::Create(const IntSize& aSize,
|
||||
SurfaceFormat aFormat,
|
||||
BackendType aBackend)
|
||||
{
|
||||
if (aFormat != SurfaceFormat::B8G8R8A8 &&
|
||||
aFormat != SurfaceFormat::B8G8R8X8) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<MacIOSurface> surf = MacIOSurface::CreateIOSurface(aSize.width, aSize.height,
|
||||
1.0,
|
||||
aFormat == SurfaceFormat::B8G8R8A8);
|
||||
if (!surf) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Create(surf, aBackend);
|
||||
}
|
||||
|
||||
bool
|
||||
MacIOSurfaceTextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
aOutDescriptor = SurfaceDescriptorMacIOSurface(mSurface->GetIOSurfaceID(),
|
||||
mSurface->GetContentsScaleFactor(),
|
||||
!mSurface->HasAlpha());
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureData::FillInfo(TextureData::Info& aInfo) const
|
||||
{
|
||||
aInfo.size = gfx::IntSize(mSurface->GetDevicePixelWidth(), mSurface->GetDevicePixelHeight());
|
||||
aInfo.format = mSurface->HasAlpha() ? SurfaceFormat::B8G8R8A8 : SurfaceFormat::B8G8R8X8;
|
||||
aInfo.hasIntermediateBuffer = false;
|
||||
aInfo.hasSynchronization = false;
|
||||
aInfo.supportsMoz2D = true;
|
||||
aInfo.canExposeMappedData = false;
|
||||
}
|
||||
|
||||
bool
|
||||
MacIOSurfaceTextureData::Lock(OpenMode)
|
||||
{
|
||||
mSurface->Lock(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureData::Unlock()
|
||||
{
|
||||
mSurface->Unlock(false);
|
||||
}
|
||||
|
||||
already_AddRefed<DataSourceSurface>
|
||||
MacIOSurfaceTextureData::GetAsSurface()
|
||||
{
|
||||
RefPtr<SourceSurface> surf = CreateSourceSurfaceFromMacIOSurface(mSurface);
|
||||
return surf->GetDataSurface();
|
||||
}
|
||||
|
||||
already_AddRefed<DrawTarget>
|
||||
MacIOSurfaceTextureData::BorrowDrawTarget()
|
||||
{
|
||||
MOZ_ASSERT(mBackend != BackendType::NONE);
|
||||
if (mBackend == BackendType::NONE) {
|
||||
// shouldn't happen, but degrade gracefully
|
||||
return nullptr;
|
||||
}
|
||||
return Factory::CreateDrawTargetForData(
|
||||
mBackend,
|
||||
(unsigned char*)mSurface->GetBaseAddress(),
|
||||
IntSize(mSurface->GetWidth(), mSurface->GetHeight()),
|
||||
mSurface->GetBytesPerRow(),
|
||||
mSurface->HasAlpha() ? SurfaceFormat::B8G8R8A8 : SurfaceFormat::B8G8R8X8,
|
||||
true);
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureData::Deallocate(LayersIPCChannel*)
|
||||
{
|
||||
mSurface = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureData::Forget(LayersIPCChannel*)
|
||||
{
|
||||
mSurface = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
MacIOSurfaceTextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
{
|
||||
RefPtr<DrawTarget> dt = BorrowDrawTarget();
|
||||
if (!dt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dt->CopySurface(aSurface, IntRect(IntPoint(), aSurface->GetSize()), IntPoint());
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_MACIOSURFACETEXTURECLIENTOGL_H
|
||||
#define MOZILLA_GFX_MACIOSURFACETEXTURECLIENTOGL_H
|
||||
|
||||
#include "mozilla/layers/TextureClientOGL.h"
|
||||
|
||||
class MacIOSurface;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class MacIOSurfaceTextureData : public TextureData
|
||||
{
|
||||
public:
|
||||
static MacIOSurfaceTextureData* Create(MacIOSurface* aSurface,
|
||||
gfx::BackendType aBackend);
|
||||
|
||||
static MacIOSurfaceTextureData*
|
||||
Create(const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat,
|
||||
gfx::BackendType aBackend);
|
||||
|
||||
~MacIOSurfaceTextureData();
|
||||
|
||||
virtual void FillInfo(TextureData::Info& aInfo) const override;
|
||||
|
||||
virtual bool Lock(OpenMode) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
|
||||
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual void Deallocate(LayersIPCChannel*) override;
|
||||
|
||||
virtual void Forget(LayersIPCChannel*) override;
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
// For debugging purposes only.
|
||||
already_AddRefed<gfx::DataSourceSurface> GetAsSurface();
|
||||
|
||||
protected:
|
||||
MacIOSurfaceTextureData(MacIOSurface* aSurface,
|
||||
gfx::BackendType aBackend);
|
||||
|
||||
RefPtr<MacIOSurface> mSurface;
|
||||
gfx::BackendType mBackend;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_GFX_MACIOSURFACETEXTURECLIENTOGL_H
|
||||
|
|
@ -1,180 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "MacIOSurfaceTextureHostOGL.h"
|
||||
#include "mozilla/gfx/MacIOSurface.h"
|
||||
#include "GLContextCGL.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
MacIOSurfaceTextureHostOGL::MacIOSurfaceTextureHostOGL(TextureFlags aFlags,
|
||||
const SurfaceDescriptorMacIOSurface& aDescriptor)
|
||||
: TextureHost(aFlags)
|
||||
{
|
||||
MOZ_COUNT_CTOR(MacIOSurfaceTextureHostOGL);
|
||||
mSurface = MacIOSurface::LookupSurface(aDescriptor.surfaceId(),
|
||||
aDescriptor.scaleFactor(),
|
||||
!aDescriptor.isOpaque());
|
||||
}
|
||||
|
||||
MacIOSurfaceTextureHostOGL::~MacIOSurfaceTextureHostOGL()
|
||||
{
|
||||
MOZ_COUNT_DTOR(MacIOSurfaceTextureHostOGL);
|
||||
}
|
||||
|
||||
GLTextureSource*
|
||||
MacIOSurfaceTextureHostOGL::CreateTextureSourceForPlane(size_t aPlane)
|
||||
{
|
||||
MOZ_ASSERT(mSurface);
|
||||
|
||||
GLuint textureHandle;
|
||||
gl::GLContext* gl = mCompositor->gl();
|
||||
gl->fGenTextures(1, &textureHandle);
|
||||
gl->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, textureHandle);
|
||||
gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
gl->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
|
||||
mSurface->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(gl)->GetCGLContext(), aPlane);
|
||||
|
||||
return new GLTextureSource(mCompositor, textureHandle, LOCAL_GL_TEXTURE_RECTANGLE_ARB,
|
||||
gfx::IntSize(mSurface->GetDevicePixelWidth(aPlane),
|
||||
mSurface->GetDevicePixelHeight(aPlane)),
|
||||
// XXX: This isn't really correct (but isn't used), we should be using the
|
||||
// format of the individual plane, not of the whole buffer.
|
||||
mSurface->GetFormat());
|
||||
}
|
||||
|
||||
bool
|
||||
MacIOSurfaceTextureHostOGL::Lock()
|
||||
{
|
||||
if (!gl() || !gl()->MakeCurrent() || !mSurface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mTextureSource) {
|
||||
mTextureSource = CreateTextureSourceForPlane(0);
|
||||
|
||||
RefPtr<TextureSource> prev = mTextureSource;
|
||||
for (size_t i = 1; i < mSurface->GetPlaneCount(); i++) {
|
||||
RefPtr<TextureSource> next = CreateTextureSourceForPlane(i);
|
||||
prev->SetNextSibling(next);
|
||||
prev = next;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureHostOGL::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
CompositorOGL* glCompositor = AssertGLCompositor(aCompositor);
|
||||
if (!glCompositor) {
|
||||
mTextureSource = nullptr;
|
||||
mCompositor = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCompositor != glCompositor) {
|
||||
// Cannot share GL texture identifiers across compositors.
|
||||
mTextureSource = nullptr;
|
||||
}
|
||||
mCompositor = glCompositor;
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
MacIOSurfaceTextureHostOGL::GetFormat() const {
|
||||
if (!mSurface) {
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
return mSurface->GetFormat();
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
MacIOSurfaceTextureHostOGL::GetReadFormat() const {
|
||||
if (!mSurface) {
|
||||
return gfx::SurfaceFormat::UNKNOWN;
|
||||
}
|
||||
return mSurface->GetReadFormat();
|
||||
}
|
||||
|
||||
gfx::IntSize
|
||||
MacIOSurfaceTextureHostOGL::GetSize() const {
|
||||
if (!mSurface) {
|
||||
return gfx::IntSize();
|
||||
}
|
||||
return gfx::IntSize(mSurface->GetDevicePixelWidth(),
|
||||
mSurface->GetDevicePixelHeight());
|
||||
}
|
||||
|
||||
gl::GLContext*
|
||||
MacIOSurfaceTextureHostOGL::gl() const
|
||||
{
|
||||
return mCompositor ? mCompositor->gl() : nullptr;
|
||||
}
|
||||
|
||||
MacIOSurfaceTextureSourceOGL::MacIOSurfaceTextureSourceOGL(
|
||||
CompositorOGL* aCompositor,
|
||||
MacIOSurface* aSurface)
|
||||
: mCompositor(aCompositor)
|
||||
, mSurface(aSurface)
|
||||
{
|
||||
MOZ_ASSERT(aCompositor);
|
||||
MOZ_COUNT_CTOR(MacIOSurfaceTextureSourceOGL);
|
||||
}
|
||||
|
||||
MacIOSurfaceTextureSourceOGL::~MacIOSurfaceTextureSourceOGL()
|
||||
{
|
||||
MOZ_COUNT_DTOR(MacIOSurfaceTextureSourceOGL);
|
||||
}
|
||||
|
||||
gfx::IntSize
|
||||
MacIOSurfaceTextureSourceOGL::GetSize() const
|
||||
{
|
||||
return gfx::IntSize(mSurface->GetDevicePixelWidth(),
|
||||
mSurface->GetDevicePixelHeight());
|
||||
}
|
||||
|
||||
gfx::SurfaceFormat
|
||||
MacIOSurfaceTextureSourceOGL::GetFormat() const
|
||||
{
|
||||
return mSurface->HasAlpha() ? gfx::SurfaceFormat::R8G8B8A8
|
||||
: gfx::SurfaceFormat::R8G8B8X8;
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureSourceOGL::BindTexture(GLenum aTextureUnit,
|
||||
gfx::SamplingFilter aSamplingFilter)
|
||||
{
|
||||
gl::GLContext* gl = this->gl();
|
||||
if (!gl || !gl->MakeCurrent()) {
|
||||
NS_WARNING("Trying to bind a texture without a working GLContext");
|
||||
return;
|
||||
}
|
||||
GLuint tex = mCompositor->GetTemporaryTexture(GetTextureTarget(), aTextureUnit);
|
||||
|
||||
gl->fActiveTexture(aTextureUnit);
|
||||
gl->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, tex);
|
||||
mSurface->CGLTexImageIOSurface2D(gl::GLContextCGL::Cast(gl)->GetCGLContext());
|
||||
ApplySamplingFilterToBoundTexture(gl, aSamplingFilter, LOCAL_GL_TEXTURE_RECTANGLE_ARB);
|
||||
}
|
||||
|
||||
void
|
||||
MacIOSurfaceTextureSourceOGL::SetCompositor(Compositor* aCompositor)
|
||||
{
|
||||
mCompositor = AssertGLCompositor(aCompositor);
|
||||
if (mCompositor && mNextSibling) {
|
||||
mNextSibling->SetCompositor(aCompositor);
|
||||
}
|
||||
}
|
||||
|
||||
gl::GLContext*
|
||||
MacIOSurfaceTextureSourceOGL::gl() const
|
||||
{
|
||||
return mCompositor ? mCompositor->gl() : nullptr;
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,114 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_MACIOSURFACETEXTUREHOSTOGL_H
|
||||
#define MOZILLA_GFX_MACIOSURFACETEXTUREHOSTOGL_H
|
||||
|
||||
#include "mozilla/layers/CompositorOGL.h"
|
||||
#include "mozilla/layers/TextureHostOGL.h"
|
||||
|
||||
class MacIOSurface;
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
/**
|
||||
* A texture source meant for use with MacIOSurfaceTextureHostOGL.
|
||||
*
|
||||
* It does not own any GL texture, and attaches its shared handle to one of
|
||||
* the compositor's temporary textures when binding.
|
||||
*/
|
||||
class MacIOSurfaceTextureSourceOGL : public TextureSource
|
||||
, public TextureSourceOGL
|
||||
{
|
||||
public:
|
||||
MacIOSurfaceTextureSourceOGL(CompositorOGL* aCompositor,
|
||||
MacIOSurface* aSurface);
|
||||
virtual ~MacIOSurfaceTextureSourceOGL();
|
||||
|
||||
virtual const char* Name() const override { return "MacIOSurfaceTextureSourceOGL"; }
|
||||
|
||||
virtual TextureSourceOGL* AsSourceOGL() override { return this; }
|
||||
|
||||
virtual void BindTexture(GLenum activetex,
|
||||
gfx::SamplingFilter aSamplingFilter) override;
|
||||
|
||||
virtual bool IsValid() const override { return !!gl(); }
|
||||
|
||||
virtual gfx::IntSize GetSize() const override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override;
|
||||
|
||||
virtual GLenum GetTextureTarget() const override { return LOCAL_GL_TEXTURE_RECTANGLE_ARB; }
|
||||
|
||||
virtual GLenum GetWrapMode() const override { return LOCAL_GL_CLAMP_TO_EDGE; }
|
||||
|
||||
// MacIOSurfaceTextureSourceOGL doesn't own any gl texture
|
||||
virtual void DeallocateDeviceData() override {}
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
gl::GLContext* gl() const;
|
||||
|
||||
protected:
|
||||
RefPtr<CompositorOGL> mCompositor;
|
||||
RefPtr<MacIOSurface> mSurface;
|
||||
};
|
||||
|
||||
/**
|
||||
* A TextureHost for shared MacIOSurface
|
||||
*
|
||||
* Most of the logic actually happens in MacIOSurfaceTextureSourceOGL.
|
||||
*/
|
||||
class MacIOSurfaceTextureHostOGL : public TextureHost
|
||||
{
|
||||
public:
|
||||
MacIOSurfaceTextureHostOGL(TextureFlags aFlags,
|
||||
const SurfaceDescriptorMacIOSurface& aDescriptor);
|
||||
virtual ~MacIOSurfaceTextureHostOGL();
|
||||
|
||||
// MacIOSurfaceTextureSourceOGL doesn't own any GL texture
|
||||
virtual void DeallocateDeviceData() override {}
|
||||
|
||||
virtual void SetCompositor(Compositor* aCompositor) override;
|
||||
|
||||
virtual Compositor* GetCompositor() override { return mCompositor; }
|
||||
|
||||
virtual bool Lock() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override;
|
||||
virtual gfx::SurfaceFormat GetReadFormat() const override;
|
||||
|
||||
virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override
|
||||
{
|
||||
aTexture = mTextureSource;
|
||||
return !!aTexture;
|
||||
}
|
||||
|
||||
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
|
||||
{
|
||||
return nullptr; // XXX - implement this (for MOZ_DUMP_PAINTING)
|
||||
}
|
||||
|
||||
gl::GLContext* gl() const;
|
||||
|
||||
virtual gfx::IntSize GetSize() const override;
|
||||
|
||||
#ifdef MOZ_LAYERS_HAVE_LOG
|
||||
virtual const char* Name() override { return "MacIOSurfaceTextureHostOGL"; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
GLTextureSource* CreateTextureSourceForPlane(size_t aPlane);
|
||||
|
||||
RefPtr<CompositorOGL> mCompositor;
|
||||
RefPtr<GLTextureSource> mTextureSource;
|
||||
RefPtr<MacIOSurface> mSurface;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_GFX_MACIOSURFACETEXTUREHOSTOGL_H
|
||||
|
|
@ -69,7 +69,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android'):
|
|||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in {
|
||||
'android',
|
||||
'cocoa',
|
||||
'gtk2',
|
||||
'gtk3',
|
||||
'uikit',
|
||||
|
|
@ -455,7 +454,7 @@ def write_mozbuild(sources):
|
|||
f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android'):\n")
|
||||
write_sources(f, sources['android'], 4)
|
||||
|
||||
f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] in {'cocoa', 'uikit'}:\n")
|
||||
f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] in {'uikit'}:\n")
|
||||
write_sources(f, sources['mac'], 4)
|
||||
|
||||
f.write("if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:\n")
|
||||
|
|
|
|||
|
|
@ -528,7 +528,7 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android'):
|
|||
'skia/src/ports/SkFontHost_cairo.cpp',
|
||||
'skia/src/ports/SkFontHost_FreeType_common.cpp',
|
||||
]
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in {'cocoa', 'uikit'}:
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in {'uikit'}:
|
||||
SOURCES += [
|
||||
'skia/src/ports/SkDebug_stdio.cpp',
|
||||
'skia/src/ports/SkOSFile_posix.cpp',
|
||||
|
|
@ -679,7 +679,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android'):
|
|||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in {
|
||||
'android',
|
||||
'cocoa',
|
||||
'gtk2',
|
||||
'gtk3',
|
||||
'uikit',
|
||||
|
|
|
|||
|
|
@ -1,10 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# 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/.
|
||||
|
||||
SOURCES += [
|
||||
'nsIconChannelCocoa.mm',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_image_encoders_icon_mac_nsIconChannel_h
|
||||
#define mozilla_image_encoders_icon_mac_nsIconChannel_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsILoadGroup.h"
|
||||
#include "nsILoadInfo.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIInputStreamPump.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
class nsIFile;
|
||||
|
||||
class nsIconChannel final : public nsIChannel, public nsIStreamListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIREQUEST
|
||||
NS_DECL_NSICHANNEL
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
nsIconChannel();
|
||||
|
||||
nsresult Init(nsIURI* uri);
|
||||
|
||||
protected:
|
||||
virtual ~nsIconChannel();
|
||||
|
||||
nsCOMPtr<nsIURI> mUrl;
|
||||
nsCOMPtr<nsIURI> mOriginalURI;
|
||||
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
||||
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
|
||||
nsCOMPtr<nsISupports> mOwner;
|
||||
nsCOMPtr<nsILoadInfo> mLoadInfo;
|
||||
|
||||
nsCOMPtr<nsIInputStreamPump> mPump;
|
||||
nsCOMPtr<nsIStreamListener> mListener;
|
||||
|
||||
nsresult MakeInputStream(nsIInputStream** _retval, bool nonBlocking);
|
||||
|
||||
nsresult ExtractIconInfoFromUrl(nsIFile** aLocalFile,
|
||||
uint32_t* aDesiredImageSize,
|
||||
nsACString& aContentType,
|
||||
nsACString& aFileExtension);
|
||||
};
|
||||
|
||||
#endif // mozilla_image_encoders_icon_mac_nsIconChannel_h
|
||||
|
|
@ -1,565 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIconChannel.h"
|
||||
#include "mozilla/EndianUtils.h"
|
||||
#include "nsIIconURI.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsMemory.h"
|
||||
#include "nsIStringStream.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsIPipe.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsCExternalHandlerService.h"
|
||||
#include "nsILocalFileMac.h"
|
||||
#include "nsIFileURL.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsProxyRelease.h"
|
||||
#include "nsContentSecurityManager.h"
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
// nsIconChannel methods
|
||||
nsIconChannel::nsIconChannel()
|
||||
{
|
||||
}
|
||||
|
||||
nsIconChannel::~nsIconChannel()
|
||||
{
|
||||
if (mLoadInfo) {
|
||||
NS_ReleaseOnMainThread(mLoadInfo.forget());
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsIconChannel,
|
||||
nsIChannel,
|
||||
nsIRequest,
|
||||
nsIRequestObserver,
|
||||
nsIStreamListener)
|
||||
|
||||
nsresult
|
||||
nsIconChannel::Init(nsIURI* uri)
|
||||
{
|
||||
NS_ASSERTION(uri, "no uri");
|
||||
mUrl = uri;
|
||||
mOriginalURI = uri;
|
||||
nsresult rv;
|
||||
mPump = do_CreateInstance(NS_INPUTSTREAMPUMP_CONTRACTID, &rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIRequest methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::GetName(nsACString& result)
|
||||
{
|
||||
return mUrl->GetSpec(result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::IsPending(bool* result)
|
||||
{
|
||||
return mPump->IsPending(result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::GetStatus(nsresult* status)
|
||||
{
|
||||
return mPump->GetStatus(status);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::Cancel(nsresult status)
|
||||
{
|
||||
return mPump->Cancel(status);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::Suspend(void)
|
||||
{
|
||||
return mPump->Suspend();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::Resume(void)
|
||||
{
|
||||
return mPump->Resume();
|
||||
}
|
||||
|
||||
// nsIRequestObserver methods
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::OnStartRequest(nsIRequest* aRequest,
|
||||
nsISupports* aContext)
|
||||
{
|
||||
if (mListener) {
|
||||
return mListener->OnStartRequest(this, aContext);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::OnStopRequest(nsIRequest* aRequest,
|
||||
nsISupports* aContext,
|
||||
nsresult aStatus)
|
||||
{
|
||||
if (mListener) {
|
||||
mListener->OnStopRequest(this, aContext, aStatus);
|
||||
mListener = nullptr;
|
||||
}
|
||||
|
||||
// Remove from load group
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->RemoveRequest(this, nullptr, aStatus);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIStreamListener methods
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::OnDataAvailable(nsIRequest* aRequest,
|
||||
nsISupports* aContext,
|
||||
nsIInputStream* aStream,
|
||||
uint64_t aOffset,
|
||||
uint32_t aCount)
|
||||
{
|
||||
if (mListener) {
|
||||
return mListener->OnDataAvailable(this, aContext, aStream, aOffset, aCount);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIChannel methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::GetOriginalURI(nsIURI** aURI)
|
||||
{
|
||||
*aURI = mOriginalURI;
|
||||
NS_ADDREF(*aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::SetOriginalURI(nsIURI* aURI)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
mOriginalURI = aURI;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::GetURI(nsIURI** aURI)
|
||||
{
|
||||
*aURI = mUrl;
|
||||
NS_IF_ADDREF(*aURI);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::Open(nsIInputStream** _retval)
|
||||
{
|
||||
return MakeInputStream(_retval, false);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::Open2(nsIInputStream** aStream)
|
||||
{
|
||||
nsCOMPtr<nsIStreamListener> listener;
|
||||
nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return Open(aStream);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIconChannel::ExtractIconInfoFromUrl(nsIFile** aLocalFile,
|
||||
uint32_t* aDesiredImageSize,
|
||||
nsACString& aContentType,
|
||||
nsACString& aFileExtension)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIMozIconURI> iconURI (do_QueryInterface(mUrl, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
iconURI->GetImageSize(aDesiredImageSize);
|
||||
iconURI->GetContentType(aContentType);
|
||||
iconURI->GetFileExtension(aFileExtension);
|
||||
|
||||
nsCOMPtr<nsIURL> url;
|
||||
rv = iconURI->GetIconURL(getter_AddRefs(url));
|
||||
if (NS_FAILED(rv) || !url) return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(url, &rv);
|
||||
if (NS_FAILED(rv) || !fileURL) return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIFile> file;
|
||||
rv = fileURL->GetFile(getter_AddRefs(file));
|
||||
if (NS_FAILED(rv) || !file) return NS_OK;
|
||||
|
||||
nsCOMPtr<nsILocalFileMac> localFileMac (do_QueryInterface(file, &rv));
|
||||
if (NS_FAILED(rv) || !localFileMac) return NS_OK;
|
||||
|
||||
*aLocalFile = file;
|
||||
NS_IF_ADDREF(*aLocalFile);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::AsyncOpen(nsIStreamListener* aListener,
|
||||
nsISupports* ctxt)
|
||||
{
|
||||
MOZ_ASSERT(!mLoadInfo ||
|
||||
mLoadInfo->GetSecurityMode() == 0 ||
|
||||
mLoadInfo->GetInitialSecurityCheckDone() ||
|
||||
(mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL &&
|
||||
nsContentUtils::IsSystemPrincipal(mLoadInfo->LoadingPrincipal())),
|
||||
"security flags in loadInfo but asyncOpen2() not called");
|
||||
|
||||
nsCOMPtr<nsIInputStream> inStream;
|
||||
nsresult rv = MakeInputStream(getter_AddRefs(inStream), true);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Init our stream pump
|
||||
rv = mPump->Init(inStream, int64_t(-1), int64_t(-1), 0, 0, false);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = mPump->AsyncRead(this, ctxt);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Store our real listener
|
||||
mListener = aListener;
|
||||
// Add ourself to the load group, if available
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->AddRequest(this, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::AsyncOpen2(nsIStreamListener* aListener)
|
||||
{
|
||||
nsCOMPtr<nsIStreamListener> listener = aListener;
|
||||
nsresult rv = nsContentSecurityManager::doContentSecurityCheck(this, listener);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return AsyncOpen(listener, nullptr);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIconChannel::MakeInputStream(nsIInputStream** _retval,
|
||||
bool aNonBlocking)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
nsXPIDLCString contentType;
|
||||
nsAutoCString fileExt;
|
||||
nsCOMPtr<nsIFile> fileloc; // file we want an icon for
|
||||
uint32_t desiredImageSize;
|
||||
nsresult rv = ExtractIconInfoFromUrl(getter_AddRefs(fileloc),
|
||||
&desiredImageSize, contentType, fileExt);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool fileExists = false;
|
||||
if (fileloc) {
|
||||
// ensure that we DO NOT resolve aliases, very important for file views
|
||||
fileloc->SetFollowLinks(false);
|
||||
fileloc->Exists(&fileExists);
|
||||
}
|
||||
|
||||
NSImage* iconImage = nil;
|
||||
|
||||
// first try to get the icon from the file if it exists
|
||||
if (fileExists) {
|
||||
nsCOMPtr<nsILocalFileMac> localFileMac(do_QueryInterface(fileloc, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
CFURLRef macURL;
|
||||
if (NS_SUCCEEDED(localFileMac->GetCFURL(&macURL))) {
|
||||
iconImage = [[NSWorkspace sharedWorkspace]
|
||||
iconForFile:[(NSURL*)macURL path]];
|
||||
::CFRelease(macURL);
|
||||
}
|
||||
}
|
||||
|
||||
// if we don't have an icon yet try to get one by extension
|
||||
if (!iconImage && !fileExt.IsEmpty()) {
|
||||
NSString* fileExtension = [NSString stringWithUTF8String:fileExt.get()];
|
||||
iconImage = [[NSWorkspace sharedWorkspace] iconForFileType:fileExtension];
|
||||
}
|
||||
|
||||
// If we still don't have an icon, get the generic document icon.
|
||||
if (!iconImage) {
|
||||
iconImage = [[NSWorkspace sharedWorkspace]
|
||||
iconForFileType:NSFileTypeUnknown];
|
||||
}
|
||||
|
||||
if (!iconImage) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// we have an icon now, size it
|
||||
NSRect desiredSizeRect = NSMakeRect(0, 0, desiredImageSize, desiredImageSize);
|
||||
[iconImage setSize:desiredSizeRect.size];
|
||||
|
||||
[iconImage lockFocus];
|
||||
NSBitmapImageRep* bitmapRep = [[[NSBitmapImageRep alloc]
|
||||
initWithFocusedViewRect:desiredSizeRect]
|
||||
autorelease];
|
||||
[iconImage unlockFocus];
|
||||
|
||||
// we expect the following things to be true about our bitmapRep
|
||||
NS_ENSURE_TRUE(![bitmapRep isPlanar] &&
|
||||
// Not necessarily: on a HiDPI-capable system, we'll get
|
||||
// a 2x bitmap
|
||||
// (unsigned int)[bitmapRep bytesPerPlane] ==
|
||||
// desiredImageSize * desiredImageSize * 4 &&
|
||||
[bitmapRep bitsPerPixel] == 32 &&
|
||||
[bitmapRep samplesPerPixel] == 4 &&
|
||||
[bitmapRep hasAlpha] == YES,
|
||||
NS_ERROR_UNEXPECTED);
|
||||
|
||||
// check what size we actually got, and ensure it isn't too big to return
|
||||
uint32_t actualImageSize = [bitmapRep bytesPerRow] / 4;
|
||||
NS_ENSURE_TRUE(actualImageSize < 256, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// now we can validate the amount of data
|
||||
NS_ENSURE_TRUE((unsigned int)[bitmapRep bytesPerPlane] ==
|
||||
actualImageSize * actualImageSize * 4,
|
||||
NS_ERROR_UNEXPECTED);
|
||||
|
||||
// rgba, pre-multiplied data
|
||||
uint8_t* bitmapRepData = (uint8_t*)[bitmapRep bitmapData];
|
||||
|
||||
// create our buffer
|
||||
int32_t bufferCapacity = 2 + [bitmapRep bytesPerPlane];
|
||||
AutoTArray<uint8_t, 3 + 16 * 16 * 5> iconBuffer; // initial size is for
|
||||
// 16x16
|
||||
iconBuffer.SetLength(bufferCapacity);
|
||||
|
||||
uint8_t* iconBufferPtr = iconBuffer.Elements();
|
||||
|
||||
// write header data into buffer
|
||||
*iconBufferPtr++ = actualImageSize;
|
||||
*iconBufferPtr++ = actualImageSize;
|
||||
|
||||
uint32_t dataCount = [bitmapRep bytesPerPlane];
|
||||
uint32_t index = 0;
|
||||
while (index < dataCount) {
|
||||
// get data from the bitmap
|
||||
uint8_t r = bitmapRepData[index++];
|
||||
uint8_t g = bitmapRepData[index++];
|
||||
uint8_t b = bitmapRepData[index++];
|
||||
uint8_t a = bitmapRepData[index++];
|
||||
|
||||
// write data out to our buffer
|
||||
// non-cairo uses native image format, but the A channel is ignored.
|
||||
// cairo uses ARGB (highest to lowest bits)
|
||||
#if MOZ_LITTLE_ENDIAN
|
||||
*iconBufferPtr++ = b;
|
||||
*iconBufferPtr++ = g;
|
||||
*iconBufferPtr++ = r;
|
||||
*iconBufferPtr++ = a;
|
||||
#else
|
||||
*iconBufferPtr++ = a;
|
||||
*iconBufferPtr++ = r;
|
||||
*iconBufferPtr++ = g;
|
||||
*iconBufferPtr++ = b;
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_ASSERTION(iconBufferPtr == iconBuffer.Elements() + bufferCapacity,
|
||||
"buffer size miscalculation");
|
||||
|
||||
// Now, create a pipe and stuff our data into it
|
||||
nsCOMPtr<nsIInputStream> inStream;
|
||||
nsCOMPtr<nsIOutputStream> outStream;
|
||||
rv = NS_NewPipe(getter_AddRefs(inStream), getter_AddRefs(outStream),
|
||||
bufferCapacity, bufferCapacity, aNonBlocking);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
uint32_t written;
|
||||
rv = outStream->Write((char*)iconBuffer.Elements(), bufferCapacity,
|
||||
&written);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_IF_ADDREF(*_retval = inStream);
|
||||
}
|
||||
}
|
||||
|
||||
// Drop notification callbacks to prevent cycles.
|
||||
mCallbacks = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::GetLoadFlags(uint32_t* aLoadAttributes)
|
||||
{
|
||||
return mPump->GetLoadFlags(aLoadAttributes);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::SetLoadFlags(uint32_t aLoadAttributes)
|
||||
{
|
||||
return mPump->SetLoadFlags(aLoadAttributes);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::GetContentType(nsACString& aContentType)
|
||||
{
|
||||
aContentType.AssignLiteral(IMAGE_ICON_MS);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::SetContentType(const nsACString& aContentType)
|
||||
{
|
||||
//It doesn't make sense to set the content-type on this type
|
||||
// of channel...
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::GetContentCharset(nsACString& aContentCharset)
|
||||
{
|
||||
aContentCharset.AssignLiteral(IMAGE_ICON_MS);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::SetContentCharset(const nsACString& aContentCharset)
|
||||
{
|
||||
//It doesn't make sense to set the content-type on this type
|
||||
// of channel...
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::GetContentDisposition(uint32_t* aContentDisposition)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::SetContentDisposition(uint32_t aContentDisposition)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::
|
||||
GetContentDispositionFilename(nsAString& aContentDispositionFilename)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::
|
||||
SetContentDispositionFilename(const nsAString& aContentDispositionFilename)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::
|
||||
GetContentDispositionHeader(nsACString& aContentDispositionHeader)
|
||||
{
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::GetContentLength(int64_t* aContentLength)
|
||||
{
|
||||
*aContentLength = 0;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::SetContentLength(int64_t aContentLength)
|
||||
{
|
||||
NS_NOTREACHED("nsIconChannel::SetContentLength");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::GetLoadGroup(nsILoadGroup** aLoadGroup)
|
||||
{
|
||||
*aLoadGroup = mLoadGroup;
|
||||
NS_IF_ADDREF(*aLoadGroup);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::SetLoadGroup(nsILoadGroup* aLoadGroup)
|
||||
{
|
||||
mLoadGroup = aLoadGroup;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::GetOwner(nsISupports** aOwner)
|
||||
{
|
||||
*aOwner = mOwner.get();
|
||||
NS_IF_ADDREF(*aOwner);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::SetOwner(nsISupports* aOwner)
|
||||
{
|
||||
mOwner = aOwner;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::GetLoadInfo(nsILoadInfo** aLoadInfo)
|
||||
{
|
||||
NS_IF_ADDREF(*aLoadInfo = mLoadInfo);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::SetLoadInfo(nsILoadInfo* aLoadInfo)
|
||||
{
|
||||
mLoadInfo = aLoadInfo;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::
|
||||
GetNotificationCallbacks(nsIInterfaceRequestor** aNotificationCallbacks)
|
||||
{
|
||||
*aNotificationCallbacks = mCallbacks.get();
|
||||
NS_IF_ADDREF(*aNotificationCallbacks);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::
|
||||
SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
|
||||
{
|
||||
mCallbacks = aNotificationCallbacks;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIconChannel::GetSecurityInfo(nsISupports** aSecurityInfo)
|
||||
{
|
||||
*aSecurityInfo = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -21,8 +21,5 @@ if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
|
|||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
platform = 'win'
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
platform = 'mac'
|
||||
|
||||
if platform:
|
||||
LOCAL_INCLUDES += [platform]
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@ if 'gtk' in toolkit:
|
|||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
DIRS += ['icon/win', 'icon']
|
||||
|
||||
if toolkit == 'cocoa':
|
||||
DIRS += ['icon/mac', 'icon']
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'EXIF.cpp',
|
||||
'iccjpeg.c',
|
||||
|
|
|
|||
|
|
@ -1,15 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# 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/.
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'nsCollationMacUC.cpp',
|
||||
'nsDateTimeFormatMac.cpp',
|
||||
'nsMacCharset.cpp',
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
LOCAL_INCLUDES += [
|
||||
'..',
|
||||
]
|
||||
|
|
@ -1,253 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsCollationMacUC.h"
|
||||
#include "nsILocaleService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "prmem.h"
|
||||
#include "nsString.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsCollationMacUC, nsICollation)
|
||||
|
||||
nsCollationMacUC::nsCollationMacUC()
|
||||
: mInit(false)
|
||||
, mHasCollator(false)
|
||||
, mLocaleICU(nullptr)
|
||||
, mLastStrength(-1)
|
||||
, mCollatorICU(nullptr)
|
||||
{ }
|
||||
|
||||
nsCollationMacUC::~nsCollationMacUC()
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsresult res =
|
||||
#endif
|
||||
CleanUpCollator();
|
||||
NS_ASSERTION(NS_SUCCEEDED(res), "CleanUpCollator failed");
|
||||
if (mLocaleICU) {
|
||||
free(mLocaleICU);
|
||||
mLocaleICU = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsCollationMacUC::ConvertStrength(const int32_t aNSStrength,
|
||||
UCollationStrength* aICUStrength,
|
||||
UColAttributeValue* aCaseLevelOut)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aICUStrength);
|
||||
NS_ENSURE_TRUE((aNSStrength < 4), NS_ERROR_FAILURE);
|
||||
|
||||
UCollationStrength strength = UCOL_DEFAULT;
|
||||
UColAttributeValue caseLevel = UCOL_OFF;
|
||||
switch (aNSStrength) {
|
||||
case kCollationCaseInSensitive:
|
||||
strength = UCOL_PRIMARY;
|
||||
break;
|
||||
case kCollationCaseInsensitiveAscii:
|
||||
strength = UCOL_SECONDARY;
|
||||
break;
|
||||
case kCollationAccentInsenstive:
|
||||
caseLevel = UCOL_ON;
|
||||
strength = UCOL_PRIMARY;
|
||||
break;
|
||||
case kCollationCaseSensitive:
|
||||
strength = UCOL_TERTIARY;
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("Bad aNSStrength passed to ConvertStrength.");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
*aICUStrength = strength;
|
||||
*aCaseLevelOut = caseLevel;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsCollationMacUC::ConvertLocaleICU(nsILocale* aNSLocale, char** aICULocale)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aNSLocale);
|
||||
NS_ENSURE_ARG_POINTER(aICULocale);
|
||||
|
||||
nsAutoString localeString;
|
||||
nsresult res = aNSLocale->GetCategory(NS_LITERAL_STRING("NSILOCALE_COLLATE"), localeString);
|
||||
NS_ENSURE_TRUE(NS_SUCCEEDED(res) && !localeString.IsEmpty(),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_LossyConvertUTF16toASCII tmp(localeString);
|
||||
tmp.ReplaceChar('-', '_');
|
||||
char* locale = (char*)malloc(tmp.Length() + 1);
|
||||
if (!locale) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
strcpy(locale, tmp.get());
|
||||
|
||||
*aICULocale = locale;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsCollationMacUC::EnsureCollator(const int32_t newStrength)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
|
||||
if (mHasCollator && (mLastStrength == newStrength))
|
||||
return NS_OK;
|
||||
|
||||
nsresult res;
|
||||
res = CleanUpCollator();
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
NS_ENSURE_TRUE(mLocaleICU, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
UErrorCode status;
|
||||
status = U_ZERO_ERROR;
|
||||
mCollatorICU = ucol_open(mLocaleICU, &status);
|
||||
NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
|
||||
|
||||
UCollationStrength strength;
|
||||
UColAttributeValue caseLevel;
|
||||
res = ConvertStrength(newStrength, &strength, &caseLevel);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
ucol_setAttribute(mCollatorICU, UCOL_STRENGTH, strength, &status);
|
||||
NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
|
||||
ucol_setAttribute(mCollatorICU, UCOL_CASE_LEVEL, caseLevel, &status);
|
||||
NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
|
||||
ucol_setAttribute(mCollatorICU, UCOL_ALTERNATE_HANDLING, UCOL_DEFAULT, &status);
|
||||
NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
|
||||
ucol_setAttribute(mCollatorICU, UCOL_NUMERIC_COLLATION, UCOL_OFF, &status);
|
||||
NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
|
||||
ucol_setAttribute(mCollatorICU, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
|
||||
NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
|
||||
ucol_setAttribute(mCollatorICU, UCOL_CASE_FIRST, UCOL_DEFAULT, &status);
|
||||
NS_ENSURE_TRUE(U_SUCCESS(status), NS_ERROR_FAILURE);
|
||||
|
||||
mHasCollator = true;
|
||||
|
||||
mLastStrength = newStrength;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsCollationMacUC::CleanUpCollator(void)
|
||||
{
|
||||
if (mHasCollator) {
|
||||
ucol_close(mCollatorICU);
|
||||
mHasCollator = false;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsCollationMacUC::Initialize(nsILocale* locale)
|
||||
{
|
||||
NS_ENSURE_TRUE((!mInit), NS_ERROR_ALREADY_INITIALIZED);
|
||||
nsCOMPtr<nsILocale> appLocale;
|
||||
|
||||
nsresult rv;
|
||||
if (!locale) {
|
||||
nsCOMPtr<nsILocaleService> localeService = do_GetService(NS_LOCALESERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = localeService->GetApplicationLocale(getter_AddRefs(appLocale));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
locale = appLocale;
|
||||
}
|
||||
|
||||
rv = ConvertLocaleICU(locale, &mLocaleICU);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mInit = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsCollationMacUC::AllocateRawSortKey(int32_t strength, const nsAString& stringIn,
|
||||
uint8_t** key, uint32_t* outLen)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
|
||||
NS_ENSURE_ARG_POINTER(key);
|
||||
NS_ENSURE_ARG_POINTER(outLen);
|
||||
|
||||
nsresult res = EnsureCollator(strength);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
uint32_t stringInLen = stringIn.Length();
|
||||
|
||||
const UChar* str = (const UChar*)stringIn.BeginReading();
|
||||
|
||||
int32_t keyLength = ucol_getSortKey(mCollatorICU, str, stringInLen, nullptr, 0);
|
||||
NS_ENSURE_TRUE((stringInLen == 0 || keyLength > 0), NS_ERROR_FAILURE);
|
||||
|
||||
// Since key is freed elsewhere with PR_Free, allocate with PR_Malloc.
|
||||
uint8_t* newKey = (uint8_t*)PR_Malloc(keyLength + 1);
|
||||
if (!newKey) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
keyLength = ucol_getSortKey(mCollatorICU, str, stringInLen, newKey, keyLength + 1);
|
||||
NS_ENSURE_TRUE((stringInLen == 0 || keyLength > 0), NS_ERROR_FAILURE);
|
||||
|
||||
*key = newKey;
|
||||
*outLen = keyLength;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsCollationMacUC::CompareString(int32_t strength, const nsAString& string1,
|
||||
const nsAString& string2, int32_t* result)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
*result = 0;
|
||||
|
||||
nsresult rv = EnsureCollator(strength);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
UCollationResult uresult;
|
||||
uresult = ucol_strcoll(mCollatorICU,
|
||||
(const UChar*)string1.BeginReading(),
|
||||
string1.Length(),
|
||||
(const UChar*)string2.BeginReading(),
|
||||
string2.Length());
|
||||
int32_t res;
|
||||
switch (uresult) {
|
||||
case UCOL_LESS:
|
||||
res = -1;
|
||||
break;
|
||||
case UCOL_EQUAL:
|
||||
res = 0;
|
||||
break;
|
||||
case UCOL_GREATER:
|
||||
res = 1;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("ucol_strcoll returned bad UCollationResult");
|
||||
}
|
||||
*result = res;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsCollationMacUC::CompareRawSortKey(const uint8_t* key1, uint32_t len1,
|
||||
const uint8_t* key2, uint32_t len2,
|
||||
int32_t* result)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInit, NS_ERROR_NOT_INITIALIZED);
|
||||
NS_ENSURE_ARG_POINTER(key1);
|
||||
NS_ENSURE_ARG_POINTER(key2);
|
||||
NS_ENSURE_ARG_POINTER(result);
|
||||
*result = 0;
|
||||
|
||||
int32_t tmpResult = strcmp((const char*)key1, (const char*)key2);
|
||||
int32_t res;
|
||||
if (tmpResult < 0) {
|
||||
res = -1;
|
||||
} else if (tmpResult > 0) {
|
||||
res = 1;
|
||||
} else {
|
||||
res = 0;
|
||||
}
|
||||
*result = res;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsCollationMacUC_h_
|
||||
#define nsCollationMacUC_h_
|
||||
|
||||
#include "nsICollation.h"
|
||||
#include "nsCollation.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
#include "unicode/ucol.h"
|
||||
|
||||
class nsCollationMacUC final : public nsICollation {
|
||||
|
||||
public:
|
||||
nsCollationMacUC();
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsICollation interface
|
||||
NS_DECL_NSICOLLATION
|
||||
|
||||
protected:
|
||||
~nsCollationMacUC();
|
||||
|
||||
nsresult ConvertLocaleICU(nsILocale* aNSLocale, char** aICULocale);
|
||||
nsresult ConvertStrength(const int32_t aStrength,
|
||||
UCollationStrength* aStrengthOut,
|
||||
UColAttributeValue* aCaseLevelOut);
|
||||
nsresult EnsureCollator(const int32_t newStrength);
|
||||
nsresult CleanUpCollator(void);
|
||||
|
||||
private:
|
||||
bool mInit;
|
||||
bool mHasCollator;
|
||||
char* mLocaleICU;
|
||||
int32_t mLastStrength;
|
||||
UCollator* mCollatorICU;
|
||||
};
|
||||
|
||||
#endif /* nsCollationMacUC_h_ */
|
||||
|
|
@ -1,266 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsDateTimeFormatMac.h"
|
||||
#include <CoreFoundation/CFDateFormatter.h>
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsILocaleService.h"
|
||||
#include "nsCRT.h"
|
||||
#include "plstr.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsDateTimeFormatMac, nsIDateTimeFormat)
|
||||
|
||||
nsresult nsDateTimeFormatMac::Initialize(nsILocale* locale)
|
||||
{
|
||||
nsAutoString localeStr;
|
||||
nsAutoString category(NS_LITERAL_STRING("NSILOCALE_TIME"));
|
||||
nsresult res;
|
||||
|
||||
// use cached info if match with stored locale
|
||||
if (nullptr == locale) {
|
||||
if (!mLocale.IsEmpty() &&
|
||||
mLocale.Equals(mAppLocale, nsCaseInsensitiveStringComparator())) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
else {
|
||||
res = locale->GetCategory(category, localeStr);
|
||||
if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
|
||||
if (!mLocale.IsEmpty() &&
|
||||
mLocale.Equals(localeStr,
|
||||
nsCaseInsensitiveStringComparator())) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get application locale
|
||||
nsCOMPtr<nsILocaleService> localeService =
|
||||
do_GetService(NS_LOCALESERVICE_CONTRACTID, &res);
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
nsCOMPtr<nsILocale> appLocale;
|
||||
res = localeService->GetApplicationLocale(getter_AddRefs(appLocale));
|
||||
if (NS_SUCCEEDED(res)) {
|
||||
res = appLocale->GetCategory(category, localeStr);
|
||||
if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
|
||||
mAppLocale = localeStr; // cache app locale name
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// use app default if no locale specified
|
||||
if (nullptr == locale) {
|
||||
mUseDefaultLocale = true;
|
||||
}
|
||||
else {
|
||||
mUseDefaultLocale = false;
|
||||
res = locale->GetCategory(category, localeStr);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(res) && !localeStr.IsEmpty()) {
|
||||
mLocale.Assign(localeStr); // cache locale name
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// performs a locale sensitive date formatting operation on the time_t parameter
|
||||
nsresult nsDateTimeFormatMac::FormatTime(nsILocale* locale,
|
||||
const nsDateFormatSelector dateFormatSelector,
|
||||
const nsTimeFormatSelector timeFormatSelector,
|
||||
const time_t timetTime,
|
||||
nsAString& stringOut)
|
||||
{
|
||||
struct tm tmTime;
|
||||
return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, localtime_r(&timetTime, &tmTime), stringOut);
|
||||
}
|
||||
|
||||
// performs a locale sensitive date formatting operation on the struct tm parameter
|
||||
nsresult nsDateTimeFormatMac::FormatTMTime(nsILocale* locale,
|
||||
const nsDateFormatSelector dateFormatSelector,
|
||||
const nsTimeFormatSelector timeFormatSelector,
|
||||
const struct tm* tmTime,
|
||||
nsAString& stringOut)
|
||||
{
|
||||
nsresult res = NS_OK;
|
||||
|
||||
// set up locale data
|
||||
(void) Initialize(locale);
|
||||
|
||||
// return, nothing to format
|
||||
if (dateFormatSelector == kDateFormatNone && timeFormatSelector == kTimeFormatNone) {
|
||||
stringOut.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(tmTime->tm_mon >= 0, "tm is not set correctly");
|
||||
NS_ASSERTION(tmTime->tm_mday >= 1, "tm is not set correctly");
|
||||
NS_ASSERTION(tmTime->tm_hour >= 0, "tm is not set correctly");
|
||||
NS_ASSERTION(tmTime->tm_min >= 0, "tm is not set correctly");
|
||||
NS_ASSERTION(tmTime->tm_sec >= 0, "tm is not set correctly");
|
||||
NS_ASSERTION(tmTime->tm_wday >= 0, "tm is not set correctly");
|
||||
|
||||
// Got the locale for the formatter:
|
||||
CFLocaleRef formatterLocale;
|
||||
if (!locale) {
|
||||
formatterLocale = CFLocaleCopyCurrent();
|
||||
} else {
|
||||
CFStringRef localeStr = CFStringCreateWithCharacters(nullptr,
|
||||
reinterpret_cast<const UniChar*>(mLocale.get()),
|
||||
mLocale.Length());
|
||||
formatterLocale = CFLocaleCreate(nullptr, localeStr);
|
||||
CFRelease(localeStr);
|
||||
}
|
||||
|
||||
// Get the date style for the formatter:
|
||||
CFDateFormatterStyle dateStyle;
|
||||
switch (dateFormatSelector) {
|
||||
case kDateFormatLong:
|
||||
dateStyle = kCFDateFormatterLongStyle;
|
||||
break;
|
||||
case kDateFormatShort:
|
||||
dateStyle = kCFDateFormatterShortStyle;
|
||||
break;
|
||||
case kDateFormatYearMonth:
|
||||
case kDateFormatWeekday:
|
||||
dateStyle = kCFDateFormatterNoStyle; // formats handled below
|
||||
break;
|
||||
case kDateFormatNone:
|
||||
dateStyle = kCFDateFormatterNoStyle;
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Unknown nsDateFormatSelector");
|
||||
res = NS_ERROR_FAILURE;
|
||||
dateStyle = kCFDateFormatterNoStyle;
|
||||
}
|
||||
|
||||
// Get the time style for the formatter:
|
||||
CFDateFormatterStyle timeStyle;
|
||||
switch (timeFormatSelector) {
|
||||
case kTimeFormatSeconds:
|
||||
case kTimeFormatSecondsForce24Hour: // 24 hour part fixed below
|
||||
timeStyle = kCFDateFormatterMediumStyle;
|
||||
break;
|
||||
case kTimeFormatNoSeconds:
|
||||
case kTimeFormatNoSecondsForce24Hour: // 24 hour part fixed below
|
||||
timeStyle = kCFDateFormatterShortStyle;
|
||||
break;
|
||||
case kTimeFormatNone:
|
||||
timeStyle = kCFDateFormatterNoStyle;
|
||||
break;
|
||||
default:
|
||||
NS_ERROR("Unknown nsTimeFormatSelector");
|
||||
res = NS_ERROR_FAILURE;
|
||||
timeStyle = kCFDateFormatterNoStyle;
|
||||
}
|
||||
|
||||
// Create the formatter and fix up its formatting as necessary:
|
||||
CFDateFormatterRef formatter =
|
||||
CFDateFormatterCreate(nullptr, formatterLocale, dateStyle, timeStyle);
|
||||
|
||||
CFRelease(formatterLocale);
|
||||
|
||||
if (dateFormatSelector == kDateFormatYearMonth ||
|
||||
dateFormatSelector == kDateFormatWeekday) {
|
||||
CFStringRef dateFormat =
|
||||
dateFormatSelector == kDateFormatYearMonth ? CFSTR("yyyy/MM ") : CFSTR("EEE ");
|
||||
|
||||
CFStringRef oldFormat = CFDateFormatterGetFormat(formatter);
|
||||
CFMutableStringRef newFormat = CFStringCreateMutableCopy(nullptr, 0, oldFormat);
|
||||
CFStringInsert(newFormat, 0, dateFormat);
|
||||
CFDateFormatterSetFormat(formatter, newFormat);
|
||||
CFRelease(newFormat); // note we don't own oldFormat
|
||||
}
|
||||
|
||||
if (timeFormatSelector == kTimeFormatSecondsForce24Hour ||
|
||||
timeFormatSelector == kTimeFormatNoSecondsForce24Hour) {
|
||||
// Replace "h" with "H", and remove "a":
|
||||
CFStringRef oldFormat = CFDateFormatterGetFormat(formatter);
|
||||
CFMutableStringRef newFormat = CFStringCreateMutableCopy(nullptr, 0, oldFormat);
|
||||
CFIndex replaceCount = CFStringFindAndReplace(newFormat,
|
||||
CFSTR("h"), CFSTR("H"),
|
||||
CFRangeMake(0, CFStringGetLength(newFormat)),
|
||||
0);
|
||||
NS_ASSERTION(replaceCount <= 2, "Unexpected number of \"h\" occurrences");
|
||||
replaceCount = CFStringFindAndReplace(newFormat,
|
||||
CFSTR("a"), CFSTR(""),
|
||||
CFRangeMake(0, CFStringGetLength(newFormat)),
|
||||
0);
|
||||
NS_ASSERTION(replaceCount <= 1, "Unexpected number of \"a\" occurrences");
|
||||
CFDateFormatterSetFormat(formatter, newFormat);
|
||||
CFRelease(newFormat); // note we don't own oldFormat
|
||||
}
|
||||
|
||||
// Now get the formatted date:
|
||||
CFGregorianDate date;
|
||||
date.second = tmTime->tm_sec;
|
||||
date.minute = tmTime->tm_min;
|
||||
date.hour = tmTime->tm_hour;
|
||||
date.day = tmTime->tm_mday; // Mac is 1-based, tm is 1-based
|
||||
date.month = tmTime->tm_mon + 1; // Mac is 1-based, tm is 0-based
|
||||
date.year = tmTime->tm_year + 1900;
|
||||
|
||||
CFTimeZoneRef timeZone = CFTimeZoneCopySystem(); // tmTime is in local time
|
||||
CFAbsoluteTime absTime = CFGregorianDateGetAbsoluteTime(date, timeZone);
|
||||
CFRelease(timeZone);
|
||||
|
||||
CFStringRef formattedDate = CFDateFormatterCreateStringWithAbsoluteTime(nullptr,
|
||||
formatter,
|
||||
absTime);
|
||||
|
||||
CFIndex stringLen = CFStringGetLength(formattedDate);
|
||||
|
||||
AutoTArray<UniChar, 256> stringBuffer;
|
||||
stringBuffer.SetLength(stringLen + 1);
|
||||
CFStringGetCharacters(formattedDate, CFRangeMake(0, stringLen), stringBuffer.Elements());
|
||||
stringOut.Assign(reinterpret_cast<char16_t*>(stringBuffer.Elements()), stringLen);
|
||||
|
||||
CFRelease(formattedDate);
|
||||
CFRelease(formatter);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// performs a locale sensitive date formatting operation on the PRTime parameter
|
||||
nsresult nsDateTimeFormatMac::FormatPRTime(nsILocale* locale,
|
||||
const nsDateFormatSelector dateFormatSelector,
|
||||
const nsTimeFormatSelector timeFormatSelector,
|
||||
const PRTime prTime,
|
||||
nsAString& stringOut)
|
||||
{
|
||||
PRExplodedTime explodedTime;
|
||||
PR_ExplodeTime(prTime, PR_LocalTimeParameters, &explodedTime);
|
||||
|
||||
return FormatPRExplodedTime(locale, dateFormatSelector, timeFormatSelector, &explodedTime, stringOut);
|
||||
}
|
||||
|
||||
// performs a locale sensitive date formatting operation on the PRExplodedTime parameter
|
||||
nsresult nsDateTimeFormatMac::FormatPRExplodedTime(nsILocale* locale,
|
||||
const nsDateFormatSelector dateFormatSelector,
|
||||
const nsTimeFormatSelector timeFormatSelector,
|
||||
const PRExplodedTime* explodedTime,
|
||||
nsAString& stringOut)
|
||||
{
|
||||
struct tm tmTime;
|
||||
memset( &tmTime, 0, sizeof(tmTime) );
|
||||
|
||||
tmTime.tm_yday = explodedTime->tm_yday;
|
||||
tmTime.tm_wday = explodedTime->tm_wday;
|
||||
tmTime.tm_year = explodedTime->tm_year;
|
||||
tmTime.tm_year -= 1900;
|
||||
tmTime.tm_mon = explodedTime->tm_month;
|
||||
tmTime.tm_mday = explodedTime->tm_mday;
|
||||
tmTime.tm_hour = explodedTime->tm_hour;
|
||||
tmTime.tm_min = explodedTime->tm_min;
|
||||
tmTime.tm_sec = explodedTime->tm_sec;
|
||||
|
||||
return FormatTMTime(locale, dateFormatSelector, timeFormatSelector, &tmTime, stringOut);
|
||||
}
|
||||
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#ifndef nsDateTimeFormatMac_h__
|
||||
#define nsDateTimeFormatMac_h__
|
||||
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDateTimeFormat.h"
|
||||
|
||||
|
||||
class nsDateTimeFormatMac : public nsIDateTimeFormat {
|
||||
|
||||
public:
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
// performs a locale sensitive date formatting operation on the time_t parameter
|
||||
NS_IMETHOD FormatTime(nsILocale* locale,
|
||||
const nsDateFormatSelector dateFormatSelector,
|
||||
const nsTimeFormatSelector timeFormatSelector,
|
||||
const time_t timetTime,
|
||||
nsAString& stringOut) override;
|
||||
|
||||
// performs a locale sensitive date formatting operation on the struct tm parameter
|
||||
NS_IMETHOD FormatTMTime(nsILocale* locale,
|
||||
const nsDateFormatSelector dateFormatSelector,
|
||||
const nsTimeFormatSelector timeFormatSelector,
|
||||
const struct tm* tmTime,
|
||||
nsAString& stringOut) override;
|
||||
// performs a locale sensitive date formatting operation on the PRTime parameter
|
||||
NS_IMETHOD FormatPRTime(nsILocale* locale,
|
||||
const nsDateFormatSelector dateFormatSelector,
|
||||
const nsTimeFormatSelector timeFormatSelector,
|
||||
const PRTime prTime,
|
||||
nsAString& stringOut) override;
|
||||
|
||||
// performs a locale sensitive date formatting operation on the PRExplodedTime parameter
|
||||
NS_IMETHOD FormatPRExplodedTime(nsILocale* locale,
|
||||
const nsDateFormatSelector dateFormatSelector,
|
||||
const nsTimeFormatSelector timeFormatSelector,
|
||||
const PRExplodedTime* explodedTime,
|
||||
nsAString& stringOut) override;
|
||||
|
||||
nsDateTimeFormatMac() {}
|
||||
|
||||
protected:
|
||||
virtual ~nsDateTimeFormatMac() {}
|
||||
|
||||
private:
|
||||
// init this interface to a specified locale
|
||||
NS_IMETHOD Initialize(nsILocale* locale);
|
||||
|
||||
nsString mLocale;
|
||||
nsString mAppLocale;
|
||||
bool mUseDefaultLocale;
|
||||
};
|
||||
|
||||
#endif /* nsDateTimeFormatMac_h__ */
|
||||
|
|
@ -1,59 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#include "nsIPlatformCharset.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsPlatformCharset.h"
|
||||
#include "nsEncoderDecoderUtils.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPlatformCharset, nsIPlatformCharset)
|
||||
|
||||
nsPlatformCharset::nsPlatformCharset()
|
||||
{
|
||||
}
|
||||
nsPlatformCharset::~nsPlatformCharset()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPlatformCharset::GetCharset(nsPlatformCharsetSel selector, nsACString& oResult)
|
||||
{
|
||||
oResult.AssignLiteral("UTF-8");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPlatformCharset::GetDefaultCharsetForLocale(const nsAString& localeName, nsACString &oResult)
|
||||
{
|
||||
oResult.AssignLiteral("UTF-8");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPlatformCharset::Init()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPlatformCharset::MapToCharset(nsAString& inANSICodePage, nsACString& outCharset)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPlatformCharset::InitGetCharset(nsACString &oString)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPlatformCharset::VerifyCharset(nsCString &aCharset)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -9,8 +9,6 @@ toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
|
|||
|
||||
if toolkit == 'windows':
|
||||
DIRS += ['windows']
|
||||
elif toolkit == 'cocoa':
|
||||
DIRS += ['mac']
|
||||
else:
|
||||
DIRS += ['unix']
|
||||
|
||||
|
|
|
|||
|
|
@ -32,10 +32,6 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
SOURCES += [
|
||||
'nsUniscribeBreaker.cpp',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
UNIFIED_SOURCES += [
|
||||
'nsCarbonBreaker.cpp',
|
||||
]
|
||||
else:
|
||||
SOURCES += [
|
||||
'nsRuleBreaker.cpp',
|
||||
|
|
|
|||
|
|
@ -1,44 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <stdint.h>
|
||||
#include "nsDebug.h"
|
||||
#include "nscore.h"
|
||||
|
||||
void
|
||||
NS_GetComplexLineBreaks(const char16_t* aText, uint32_t aLength,
|
||||
uint8_t* aBreakBefore)
|
||||
{
|
||||
NS_ASSERTION(aText, "aText shouldn't be null");
|
||||
|
||||
memset(aBreakBefore, 0, aLength * sizeof(uint8_t));
|
||||
|
||||
CFStringRef str = ::CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, reinterpret_cast<const UniChar*>(aText), aLength, kCFAllocatorNull);
|
||||
if (!str) {
|
||||
return;
|
||||
}
|
||||
|
||||
CFStringTokenizerRef st = ::CFStringTokenizerCreate(kCFAllocatorDefault, str,
|
||||
::CFRangeMake(0, aLength),
|
||||
kCFStringTokenizerUnitLineBreak,
|
||||
nullptr);
|
||||
if (!st) {
|
||||
::CFRelease(str);
|
||||
return;
|
||||
}
|
||||
|
||||
CFStringTokenizerTokenType tt = ::CFStringTokenizerAdvanceToNextToken(st);
|
||||
while (tt != kCFStringTokenizerTokenNone) {
|
||||
CFRange r = ::CFStringTokenizerGetCurrentTokenRange(st);
|
||||
if (r.location != 0) { // Ignore leading edge
|
||||
aBreakBefore[r.location] = true;
|
||||
}
|
||||
tt = CFStringTokenizerAdvanceToNextToken(st);
|
||||
}
|
||||
|
||||
::CFRelease(st);
|
||||
::CFRelease(str);
|
||||
}
|
||||
|
|
@ -14,11 +14,6 @@ SOURCES += [
|
|||
'xpcshell.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
SOURCES += [
|
||||
'xpcshellMacUtils.mm',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
// Functions to setup and release the Mac memory pool
|
||||
void InitAutoreleasePool();
|
||||
void FinishAutoreleasePool();
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <Foundation/Foundation.h>
|
||||
|
||||
static NSAutoreleasePool *pool = NULL;
|
||||
|
||||
void InitAutoreleasePool()
|
||||
{
|
||||
pool = [[NSAutoreleasePool alloc] init];
|
||||
}
|
||||
|
||||
void FinishAutoreleasePool()
|
||||
{
|
||||
[pool release];
|
||||
}
|
||||
|
|
@ -63,10 +63,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
|||
LOCAL_INCLUDES += [
|
||||
'/dom/system/windows',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'/dom/system/mac',
|
||||
]
|
||||
elif 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:
|
||||
LOCAL_INCLUDES += [
|
||||
'/widget/gtk',
|
||||
|
|
|
|||
|
|
@ -350,9 +350,6 @@ include text-svgglyphs/reftest.list
|
|||
# text-transform/
|
||||
include text-transform/reftest.list
|
||||
|
||||
# theme (osx)
|
||||
include ../../toolkit/themes/osx/reftests/reftest.list
|
||||
|
||||
include ../../toolkit/content/tests/reftests/reftest.list
|
||||
|
||||
# -moz-transform/
|
||||
|
|
|
|||
|
|
@ -4667,7 +4667,7 @@ CSSParserImpl::ParseSupportsConditionInParens(bool& aConditionMet)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (AgentRulesEnabled() &&
|
||||
if ((AgentRulesEnabled() || ChromeRulesEnabled()) &&
|
||||
mToken.mType == eCSSToken_Function &&
|
||||
mToken.mIdent.LowerCaseEqualsLiteral("-moz-bool-pref")) {
|
||||
return ParseSupportsMozBoolPrefName(aConditionMet);
|
||||
|
|
|
|||
|
|
@ -466,20 +466,60 @@ GetOperatingSystemVersion(nsPresContext* aPresContext, const nsMediaFeature* aFe
|
|||
|
||||
static nsresult
|
||||
GetPrefersColorScheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
|
||||
nsCSSValue& aResult)
|
||||
nsCSSValue& aResult)
|
||||
{
|
||||
switch(Preferences::GetInt("browser.display.prefers_color_scheme", 1)) {
|
||||
case 1:
|
||||
aResult.SetIntValue(NS_STYLE_PREFERS_COLOR_SCHEME_LIGHT,
|
||||
eCSSUnit_Enumerated);
|
||||
break;
|
||||
aResult.SetIntValue(NS_STYLE_PREFERS_COLOR_SCHEME_LIGHT,
|
||||
eCSSUnit_Enumerated);
|
||||
break;
|
||||
case 2:
|
||||
aResult.SetIntValue(NS_STYLE_PREFERS_COLOR_SCHEME_DARK,
|
||||
eCSSUnit_Enumerated);
|
||||
break;
|
||||
aResult.SetIntValue(NS_STYLE_PREFERS_COLOR_SCHEME_DARK,
|
||||
eCSSUnit_Enumerated);
|
||||
break;
|
||||
case 3:
|
||||
// If the pref is 3, we follow ui.color_scheme instead. When following
|
||||
// ui.color_scheme, light theme is the fallback behavior.
|
||||
switch(Preferences::GetInt("ui.color_scheme", 1)) {
|
||||
case 2:
|
||||
aResult.SetIntValue(NS_STYLE_PREFERS_COLOR_SCHEME_DARK,
|
||||
eCSSUnit_Enumerated);
|
||||
break;
|
||||
default:
|
||||
aResult.SetIntValue(NS_STYLE_PREFERS_COLOR_SCHEME_LIGHT,
|
||||
eCSSUnit_Enumerated);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
aResult.Reset();
|
||||
aResult.Reset();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
GetDarkTheme(nsPresContext* aPresContext, const nsMediaFeature* aFeature,
|
||||
nsCSSValue& aResult)
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
// Under Windows, do nothing if High Contrast Theme is on.
|
||||
if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseAccessibilityTheme, 0)) {
|
||||
aResult.Reset();
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(Preferences::GetInt("ui.color_scheme", 1)) {
|
||||
case 1:
|
||||
aResult.SetIntValue(0, eCSSUnit_Integer);
|
||||
break;
|
||||
case 2:
|
||||
aResult.SetIntValue(1, eCSSUnit_Integer);
|
||||
break;
|
||||
default:
|
||||
aResult.Reset();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -645,6 +685,14 @@ nsMediaFeatures::features[] = {
|
|||
},
|
||||
|
||||
// Mozilla extensions
|
||||
{
|
||||
&nsGkAtoms::_moz_dark_theme,
|
||||
nsMediaFeature::eMinMaxNotAllowed,
|
||||
nsMediaFeature::eBoolInteger,
|
||||
nsMediaFeature::eNoRequirements,
|
||||
{ nullptr },
|
||||
GetDarkTheme
|
||||
},
|
||||
{
|
||||
&nsGkAtoms::_moz_device_pixel_ratio,
|
||||
nsMediaFeature::eMinMaxAllowed,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,4 @@
|
|||
# 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/.
|
||||
|
||||
# Disable movemail for Thunderbird on OSX
|
||||
if CONFIG['MOZ_MOVEMAIL'] and not (CONFIG['MOZ_THUNDERBIRD'] and CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa'):
|
||||
FINAL_TARGET_FILES.isp += ['movemail.rdf']
|
||||
# Stub. This was configuring special snowflake OSX stuff.
|
||||
|
|
@ -61,8 +61,6 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
|||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3', 'qt'):
|
||||
SOURCES += ['nsMessengerUnixIntegration.cpp']
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
SOURCES += ['nsMessengerOSXIntegration.mm']
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'folderLookupService.js',
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsMessengerOSXIntegration_h
|
||||
#define __nsMessengerOSXIntegration_h
|
||||
|
||||
#include "nsIMessengerOSIntegration.h"
|
||||
#include "nsIFolderListener.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIAlertsService.h"
|
||||
#include "mozINewMailListener.h"
|
||||
|
||||
#define NS_MESSENGEROSXINTEGRATION_CID \
|
||||
{0xaa83266, 0x4225, 0x4c4b, \
|
||||
{0x93, 0xf8, 0x94, 0xb1, 0x82, 0x58, 0x6f, 0x93}}
|
||||
|
||||
class nsIStringBundle;
|
||||
|
||||
class nsMessengerOSXIntegration : public nsIMessengerOSIntegration,
|
||||
public nsIFolderListener,
|
||||
public nsIObserver,
|
||||
public mozINewMailListener
|
||||
{
|
||||
public:
|
||||
nsMessengerOSXIntegration();
|
||||
virtual nsresult Init();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMESSENGEROSINTEGRATION
|
||||
NS_DECL_NSIFOLDERLISTENER
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_MOZINEWMAILLISTENER
|
||||
|
||||
private:
|
||||
virtual ~nsMessengerOSXIntegration();
|
||||
|
||||
nsCOMPtr<nsIAtom> mBiffStateAtom;
|
||||
nsCOMPtr<nsIAtom> mNewMailReceivedAtom;
|
||||
nsresult ShowAlertMessage(const nsAString& aAlertTitle, const nsAString& aAlertText, const nsACString& aFolderURI);
|
||||
nsresult OnAlertFinished();
|
||||
nsresult OnAlertClicked(const char16_t * aAlertCookie);
|
||||
#ifdef MOZ_SUITE
|
||||
nsresult OnAlertClickedSimple();
|
||||
#endif
|
||||
nsresult GetStringBundle(nsIStringBundle **aBundle);
|
||||
void FillToolTipInfo(nsIMsgFolder *aFolder, int32_t aNewCount);
|
||||
nsresult GetFirstFolderWithNewMail(nsIMsgFolder* aFolder, nsCString& aFolderURI);
|
||||
nsresult BadgeDockIcon();
|
||||
nsresult RestoreDockIcon();
|
||||
nsresult BounceDockIcon();
|
||||
nsresult GetNewMailAuthors(nsIMsgFolder* aFolder, nsString& aAuthors, int32_t aNewCount, int32_t* aNotDisplayed);
|
||||
|
||||
int32_t mUnreadTotal;
|
||||
int32_t mUnreadChat;
|
||||
};
|
||||
|
||||
#endif // __nsMessengerOSXIntegration_h
|
||||
|
|
@ -1,700 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsMsgUtils.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsMessengerOSXIntegration.h"
|
||||
#include "nsIMsgMailSession.h"
|
||||
#include "nsIMsgIncomingServer.h"
|
||||
#include "nsIMsgIdentity.h"
|
||||
#include "nsIMsgAccount.h"
|
||||
#include "nsIMsgFolder.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsMsgBaseCID.h"
|
||||
#include "nsMsgFolderFlags.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsIDirectoryService.h"
|
||||
#include "MailNewsTypes.h"
|
||||
#include "nsIWindowMediator.h"
|
||||
#include "nsIDOMChromeWindow.h"
|
||||
#include "mozIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIMessengerWindowService.h"
|
||||
#include "prprf.h"
|
||||
#include "nsIAlertsService.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsToolkitCompsCID.h"
|
||||
#include "nsIMsgDatabase.h"
|
||||
#include "nsIMsgHdr.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsMsgLocalCID.h"
|
||||
#include "nsIMsgMailNewsUrl.h"
|
||||
#include "nsIMsgWindow.h"
|
||||
#include "nsIMsgAccountManager.h"
|
||||
#include "nsIMessenger.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "mozINewMailNotificationService.h"
|
||||
#include "mozilla/mailnews/MimeHeaderParser.h"
|
||||
|
||||
#include <Carbon/Carbon.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#define kBiffAnimateDockIconPref "mail.biff.animate_dock_icon"
|
||||
#define kMaxDisplayCount 10
|
||||
|
||||
using namespace mozilla::mailnews;
|
||||
|
||||
// HACK: Limitations in Focus/SetFocus on Mac (see bug 465446)
|
||||
nsresult FocusAppNative()
|
||||
{
|
||||
ProcessSerialNumber psn;
|
||||
|
||||
if (::GetCurrentProcess(&psn) != 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (::SetFrontProcess(&psn) != 0)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void openMailWindow(const nsCString& aUri)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIMsgMailSession> mailSession ( do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIMsgWindow> topMostMsgWindow;
|
||||
rv = mailSession->GetTopmostMsgWindow(getter_AddRefs(topMostMsgWindow));
|
||||
if (topMostMsgWindow)
|
||||
{
|
||||
if (!aUri.IsEmpty())
|
||||
{
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> msgUri(do_CreateInstance(NS_MAILBOXURL_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
rv = msgUri->SetSpec(aUri);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
bool isMessageUri = false;
|
||||
msgUri->GetIsMessageUri(&isMessageUri);
|
||||
if (isMessageUri)
|
||||
{
|
||||
nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
// SeaMonkey only supports message uris, whereas Thunderbird only
|
||||
// supports message headers. This should be simplified/removed when
|
||||
// bug 507593 is implemented.
|
||||
#ifdef MOZ_SUITE
|
||||
nsCOMPtr<mozIDOMWindowProxy> newWindow;
|
||||
wwatch->OpenWindow(0, "chrome://messenger/content/messageWindow.xul",
|
||||
"_blank", "all,chrome,dialog=no,status,toolbar", msgUri,
|
||||
getter_AddRefs(newWindow));
|
||||
#else
|
||||
nsCOMPtr<nsIMessenger> messenger(do_CreateInstance(NS_MESSENGER_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIMsgDBHdr> msgHdr;
|
||||
messenger->MsgHdrFromURI(aUri, getter_AddRefs(msgHdr));
|
||||
if (msgHdr)
|
||||
{
|
||||
nsCOMPtr<mozIDOMWindowProxy> newWindow;
|
||||
wwatch->OpenWindow(0, "chrome://messenger/content/messageWindow.xul",
|
||||
"_blank", "all,chrome,dialog=no,status,toolbar", msgHdr,
|
||||
getter_AddRefs(newWindow));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsIMsgWindowCommands> windowCommands;
|
||||
topMostMsgWindow->GetWindowCommands(getter_AddRefs(windowCommands));
|
||||
if (windowCommands)
|
||||
windowCommands->SelectFolder(aUri);
|
||||
}
|
||||
}
|
||||
|
||||
FocusAppNative();
|
||||
nsCOMPtr<mozIDOMWindowProxy> domWindow;
|
||||
topMostMsgWindow->GetDomWindow(getter_AddRefs(domWindow));
|
||||
if (domWindow) {
|
||||
nsCOMPtr<nsPIDOMWindowOuter> privateWindow = nsPIDOMWindowOuter::From(domWindow);
|
||||
privateWindow->Focus();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// the user doesn't have a mail window open already so open one for them...
|
||||
nsCOMPtr<nsIMessengerWindowService> messengerWindowService =
|
||||
do_GetService(NS_MESSENGERWINDOWSERVICE_CONTRACTID);
|
||||
// if we want to preselect the first account with new mail,
|
||||
// here is where we would try to generate a uri to pass in
|
||||
// (and add code to the messenger window service to make that work)
|
||||
if (messengerWindowService)
|
||||
messengerWindowService->OpenMessengerWindowWithUri(
|
||||
"mail:3pane", aUri.get(), nsMsgKey_None);
|
||||
}
|
||||
}
|
||||
|
||||
nsMessengerOSXIntegration::nsMessengerOSXIntegration()
|
||||
{
|
||||
mBiffStateAtom = MsgGetAtom("BiffState");
|
||||
mNewMailReceivedAtom = MsgGetAtom("NewMailReceived");
|
||||
mUnreadTotal = 0;
|
||||
}
|
||||
|
||||
nsMessengerOSXIntegration::~nsMessengerOSXIntegration()
|
||||
{
|
||||
RestoreDockIcon();
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsMessengerOSXIntegration)
|
||||
NS_IMPL_RELEASE(nsMessengerOSXIntegration)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsMessengerOSXIntegration)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMessengerOSIntegration)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIMessengerOSIntegration)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFolderListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIObserver)
|
||||
NS_INTERFACE_MAP_ENTRY(mozINewMailListener)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
||||
nsresult
|
||||
nsMessengerOSXIntegration::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return observerService->AddObserver(this, "mail-startup-done", false);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMessengerOSXIntegration::OnItemPropertyChanged(nsIMsgFolder *, nsIAtom *, char const *, char const *)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMessengerOSXIntegration::OnItemUnicharPropertyChanged(nsIMsgFolder *, nsIAtom *, const char16_t *, const char16_t *)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMessengerOSXIntegration::OnItemRemoved(nsIMsgFolder *, nsISupports *)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMessengerOSXIntegration::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
|
||||
{
|
||||
if (!strcmp(aTopic, "alertfinished"))
|
||||
return OnAlertFinished();
|
||||
|
||||
if (!strcmp(aTopic, "alertclickcallback"))
|
||||
return OnAlertClicked(aData);
|
||||
|
||||
#ifdef MOZ_SUITE
|
||||
// SeaMonkey does most of the GUI work in JS code when clicking on a mail
|
||||
// notification, so it needs an extra function here
|
||||
if (!strcmp(aTopic, "alertclicksimplecallback"))
|
||||
return OnAlertClickedSimple();
|
||||
#endif
|
||||
|
||||
if (!strcmp(aTopic, "mail-startup-done")) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
observerService->RemoveObserver(this, "mail-startup-done");
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
||||
}
|
||||
|
||||
// Register with the new mail service for changes to the unread message count
|
||||
nsCOMPtr<mozINewMailNotificationService> newmail
|
||||
= do_GetService(MOZ_NEWMAILNOTIFICATIONSERVICE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv); // This should really be an assert with a helpful message
|
||||
rv = newmail->AddListener(this, mozINewMailNotificationService::count);
|
||||
NS_ENSURE_SUCCESS(rv, rv); // This should really be an assert with a helpful message
|
||||
|
||||
// Get the initial unread count. Ignore return value; if code above didn't fail, this won't
|
||||
rv = newmail->GetMessageCount(&mUnreadTotal);
|
||||
BadgeDockIcon();
|
||||
|
||||
// register with the mail sesson for folder events
|
||||
// we care about new count, biff status
|
||||
nsCOMPtr<nsIMsgMailSession> mailSession = do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return mailSession->AddFolderListener(this, nsIFolderListener::boolPropertyChanged | nsIFolderListener::intPropertyChanged);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMessengerOSXIntegration::GetStringBundle(nsIStringBundle **aBundle)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aBundle);
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
if (bundleService && NS_SUCCEEDED(rv))
|
||||
bundleService->CreateBundle("chrome://messenger/locale/messenger.properties", getter_AddRefs(bundle));
|
||||
bundle.swap(*aBundle);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
nsMessengerOSXIntegration::FillToolTipInfo(nsIMsgFolder *aFolder, int32_t aNewCount)
|
||||
{
|
||||
if (aFolder)
|
||||
{
|
||||
nsString authors;
|
||||
int32_t numNotDisplayed;
|
||||
nsresult rv = GetNewMailAuthors(aFolder, authors, aNewCount, &numNotDisplayed);
|
||||
|
||||
// If all senders are vetoed, the authors string will be empty.
|
||||
if (NS_FAILED(rv) || authors.IsEmpty())
|
||||
return;
|
||||
|
||||
// If this isn't the root folder, get it so we can report for it.
|
||||
// GetRootFolder always returns the server's root, so calling on the root itself is fine.
|
||||
nsCOMPtr<nsIMsgFolder> rootFolder;
|
||||
aFolder->GetRootFolder(getter_AddRefs(rootFolder));
|
||||
if (!rootFolder)
|
||||
return;
|
||||
|
||||
nsString accountName;
|
||||
rootFolder->GetPrettiestName(accountName);
|
||||
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
GetStringBundle(getter_AddRefs(bundle));
|
||||
if (bundle)
|
||||
{
|
||||
nsAutoString numNewMsgsText;
|
||||
numNewMsgsText.AppendInt(aNewCount);
|
||||
nsString finalText;
|
||||
nsCString uri;
|
||||
aFolder->GetURI(uri);
|
||||
|
||||
if (numNotDisplayed > 0)
|
||||
{
|
||||
nsAutoString numNotDisplayedText;
|
||||
numNotDisplayedText.AppendInt(numNotDisplayed);
|
||||
const char16_t *formatStrings[3] = { numNewMsgsText.get(), authors.get(), numNotDisplayedText.get() };
|
||||
bundle->FormatStringFromName(u"macBiffNotification_messages_extra",
|
||||
formatStrings,
|
||||
3,
|
||||
getter_Copies(finalText));
|
||||
}
|
||||
else
|
||||
{
|
||||
const char16_t *formatStrings[2] = { numNewMsgsText.get(), authors.get() };
|
||||
|
||||
if (aNewCount == 1)
|
||||
{
|
||||
bundle->FormatStringFromName(u"macBiffNotification_message",
|
||||
formatStrings,
|
||||
2,
|
||||
getter_Copies(finalText));
|
||||
// Since there is only 1 message, use the most recent mail's URI instead of the folder's
|
||||
nsCOMPtr<nsIMsgDatabase> db;
|
||||
rv = aFolder->GetMsgDatabase(getter_AddRefs(db));
|
||||
if (NS_SUCCEEDED(rv) && db)
|
||||
{
|
||||
uint32_t numNewKeys;
|
||||
uint32_t *newMessageKeys;
|
||||
rv = db->GetNewList(&numNewKeys, &newMessageKeys);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr<nsIMsgDBHdr> hdr;
|
||||
rv = db->GetMsgHdrForKey(newMessageKeys[numNewKeys - 1],
|
||||
getter_AddRefs(hdr));
|
||||
if (NS_SUCCEEDED(rv) && hdr)
|
||||
aFolder->GetUriForMsg(hdr, uri);
|
||||
}
|
||||
NS_Free(newMessageKeys);
|
||||
}
|
||||
}
|
||||
else
|
||||
bundle->FormatStringFromName(u"macBiffNotification_messages",
|
||||
formatStrings,
|
||||
2,
|
||||
getter_Copies(finalText));
|
||||
}
|
||||
ShowAlertMessage(accountName, finalText, uri);
|
||||
} // if we got a bundle
|
||||
} // if we got a folder
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMessengerOSXIntegration::ShowAlertMessage(const nsAString& aAlertTitle,
|
||||
const nsAString& aAlertText,
|
||||
const nsACString& aFolderURI)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIAlertsService> alertsService (do_GetService(NS_ALERTSERVICE_CONTRACTID, &rv));
|
||||
// If we have an nsIAlertsService implementation, use it:
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
alertsService->ShowAlertNotification(EmptyString(),
|
||||
aAlertTitle, aAlertText, true,
|
||||
NS_ConvertASCIItoUTF16(aFolderURI),
|
||||
this, EmptyString(),
|
||||
NS_LITERAL_STRING("auto"),
|
||||
EmptyString(), EmptyString(),
|
||||
nullptr,
|
||||
false,
|
||||
false);
|
||||
}
|
||||
|
||||
BounceDockIcon();
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
OnAlertFinished();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMessengerOSXIntegration::OnItemIntPropertyChanged(nsIMsgFolder *aFolder,
|
||||
nsIAtom *aProperty,
|
||||
int64_t aOldValue,
|
||||
int64_t aNewValue)
|
||||
{
|
||||
// if we got new mail show an alert
|
||||
if (aNewValue == nsIMsgFolder::nsMsgBiffState_NewMail)
|
||||
{
|
||||
bool performingBiff = false;
|
||||
nsCOMPtr<nsIMsgIncomingServer> server;
|
||||
aFolder->GetServer(getter_AddRefs(server));
|
||||
if (server)
|
||||
server->GetPerformingBiff(&performingBiff);
|
||||
if (!performingBiff)
|
||||
return NS_OK; // kick out right now...
|
||||
|
||||
// Biff happens for the root folder, but we want info for the child with new mail
|
||||
nsCString folderUri;
|
||||
GetFirstFolderWithNewMail(aFolder, folderUri);
|
||||
nsCOMPtr<nsIMsgFolder> childFolder;
|
||||
nsresult rv = aFolder->GetChildWithURI(folderUri, true, true,
|
||||
getter_AddRefs(childFolder));
|
||||
if (NS_FAILED(rv) || !childFolder)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
int32_t numNewMessages = 0;
|
||||
childFolder->GetNumNewMessages(true, &numNewMessages);
|
||||
FillToolTipInfo(childFolder, numNewMessages);
|
||||
}
|
||||
else if (mNewMailReceivedAtom == aProperty)
|
||||
{
|
||||
FillToolTipInfo(aFolder, aNewValue);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMessengerOSXIntegration::OnAlertClicked(const char16_t* aAlertCookie)
|
||||
{
|
||||
openMailWindow(NS_ConvertUTF16toUTF8(aAlertCookie));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MOZ_SUITE
|
||||
nsresult
|
||||
nsMessengerOSXIntegration::OnAlertClickedSimple()
|
||||
{
|
||||
// SeaMonkey only function; only focus the app here, rest of the work will
|
||||
// be done in suite/mailnews/mailWidgets.xml
|
||||
FocusAppNative();
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
nsMessengerOSXIntegration::OnAlertFinished()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMessengerOSXIntegration::BounceDockIcon()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bool bounceDockIcon = false;
|
||||
rv = prefBranch->GetBoolPref(kBiffAnimateDockIconPref, &bounceDockIcon);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!bounceDockIcon)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIWindowMediator> mediator(do_GetService(NS_WINDOWMEDIATOR_CONTRACTID));
|
||||
if (mediator)
|
||||
{
|
||||
nsCOMPtr<mozIDOMWindowProxy> domWindow;
|
||||
mediator->GetMostRecentWindow(u"mail:3pane", getter_AddRefs(domWindow));
|
||||
if (domWindow)
|
||||
{
|
||||
nsCOMPtr<nsIDOMChromeWindow> chromeWindow(do_QueryInterface(domWindow));
|
||||
chromeWindow->GetAttention();
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMessengerOSXIntegration::RestoreDockIcon()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
id tile = [[NSApplication sharedApplication] dockTile];
|
||||
[tile setBadgeLabel: nil];
|
||||
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMessengerOSXIntegration::BadgeDockIcon()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
int32_t unreadCount = mUnreadTotal;
|
||||
// If count is less than one, we should restore the original dock icon.
|
||||
if (unreadCount < 1)
|
||||
{
|
||||
RestoreDockIcon();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Draw the number, first giving extensions a chance to modify.
|
||||
// Extensions might wish to transform "1000" into "100+" or some
|
||||
// other short string. Getting back the empty string will cause
|
||||
// nothing to be drawn and us to return early.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIObserverService> os
|
||||
(do_GetService("@mozilla.org/observer-service;1", &rv));
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
RestoreDockIcon();
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsString> str
|
||||
(do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
RestoreDockIcon();
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsAutoString total;
|
||||
total.AppendInt(unreadCount);
|
||||
str->SetData(total);
|
||||
os->NotifyObservers(str, "before-unread-count-display",
|
||||
total.get());
|
||||
nsAutoString badgeString;
|
||||
str->GetData(badgeString);
|
||||
if (badgeString.IsEmpty())
|
||||
{
|
||||
RestoreDockIcon();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
id tile = [[NSApplication sharedApplication] dockTile];
|
||||
[tile setBadgeLabel:[NSString stringWithFormat:@"%S", (const unichar*)badgeString.get()]];
|
||||
return NS_OK;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMessengerOSXIntegration::OnItemPropertyFlagChanged(nsIMsgDBHdr *item, nsIAtom *property, uint32_t oldFlag, uint32_t newFlag)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMessengerOSXIntegration::OnItemAdded(nsIMsgFolder *, nsISupports *)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMessengerOSXIntegration::OnItemBoolPropertyChanged(nsIMsgFolder *aItem,
|
||||
nsIAtom *aProperty,
|
||||
bool aOldValue,
|
||||
bool aNewValue)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMessengerOSXIntegration::OnItemEvent(nsIMsgFolder *, nsIAtom *)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMessengerOSXIntegration::GetNewMailAuthors(nsIMsgFolder* aFolder,
|
||||
nsString& aAuthors,
|
||||
int32_t aNewCount,
|
||||
int32_t* aNotDisplayed)
|
||||
{
|
||||
// Get a list of names or email addresses for the folder's authors
|
||||
// with new mail. Note that we only process the most recent "new"
|
||||
// mail (aNewCount), working from most recently added. Duplicates
|
||||
// are removed, and names are displayed to a set limit
|
||||
// (kMaxDisplayCount) with the remaining count being returned in
|
||||
// aNotDisplayed. Extension developers can listen for
|
||||
// "newmail-notification-requested" and then make a decision about
|
||||
// including a given author or not. As a result, it is possible that
|
||||
// the resulting length of aAuthors will be 0.
|
||||
nsCOMPtr<nsIMsgDatabase> db;
|
||||
nsresult rv = aFolder->GetMsgDatabase(getter_AddRefs(db));
|
||||
uint32_t numNewKeys = 0;
|
||||
if (NS_SUCCEEDED(rv) && db)
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> os =
|
||||
do_GetService("@mozilla.org/observer-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Get proper l10n list separator -- ", " in English
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
GetStringBundle(getter_AddRefs(bundle));
|
||||
if (!bundle)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
uint32_t *newMessageKeys;
|
||||
rv = db->GetNewList(&numNewKeys, &newMessageKeys);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsString listSeparator;
|
||||
bundle->GetStringFromName(u"macBiffNotification_separator", getter_Copies(listSeparator));
|
||||
|
||||
int32_t displayed = 0;
|
||||
for (int32_t i = numNewKeys - 1; i >= 0; i--, aNewCount--)
|
||||
{
|
||||
if (0 == aNewCount || displayed == kMaxDisplayCount)
|
||||
break;
|
||||
|
||||
nsCOMPtr<nsIMsgDBHdr> hdr;
|
||||
rv = db->GetMsgHdrForKey(newMessageKeys[i],
|
||||
getter_AddRefs(hdr));
|
||||
if (NS_SUCCEEDED(rv) && hdr)
|
||||
{
|
||||
nsString author;
|
||||
rv = hdr->GetMime2DecodedAuthor(author);
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
nsString name;
|
||||
ExtractName(DecodedHeader(author), name);
|
||||
|
||||
// Give extensions a chance to suppress notifications for this author
|
||||
nsCOMPtr<nsISupportsPRBool> notify =
|
||||
do_CreateInstance(NS_SUPPORTS_PRBOOL_CONTRACTID);
|
||||
|
||||
notify->SetData(true);
|
||||
os->NotifyObservers(notify, "newmail-notification-requested",
|
||||
author.get());
|
||||
|
||||
bool includeSender;
|
||||
notify->GetData(&includeSender);
|
||||
|
||||
// Don't add unwanted or duplicate names
|
||||
if (includeSender && aAuthors.Find(name, true) == -1)
|
||||
{
|
||||
if (displayed > 0)
|
||||
aAuthors.Append(listSeparator);
|
||||
aAuthors.Append(name);
|
||||
displayed++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_Free(newMessageKeys);
|
||||
}
|
||||
*aNotDisplayed = aNewCount;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMessengerOSXIntegration::GetFirstFolderWithNewMail(nsIMsgFolder* aFolder, nsCString& aFolderURI)
|
||||
{
|
||||
// Find the subfolder in aFolder with new mail and return the folderURI
|
||||
if (aFolder)
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> msgFolder;
|
||||
// enumerate over the folders under this root folder till we find one with new mail....
|
||||
nsCOMPtr<nsIArray> allFolders;
|
||||
nsresult rv = aFolder->GetDescendants(getter_AddRefs(allFolders));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
rv = allFolders->Enumerate(getter_AddRefs(enumerator));
|
||||
if (NS_SUCCEEDED(rv) && enumerator)
|
||||
{
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
int32_t numNewMessages = 0;
|
||||
bool hasMore = false;
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore)
|
||||
{
|
||||
rv = enumerator->GetNext(getter_AddRefs(supports));
|
||||
if (NS_SUCCEEDED(rv) && supports)
|
||||
{
|
||||
msgFolder = do_QueryInterface(supports, &rv);
|
||||
if (msgFolder)
|
||||
{
|
||||
numNewMessages = 0;
|
||||
msgFolder->GetNumNewMessages(false, &numNewMessages);
|
||||
if (numNewMessages)
|
||||
break; // kick out of the while loop
|
||||
}
|
||||
} // if we have a folder
|
||||
} // if we have more potential folders to enumerate
|
||||
} // if enumerator
|
||||
|
||||
if (msgFolder)
|
||||
msgFolder->GetURI(aFolderURI);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Method implementations for mozINewMailListener
|
||||
*/
|
||||
NS_IMETHODIMP
|
||||
nsMessengerOSXIntegration::OnCountChanged(uint32_t count)
|
||||
{
|
||||
mUnreadTotal = count;
|
||||
BadgeDockIcon();
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -35,10 +35,6 @@ if CONFIG['OS_ARCH'] == 'WINNT':
|
|||
else:
|
||||
OS_LIBS += CONFIG['MOZ_ZLIB_LIBS']
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
OS_LIBS += CONFIG['TK_LIBS']
|
||||
OS_LIBS += ['-framework Cocoa']
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/mailnews/addrbook/src',
|
||||
'/mailnews/base/search/src',
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue