mirror of
https://github.com/ManchildProductions/UXP-Fixed.git
synced 2026-05-26 22:49:27 +00:00
Issue #1751 - Remove Mac code behind MOZ_WIDGET_TOOLKIT == 'cocoa'
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
@@ -459,7 +458,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")
|
||||
|
||||
+1
-2
@@ -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',
|
||||
|
||||
@@ -347,9 +347,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/
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -35,16 +35,6 @@ SOURCES += [
|
||||
'nsURLFetcher.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
SOURCES += [
|
||||
'nsMsgAppleDoubleEncode.cpp',
|
||||
'nsMsgAppleEncode.cpp',
|
||||
]
|
||||
EXPORTS += [
|
||||
'nsMsgAppleCodes.h',
|
||||
'nsMsgAppleDouble.h',
|
||||
]
|
||||
|
||||
EXTRA_COMPONENTS += [
|
||||
'nsSMTPProtocolHandler.js',
|
||||
'nsSMTPProtocolHandler.manifest',
|
||||
|
||||
@@ -1,106 +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/. */
|
||||
|
||||
/*
|
||||
** AD_Codes.h
|
||||
**
|
||||
** ---------------
|
||||
**
|
||||
** Head file for Apple Decode/Encode essential codes.
|
||||
**
|
||||
**
|
||||
*/
|
||||
|
||||
#ifndef ad_codes_h
|
||||
#define ad_codes_h
|
||||
|
||||
/*
|
||||
** applefile definitions used
|
||||
*/
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=mac68k
|
||||
#endif
|
||||
|
||||
#define APPLESINGLE_MAGIC 0x00051600L
|
||||
#define APPLEDOUBLE_MAGIC 0x00051607L
|
||||
#define VERSION 0x00020000
|
||||
|
||||
#define NUM_ENTRIES 6
|
||||
|
||||
#define ENT_DFORK 1L
|
||||
#define ENT_RFORK 2L
|
||||
#define ENT_NAME 3L
|
||||
#define ENT_COMMENT 4L
|
||||
#define ENT_DATES 8L
|
||||
#define ENT_FINFO 9L
|
||||
#define CONVERT_TIME 1265437696L
|
||||
|
||||
/*
|
||||
** data type used in the encoder/decoder.
|
||||
*/
|
||||
typedef struct ap_header
|
||||
{
|
||||
int32_t magic;
|
||||
int32_t version;
|
||||
char fill[16];
|
||||
int16_t entries;
|
||||
|
||||
} ap_header;
|
||||
|
||||
typedef struct ap_entry
|
||||
{
|
||||
int32_t id;
|
||||
int32_t offset;
|
||||
int32_t length;
|
||||
|
||||
} ap_entry;
|
||||
|
||||
typedef struct ap_dates
|
||||
{
|
||||
int32_t create, modify, backup, access;
|
||||
|
||||
} ap_dates;
|
||||
|
||||
typedef struct myFInfo /* the mac FInfo structure for the cross platform. */
|
||||
{
|
||||
int32_t fdType, fdCreator;
|
||||
int16_t fdFlags;
|
||||
int32_t fdLocation; /* it really should be a pointer, but just a place-holder */
|
||||
int16_t fdFldr;
|
||||
|
||||
} myFInfo;
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
/*
|
||||
** string utils.
|
||||
*/
|
||||
int write_stream(appledouble_encode_object *p_ap_encode_obj, const char *s,int len);
|
||||
|
||||
int fill_apple_mime_header(appledouble_encode_object *p_ap_encode_obj);
|
||||
int ap_encode_file_infor(appledouble_encode_object *p_ap_encode_obj);
|
||||
int ap_encode_header(appledouble_encode_object* p_ap_encode_obj, bool firstTime);
|
||||
int ap_encode_data( appledouble_encode_object* p_ap_encode_obj, bool firstTime);
|
||||
|
||||
/*
|
||||
** the prototypes for the ap_decoder.
|
||||
*/
|
||||
int fetch_a_line(appledouble_decode_object* p_ap_decode_obj, char *buff);
|
||||
int ParseFileHeader(appledouble_decode_object* p_ap_decode_obj);
|
||||
int ap_seek_part_start(appledouble_decode_object* p_ap_decode_obj);
|
||||
void parse_param(char *p, char **param, char**define, char **np);
|
||||
int ap_seek_to_boundary(appledouble_decode_object* p_ap_decode_obj, bool firstime);
|
||||
int ap_parse_header(appledouble_decode_object* p_ap_decode_obj,bool firstime);
|
||||
int ap_decode_file_infor(appledouble_decode_object* p_ap_decode_obj);
|
||||
int ap_decode_process_header(appledouble_decode_object* p_ap_decode_obj, bool firstime);
|
||||
int ap_decode_process_data( appledouble_decode_object* p_ap_decode_obj, bool firstime);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#if PRAGMA_STRUCT_ALIGN
|
||||
#pragma options align=reset
|
||||
#endif
|
||||
|
||||
#endif /* ad_codes_h */
|
||||
@@ -1,207 +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/. */
|
||||
|
||||
/*
|
||||
* AppleDouble.h
|
||||
* -------------
|
||||
*
|
||||
* The header file for a stream based apple single/double encodor/decodor.
|
||||
*
|
||||
* 2aug95 mym
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef AppleDouble_h
|
||||
#define AppleDouble_h
|
||||
|
||||
#include "msgCore.h"
|
||||
#include "nsComposeStrings.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
#include <CoreServices/CoreServices.h>
|
||||
|
||||
#define NOERR 0
|
||||
#define errDone 1
|
||||
/* Done with current operation. */
|
||||
#define errEOB 2
|
||||
/* End of a buffer. */
|
||||
#define errEOP 3
|
||||
/* End of a Part. */
|
||||
|
||||
|
||||
#define errFileOpen NS_ERROR_GET_CODE(NS_MSG_UNABLE_TO_OPEN_TMP_FILE)
|
||||
#define errFileWrite -202 /*Error writing temporary file.*/
|
||||
#define errUsrCancel -2 /*MK_INTERRUPTED */
|
||||
#define errDecoding -1
|
||||
|
||||
/*
|
||||
** The envirment block data type.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
kInit,
|
||||
kDoingHeaderPortion,
|
||||
kDoneHeaderPortion,
|
||||
kDoingDataPortion,
|
||||
kDoneDataPortion
|
||||
};
|
||||
|
||||
typedef struct _appledouble_encode_object
|
||||
{
|
||||
char fname[256];
|
||||
FSIORefNum fileId; /* the id for the open file (data/resource fork) */
|
||||
|
||||
int state;
|
||||
int text_file_type; /* if the file has a text file type with it. */
|
||||
char *boundary; /* the boundary string. */
|
||||
|
||||
int status; /* the error code if anyerror happens. */
|
||||
char b_overflow[200];
|
||||
int s_overflow;
|
||||
|
||||
int state64; /* the left over state of base64 enocding */
|
||||
int ct; /* the character count of base64 encoding */
|
||||
int c1, c2; /* the left of the last base64 encoding */
|
||||
|
||||
char *outbuff; /* the outbuff by the caller. */
|
||||
int s_outbuff; /* the size of the buffer. */
|
||||
int pos_outbuff; /* the offset in the current buffer. */
|
||||
|
||||
} appledouble_encode_object;
|
||||
|
||||
/* The possible content transfer encodings */
|
||||
|
||||
enum
|
||||
{
|
||||
kEncodeNone,
|
||||
kEncodeQP,
|
||||
kEncodeBase64,
|
||||
kEncodeUU
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kGeneralMine,
|
||||
kAppleDouble,
|
||||
kAppleSingle
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kInline,
|
||||
kDontCare
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
kHeaderPortion,
|
||||
kDataPortion
|
||||
};
|
||||
|
||||
/* the decode states. */
|
||||
enum
|
||||
{
|
||||
kBeginParseHeader = 3,
|
||||
kParsingHeader,
|
||||
kBeginSeekBoundary,
|
||||
kSeekingBoundary,
|
||||
kBeginHeaderPortion,
|
||||
kProcessingHeaderPortion,
|
||||
kBeginDataPortion,
|
||||
kProcessingDataPortion,
|
||||
kFinishing
|
||||
};
|
||||
|
||||
/* uuencode states */
|
||||
enum
|
||||
{
|
||||
kWaitingForBegin = (int) 0,
|
||||
kBegin,
|
||||
kMainBody,
|
||||
kEnd
|
||||
};
|
||||
|
||||
typedef struct _appledouble_decode_object
|
||||
{
|
||||
int is_binary;
|
||||
int is_apple_single; /* if the object encoded is in apple single */
|
||||
int write_as_binhex;
|
||||
|
||||
int messagetype;
|
||||
char* boundary0; /* the boundary for the enclosure. */
|
||||
int deposition; /* the deposition. */
|
||||
int encoding; /* the encoding method. */
|
||||
int which_part;
|
||||
|
||||
char fname[256];
|
||||
// nsIOFileStream *fileSpec; /* the stream for data fork work. */
|
||||
|
||||
int state;
|
||||
|
||||
int rksize; /* the resource fork size count. */
|
||||
int dksize; /* the data fork size count. */
|
||||
|
||||
int status; /* the error code if anyerror happens. */
|
||||
char b_leftover[256];
|
||||
int s_leftover;
|
||||
|
||||
int encode; /* the encode type of the message. */
|
||||
int state64; /* the left over state of base64 enocding */
|
||||
int left; /* the character count of base64 encoding */
|
||||
int c[4]; /* the left of the last base64 encoding */
|
||||
int uu_starts_line; /* is decoder at the start of a line? (uuencode) */
|
||||
int uu_state; /* state w/r/t the uuencode body */
|
||||
int uu_bytes_written; /* bytes written from the current tuple (uuencode) */
|
||||
int uu_line_bytes; /* encoded bytes remaining in the current line (uuencode) */
|
||||
|
||||
char *inbuff; /* the outbuff by the caller. */
|
||||
int s_inbuff; /* the size of the buffer. */
|
||||
int pos_inbuff; /* the offset in the current buffer. */
|
||||
|
||||
|
||||
nsCOMPtr <nsIFile> tmpFile; /* the temp file to hold the decode data fork */
|
||||
/* when doing the binhex exporting. */
|
||||
nsCOMPtr <nsIOutputStream> tmpFileStream; /* The output File Stream */
|
||||
int32_t data_size; /* the size of the data in the tmp file. */
|
||||
|
||||
} appledouble_decode_object;
|
||||
|
||||
|
||||
/*
|
||||
** The protypes.
|
||||
*/
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
int ap_encode_init(appledouble_encode_object *p_ap_encode_obj,
|
||||
const char* fname,
|
||||
char* separator);
|
||||
|
||||
int ap_encode_next(appledouble_encode_object* p_ap_encode_obj,
|
||||
char *to_buff,
|
||||
int32_t buff_size,
|
||||
int32_t* real_size);
|
||||
|
||||
int ap_encode_end(appledouble_encode_object* p_ap_encode_obj,
|
||||
bool is_aborting);
|
||||
|
||||
int ap_decode_init(appledouble_decode_object* p_ap_decode_obj,
|
||||
bool is_apple_single,
|
||||
bool write_as_bin_hex,
|
||||
void *closure);
|
||||
|
||||
int ap_decode_next(appledouble_decode_object* p_ap_decode_obj,
|
||||
char *in_buff,
|
||||
int32_t buff_size);
|
||||
|
||||
int ap_decode_end(appledouble_decode_object* p_ap_decode_obj,
|
||||
bool is_aborting);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
@@ -1,266 +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/. */
|
||||
|
||||
/*
|
||||
*
|
||||
* apple-double.c
|
||||
* --------------
|
||||
*
|
||||
* The codes to do apple double encoding/decoding.
|
||||
*
|
||||
* 02aug95 mym created.
|
||||
*
|
||||
*/
|
||||
#include "nsID.h"
|
||||
#include "nscore.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsMsgAppleDouble.h"
|
||||
#include "nsMsgAppleCodes.h"
|
||||
#include "nsMsgCompUtils.h"
|
||||
#include "nsCExternalHandlerService.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "prmem.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
|
||||
void
|
||||
MacGetFileType(nsIFile *fs,
|
||||
bool *useDefault,
|
||||
char **fileType,
|
||||
char **encoding)
|
||||
{
|
||||
if ((fs == NULL) || (fileType == NULL) || (encoding == NULL))
|
||||
return;
|
||||
|
||||
bool exists = false;
|
||||
fs->Exists(&exists);
|
||||
if (!exists)
|
||||
return;
|
||||
|
||||
*useDefault = TRUE;
|
||||
*fileType = NULL;
|
||||
*encoding = NULL;
|
||||
|
||||
nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(fs);
|
||||
FSRef fsRef;
|
||||
FSCatalogInfo catalogInfo;
|
||||
OSErr err = errFileOpen;
|
||||
if (NS_SUCCEEDED(macFile->GetFSRef(&fsRef)))
|
||||
err = ::FSGetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, &catalogInfo, nullptr, nullptr, nullptr);
|
||||
|
||||
if ( (err != noErr) || (((FileInfo*)(&catalogInfo.finderInfo))->fileType == 'TEXT') )
|
||||
*fileType = strdup(APPLICATION_OCTET_STREAM);
|
||||
else
|
||||
{
|
||||
// At this point, we should call the mime service and
|
||||
// see what we can find out?
|
||||
nsresult rv;
|
||||
nsCOMPtr <nsIURI> tURI;
|
||||
if (NS_SUCCEEDED(NS_NewFileURI(getter_AddRefs(tURI), fs)) && tURI)
|
||||
{
|
||||
nsCOMPtr<nsIMIMEService> mimeFinder (do_GetService(NS_MIMESERVICE_CONTRACTID, &rv));
|
||||
if (NS_SUCCEEDED(rv) && mimeFinder)
|
||||
{
|
||||
nsAutoCString mimeType;
|
||||
rv = mimeFinder->GetTypeFromURI(tURI, mimeType);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
*fileType = ToNewCString(mimeType);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we hit here, return something...default to this...
|
||||
*fileType = strdup(APPLICATION_OCTET_STREAM);
|
||||
}
|
||||
}
|
||||
|
||||
//#pragma cplusplus reset
|
||||
|
||||
/*
|
||||
* ap_encode_init
|
||||
* --------------
|
||||
*
|
||||
* Setup the encode envirment
|
||||
*/
|
||||
|
||||
int ap_encode_init( appledouble_encode_object *p_ap_encode_obj,
|
||||
const char *fname,
|
||||
char *separator)
|
||||
{
|
||||
nsCOMPtr <nsIFile> myFile;
|
||||
NS_NewNativeLocalFile(nsDependentCString(fname), true, getter_AddRefs(myFile));
|
||||
bool exists;
|
||||
if (myFile && NS_SUCCEEDED(myFile->Exists(&exists)) && !exists)
|
||||
return -1;
|
||||
|
||||
nsCOMPtr<nsILocalFileMac> macFile = do_QueryInterface(myFile);
|
||||
nsAutoCString path;
|
||||
macFile->GetNativePath(path);
|
||||
|
||||
memset(p_ap_encode_obj, 0, sizeof(appledouble_encode_object));
|
||||
|
||||
/*
|
||||
** Fill out the source file inforamtion.
|
||||
*/
|
||||
memcpy(p_ap_encode_obj->fname, path.get(), path.Length());
|
||||
p_ap_encode_obj->fname[path.Length()] = '\0';
|
||||
|
||||
p_ap_encode_obj->boundary = strdup(separator);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
/*
|
||||
** ap_encode_next
|
||||
** --------------
|
||||
**
|
||||
** return :
|
||||
** noErr : everything is ok
|
||||
** errDone : when encoding is done.
|
||||
** errors : otherwise.
|
||||
*/
|
||||
int ap_encode_next(
|
||||
appledouble_encode_object* p_ap_encode_obj,
|
||||
char *to_buff,
|
||||
int32_t buff_size,
|
||||
int32_t* real_size)
|
||||
{
|
||||
int status;
|
||||
|
||||
/*
|
||||
** install the out buff now.
|
||||
*/
|
||||
p_ap_encode_obj->outbuff = to_buff;
|
||||
p_ap_encode_obj->s_outbuff = buff_size;
|
||||
p_ap_encode_obj->pos_outbuff = 0;
|
||||
|
||||
/*
|
||||
** first copy the outstandind data in the overflow buff to the out buffer.
|
||||
*/
|
||||
if (p_ap_encode_obj->s_overflow)
|
||||
{
|
||||
status = write_stream(p_ap_encode_obj,
|
||||
(const char*)(p_ap_encode_obj->b_overflow),
|
||||
p_ap_encode_obj->s_overflow);
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
p_ap_encode_obj->s_overflow = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** go the next processing stage based on the current state.
|
||||
*/
|
||||
switch (p_ap_encode_obj->state)
|
||||
{
|
||||
case kInit:
|
||||
/*
|
||||
** We are in the starting position, fill out the header.
|
||||
*/
|
||||
status = fill_apple_mime_header(p_ap_encode_obj);
|
||||
if (status != noErr)
|
||||
break; /* some error happens */
|
||||
|
||||
p_ap_encode_obj->state = kDoingHeaderPortion;
|
||||
status = ap_encode_header(p_ap_encode_obj, true);
|
||||
/* it is the first time to calling */
|
||||
if (status == errDone)
|
||||
{
|
||||
p_ap_encode_obj->state = kDoneHeaderPortion;
|
||||
}
|
||||
else
|
||||
{
|
||||
break; /* we need more work on header portion. */
|
||||
}
|
||||
|
||||
/*
|
||||
** we are done with the header, so let's go to the data port.
|
||||
*/
|
||||
p_ap_encode_obj->state = kDoingDataPortion;
|
||||
status = ap_encode_data(p_ap_encode_obj, true);
|
||||
/* it is first time call do data portion */
|
||||
|
||||
if (status == errDone)
|
||||
{
|
||||
p_ap_encode_obj->state = kDoneDataPortion;
|
||||
status = noErr;
|
||||
}
|
||||
break;
|
||||
|
||||
case kDoingHeaderPortion:
|
||||
|
||||
status = ap_encode_header(p_ap_encode_obj, false);
|
||||
/* continue with the header portion. */
|
||||
if (status == errDone)
|
||||
{
|
||||
p_ap_encode_obj->state = kDoneHeaderPortion;
|
||||
}
|
||||
else
|
||||
{
|
||||
break; /* we need more work on header portion. */
|
||||
}
|
||||
|
||||
/*
|
||||
** start the data portion.
|
||||
*/
|
||||
p_ap_encode_obj->state = kDoingDataPortion;
|
||||
status = ap_encode_data(p_ap_encode_obj, true);
|
||||
/* it is the first time calling */
|
||||
if (status == errDone)
|
||||
{
|
||||
p_ap_encode_obj->state = kDoneDataPortion;
|
||||
status = noErr;
|
||||
}
|
||||
break;
|
||||
|
||||
case kDoingDataPortion:
|
||||
|
||||
status = ap_encode_data(p_ap_encode_obj, false);
|
||||
/* it is not the first time */
|
||||
|
||||
if (status == errDone)
|
||||
{
|
||||
p_ap_encode_obj->state = kDoneDataPortion;
|
||||
status = noErr;
|
||||
}
|
||||
break;
|
||||
|
||||
case kDoneDataPortion:
|
||||
status = errDone; /* we are really done. */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*real_size = p_ap_encode_obj->pos_outbuff;
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
** ap_encode_end
|
||||
** -------------
|
||||
**
|
||||
** clear the apple encoding.
|
||||
*/
|
||||
|
||||
int ap_encode_end(
|
||||
appledouble_encode_object *p_ap_encode_obj,
|
||||
bool is_aborting)
|
||||
{
|
||||
/*
|
||||
** clear up the apple doubler.
|
||||
*/
|
||||
if (p_ap_encode_obj == NULL)
|
||||
return noErr;
|
||||
|
||||
if (p_ap_encode_obj->fileId) /* close the file if it is open. */
|
||||
::FSCloseFork(p_ap_encode_obj->fileId);
|
||||
|
||||
PR_FREEIF(p_ap_encode_obj->boundary); /* the boundary string. */
|
||||
|
||||
return noErr;
|
||||
}
|
||||
@@ -1,703 +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/. */
|
||||
|
||||
/*
|
||||
*
|
||||
* apple_double_encode.c
|
||||
* ---------------------
|
||||
*
|
||||
* The routines doing the Apple Double Encoding.
|
||||
*
|
||||
* 2aug95 mym Created.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "prprf.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsMsgAppleDouble.h"
|
||||
#include "nsMsgAppleCodes.h"
|
||||
#include "nsILocalFileMac.h"
|
||||
|
||||
/*
|
||||
** Local Functions prototypes.
|
||||
*/
|
||||
static int output64chunk( appledouble_encode_object* p_ap_encode_obj,
|
||||
int c1, int c2, int c3, int pads);
|
||||
|
||||
static int to64(appledouble_encode_object* p_ap_encode_obj,
|
||||
char *p,
|
||||
int in_size);
|
||||
|
||||
static int finish64(appledouble_encode_object* p_ap_encode_obj);
|
||||
|
||||
|
||||
#define BUFF_LEFT(p) ((p)->s_outbuff - (p)->pos_outbuff)
|
||||
|
||||
/*
|
||||
** write_stream.
|
||||
*/
|
||||
int write_stream(
|
||||
appledouble_encode_object *p_ap_encode_obj,
|
||||
const char *out_string,
|
||||
int len)
|
||||
{
|
||||
if (p_ap_encode_obj->pos_outbuff + len < p_ap_encode_obj->s_outbuff)
|
||||
{
|
||||
memcpy(p_ap_encode_obj->outbuff + p_ap_encode_obj->pos_outbuff,
|
||||
out_string,
|
||||
len);
|
||||
p_ap_encode_obj->pos_outbuff += len;
|
||||
return noErr;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
** If the buff doesn't have enough space, use the overflow buffer then.
|
||||
*/
|
||||
int s_len = p_ap_encode_obj->s_outbuff - p_ap_encode_obj->pos_outbuff;
|
||||
|
||||
memcpy(p_ap_encode_obj->outbuff + p_ap_encode_obj->pos_outbuff,
|
||||
out_string,
|
||||
s_len);
|
||||
memcpy(p_ap_encode_obj->b_overflow + p_ap_encode_obj->s_overflow,
|
||||
out_string + s_len,
|
||||
p_ap_encode_obj->s_overflow += (len - s_len));
|
||||
p_ap_encode_obj->pos_outbuff += s_len;
|
||||
return errEOB;
|
||||
}
|
||||
}
|
||||
|
||||
int fill_apple_mime_header(
|
||||
appledouble_encode_object *p_ap_encode_obj)
|
||||
{
|
||||
int status;
|
||||
|
||||
char tmpstr[266];
|
||||
|
||||
#if 0
|
||||
// strcpy(tmpstr, "Content-Type: multipart/mixed; boundary=\"-\"\n\n---\n");
|
||||
// status = write_stream(p_ap_encode_env,
|
||||
// tmpstr,
|
||||
// strlen(tmpstr));
|
||||
// if (status != noErr)
|
||||
// return status;
|
||||
|
||||
PR_snprintf(tmpstr, sizeof(tmpstr),
|
||||
"Content-Type: multipart/appledouble; boundary=\"=\"; name=\"");
|
||||
status = write_stream(p_ap_encode_obj, (const char*)tmpstr, strlen(tmpstr));
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
status = write_stream(p_ap_encode_obj,
|
||||
p_ap_encode_obj->fname,
|
||||
strlen(p_ap_encode_obj->fname));
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
PR_snprintf(tmpstr, sizeof(tmpstr),
|
||||
"\"\r\nContent-Disposition: inline; filename=\"%s\"\r\n\r\n\r\n--=\r\n",
|
||||
p_ap_encode_obj->fname);
|
||||
#endif /* 0 */
|
||||
PR_snprintf(tmpstr, sizeof(tmpstr), "--%s" CRLF, p_ap_encode_obj->boundary);
|
||||
status = write_stream(p_ap_encode_obj, (const char*)tmpstr, strlen(tmpstr));
|
||||
return status;
|
||||
}
|
||||
|
||||
int ap_encode_file_infor(
|
||||
appledouble_encode_object *p_ap_encode_obj)
|
||||
{
|
||||
ap_header head;
|
||||
ap_entry entries[NUM_ENTRIES];
|
||||
ap_dates dates;
|
||||
short i;
|
||||
long comlen;
|
||||
char comment[256];
|
||||
int status;
|
||||
|
||||
nsCOMPtr <nsIFile> resFile;
|
||||
NS_NewNativeLocalFile(nsDependentCString(p_ap_encode_obj->fname), true,
|
||||
getter_AddRefs(resFile));
|
||||
if (!resFile)
|
||||
return errFileOpen;
|
||||
|
||||
FSRef ref;
|
||||
nsCOMPtr <nsILocalFileMac> macFile = do_QueryInterface(resFile);
|
||||
if (NS_FAILED(macFile->GetFSRef(&ref)))
|
||||
return errFileOpen;
|
||||
|
||||
FSCatalogInfo catalogInfo;
|
||||
if (::FSGetCatalogInfo(&ref, kFSCatInfoFinderInfo, &catalogInfo, nullptr, nullptr, nullptr) != noErr)
|
||||
{
|
||||
return errFileOpen;
|
||||
}
|
||||
|
||||
/* get a file comment, if possible */
|
||||
#if 1
|
||||
// Carbon doesn't support GetWDInfo(). (Bug 555684)
|
||||
|
||||
// not sure why working directories are needed here...
|
||||
comlen = 0;
|
||||
#else
|
||||
long procID;
|
||||
procID = 0;
|
||||
GetWDInfo(p_ap_encode_obj->vRefNum, &fpb->ioVRefNum, &fpb->ioDirID, &procID);
|
||||
IOParam vinfo;
|
||||
memset((void *) &vinfo, '\0', sizeof (vinfo));
|
||||
GetVolParmsInfoBuffer vp;
|
||||
vinfo.ioCompletion = nil;
|
||||
vinfo.ioVRefNum = fpb->ioVRefNum;
|
||||
vinfo.ioBuffer = (Ptr) &vp;
|
||||
vinfo.ioReqCount = sizeof (vp);
|
||||
comlen = 0;
|
||||
if (PBHGetVolParmsSync((HParmBlkPtr) &vinfo) == noErr &&
|
||||
((vp.vMAttrib >> bHasDesktopMgr) & 1))
|
||||
{
|
||||
DTPBRec dtp;
|
||||
memset((void *) &dtp, '\0', sizeof (dtp));
|
||||
dtp.ioVRefNum = fpb->ioVRefNum;
|
||||
if (PBDTGetPath(&dtp) == noErr)
|
||||
{
|
||||
dtp.ioCompletion = nil;
|
||||
dtp.ioDTBuffer = (Ptr) comment;
|
||||
dtp.ioNamePtr = fpb->ioNamePtr;
|
||||
dtp.ioDirID = fpb->ioFlParID;
|
||||
if (PBDTGetCommentSync(&dtp) == noErr)
|
||||
comlen = dtp.ioDTActCount;
|
||||
}
|
||||
}
|
||||
#endif /* ! 1 */
|
||||
|
||||
/* write header */
|
||||
// head.magic = dfork ? APPLESINGLE_MAGIC : APPLEDOUBLE_MAGIC;
|
||||
head.magic = APPLEDOUBLE_MAGIC; /* always do apple double */
|
||||
head.version = VERSION;
|
||||
memset(head.fill, '\0', sizeof (head.fill));
|
||||
head.entries = NUM_ENTRIES - 1;
|
||||
status = to64(p_ap_encode_obj,
|
||||
(char *) &head,
|
||||
sizeof (head));
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
/* write entry descriptors */
|
||||
nsAutoCString leafname;
|
||||
macFile->GetNativeLeafName(leafname);
|
||||
entries[0].offset = sizeof (head) + sizeof (ap_entry) * head.entries;
|
||||
entries[0].id = ENT_NAME;
|
||||
entries[0].length = leafname.Length();
|
||||
entries[1].id = ENT_FINFO;
|
||||
entries[1].length = sizeof (FInfo) + sizeof (FXInfo);
|
||||
entries[2].id = ENT_DATES;
|
||||
entries[2].length = sizeof (ap_dates);
|
||||
entries[3].id = ENT_COMMENT;
|
||||
entries[3].length = comlen;
|
||||
entries[4].id = ENT_RFORK;
|
||||
entries[4].length = catalogInfo.rsrcLogicalSize;
|
||||
entries[5].id = ENT_DFORK;
|
||||
entries[5].length = catalogInfo.dataLogicalSize;
|
||||
|
||||
/* correct the link in the entries. */
|
||||
for (i = 1; i < NUM_ENTRIES; ++i)
|
||||
{
|
||||
entries[i].offset = entries[i-1].offset + entries[i-1].length;
|
||||
}
|
||||
status = to64(p_ap_encode_obj,
|
||||
(char *) entries,
|
||||
sizeof (ap_entry) * head.entries);
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
/* write name */
|
||||
status = to64(p_ap_encode_obj,
|
||||
(char *) leafname.get(),
|
||||
leafname.Length());
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
/* write finder info */
|
||||
status = to64(p_ap_encode_obj,
|
||||
(char *) &catalogInfo.finderInfo,
|
||||
sizeof (FInfo));
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
status = to64(p_ap_encode_obj,
|
||||
(char *) &catalogInfo.extFinderInfo,
|
||||
sizeof (FXInfo));
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
/* write dates */
|
||||
dates.create = catalogInfo.createDate.lowSeconds + CONVERT_TIME;
|
||||
dates.modify = catalogInfo.contentModDate.lowSeconds + CONVERT_TIME;
|
||||
dates.backup = catalogInfo.backupDate.lowSeconds + CONVERT_TIME;
|
||||
dates.access = catalogInfo.accessDate.lowSeconds + CONVERT_TIME;
|
||||
status = to64(p_ap_encode_obj,
|
||||
(char *) &dates,
|
||||
sizeof (ap_dates));
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
/* write comment */
|
||||
if (comlen)
|
||||
{
|
||||
status = to64(p_ap_encode_obj,
|
||||
comment,
|
||||
comlen * sizeof(char));
|
||||
}
|
||||
/*
|
||||
** Get some help information on deciding the file type.
|
||||
*/
|
||||
if (((FileInfo*)(&catalogInfo.finderInfo))->fileType == 'TEXT' ||
|
||||
((FileInfo*)(&catalogInfo.finderInfo))->fileType == 'text')
|
||||
{
|
||||
p_ap_encode_obj->text_file_type = true;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
/*
|
||||
** ap_encode_header
|
||||
**
|
||||
** encode the file header and the resource fork.
|
||||
**
|
||||
*/
|
||||
int ap_encode_header(
|
||||
appledouble_encode_object* p_ap_encode_obj,
|
||||
bool firstime)
|
||||
{
|
||||
char rd_buff[256];
|
||||
FSIORefNum fileId;
|
||||
OSErr retval = noErr;
|
||||
int status;
|
||||
ByteCount inCount;
|
||||
|
||||
if (firstime)
|
||||
{
|
||||
PL_strcpy(rd_buff,
|
||||
"Content-Type: application/applefile\r\nContent-Transfer-Encoding: base64\r\n\r\n");
|
||||
status = write_stream(p_ap_encode_obj, (const char*)rd_buff, strlen(rd_buff));
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
status = ap_encode_file_infor(p_ap_encode_obj);
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
/*
|
||||
** preparing to encode the resource fork.
|
||||
*/
|
||||
nsCOMPtr <nsIFile> myFile;
|
||||
NS_NewNativeLocalFile(nsDependentCString(p_ap_encode_obj->fname), true, getter_AddRefs(myFile));
|
||||
if (!myFile)
|
||||
return errFileOpen;
|
||||
|
||||
FSRef ref;
|
||||
nsCOMPtr <nsILocalFileMac> macFile = do_QueryInterface(myFile);
|
||||
if (NS_FAILED(macFile->GetFSRef(&ref)))
|
||||
return errFileOpen;
|
||||
|
||||
HFSUniStr255 forkName;
|
||||
::FSGetResourceForkName(&forkName);
|
||||
retval = ::FSOpenFork(&ref, forkName.length, forkName.unicode, fsRdPerm, &p_ap_encode_obj->fileId);
|
||||
if (retval != noErr)
|
||||
return retval;
|
||||
}
|
||||
|
||||
fileId = p_ap_encode_obj->fileId;
|
||||
while (retval == noErr)
|
||||
{
|
||||
if (BUFF_LEFT(p_ap_encode_obj) < 400)
|
||||
break;
|
||||
|
||||
inCount = 0;
|
||||
retval = ::FSReadFork(fileId, fsAtMark, 0, 256, rd_buff, &inCount);
|
||||
if (inCount)
|
||||
{
|
||||
status = to64(p_ap_encode_obj,
|
||||
rd_buff,
|
||||
inCount);
|
||||
if (status != noErr)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
if (retval == eofErr)
|
||||
{
|
||||
::FSCloseFork(fileId);
|
||||
p_ap_encode_obj->fileId = 0;
|
||||
|
||||
status = finish64(p_ap_encode_obj);
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
/*
|
||||
** write out the boundary
|
||||
*/
|
||||
PR_snprintf(rd_buff, sizeof(rd_buff),
|
||||
CRLF "--%s" CRLF,
|
||||
p_ap_encode_obj->boundary);
|
||||
|
||||
status = write_stream(p_ap_encode_obj, (const char*)rd_buff, strlen(rd_buff));
|
||||
if (status == noErr)
|
||||
status = errDone;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// This is unused for now and Clang complains about that is it is ifdefed out
|
||||
static void replace(char *p, int len, char frm, char to)
|
||||
{
|
||||
for (; len > 0; len--, p++)
|
||||
if (*p == frm) *p = to;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Description of the various file formats and their magic numbers */
|
||||
struct magic
|
||||
{
|
||||
const char *name; /* Name of the file format */
|
||||
const char *num; /* The magic number */
|
||||
int len; /* Length (0 means strlen(magicnum)) */
|
||||
};
|
||||
|
||||
/* The magic numbers of the file formats we know about */
|
||||
static struct magic magic[] =
|
||||
{
|
||||
{ "image/gif", "GIF", 0 },
|
||||
{ "image/jpeg", "\377\330\377", 0 },
|
||||
{ "video/mpeg", "\0\0\001\263", 4 },
|
||||
{ "application/postscript", "%!", 0 },
|
||||
};
|
||||
static int num_magic = MOZ_ARRAY_LENGTH(magic);
|
||||
|
||||
static const char *text_type = TEXT_PLAIN; /* the text file type. */
|
||||
static const char *default_type = APPLICATION_OCTET_STREAM;
|
||||
|
||||
|
||||
/*
|
||||
* Determins the format of the file "inputf". The name
|
||||
* of the file format (or NULL on error) is returned.
|
||||
*/
|
||||
static const char *magic_look(char *inbuff, int numread)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<num_magic; i++)
|
||||
{
|
||||
if (magic[i].len == 0)
|
||||
magic[i].len = strlen(magic[i].num);
|
||||
}
|
||||
|
||||
for (i=0; i<num_magic; i++)
|
||||
{
|
||||
if (numread >= magic[i].len)
|
||||
{
|
||||
for (j=0; j<magic[i].len; j++)
|
||||
{
|
||||
if (inbuff[j] != magic[i].num[j]) break;
|
||||
}
|
||||
|
||||
if (j == magic[i].len)
|
||||
return magic[i].name;
|
||||
}
|
||||
}
|
||||
|
||||
return default_type;
|
||||
}
|
||||
/*
|
||||
** ap_encode_data
|
||||
**
|
||||
** ---------------
|
||||
**
|
||||
** encode on the data fork.
|
||||
**
|
||||
*/
|
||||
int ap_encode_data(
|
||||
appledouble_encode_object* p_ap_encode_obj,
|
||||
bool firstime)
|
||||
{
|
||||
char rd_buff[256];
|
||||
FSIORefNum fileId;
|
||||
OSErr retval = noErr;
|
||||
ByteCount in_count;
|
||||
int status;
|
||||
|
||||
if (firstime)
|
||||
{
|
||||
const char* magic_type;
|
||||
|
||||
/*
|
||||
** preparing to encode the data fork.
|
||||
*/
|
||||
nsCOMPtr <nsIFile> resFile;
|
||||
NS_NewNativeLocalFile(nsDependentCString(p_ap_encode_obj->fname), true,
|
||||
getter_AddRefs(resFile));
|
||||
if (!resFile)
|
||||
return errFileOpen;
|
||||
|
||||
FSRef ref;
|
||||
nsCOMPtr <nsILocalFileMac> macFile = do_QueryInterface(resFile);
|
||||
if (NS_FAILED(macFile->GetFSRef(&ref)))
|
||||
return errFileOpen;
|
||||
|
||||
HFSUniStr255 forkName;
|
||||
::FSGetDataForkName(&forkName);
|
||||
retval = ::FSOpenFork(&ref, forkName.length, forkName.unicode, fsRdPerm, &fileId);
|
||||
if (retval != noErr)
|
||||
return retval;
|
||||
|
||||
p_ap_encode_obj->fileId = fileId;
|
||||
|
||||
|
||||
if (!p_ap_encode_obj->text_file_type)
|
||||
{
|
||||
/*
|
||||
** do a smart check for the file type.
|
||||
*/
|
||||
in_count = 0;
|
||||
retval = ::FSReadFork(fileId, fsFromStart, 0, 256, rd_buff, &in_count);
|
||||
magic_type = magic_look(rd_buff, in_count);
|
||||
|
||||
/* don't forget to rewind the index to start point. */
|
||||
::FSSetForkPosition(fileId, fsFromStart, 0);
|
||||
/* and reset retVal just in case... */
|
||||
if (retval == eofErr)
|
||||
retval = noErr;
|
||||
}
|
||||
else
|
||||
{
|
||||
magic_type = text_type; /* we already know it is a text type. */
|
||||
}
|
||||
|
||||
/*
|
||||
** the data portion header information.
|
||||
*/
|
||||
nsAutoCString leafName;
|
||||
resFile->GetNativeLeafName(leafName);
|
||||
PR_snprintf(rd_buff, sizeof(rd_buff),
|
||||
"Content-Type: %s; name=\"%s\"" CRLF "Content-Transfer-Encoding: base64" CRLF "Content-Disposition: inline; filename=\"%s\"" CRLF CRLF,
|
||||
magic_type,
|
||||
leafName.get(),
|
||||
leafName.get());
|
||||
|
||||
status = write_stream(p_ap_encode_obj, (const char*)rd_buff, strlen(rd_buff));
|
||||
if (status != noErr)
|
||||
return status;
|
||||
}
|
||||
|
||||
while (retval == noErr)
|
||||
{
|
||||
if (BUFF_LEFT(p_ap_encode_obj) < 400)
|
||||
break;
|
||||
|
||||
in_count = 0;
|
||||
retval = ::FSReadFork(p_ap_encode_obj->fileId, fsAtMark, 0, 256, rd_buff, &in_count);
|
||||
if (in_count)
|
||||
{
|
||||
#if 0
|
||||
/* replace(rd_buff, in_count, '\r', '\n'); */
|
||||
#endif
|
||||
/* ** may be need to do character set conversion here for localization. ** */
|
||||
status = to64(p_ap_encode_obj,
|
||||
rd_buff,
|
||||
in_count);
|
||||
if (status != noErr)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
if (retval == eofErr)
|
||||
{
|
||||
::FSCloseFork(p_ap_encode_obj->fileId);
|
||||
p_ap_encode_obj->fileId = 0;
|
||||
|
||||
status = finish64(p_ap_encode_obj);
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
/* write out the boundary */
|
||||
|
||||
PR_snprintf(rd_buff, sizeof(rd_buff),
|
||||
CRLF "--%s--" CRLF CRLF,
|
||||
p_ap_encode_obj->boundary);
|
||||
|
||||
status = write_stream(p_ap_encode_obj, (const char*)rd_buff, strlen(rd_buff));
|
||||
|
||||
if (status == noErr)
|
||||
status = errDone;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static char basis_64[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/*
|
||||
** convert the stream in the inbuff to 64 format and put it in the out buff.
|
||||
** To make the life easier, the caller will responcable of the cheking of the outbuff's bundary.
|
||||
*/
|
||||
static int
|
||||
to64(appledouble_encode_object* p_ap_encode_obj,
|
||||
char *p,
|
||||
int in_size)
|
||||
{
|
||||
int status;
|
||||
int c1, c2, c3, ct;
|
||||
unsigned char *inbuff = (unsigned char*)p;
|
||||
|
||||
ct = p_ap_encode_obj->ct; /* the char count left last time. */
|
||||
|
||||
/*
|
||||
** resume the left state of the last conversion.
|
||||
*/
|
||||
switch (p_ap_encode_obj->state64)
|
||||
{
|
||||
case 0:
|
||||
p_ap_encode_obj->c1 = c1 = *inbuff ++;
|
||||
if (--in_size <= 0)
|
||||
{
|
||||
p_ap_encode_obj->state64 = 1;
|
||||
return noErr;
|
||||
}
|
||||
p_ap_encode_obj->c2 = c2 = *inbuff ++;
|
||||
if (--in_size <= 0)
|
||||
{
|
||||
p_ap_encode_obj->state64 = 2;
|
||||
return noErr;
|
||||
}
|
||||
c3 = *inbuff ++; --in_size;
|
||||
break;
|
||||
case 1:
|
||||
c1 = p_ap_encode_obj->c1;
|
||||
p_ap_encode_obj->c2 = c2 = *inbuff ++;
|
||||
if (--in_size <= 0)
|
||||
{
|
||||
p_ap_encode_obj->state64 = 2;
|
||||
return noErr;
|
||||
}
|
||||
c3 = *inbuff ++; --in_size;
|
||||
break;
|
||||
case 2:
|
||||
c1 = p_ap_encode_obj->c1;
|
||||
c2 = p_ap_encode_obj->c2;
|
||||
c3 = *inbuff ++; --in_size;
|
||||
break;
|
||||
}
|
||||
|
||||
while (in_size >= 0)
|
||||
{
|
||||
status = output64chunk(p_ap_encode_obj,
|
||||
c1,
|
||||
c2,
|
||||
c3,
|
||||
0);
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
ct += 4;
|
||||
if (ct > 71)
|
||||
{
|
||||
status = write_stream(p_ap_encode_obj,
|
||||
CRLF,
|
||||
2);
|
||||
if (status != noErr)
|
||||
return status;
|
||||
|
||||
ct = 0;
|
||||
}
|
||||
|
||||
if (in_size <= 0)
|
||||
{
|
||||
p_ap_encode_obj->state64 = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
c1 = (int)*inbuff++;
|
||||
if (--in_size <= 0)
|
||||
{
|
||||
p_ap_encode_obj->c1 = c1;
|
||||
p_ap_encode_obj->state64 = 1;
|
||||
break;
|
||||
}
|
||||
c2 = *inbuff++;
|
||||
if (--in_size <= 0)
|
||||
{
|
||||
p_ap_encode_obj->c1 = c1;
|
||||
p_ap_encode_obj->c2 = c2;
|
||||
p_ap_encode_obj->state64 = 2;
|
||||
break;
|
||||
}
|
||||
c3 = *inbuff++;
|
||||
in_size--;
|
||||
}
|
||||
p_ap_encode_obj->ct = ct;
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
** clear the left base64 encodes.
|
||||
*/
|
||||
static int
|
||||
finish64(appledouble_encode_object* p_ap_encode_obj)
|
||||
{
|
||||
int status;
|
||||
|
||||
switch (p_ap_encode_obj->state64)
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
status = output64chunk(p_ap_encode_obj,
|
||||
p_ap_encode_obj->c1,
|
||||
0,
|
||||
0,
|
||||
2);
|
||||
break;
|
||||
case 2:
|
||||
status = output64chunk(p_ap_encode_obj,
|
||||
p_ap_encode_obj->c1,
|
||||
p_ap_encode_obj->c2,
|
||||
0,
|
||||
1);
|
||||
break;
|
||||
}
|
||||
status = write_stream(p_ap_encode_obj, CRLF, 2);
|
||||
p_ap_encode_obj->state64 = 0;
|
||||
p_ap_encode_obj->ct = 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
static int output64chunk(
|
||||
appledouble_encode_object* p_ap_encode_obj,
|
||||
int c1, int c2, int c3, int pads)
|
||||
{
|
||||
char tmpstr[32];
|
||||
char *p = tmpstr;
|
||||
|
||||
*p++ = basis_64[c1>>2];
|
||||
*p++ = basis_64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];
|
||||
if (pads == 2)
|
||||
{
|
||||
*p++ = '=';
|
||||
*p++ = '=';
|
||||
}
|
||||
else if (pads)
|
||||
{
|
||||
*p++ = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
|
||||
*p++ = '=';
|
||||
}
|
||||
else
|
||||
{
|
||||
*p++ = basis_64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
|
||||
*p++ = basis_64[c3 & 0x3F];
|
||||
}
|
||||
return write_stream(p_ap_encode_obj, (const char*) tmpstr, p-tmpstr);
|
||||
}
|
||||
@@ -35,13 +35,6 @@ LOCAL_INCLUDES += [
|
||||
'../vcard/src',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
LOCAL_INCLUDES += [
|
||||
'../applemail/src',
|
||||
]
|
||||
OS_LIBS += CONFIG['TK_LIBS']
|
||||
OS_LIBS += ['-framework Cocoa']
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
LOCAL_INCLUDES += [
|
||||
]
|
||||
|
||||
@@ -1,11 +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 "OSXRunLoopSingleton.h"
|
||||
|
||||
void cubeb_set_coreaudio_notification_runloop()
|
||||
{
|
||||
mozilla_set_coreaudio_notification_runloop_if_needed();
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Copyright © 2014 Mozilla Foundation
|
||||
*
|
||||
* This program is made available under an ISC-style license. See the
|
||||
* accompanying file LICENSE for details.
|
||||
*/
|
||||
|
||||
/* On OSX 10.6 and after, the notification callbacks from the audio hardware are
|
||||
* called on the main thread. Setting the kAudioHardwarePropertyRunLoop property
|
||||
* to null tells the OSX to use a separate thread for that.
|
||||
*
|
||||
* This has to be called only once per process, so it is in a separate header
|
||||
* for easy integration in other code bases. */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void cubeb_set_coreaudio_notification_runloop();
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
@@ -55,10 +55,6 @@ if CONFIG['OS_TARGET'] == 'Darwin':
|
||||
'cubeb_audiounit.cpp',
|
||||
'cubeb_resampler.cpp'
|
||||
]
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
SOURCES += [
|
||||
'cubeb_osx_run_loop.c',
|
||||
]
|
||||
DEFINES['USE_AUDIOUNIT'] = True
|
||||
|
||||
if CONFIG['OS_TARGET'] == 'WINNT':
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
/* -*- 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 <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
|
||||
#include "NetworkInfoServiceImpl.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
static nsresult
|
||||
ListInterfaceAddresses(int aFd, const char* aIface, AddrMapType& aAddrMap);
|
||||
|
||||
nsresult
|
||||
DoListAddresses(AddrMapType& aAddrMap)
|
||||
{
|
||||
int fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
auto autoCloseSocket = MakeScopeExit([&] {
|
||||
close(fd);
|
||||
});
|
||||
|
||||
struct ifconf ifconf;
|
||||
/* 16k of space should be enough to list all interfaces. Worst case, if it's
|
||||
* not then we will error out and fail to list addresses. This should only
|
||||
* happen on pathological machines with way too many interfaces.
|
||||
*/
|
||||
char buf[16384];
|
||||
|
||||
ifconf.ifc_len = sizeof(buf);
|
||||
ifconf.ifc_buf = buf;
|
||||
if (ioctl(fd, SIOCGIFCONF, &ifconf) != 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
struct ifreq* ifreq = ifconf.ifc_req;
|
||||
int i = 0;
|
||||
while (i < ifconf.ifc_len) {
|
||||
size_t len = IFNAMSIZ + ifreq->ifr_addr.sa_len;
|
||||
|
||||
DebugOnly<nsresult> rv =
|
||||
ListInterfaceAddresses(fd, ifreq->ifr_name, aAddrMap);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "ListInterfaceAddresses failed");
|
||||
|
||||
ifreq = (struct ifreq*) ((char*)ifreq + len);
|
||||
i += len;
|
||||
}
|
||||
|
||||
autoCloseSocket.release();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ListInterfaceAddresses(int aFd, const char* aInterface, AddrMapType& aAddrMap)
|
||||
{
|
||||
struct ifreq ifreq;
|
||||
memset(&ifreq, 0, sizeof(struct ifreq));
|
||||
strncpy(ifreq.ifr_name, aInterface, IFNAMSIZ - 1);
|
||||
if (ioctl(aFd, SIOCGIFADDR, &ifreq) != 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
char host[128];
|
||||
int family;
|
||||
switch(family=ifreq.ifr_addr.sa_family) {
|
||||
case AF_INET:
|
||||
case AF_INET6:
|
||||
getnameinfo(&ifreq.ifr_addr, sizeof(ifreq.ifr_addr), host, sizeof(host), 0, 0, NI_NUMERICHOST);
|
||||
break;
|
||||
case AF_UNSPEC:
|
||||
return NS_OK;
|
||||
default:
|
||||
// Unknown family.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCString ifaceStr;
|
||||
ifaceStr.AssignASCII(aInterface);
|
||||
|
||||
nsCString addrStr;
|
||||
addrStr.AssignASCII(host);
|
||||
|
||||
aAddrMap.Put(ifaceStr, addrStr);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
@@ -257,10 +257,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
'nsURLHelperWin.cpp',
|
||||
'ShutdownLayer.cpp',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
SOURCES += [
|
||||
'nsURLHelperOSX.cpp',
|
||||
]
|
||||
else:
|
||||
SOURCES += [
|
||||
'nsURLHelperUnix.cpp',
|
||||
@@ -272,11 +268,6 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
'NetworkInfoServiceWindows.cpp',
|
||||
'nsNetworkInfoService.cpp',
|
||||
]
|
||||
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
SOURCES += [
|
||||
'NetworkInfoServiceCocoa.cpp',
|
||||
'nsNetworkInfoService.cpp',
|
||||
]
|
||||
elif CONFIG['OS_ARCH'] == 'Linux':
|
||||
SOURCES += [
|
||||
'NetworkInfoServiceLinux.cpp',
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 et cindent: */
|
||||
/* 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/. */
|
||||
|
||||
/* Mac OS X-specific local file uri parsing */
|
||||
#include "nsURLHelper.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
static nsTArray<nsCString> *gVolumeList = nullptr;
|
||||
|
||||
static bool pathBeginsWithVolName(const nsACString& path, nsACString& firstPathComponent)
|
||||
{
|
||||
// Return whether the 1st path component in path (escaped) is equal to the name
|
||||
// of a mounted volume. Return the 1st path component (unescaped) in any case.
|
||||
// This needs to be done as quickly as possible, so we cache a list of volume names.
|
||||
// XXX Register an event handler to detect drives being mounted/unmounted?
|
||||
|
||||
if (!gVolumeList) {
|
||||
gVolumeList = new nsTArray<nsCString>;
|
||||
if (!gVolumeList) {
|
||||
return false; // out of memory
|
||||
}
|
||||
}
|
||||
|
||||
// Cache a list of volume names
|
||||
if (!gVolumeList->Length()) {
|
||||
OSErr err;
|
||||
ItemCount volumeIndex = 1;
|
||||
|
||||
do {
|
||||
HFSUniStr255 volName;
|
||||
FSRef rootDirectory;
|
||||
err = ::FSGetVolumeInfo(0, volumeIndex, nullptr, kFSVolInfoNone, nullptr,
|
||||
&volName, &rootDirectory);
|
||||
if (err == noErr) {
|
||||
NS_ConvertUTF16toUTF8 volNameStr(Substring((char16_t *)volName.unicode,
|
||||
(char16_t *)volName.unicode + volName.length));
|
||||
gVolumeList->AppendElement(volNameStr);
|
||||
volumeIndex++;
|
||||
}
|
||||
} while (err == noErr);
|
||||
}
|
||||
|
||||
// Extract the first component of the path
|
||||
nsACString::const_iterator start;
|
||||
path.BeginReading(start);
|
||||
start.advance(1); // path begins with '/'
|
||||
nsACString::const_iterator directory_end;
|
||||
path.EndReading(directory_end);
|
||||
nsACString::const_iterator component_end(start);
|
||||
FindCharInReadable('/', component_end, directory_end);
|
||||
|
||||
nsAutoCString flatComponent((Substring(start, component_end)));
|
||||
NS_UnescapeURL(flatComponent);
|
||||
int32_t foundIndex = gVolumeList->IndexOf(flatComponent);
|
||||
firstPathComponent = flatComponent;
|
||||
return (foundIndex != -1);
|
||||
}
|
||||
|
||||
void
|
||||
net_ShutdownURLHelperOSX()
|
||||
{
|
||||
delete gVolumeList;
|
||||
gVolumeList = nullptr;
|
||||
}
|
||||
|
||||
static nsresult convertHFSPathtoPOSIX(const nsACString& hfsPath, nsACString& posixPath)
|
||||
{
|
||||
// Use CFURL to do the conversion. We don't want to do this by simply
|
||||
// using SwapSlashColon - we need the charset mapped from MacRoman
|
||||
// to UTF-8, and we need "/Volumes" (or whatever - Apple says this is subject to change)
|
||||
// prepended if the path is not on the boot drive.
|
||||
|
||||
CFStringRef pathStrRef = CFStringCreateWithCString(nullptr,
|
||||
PromiseFlatCString(hfsPath).get(),
|
||||
kCFStringEncodingMacRoman);
|
||||
if (!pathStrRef)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
CFURLRef urlRef = CFURLCreateWithFileSystemPath(nullptr,
|
||||
pathStrRef, kCFURLHFSPathStyle, true);
|
||||
if (urlRef) {
|
||||
UInt8 pathBuf[PATH_MAX];
|
||||
if (CFURLGetFileSystemRepresentation(urlRef, true, pathBuf, sizeof(pathBuf))) {
|
||||
posixPath = (char *)pathBuf;
|
||||
rv = NS_OK;
|
||||
}
|
||||
}
|
||||
CFRelease(pathStrRef);
|
||||
if (urlRef)
|
||||
CFRelease(urlRef);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void SwapSlashColon(char *s)
|
||||
{
|
||||
while (*s) {
|
||||
if (*s == '/')
|
||||
*s = ':';
|
||||
else if (*s == ':')
|
||||
*s = '/';
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
net_GetURLSpecFromActualFile(nsIFile *aFile, nsACString &result)
|
||||
{
|
||||
// NOTE: This is identical to the implementation in nsURLHelperUnix.cpp
|
||||
|
||||
nsresult rv;
|
||||
nsAutoCString ePath;
|
||||
|
||||
// construct URL spec from native file path
|
||||
rv = aFile->GetNativePath(ePath);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsAutoCString escPath;
|
||||
NS_NAMED_LITERAL_CSTRING(prefix, "file://");
|
||||
|
||||
// Escape the path with the directory mask
|
||||
if (NS_EscapeURL(ePath.get(), ePath.Length(), esc_Directory+esc_Forced, escPath))
|
||||
escPath.Insert(prefix, 0);
|
||||
else
|
||||
escPath.Assign(prefix + ePath);
|
||||
|
||||
// esc_Directory does not escape the semicolons, so if a filename
|
||||
// contains semicolons we need to manually escape them.
|
||||
// This replacement should be removed in bug #473280
|
||||
escPath.ReplaceSubstring(";", "%3b");
|
||||
|
||||
result = escPath;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
net_GetFileFromURLSpec(const nsACString &aURL, nsIFile **result)
|
||||
{
|
||||
// NOTE: See also the implementation in nsURLHelperUnix.cpp
|
||||
// This matches it except for the HFS path handling.
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
rv = NS_NewNativeLocalFile(EmptyCString(), true, getter_AddRefs(localFile));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsAutoCString directory, fileBaseName, fileExtension, path;
|
||||
bool bHFSPath = false;
|
||||
|
||||
rv = net_ParseFileURL(aURL, directory, fileBaseName, fileExtension);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (!directory.IsEmpty()) {
|
||||
NS_EscapeURL(directory, esc_Directory|esc_AlwaysCopy, path);
|
||||
|
||||
// The canonical form of file URLs on OSX use POSIX paths:
|
||||
// file:///path-name.
|
||||
// But, we still encounter file URLs that use HFS paths:
|
||||
// file:///volume-name/path-name
|
||||
// Determine that here and normalize HFS paths to POSIX.
|
||||
nsAutoCString possibleVolName;
|
||||
if (pathBeginsWithVolName(directory, possibleVolName)) {
|
||||
// Though we know it begins with a volume name, it could still
|
||||
// be a valid POSIX path if the boot drive is named "Mac HD"
|
||||
// and there is a directory "Mac HD" at its root. If such a
|
||||
// directory doesn't exist, we'll assume this is an HFS path.
|
||||
FSRef testRef;
|
||||
possibleVolName.Insert("/", 0);
|
||||
if (::FSPathMakeRef((UInt8*)possibleVolName.get(), &testRef, nullptr) != noErr)
|
||||
bHFSPath = true;
|
||||
}
|
||||
|
||||
if (bHFSPath) {
|
||||
// "%2F"s need to become slashes, while all other slashes need to
|
||||
// become colons. If we start out by changing "%2F"s to colons, we
|
||||
// can reply on SwapSlashColon() to do what we need
|
||||
path.ReplaceSubstring("%2F", ":");
|
||||
path.Cut(0, 1); // directory begins with '/'
|
||||
SwapSlashColon((char *)path.get());
|
||||
// At this point, path is an HFS path made using the same
|
||||
// algorithm as nsURLHelperMac. We'll convert to POSIX below.
|
||||
}
|
||||
}
|
||||
if (!fileBaseName.IsEmpty())
|
||||
NS_EscapeURL(fileBaseName, esc_FileBaseName|esc_AlwaysCopy, path);
|
||||
if (!fileExtension.IsEmpty()) {
|
||||
path += '.';
|
||||
NS_EscapeURL(fileExtension, esc_FileExtension|esc_AlwaysCopy, path);
|
||||
}
|
||||
|
||||
NS_UnescapeURL(path);
|
||||
if (path.Length() != strlen(path.get()))
|
||||
return NS_ERROR_FILE_INVALID_PATH;
|
||||
|
||||
if (bHFSPath)
|
||||
convertHFSPathtoPOSIX(path, path);
|
||||
|
||||
// assuming path is encoded in the native charset
|
||||
rv = localFile->InitWithNativePath(path);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
localFile.forget(result);
|
||||
return NS_OK;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user