зеркало из https://github.com/mozilla/gecko-dev.git
Merge last green changeset from mozilla-inbound to mozilla-central
This commit is contained in:
Коммит
30d74a0fd5
|
@ -44,7 +44,8 @@
|
|||
#include "nsMai.h"
|
||||
#include "prlink.h"
|
||||
#include "prenv.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsIGConfService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
|
@ -53,6 +54,8 @@
|
|||
#include <gtk/gtk.h>
|
||||
#include <atk/atk.h>
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
typedef GType (* AtkGetTypeType) (void);
|
||||
GType g_atk_hyperlink_impl_type = G_TYPE_INVALID;
|
||||
static bool sATKChecked = false;
|
||||
|
@ -61,10 +64,12 @@ static const char sATKLibName[] = "libatk-1.0.so.0";
|
|||
static const char sATKHyperlinkImplGetTypeSymbol[] =
|
||||
"atk_hyperlink_impl_get_type";
|
||||
static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
|
||||
static const char sSysPrefService [] =
|
||||
"@mozilla.org/system-preference-service;1";
|
||||
static const char sUseSystemPrefsKey[] =
|
||||
"config.use_system_prefs";
|
||||
static const char sAccessibilityKey [] =
|
||||
"config.use_system_prefs.accessibility";
|
||||
static const char sGconfAccessibilityKey[] =
|
||||
"/desktop/gnome/interface/accessibility";
|
||||
|
||||
/* gail function pointer */
|
||||
static guint (* gail_add_global_event_listener) (GSignalEmissionHook listener,
|
||||
|
@ -625,11 +630,17 @@ nsApplicationAccessibleWrap::Init()
|
|||
isGnomeATEnabled = !!atoi(envValue);
|
||||
} else {
|
||||
//check gconf-2 setting
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefBranch> sysPrefService =
|
||||
do_GetService(sSysPrefService, &rv);
|
||||
if (NS_SUCCEEDED(rv) && sysPrefService) {
|
||||
sysPrefService->GetBoolPref(sAccessibilityKey, &isGnomeATEnabled);
|
||||
if (Preferences::GetBool(sUseSystemPrefsKey, false)) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIGConfService> gconf =
|
||||
do_GetService(NS_GCONFSERVICE_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && gconf) {
|
||||
gconf->GetBool(NS_LITERAL_CSTRING(sGconfAccessibilityKey),
|
||||
&isGnomeATEnabled);
|
||||
}
|
||||
} else {
|
||||
isGnomeATEnabled =
|
||||
Preferences::GetBool(sAccessibilityKey, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,17 @@
|
|||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
/* Because of -moz-box-align: center above, separators will be invisible unless
|
||||
we set their min-height. See bug 583510 for more information. */
|
||||
toolbarseparator {
|
||||
min-height: 22px;
|
||||
}
|
||||
|
||||
/* We need more height when toolbar buttons show both icon and text. */
|
||||
toolbar[mode="full"] toolbarseparator {
|
||||
min-height: 36px;
|
||||
}
|
||||
|
||||
#nav-bar {
|
||||
padding-bottom: 4px !important;
|
||||
}
|
||||
|
|
|
@ -2,12 +2,6 @@
|
|||
|
||||
/* Sidebars */
|
||||
|
||||
.sidebar-placesTree {
|
||||
background-color: transparent !important;
|
||||
-moz-appearance: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
#bookmarksPanel,
|
||||
#history-panel,
|
||||
#sidebar-search-container {
|
||||
|
|
|
@ -36,13 +36,14 @@ dnl the terms of any one of the MPL, the GPL or the LGPL.
|
|||
dnl
|
||||
dnl ***** END LICENSE BLOCK *****
|
||||
|
||||
dnl MOZ_CHECK_HEADER(HEADER-FILE, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl MOZ_CHECK_HEADER(HEADER-FILE, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]])
|
||||
AC_DEFUN([MOZ_CHECK_HEADER],
|
||||
[ dnl Do the transliteration at runtime so arg 1 can be a shell variable.
|
||||
ac_safe=`echo "$1" | sed 'y%./+-%__p_%'`
|
||||
AC_MSG_CHECKING([for $1])
|
||||
AC_CACHE_VAL(ac_cv_header_$ac_safe,
|
||||
[ AC_TRY_COMPILE([#include <$1>], ,
|
||||
[ AC_TRY_COMPILE([$4
|
||||
#include <$1>], ,
|
||||
eval "ac_cv_header_$ac_safe=yes",
|
||||
eval "ac_cv_header_$ac_safe=no") ])
|
||||
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
|
||||
|
@ -54,12 +55,12 @@ AC_DEFUN([MOZ_CHECK_HEADER],
|
|||
fi
|
||||
])
|
||||
|
||||
dnl MOZ_CHECK_HEADERS(HEADER-FILE... [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
|
||||
dnl MOZ_CHECK_HEADERS(HEADER-FILE... [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]])
|
||||
AC_DEFUN([MOZ_CHECK_HEADERS],
|
||||
[ for ac_hdr in $1
|
||||
do
|
||||
MOZ_CHECK_HEADER($ac_hdr,
|
||||
[ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
|
||||
AC_DEFINE_UNQUOTED($ac_tr_hdr) $2], $3)
|
||||
AC_DEFINE_UNQUOTED($ac_tr_hdr) $2], $3, [$4])
|
||||
done
|
||||
])
|
||||
|
|
|
@ -5935,12 +5935,11 @@ if test "$MOZ_XTF"; then
|
|||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl Pref extensions (autoconfig and system-pref)
|
||||
dnl Pref extensions (autoconfig)
|
||||
dnl ========================================================
|
||||
MOZ_ARG_DISABLE_BOOL(pref-extensions,
|
||||
[ --disable-pref-extensions
|
||||
Disable pref extensions such as autoconfig and
|
||||
system-pref],
|
||||
Disable pref extensions such as autoconfig],
|
||||
MOZ_PREF_EXTENSIONS=,
|
||||
MOZ_PREF_EXTENSIONS=1 )
|
||||
|
||||
|
@ -8761,8 +8760,8 @@ if test "$USE_FC_FREETYPE"; then
|
|||
if test "$COMPILE_ENVIRONMENT"; then
|
||||
_SAVE_CPPFLAGS="$CPPFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $FT2_CFLAGS $XCFLAGS"
|
||||
AC_CHECK_HEADERS(fontconfig/fcfreetype.h, ,
|
||||
[AC_MSG_ERROR(Can't find header fontconfig/fcfreetype.h.)])
|
||||
MOZ_CHECK_HEADERS([fontconfig/fcfreetype.h], ,
|
||||
[AC_MSG_ERROR(Can't find header fontconfig/fcfreetype.h.)], [#include <fontconfig/fontconfig.h>])
|
||||
CPPFLAGS="$_SAVE_CPPFLAGS"
|
||||
else
|
||||
AC_DEFINE(HAVE_FONTCONFIG_FCFREETYPE_H)
|
||||
|
|
|
@ -1290,11 +1290,6 @@ public:
|
|||
static void TraceWrapper(nsWrapperCache* aCache, TraceCallback aCallback,
|
||||
void *aClosure);
|
||||
|
||||
/**
|
||||
* Convert nsIContent::IME_STATUS_* to nsIWidget::IME_STATUS_*
|
||||
*/
|
||||
static PRUint32 GetWidgetStatusFromIMEStatus(PRUint32 aState);
|
||||
|
||||
/*
|
||||
* Notify when the first XUL menu is opened and when the all XUL menus are
|
||||
* closed. At opening, aInstalling should be TRUE, otherwise, it should be
|
||||
|
|
|
@ -63,8 +63,11 @@ class nsIDOMCSSStyleDeclaration;
|
|||
namespace mozilla {
|
||||
namespace css {
|
||||
class StyleRule;
|
||||
}
|
||||
}
|
||||
} // namespace css
|
||||
namespace widget {
|
||||
struct IMEState;
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
||||
enum nsLinkState {
|
||||
eLinkState_Unknown = 0,
|
||||
|
@ -75,8 +78,8 @@ enum nsLinkState {
|
|||
|
||||
// IID for the nsIContent interface
|
||||
#define NS_ICONTENT_IID \
|
||||
{ 0x3128b3a0, 0xb609, 0x44e3, \
|
||||
{ 0xad, 0x91, 0xdc, 0xf1, 0x4a, 0x3f, 0xf6, 0xa0 } }
|
||||
{ 0xed40a3e5, 0xd7ed, 0x473e, \
|
||||
{ 0x85, 0xe3, 0x82, 0xc3, 0xf0, 0x41, 0xdb, 0x52 } }
|
||||
|
||||
/**
|
||||
* A node of content in a document's content model. This interface
|
||||
|
@ -84,6 +87,8 @@ enum nsLinkState {
|
|||
*/
|
||||
class nsIContent : public nsINode {
|
||||
public:
|
||||
typedef mozilla::widget::IMEState IMEState;
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
// If you're using the external API, the only thing you can know about
|
||||
// nsIContent is that it exists with an IID
|
||||
|
@ -604,40 +609,18 @@ public:
|
|||
* Get desired IME state for the content.
|
||||
*
|
||||
* @return The desired IME status for the content.
|
||||
* This is a combination of IME_STATUS_* flags,
|
||||
* controlling what happens to IME when the content takes focus.
|
||||
* If this is IME_STATUS_NONE, IME remains in its current state.
|
||||
* IME_STATUS_ENABLE and IME_STATUS_DISABLE must not be set
|
||||
* together; likewise IME_STATUS_OPEN and IME_STATUS_CLOSE must
|
||||
* not be set together.
|
||||
* If you return IME_STATUS_DISABLE, you should not set the
|
||||
* OPEN or CLOSE flag; that way, when IME is next enabled,
|
||||
* the previous OPEN/CLOSE state will be restored (unless the newly
|
||||
* focused content specifies the OPEN/CLOSE state by setting the OPEN
|
||||
* or CLOSE flag with the ENABLE flag).
|
||||
* IME_STATUS_PASSWORD should be returned only from password editor,
|
||||
* this value has a special meaning. It is used as alternative of
|
||||
* IME_STATUS_DISABLED.
|
||||
* IME_STATUS_PLUGIN should be returned only when plug-in has focus.
|
||||
* When a plug-in is focused content, we should send native events
|
||||
* directly. Because we don't process some native events, but they may
|
||||
* be needed by the plug-in.
|
||||
* This is a combination of an IME enabled value and
|
||||
* an IME open value of widget::IMEState.
|
||||
* If you return DISABLED, you should not set the OPEN and CLOSE
|
||||
* value.
|
||||
* PASSWORD should be returned only from password editor, this value
|
||||
* has a special meaning. It is used as alternative of DISABLED.
|
||||
* PLUGIN should be returned only when plug-in has focus. When a
|
||||
* plug-in is focused content, we should send native events directly.
|
||||
* Because we don't process some native events, but they may be needed
|
||||
* by the plug-in.
|
||||
*/
|
||||
enum {
|
||||
IME_STATUS_NONE = 0x0000,
|
||||
IME_STATUS_ENABLE = 0x0001,
|
||||
IME_STATUS_DISABLE = 0x0002,
|
||||
IME_STATUS_PASSWORD = 0x0004,
|
||||
IME_STATUS_PLUGIN = 0x0008,
|
||||
IME_STATUS_OPEN = 0x0010,
|
||||
IME_STATUS_CLOSE = 0x0020
|
||||
};
|
||||
enum {
|
||||
IME_STATUS_MASK_ENABLED = IME_STATUS_ENABLE | IME_STATUS_DISABLE |
|
||||
IME_STATUS_PASSWORD | IME_STATUS_PLUGIN,
|
||||
IME_STATUS_MASK_OPENED = IME_STATUS_OPEN | IME_STATUS_CLOSE
|
||||
};
|
||||
virtual PRUint32 GetDesiredIMEState();
|
||||
virtual IMEState GetDesiredIMEState();
|
||||
|
||||
/**
|
||||
* Gets content node with the binding (or native code, possibly on the
|
||||
|
|
|
@ -212,6 +212,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
|
|||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::widget;
|
||||
using namespace mozilla;
|
||||
|
||||
const char kLoadAsData[] = "loadAsData";
|
||||
|
@ -4026,25 +4027,6 @@ nsContentUtils::DropJSObjects(void* aScriptObjectHolder)
|
|||
return rv;
|
||||
}
|
||||
|
||||
/* static */
|
||||
PRUint32
|
||||
nsContentUtils::GetWidgetStatusFromIMEStatus(PRUint32 aState)
|
||||
{
|
||||
switch (aState & nsIContent::IME_STATUS_MASK_ENABLED) {
|
||||
case nsIContent::IME_STATUS_DISABLE:
|
||||
return nsIWidget::IME_STATUS_DISABLED;
|
||||
case nsIContent::IME_STATUS_ENABLE:
|
||||
return nsIWidget::IME_STATUS_ENABLED;
|
||||
case nsIContent::IME_STATUS_PASSWORD:
|
||||
return nsIWidget::IME_STATUS_PASSWORD;
|
||||
case nsIContent::IME_STATUS_PLUGIN:
|
||||
return nsIWidget::IME_STATUS_PLUGIN;
|
||||
default:
|
||||
NS_ERROR("The given state doesn't have valid enable state");
|
||||
return nsIWidget::IME_STATUS_ENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsContentUtils::NotifyInstalledMenuKeyboardListener(bool aInstalling)
|
||||
|
|
|
@ -109,6 +109,7 @@
|
|||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
|
||||
|
@ -1363,11 +1364,11 @@ nsIContent::GetFlattenedTreeParent() const
|
|||
return parent;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsIContent::IMEState
|
||||
nsIContent::GetDesiredIMEState()
|
||||
{
|
||||
if (!IsEditableInternal()) {
|
||||
return IME_STATUS_DISABLE;
|
||||
return IMEState(IMEState::DISABLED);
|
||||
}
|
||||
// NOTE: The content for independent editors (e.g., input[type=text],
|
||||
// textarea) must override this method, so, we don't need to worry about
|
||||
|
@ -1380,26 +1381,23 @@ nsIContent::GetDesiredIMEState()
|
|||
}
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (!doc) {
|
||||
return IME_STATUS_DISABLE;
|
||||
return IMEState(IMEState::DISABLED);
|
||||
}
|
||||
nsIPresShell* ps = doc->GetShell();
|
||||
if (!ps) {
|
||||
return IME_STATUS_DISABLE;
|
||||
return IMEState(IMEState::DISABLED);
|
||||
}
|
||||
nsPresContext* pc = ps->GetPresContext();
|
||||
if (!pc) {
|
||||
return IME_STATUS_DISABLE;
|
||||
return IMEState(IMEState::DISABLED);
|
||||
}
|
||||
nsIEditor* editor = GetHTMLEditor(pc);
|
||||
nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(editor);
|
||||
if (!imeEditor) {
|
||||
return IME_STATUS_DISABLE;
|
||||
return IMEState(IMEState::DISABLED);
|
||||
}
|
||||
// Use "enable" for the default value because IME is disabled unexpectedly,
|
||||
// it makes serious a11y problem.
|
||||
PRUint32 state = IME_STATUS_ENABLE;
|
||||
nsresult rv = imeEditor->GetPreferredIMEState(&state);
|
||||
NS_ENSURE_SUCCESS(rv, IME_STATUS_ENABLE);
|
||||
IMEState state;
|
||||
imeEditor->GetPreferredIMEState(&state);
|
||||
return state;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@
|
|||
|
||||
#include "nsIMEStateManager.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsISupports.h"
|
||||
|
@ -51,6 +50,8 @@
|
|||
#include "nsIDocument.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDOMMouseEvent.h"
|
||||
#include "nsIDOMNSEvent.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsINode.h"
|
||||
#include "nsIFrame.h"
|
||||
|
@ -68,6 +69,8 @@
|
|||
#include "nsIForm.h"
|
||||
#include "nsHTMLFormElement.h"
|
||||
|
||||
using namespace mozilla::widget;
|
||||
|
||||
/******************************************************************/
|
||||
/* nsIMEStateManager */
|
||||
/******************************************************************/
|
||||
|
@ -87,8 +90,10 @@ nsIMEStateManager::OnDestroyPresContext(nsPresContext* aPresContext)
|
|||
return NS_OK;
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget(sPresContext);
|
||||
if (widget) {
|
||||
PRUint32 newState = GetNewIMEState(sPresContext, nsnull);
|
||||
SetIMEState(newState, nsnull, widget, IMEContext::FOCUS_REMOVED);
|
||||
IMEState newState = GetNewIMEState(sPresContext, nsnull);
|
||||
InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
|
||||
InputContextAction::LOST_FOCUS);
|
||||
SetIMEState(newState, nsnull, widget, action);
|
||||
}
|
||||
sContent = nsnull;
|
||||
sPresContext = nsnull;
|
||||
|
@ -112,8 +117,10 @@ nsIMEStateManager::OnRemoveContent(nsPresContext* aPresContext,
|
|||
nsresult rv = widget->CancelIMEComposition();
|
||||
if (NS_FAILED(rv))
|
||||
widget->ResetInputState();
|
||||
PRUint32 newState = GetNewIMEState(sPresContext, nsnull);
|
||||
SetIMEState(newState, nsnull, widget, IMEContext::FOCUS_REMOVED);
|
||||
IMEState newState = GetNewIMEState(sPresContext, nsnull);
|
||||
InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
|
||||
InputContextAction::LOST_FOCUS);
|
||||
SetIMEState(newState, nsnull, widget, action);
|
||||
}
|
||||
|
||||
sContent = nsnull;
|
||||
|
@ -125,7 +132,16 @@ nsIMEStateManager::OnRemoveContent(nsPresContext* aPresContext,
|
|||
nsresult
|
||||
nsIMEStateManager::OnChangeFocus(nsPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
PRUint32 aReason)
|
||||
InputContextAction::Cause aCause)
|
||||
{
|
||||
InputContextAction action(aCause);
|
||||
return OnChangeFocusInternal(aPresContext, aContent, action);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
InputContextAction aAction)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPresContext);
|
||||
|
||||
|
@ -157,25 +173,22 @@ nsIMEStateManager::OnChangeFocus(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
PRUint32 newState = GetNewIMEState(aPresContext, aContent);
|
||||
IMEState newState = GetNewIMEState(aPresContext, aContent);
|
||||
if (aPresContext == sPresContext && aContent == sContent) {
|
||||
// actual focus isn't changing, but if IME enabled state is changing,
|
||||
// we should do it.
|
||||
PRUint32 newEnabledState = newState & nsIContent::IME_STATUS_MASK_ENABLED;
|
||||
if (newEnabledState == 0) {
|
||||
// the enabled state isn't changing, we should do nothing.
|
||||
return NS_OK;
|
||||
}
|
||||
IMEContext context;
|
||||
if (!widget || NS_FAILED(widget->GetInputMode(context))) {
|
||||
// this platform doesn't support IME controlling
|
||||
return NS_OK;
|
||||
}
|
||||
if (context.mStatus ==
|
||||
nsContentUtils::GetWidgetStatusFromIMEStatus(newEnabledState)) {
|
||||
InputContext context = widget->GetInputContext();
|
||||
if (context.mIMEState.mEnabled == newState.mEnabled) {
|
||||
// the enabled state isn't changing.
|
||||
return NS_OK;
|
||||
}
|
||||
aAction.mFocusChange = InputContextAction::FOCUS_NOT_CHANGED;
|
||||
} else if (aAction.mFocusChange == InputContextAction::FOCUS_NOT_CHANGED) {
|
||||
// If aContent isn't null or aContent is null but editable, somebody gets
|
||||
// focus.
|
||||
bool gotFocus = aContent || (newState.mEnabled == IMEState::ENABLED);
|
||||
aAction.mFocusChange =
|
||||
gotFocus ? InputContextAction::GOT_FOCUS : InputContextAction::LOST_FOCUS;
|
||||
}
|
||||
|
||||
// Current IME transaction should commit
|
||||
|
@ -189,10 +202,8 @@ nsIMEStateManager::OnChangeFocus(nsPresContext* aPresContext,
|
|||
oldWidget->ResetInputState();
|
||||
}
|
||||
|
||||
if (newState != nsIContent::IME_STATUS_NONE) {
|
||||
// Update IME state for new focus widget
|
||||
SetIMEState(newState, aContent, widget, aReason);
|
||||
}
|
||||
// Update IME state for new focus widget
|
||||
SetIMEState(newState, aContent, widget, aAction);
|
||||
|
||||
sPresContext = aPresContext;
|
||||
sContent = aContent;
|
||||
|
@ -205,19 +216,60 @@ nsIMEStateManager::OnInstalledMenuKeyboardListener(bool aInstalling)
|
|||
{
|
||||
sInstalledMenuKeyboardListener = aInstalling;
|
||||
|
||||
PRUint32 reason = aInstalling ? IMEContext::FOCUS_MOVED_TO_MENU
|
||||
: IMEContext::FOCUS_MOVED_FROM_MENU;
|
||||
OnChangeFocus(sPresContext, sContent, reason);
|
||||
InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
|
||||
aInstalling ? InputContextAction::MENU_GOT_PSEUDO_FOCUS :
|
||||
InputContextAction::MENU_LOST_PSEUDO_FOCUS);
|
||||
OnChangeFocusInternal(sPresContext, sContent, action);
|
||||
}
|
||||
|
||||
void
|
||||
nsIMEStateManager::UpdateIMEState(PRUint32 aNewIMEState, nsIContent* aContent)
|
||||
nsIMEStateManager::OnClickInEditor(nsPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIDOMMouseEvent* aMouseEvent)
|
||||
{
|
||||
if (sPresContext != aPresContext || sContent != aContent) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget(aPresContext);
|
||||
NS_ENSURE_TRUE(widget, );
|
||||
|
||||
bool isTrusted;
|
||||
nsCOMPtr<nsIDOMNSEvent> NSEvent = do_QueryInterface(aMouseEvent);
|
||||
nsresult rv = NSEvent->GetIsTrusted(&isTrusted);
|
||||
NS_ENSURE_SUCCESS(rv, );
|
||||
if (!isTrusted) {
|
||||
return; // ignore untrusted event.
|
||||
}
|
||||
|
||||
PRUint16 button;
|
||||
rv = aMouseEvent->GetButton(&button);
|
||||
NS_ENSURE_SUCCESS(rv, );
|
||||
if (button != 0) {
|
||||
return; // not a left click event.
|
||||
}
|
||||
|
||||
PRInt32 clickCount;
|
||||
rv = aMouseEvent->GetDetail(&clickCount);
|
||||
NS_ENSURE_SUCCESS(rv, );
|
||||
if (clickCount != 1) {
|
||||
return; // should notify only first click event.
|
||||
}
|
||||
|
||||
InputContextAction action(InputContextAction::CAUSE_MOUSE,
|
||||
InputContextAction::FOCUS_NOT_CHANGED);
|
||||
IMEState newState = GetNewIMEState(aPresContext, aContent);
|
||||
SetIMEState(newState, aContent, widget, action);
|
||||
}
|
||||
|
||||
void
|
||||
nsIMEStateManager::UpdateIMEState(const IMEState &aNewIMEState,
|
||||
nsIContent* aContent)
|
||||
{
|
||||
if (!sPresContext) {
|
||||
NS_WARNING("ISM doesn't know which editor has focus");
|
||||
return;
|
||||
}
|
||||
NS_PRECONDITION(aNewIMEState != 0, "aNewIMEState doesn't specify new state.");
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget(sPresContext);
|
||||
if (!widget) {
|
||||
NS_WARNING("focused widget is not found");
|
||||
|
@ -225,43 +277,41 @@ nsIMEStateManager::UpdateIMEState(PRUint32 aNewIMEState, nsIContent* aContent)
|
|||
}
|
||||
|
||||
// Don't update IME state when enabled state isn't actually changed.
|
||||
IMEContext context;
|
||||
nsresult rv = widget->GetInputMode(context);
|
||||
if (NS_FAILED(rv)) {
|
||||
return; // This platform doesn't support controling the IME state.
|
||||
}
|
||||
PRUint32 newEnabledState = aNewIMEState & nsIContent::IME_STATUS_MASK_ENABLED;
|
||||
if (context.mStatus ==
|
||||
nsContentUtils::GetWidgetStatusFromIMEStatus(newEnabledState)) {
|
||||
InputContext context = widget->GetInputContext();
|
||||
if (context.mIMEState.mEnabled == aNewIMEState.mEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// commit current composition
|
||||
widget->ResetInputState();
|
||||
|
||||
SetIMEState(aNewIMEState, aContent, widget, IMEContext::EDITOR_STATE_MODIFIED);
|
||||
InputContextAction action(InputContextAction::CAUSE_UNKNOWN,
|
||||
InputContextAction::FOCUS_NOT_CHANGED);
|
||||
SetIMEState(aNewIMEState, aContent, widget, action);
|
||||
}
|
||||
|
||||
PRUint32
|
||||
IMEState
|
||||
nsIMEStateManager::GetNewIMEState(nsPresContext* aPresContext,
|
||||
nsIContent* aContent)
|
||||
{
|
||||
// On Printing or Print Preview, we don't need IME.
|
||||
if (aPresContext->Type() == nsPresContext::eContext_PrintPreview ||
|
||||
aPresContext->Type() == nsPresContext::eContext_Print) {
|
||||
return nsIContent::IME_STATUS_DISABLE;
|
||||
return IMEState(IMEState::DISABLED);
|
||||
}
|
||||
|
||||
if (sInstalledMenuKeyboardListener)
|
||||
return nsIContent::IME_STATUS_DISABLE;
|
||||
if (sInstalledMenuKeyboardListener) {
|
||||
return IMEState(IMEState::DISABLED);
|
||||
}
|
||||
|
||||
if (!aContent) {
|
||||
// Even if there are no focused content, the focused document might be
|
||||
// editable, such case is design mode.
|
||||
nsIDocument* doc = aPresContext->Document();
|
||||
if (doc && doc->HasFlag(NODE_IS_EDITABLE))
|
||||
return nsIContent::IME_STATUS_ENABLE;
|
||||
return nsIContent::IME_STATUS_DISABLE;
|
||||
if (doc && doc->HasFlag(NODE_IS_EDITABLE)) {
|
||||
return IMEState(IMEState::ENABLED);
|
||||
}
|
||||
return IMEState(IMEState::DISABLED);
|
||||
}
|
||||
|
||||
return aContent->GetDesiredIMEState();
|
||||
|
@ -290,65 +340,62 @@ private:
|
|||
};
|
||||
|
||||
void
|
||||
nsIMEStateManager::SetIMEState(PRUint32 aState,
|
||||
nsIMEStateManager::SetIMEState(const IMEState &aState,
|
||||
nsIContent* aContent,
|
||||
nsIWidget* aWidget,
|
||||
PRUint32 aReason)
|
||||
InputContextAction aAction)
|
||||
{
|
||||
if (aState & nsIContent::IME_STATUS_MASK_ENABLED) {
|
||||
if (!aWidget)
|
||||
return;
|
||||
NS_ENSURE_TRUE(aWidget, );
|
||||
|
||||
PRUint32 state = nsContentUtils::GetWidgetStatusFromIMEStatus(aState);
|
||||
IMEContext context;
|
||||
context.mStatus = state;
|
||||
|
||||
if (aContent && aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
|
||||
(aContent->Tag() == nsGkAtoms::input ||
|
||||
aContent->Tag() == nsGkAtoms::textarea)) {
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type,
|
||||
context.mHTMLInputType);
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::moz_action_hint,
|
||||
context.mActionHint);
|
||||
InputContext oldContext = aWidget->GetInputContext();
|
||||
|
||||
// if we don't have an action hint and return won't submit the form use "next"
|
||||
if (context.mActionHint.IsEmpty() && aContent->Tag() == nsGkAtoms::input) {
|
||||
bool willSubmit = false;
|
||||
nsCOMPtr<nsIFormControl> control(do_QueryInterface(aContent));
|
||||
mozilla::dom::Element* formElement = control->GetFormElement();
|
||||
nsCOMPtr<nsIForm> form;
|
||||
if (control) {
|
||||
// is this a form and does it have a default submit element?
|
||||
if ((form = do_QueryInterface(formElement)) && form->GetDefaultSubmitElement()) {
|
||||
willSubmit = true;
|
||||
// is this an html form and does it only have a single text input element?
|
||||
} else if (formElement && formElement->Tag() == nsGkAtoms::form && formElement->IsHTML() &&
|
||||
static_cast<nsHTMLFormElement*>(formElement)->HasSingleTextControl()) {
|
||||
willSubmit = true;
|
||||
}
|
||||
InputContext context;
|
||||
context.mIMEState = aState;
|
||||
|
||||
if (aContent && aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
|
||||
(aContent->Tag() == nsGkAtoms::input ||
|
||||
aContent->Tag() == nsGkAtoms::textarea)) {
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type,
|
||||
context.mHTMLInputType);
|
||||
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::moz_action_hint,
|
||||
context.mActionHint);
|
||||
|
||||
// if we don't have an action hint and return won't submit the form use "next"
|
||||
if (context.mActionHint.IsEmpty() && aContent->Tag() == nsGkAtoms::input) {
|
||||
bool willSubmit = false;
|
||||
nsCOMPtr<nsIFormControl> control(do_QueryInterface(aContent));
|
||||
mozilla::dom::Element* formElement = control->GetFormElement();
|
||||
nsCOMPtr<nsIForm> form;
|
||||
if (control) {
|
||||
// is this a form and does it have a default submit element?
|
||||
if ((form = do_QueryInterface(formElement)) && form->GetDefaultSubmitElement()) {
|
||||
willSubmit = true;
|
||||
// is this an html form and does it only have a single text input element?
|
||||
} else if (formElement && formElement->Tag() == nsGkAtoms::form && formElement->IsHTML() &&
|
||||
static_cast<nsHTMLFormElement*>(formElement)->HasSingleTextControl()) {
|
||||
willSubmit = true;
|
||||
}
|
||||
context.mActionHint.Assign(willSubmit ? control->GetType() == NS_FORM_INPUT_SEARCH
|
||||
? NS_LITERAL_STRING("search")
|
||||
: NS_LITERAL_STRING("go")
|
||||
: formElement
|
||||
? NS_LITERAL_STRING("next")
|
||||
: EmptyString());
|
||||
}
|
||||
context.mActionHint.Assign(willSubmit ? control->GetType() == NS_FORM_INPUT_SEARCH
|
||||
? NS_LITERAL_STRING("search")
|
||||
: NS_LITERAL_STRING("go")
|
||||
: formElement
|
||||
? NS_LITERAL_STRING("next")
|
||||
: EmptyString());
|
||||
}
|
||||
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
context.mReason = aReason | IMEContext::FOCUS_FROM_CONTENT_PROCESS;
|
||||
} else {
|
||||
context.mReason = aReason;
|
||||
}
|
||||
|
||||
aWidget->SetInputMode(context);
|
||||
|
||||
nsContentUtils::AddScriptRunner(new IMEEnabledStateChangedEvent(state));
|
||||
}
|
||||
if (aState & nsIContent::IME_STATUS_MASK_OPENED) {
|
||||
bool open = !!(aState & nsIContent::IME_STATUS_OPEN);
|
||||
aWidget->SetIMEOpenState(open);
|
||||
|
||||
// XXX I think that we should use nsContentUtils::IsCallerChrome() instead
|
||||
// of the process type.
|
||||
if (aAction.mCause == InputContextAction::CAUSE_UNKNOWN &&
|
||||
XRE_GetProcessType() != GeckoProcessType_Content) {
|
||||
aAction.mCause = InputContextAction::CAUSE_UNKNOWN_CHROME;
|
||||
}
|
||||
|
||||
aWidget->SetInputContext(context, aAction);
|
||||
if (oldContext.mIMEState.mEnabled != context.mIMEState.mEnabled) {
|
||||
nsContentUtils::AddScriptRunner(
|
||||
new IMEEnabledStateChangedEvent(context.mIMEState.mEnabled));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,11 +40,12 @@
|
|||
#define nsIMEStateManager_h__
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsIDOMMouseEvent;
|
||||
class nsPIDOMWindow;
|
||||
class nsPresContext;
|
||||
class nsIWidget;
|
||||
class nsTextStateManager;
|
||||
class nsISelection;
|
||||
|
||||
|
@ -54,13 +55,23 @@ class nsISelection;
|
|||
|
||||
class nsIMEStateManager
|
||||
{
|
||||
protected:
|
||||
typedef mozilla::widget::IMEState IMEState;
|
||||
typedef mozilla::widget::InputContext InputContext;
|
||||
typedef mozilla::widget::InputContextAction InputContextAction;
|
||||
|
||||
public:
|
||||
static nsresult OnDestroyPresContext(nsPresContext* aPresContext);
|
||||
static nsresult OnRemoveContent(nsPresContext* aPresContext,
|
||||
nsIContent* aContent);
|
||||
/**
|
||||
* OnChangeFocus() should be called when focused content is changed or
|
||||
* IME enabled state is changed. If focus isn't actually changed and IME
|
||||
* enabled state isn't changed, this will do nothing.
|
||||
*/
|
||||
static nsresult OnChangeFocus(nsPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
PRUint32 aReason);
|
||||
InputContextAction::Cause aCause);
|
||||
static void OnInstalledMenuKeyboardListener(bool aInstalling);
|
||||
|
||||
// These two methods manage focus and selection/text observers.
|
||||
|
@ -85,14 +96,27 @@ public:
|
|||
// isn't changed by the new state, this method does nothing.
|
||||
// Note that this method changes the IME state of the active element in the
|
||||
// widget. So, the caller must have focus.
|
||||
// aNewIMEState must have an enabled state of nsIContent::IME_STATUS_*.
|
||||
// And optionally, it can have an open state of nsIContent::IME_STATUS_*.
|
||||
static void UpdateIMEState(PRUint32 aNewIMEState, nsIContent* aContent);
|
||||
static void UpdateIMEState(const IMEState &aNewIMEState,
|
||||
nsIContent* aContent);
|
||||
|
||||
// This method is called when user clicked in an editor.
|
||||
// aContent must be:
|
||||
// If the editor is for <input> or <textarea>, the element.
|
||||
// If the editor is for contenteditable, the active editinghost.
|
||||
// If the editor is for designMode, NULL.
|
||||
static void OnClickInEditor(nsPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
nsIDOMMouseEvent* aMouseEvent);
|
||||
|
||||
protected:
|
||||
static void SetIMEState(PRUint32 aState, nsIContent* aContent,
|
||||
nsIWidget* aWidget, PRUint32 aReason);
|
||||
static PRUint32 GetNewIMEState(nsPresContext* aPresContext,
|
||||
static nsresult OnChangeFocusInternal(nsPresContext* aPresContext,
|
||||
nsIContent* aContent,
|
||||
InputContextAction aAction);
|
||||
static void SetIMEState(const IMEState &aState,
|
||||
nsIContent* aContent,
|
||||
nsIWidget* aWidget,
|
||||
InputContextAction aAction);
|
||||
static IMEState GetNewIMEState(nsPresContext* aPresContext,
|
||||
nsIContent* aContent);
|
||||
|
||||
static nsIWidget* GetWidget(nsPresContext* aPresContext);
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
#include "nsIScrollableFrame.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsRange.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsPresContext.h"
|
||||
|
@ -2652,7 +2653,7 @@ nsGenericHTMLFormElement::GetForm(nsIDOMHTMLFormElement** aForm)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsIContent::IMEState
|
||||
nsGenericHTMLFormElement::GetDesiredIMEState()
|
||||
{
|
||||
nsCOMPtr<nsIEditor> editor = nsnull;
|
||||
|
@ -2662,7 +2663,7 @@ nsGenericHTMLFormElement::GetDesiredIMEState()
|
|||
nsCOMPtr<nsIEditorIMESupport> imeEditor = do_QueryInterface(editor);
|
||||
if (!imeEditor)
|
||||
return nsGenericHTMLElement::GetDesiredIMEState();
|
||||
PRUint32 state;
|
||||
IMEState state;
|
||||
rv = imeEditor->GetPreferredIMEState(&state);
|
||||
if (NS_FAILED(rv))
|
||||
return nsGenericHTMLElement::GetDesiredIMEState();
|
||||
|
|
|
@ -884,7 +884,7 @@ public:
|
|||
bool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(bool aDeep = true,
|
||||
bool aNullParent = true);
|
||||
virtual PRUint32 GetDesiredIMEState();
|
||||
virtual IMEState GetDesiredIMEState();
|
||||
virtual nsEventStates IntrinsicState() const;
|
||||
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#include "nsIObjectFrame.h"
|
||||
#include "nsNPAPIPluginInstance.h"
|
||||
#include "nsIConstraintValidation.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -116,7 +117,7 @@ public:
|
|||
bool aNotify);
|
||||
|
||||
virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, PRInt32 *aTabIndex);
|
||||
virtual PRUint32 GetDesiredIMEState();
|
||||
virtual IMEState GetDesiredIMEState();
|
||||
|
||||
// Overriden nsIFormControl methods
|
||||
NS_IMETHOD_(PRUint32) GetType() const
|
||||
|
@ -376,11 +377,11 @@ nsHTMLObjectElement::IsHTMLFocusable(bool aWithMouse,
|
|||
return false;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsIContent::IMEState
|
||||
nsHTMLObjectElement::GetDesiredIMEState()
|
||||
{
|
||||
if (Type() == eType_Plugin) {
|
||||
return nsIContent::IME_STATUS_PLUGIN;
|
||||
return IMEState(IMEState::PLUGIN);
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::GetDesiredIMEState();
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
#include "nsIDOMGetSVGDocument.h"
|
||||
#include "nsIDOMSVGDocument.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
@ -119,7 +120,7 @@ public:
|
|||
bool aNotify);
|
||||
|
||||
virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, PRInt32 *aTabIndex);
|
||||
virtual PRUint32 GetDesiredIMEState();
|
||||
virtual IMEState GetDesiredIMEState();
|
||||
|
||||
virtual void DoneAddingChildren(bool aHaveNotified);
|
||||
virtual bool IsDoneAddingChildren();
|
||||
|
@ -365,11 +366,11 @@ nsHTMLSharedObjectElement::IsHTMLFocusable(bool aWithMouse,
|
|||
return nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex);
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsIContent::IMEState
|
||||
nsHTMLSharedObjectElement::GetDesiredIMEState()
|
||||
{
|
||||
if (Type() == eType_Plugin) {
|
||||
return nsIContent::IME_STATUS_PLUGIN;
|
||||
return IMEState(IMEState::PLUGIN);
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::GetDesiredIMEState();
|
||||
|
|
|
@ -334,6 +334,11 @@ nsSMILTimeValueSpec::RegisterEventListener(Element* aTarget)
|
|||
if (!aTarget)
|
||||
return;
|
||||
|
||||
// Don't listen for accessKey events if script is disabled. (see bug 704482)
|
||||
if (mParams.mType == nsSMILTimeValueSpecParams::ACCESSKEY &&
|
||||
!aTarget->GetOwnerDocument()->IsScriptEnabled())
|
||||
return;
|
||||
|
||||
if (!mEventListener) {
|
||||
mEventListener = new EventListener(this);
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@
|
|||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
static bool IsUniversalXPConnectCapable()
|
||||
{
|
||||
|
@ -1039,13 +1040,16 @@ nsDOMWindowUtils::GetIMEIsOpen(bool *aState)
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Open state should not be available when IME is not enabled.
|
||||
IMEContext context;
|
||||
nsresult rv = widget->GetInputMode(context);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (context.mStatus != nsIWidget::IME_STATUS_ENABLED)
|
||||
InputContext context = widget->GetInputContext();
|
||||
if (context.mIMEState.mEnabled != IMEState::ENABLED) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return widget->GetIMEOpenState(aState);
|
||||
if (context.mIMEState.mOpen == IMEState::OPEN_STATE_NOT_SUPPORTED) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
*aState = (context.mIMEState.mOpen == IMEState::OPEN);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1057,11 +1061,8 @@ nsDOMWindowUtils::GetIMEStatus(PRUint32 *aState)
|
|||
if (!widget)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
IMEContext context;
|
||||
nsresult rv = widget->GetInputMode(context);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*aState = context.mStatus;
|
||||
InputContext context = widget->GetInputContext();
|
||||
*aState = static_cast<PRUint32>(context.mIMEState.mEnabled);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1075,10 +1076,7 @@ nsDOMWindowUtils::GetFocusedInputType(char** aType)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
IMEContext context;
|
||||
nsresult rv = widget->GetInputMode(context);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
InputContext context = widget->GetInputContext();
|
||||
*aType = ToNewCString(context.mHTMLInputType);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,6 @@
|
|||
#include "nsIMEStateManager.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsCaret.h"
|
||||
#include "nsIWidget.h"
|
||||
#include "nsIBaseWindow.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsFrameSelection.h"
|
||||
|
@ -96,6 +95,7 @@
|
|||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
//#define DEBUG_FOCUS 1
|
||||
//#define DEBUG_FOCUS_NAVIGATION 1
|
||||
|
@ -337,19 +337,15 @@ nsFocusManager::GetRedirectedFocus(nsIContent* aContent)
|
|||
}
|
||||
|
||||
// static
|
||||
PRUint32
|
||||
nsFocusManager::GetFocusMoveReason(PRUint32 aFlags)
|
||||
InputContextAction::Cause
|
||||
nsFocusManager::GetFocusMoveActionCause(PRUint32 aFlags)
|
||||
{
|
||||
PRUint32 reason = IMEContext::FOCUS_MOVED_UNKNOWN;
|
||||
if (aFlags & nsIFocusManager::FLAG_BYMOUSE) {
|
||||
reason = IMEContext::FOCUS_MOVED_BY_MOUSE;
|
||||
return InputContextAction::CAUSE_MOUSE;
|
||||
} else if (aFlags & nsIFocusManager::FLAG_BYKEY) {
|
||||
reason = IMEContext::FOCUS_MOVED_BY_KEY;
|
||||
} else if (aFlags & nsIFocusManager::FLAG_BYMOVEFOCUS) {
|
||||
reason = IMEContext::FOCUS_MOVED_BY_MOVEFOCUS;
|
||||
return InputContextAction::CAUSE_KEY;
|
||||
}
|
||||
|
||||
return reason;
|
||||
return InputContextAction::CAUSE_UNKNOWN;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -964,7 +960,8 @@ nsFocusManager::WindowHidden(nsIDOMWindow* aWindow)
|
|||
|
||||
nsIMEStateManager::OnTextStateBlur(nsnull, nsnull);
|
||||
if (presShell) {
|
||||
nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull, IMEContext::FOCUS_REMOVED);
|
||||
nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull,
|
||||
GetFocusMoveActionCause(0));
|
||||
SetCaretVisible(presShell, false, nsnull);
|
||||
}
|
||||
|
||||
|
@ -1523,8 +1520,10 @@ nsFocusManager::Blur(nsPIDOMWindow* aWindowToClear,
|
|||
// This has to happen before the focus is cleared below, otherwise, the IME
|
||||
// compositionend event won't get fired at the element being blurred.
|
||||
nsIMEStateManager::OnTextStateBlur(nsnull, nsnull);
|
||||
if (mActiveWindow)
|
||||
nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull, IMEContext::FOCUS_REMOVED);
|
||||
if (mActiveWindow) {
|
||||
nsIMEStateManager::OnChangeFocus(presShell->GetPresContext(), nsnull,
|
||||
GetFocusMoveActionCause(0));
|
||||
}
|
||||
|
||||
// now adjust the actual focus, by clearing the fields in the focus manager
|
||||
// and in the window.
|
||||
|
@ -1786,8 +1785,8 @@ nsFocusManager::Focus(nsPIDOMWindow* aWindow,
|
|||
}
|
||||
}
|
||||
|
||||
PRUint32 reason = GetFocusMoveReason(aFlags);
|
||||
nsIMEStateManager::OnChangeFocus(presContext, aContent, reason);
|
||||
nsIMEStateManager::OnChangeFocus(presContext, aContent,
|
||||
GetFocusMoveActionCause(aFlags));
|
||||
|
||||
// as long as this focus wasn't because a window was raised, update the
|
||||
// commands
|
||||
|
@ -1803,7 +1802,8 @@ nsFocusManager::Focus(nsPIDOMWindow* aWindow,
|
|||
nsIMEStateManager::OnTextStateFocus(presContext, aContent);
|
||||
} else {
|
||||
nsIMEStateManager::OnTextStateBlur(presContext, nsnull);
|
||||
nsIMEStateManager::OnChangeFocus(presContext, nsnull, IMEContext::FOCUS_REMOVED);
|
||||
nsIMEStateManager::OnChangeFocus(presContext, nsnull,
|
||||
GetFocusMoveActionCause(aFlags));
|
||||
if (!aWindowRaised) {
|
||||
aWindow->UpdateCommands(NS_LITERAL_STRING("focus"));
|
||||
}
|
||||
|
@ -1826,7 +1826,8 @@ nsFocusManager::Focus(nsPIDOMWindow* aWindow,
|
|||
|
||||
nsPresContext* presContext = presShell->GetPresContext();
|
||||
nsIMEStateManager::OnTextStateBlur(presContext, nsnull);
|
||||
nsIMEStateManager::OnChangeFocus(presContext, nsnull, IMEContext::FOCUS_REMOVED);
|
||||
nsIMEStateManager::OnChangeFocus(presContext, nsnull,
|
||||
GetFocusMoveActionCause(aFlags));
|
||||
|
||||
if (!aWindowRaised)
|
||||
aWindow->UpdateCommands(NS_LITERAL_STRING("focus"));
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "nsWeakReference.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
#define FOCUSMETHOD_MASK 0xF000
|
||||
#define FOCUSMETHODANDRING_MASK 0xF0F000
|
||||
|
@ -67,6 +68,8 @@ class nsFocusManager : public nsIFocusManager,
|
|||
public nsIObserver,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
typedef mozilla::widget::InputContextAction InputContextAction;
|
||||
|
||||
public:
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsFocusManager, nsIFocusManager)
|
||||
|
@ -131,11 +134,9 @@ public:
|
|||
static nsIContent* GetRedirectedFocus(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Returns a flag indicating the source and/or reason of the focus change.
|
||||
* This is used to indicate to the IME code if the focus come from a user
|
||||
* input or a script for example.
|
||||
* Returns an InputContextAction cause for aFlags.
|
||||
*/
|
||||
static PRUint32 GetFocusMoveReason(PRUint32 aFlags);
|
||||
static InputContextAction::Cause GetFocusMoveActionCause(PRUint32 aFlags);
|
||||
|
||||
static bool sMouseFocusesFormControl;
|
||||
|
||||
|
|
|
@ -172,13 +172,14 @@ parent:
|
|||
*/
|
||||
sync EndIMEComposition(bool cancel) returns (nsString composition);
|
||||
|
||||
sync GetIMEEnabled() returns (PRUint32 value);
|
||||
sync GetInputContext() returns (PRInt32 IMEEnabled, PRInt32 IMEOpen);
|
||||
|
||||
SetInputMode(PRUint32 value, nsString type, nsString actionHint, PRUint32 reason);
|
||||
|
||||
sync GetIMEOpenState() returns (bool value);
|
||||
|
||||
SetIMEOpenState(bool value);
|
||||
SetInputContext(PRInt32 IMEEnabled,
|
||||
PRInt32 IMEOpen,
|
||||
nsString type,
|
||||
nsString actionHint,
|
||||
PRInt32 cause,
|
||||
PRInt32 focusChange);
|
||||
|
||||
/**
|
||||
* Gets the DPI of the screen corresponding to this browser.
|
||||
|
|
|
@ -74,6 +74,7 @@
|
|||
using namespace mozilla::dom;
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::layout;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
// The flags passed by the webProgress notifications are 16 bits shifted
|
||||
// from the ones registered by webProgressListeners.
|
||||
|
@ -563,66 +564,60 @@ TabParent::RecvEndIMEComposition(const bool& aCancel,
|
|||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvGetIMEEnabled(PRUint32* aValue)
|
||||
TabParent::RecvGetInputContext(PRInt32* aIMEEnabled,
|
||||
PRInt32* aIMEOpen)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget) {
|
||||
*aValue = nsIWidget::IME_STATUS_DISABLED;
|
||||
*aIMEEnabled = IMEState::DISABLED;
|
||||
*aIMEOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
|
||||
return true;
|
||||
}
|
||||
|
||||
IMEContext context;
|
||||
widget->GetInputMode(context);
|
||||
*aValue = context.mStatus;
|
||||
InputContext context = widget->GetInputContext();
|
||||
*aIMEEnabled = static_cast<PRInt32>(context.mIMEState.mEnabled);
|
||||
*aIMEOpen = static_cast<PRInt32>(context.mIMEState.mOpen);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvSetInputMode(const PRUint32& aValue, const nsString& aType, const nsString& aAction, const PRUint32& aReason)
|
||||
TabParent::RecvSetInputContext(const PRInt32& aIMEEnabled,
|
||||
const PRInt32& aIMEOpen,
|
||||
const nsString& aType,
|
||||
const nsString& aActionHint,
|
||||
const PRInt32& aCause,
|
||||
const PRInt32& aFocusChange)
|
||||
{
|
||||
// mIMETabParent (which is actually static) tracks which if any TabParent has IMEFocus
|
||||
// When the input mode is set to anything but IME_STATUS_NONE, mIMETabParent should be set to this
|
||||
mIMETabParent = aValue & nsIContent::IME_STATUS_MASK_ENABLED ? this : nsnull;
|
||||
// When the input mode is set to anything but IMEState::DISABLED,
|
||||
// mIMETabParent should be set to this
|
||||
mIMETabParent =
|
||||
aIMEEnabled != static_cast<PRInt32>(IMEState::DISABLED) ? this : nsnull;
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (!widget || !AllowContentIME())
|
||||
return true;
|
||||
|
||||
IMEContext context;
|
||||
context.mStatus = aValue;
|
||||
InputContext context;
|
||||
context.mIMEState.mEnabled = static_cast<IMEState::Enabled>(aIMEEnabled);
|
||||
context.mIMEState.mOpen = static_cast<IMEState::Open>(aIMEOpen);
|
||||
context.mHTMLInputType.Assign(aType);
|
||||
context.mActionHint.Assign(aAction);
|
||||
context.mReason = aReason;
|
||||
widget->SetInputMode(context);
|
||||
context.mActionHint.Assign(aActionHint);
|
||||
InputContextAction action(
|
||||
static_cast<InputContextAction::Cause>(aCause),
|
||||
static_cast<InputContextAction::FocusChange>(aFocusChange));
|
||||
widget->SetInputContext(context, action);
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
||||
if (!observerService)
|
||||
return true;
|
||||
|
||||
nsAutoString state;
|
||||
state.AppendInt(aValue);
|
||||
state.AppendInt(aIMEEnabled);
|
||||
observerService->NotifyObservers(nsnull, "ime-enabled-state-changed", state.get());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvGetIMEOpenState(bool* aValue)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget)
|
||||
widget->GetIMEOpenState(aValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvSetIMEOpenState(const bool& aValue)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetWidget();
|
||||
if (widget && AllowContentIME())
|
||||
widget->SetIMEOpenState(aValue);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
TabParent::RecvGetDPI(float* aValue)
|
||||
{
|
||||
|
|
|
@ -103,10 +103,14 @@ public:
|
|||
virtual bool RecvNotifyIMETextHint(const nsString& aText);
|
||||
virtual bool RecvEndIMEComposition(const bool& aCancel,
|
||||
nsString* aComposition);
|
||||
virtual bool RecvGetIMEEnabled(PRUint32* aValue);
|
||||
virtual bool RecvSetInputMode(const PRUint32& aValue, const nsString& aType, const nsString& aAction, const PRUint32& aReason);
|
||||
virtual bool RecvGetIMEOpenState(bool* aValue);
|
||||
virtual bool RecvSetIMEOpenState(const bool& aValue);
|
||||
virtual bool RecvGetInputContext(PRInt32* aIMEEnabled,
|
||||
PRInt32* aIMEOpen);
|
||||
virtual bool RecvSetInputContext(const PRInt32& aIMEEnabled,
|
||||
const PRInt32& aIMEOpen,
|
||||
const nsString& aType,
|
||||
const nsString& aActionHint,
|
||||
const PRInt32& aCause,
|
||||
const PRInt32& aFocusChange);
|
||||
virtual bool RecvSetCursor(const PRUint32& aValue);
|
||||
virtual bool RecvSetBackgroundColor(const nscolor& aValue);
|
||||
virtual bool RecvGetDPI(float* aValue);
|
||||
|
|
|
@ -39,7 +39,17 @@
|
|||
#include "nsISupports.idl"
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(a64744c5-d3ff-46ba-b9b1-57f79ff7d97d)]
|
||||
%{C++
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
struct IMEState;
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
%}
|
||||
|
||||
native IMEState(mozilla::widget::IMEState);
|
||||
|
||||
[scriptable, uuid(0ba7f490-afb8-46dd-87fc-bc6137fbc899)]
|
||||
|
||||
interface nsIEditorIMESupport : nsISupports
|
||||
{
|
||||
|
@ -53,7 +63,7 @@ interface nsIEditorIMESupport : nsISupports
|
|||
* Get preferred IME status of current widget.
|
||||
*/
|
||||
|
||||
[noscript] void getPreferredIMEState(out unsigned long aState);
|
||||
[noscript] IMEState getPreferredIMEState();
|
||||
|
||||
/**
|
||||
* whether this editor has active IME transaction
|
||||
|
|
|
@ -133,6 +133,7 @@ static bool gNoisy = false;
|
|||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
// Defined in nsEditorRegistration.cpp
|
||||
extern nsIParserService *sParserService;
|
||||
|
@ -492,9 +493,7 @@ nsEditor::SetFlags(PRUint32 aFlags)
|
|||
// if we're focused and the flag change causes IME state change.
|
||||
nsCOMPtr<nsIContent> focusedContent = GetFocusedContent();
|
||||
if (focusedContent) {
|
||||
// Use "enable" for the default value because if IME is disabled
|
||||
// unexpectedly, it makes serious a11y problem.
|
||||
PRUint32 newState = nsIContent::IME_STATUS_ENABLE;
|
||||
IMEState newState;
|
||||
nsresult rv = GetPreferredIMEState(&newState);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// NOTE: When the enabled state isn't going to be modified, this method
|
||||
|
@ -2050,13 +2049,14 @@ nsEditor::ForceCompositionEnd()
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEditor::GetPreferredIMEState(PRUint32 *aState)
|
||||
nsEditor::GetPreferredIMEState(IMEState *aState)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aState);
|
||||
*aState = nsIContent::IME_STATUS_ENABLE;
|
||||
aState->mEnabled = IMEState::ENABLED;
|
||||
aState->mOpen = IMEState::DONT_CHANGE_OPEN_STATE;
|
||||
|
||||
if (IsReadonly() || IsDisabled()) {
|
||||
*aState = nsIContent::IME_STATUS_DISABLE;
|
||||
aState->mEnabled = IMEState::DISABLED;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2069,17 +2069,17 @@ nsEditor::GetPreferredIMEState(PRUint32 *aState)
|
|||
switch (frame->GetStyleUIReset()->mIMEMode) {
|
||||
case NS_STYLE_IME_MODE_AUTO:
|
||||
if (IsPasswordEditor())
|
||||
*aState = nsIContent::IME_STATUS_PASSWORD;
|
||||
aState->mEnabled = IMEState::PASSWORD;
|
||||
break;
|
||||
case NS_STYLE_IME_MODE_DISABLED:
|
||||
// we should use password state for |ime-mode: disabled;|.
|
||||
*aState = nsIContent::IME_STATUS_PASSWORD;
|
||||
aState->mEnabled = IMEState::PASSWORD;
|
||||
break;
|
||||
case NS_STYLE_IME_MODE_ACTIVE:
|
||||
*aState |= nsIContent::IME_STATUS_OPEN;
|
||||
aState->mOpen = IMEState::OPEN;
|
||||
break;
|
||||
case NS_STYLE_IME_MODE_INACTIVE:
|
||||
*aState |= nsIContent::IME_STATUS_CLOSE;
|
||||
aState->mOpen = IMEState::CLOSED;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -90,6 +90,12 @@ class nsCSSStyleSheet;
|
|||
class nsKeyEvent;
|
||||
class nsIDOMNSEvent;
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
struct IMEState;
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
||||
#define kMOZEditorBogusNodeAttrAtom nsEditProperty::mozEditorBogusNode
|
||||
#define kMOZEditorBogusNodeValue NS_LITERAL_STRING("TRUE")
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "nsIEditorMailSupport.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "nsEventListenerManager.h"
|
||||
#include "nsIMEStateManager.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
// Drag & Drop, Clipboard
|
||||
|
@ -203,13 +204,16 @@ nsEditorEventListener::InstallToEditor()
|
|||
NS_EVENT_FLAG_CAPTURE);
|
||||
elmP->AddEventListenerByType(this,
|
||||
NS_LITERAL_STRING("text"),
|
||||
NS_EVENT_FLAG_BUBBLE);
|
||||
NS_EVENT_FLAG_BUBBLE |
|
||||
NS_EVENT_FLAG_SYSTEM_EVENT);
|
||||
elmP->AddEventListenerByType(this,
|
||||
NS_LITERAL_STRING("compositionstart"),
|
||||
NS_EVENT_FLAG_BUBBLE);
|
||||
NS_EVENT_FLAG_BUBBLE |
|
||||
NS_EVENT_FLAG_SYSTEM_EVENT);
|
||||
elmP->AddEventListenerByType(this,
|
||||
NS_LITERAL_STRING("compositionend"),
|
||||
NS_EVENT_FLAG_BUBBLE);
|
||||
NS_EVENT_FLAG_BUBBLE |
|
||||
NS_EVENT_FLAG_SYSTEM_EVENT);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -289,13 +293,16 @@ nsEditorEventListener::UninstallFromEditor()
|
|||
NS_EVENT_FLAG_CAPTURE);
|
||||
elmP->RemoveEventListenerByType(this,
|
||||
NS_LITERAL_STRING("text"),
|
||||
NS_EVENT_FLAG_BUBBLE);
|
||||
NS_EVENT_FLAG_BUBBLE |
|
||||
NS_EVENT_FLAG_SYSTEM_EVENT);
|
||||
elmP->RemoveEventListenerByType(this,
|
||||
NS_LITERAL_STRING("compositionstart"),
|
||||
NS_EVENT_FLAG_BUBBLE);
|
||||
NS_EVENT_FLAG_BUBBLE |
|
||||
NS_EVENT_FLAG_SYSTEM_EVENT);
|
||||
elmP->RemoveEventListenerByType(this,
|
||||
NS_LITERAL_STRING("compositionend"),
|
||||
NS_EVENT_FLAG_BUBBLE);
|
||||
NS_EVENT_FLAG_BUBBLE |
|
||||
NS_EVENT_FLAG_SYSTEM_EVENT);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIPresShell>
|
||||
|
@ -527,6 +534,21 @@ nsEditorEventListener::MouseClick(nsIDOMEvent* aMouseEvent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Notifies clicking on editor to IMEStateManager even when the event was
|
||||
// consumed.
|
||||
nsCOMPtr<nsIContent> focusedContent = mEditor->GetFocusedContent();
|
||||
if (focusedContent) {
|
||||
nsIDocument* currentDoc = focusedContent->GetCurrentDoc();
|
||||
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
|
||||
nsPresContext* presContext =
|
||||
presShell ? presShell->GetPresContext() : nsnull;
|
||||
if (presContext && currentDoc) {
|
||||
nsIMEStateManager::OnClickInEditor(presContext,
|
||||
currentDoc->HasFlag(NODE_IS_EDITABLE) ? nsnull : focusedContent,
|
||||
mouseEvent);
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNSEvent> nsevent = do_QueryInterface(aMouseEvent);
|
||||
NS_ASSERTION(nsevent, "nsevent must not be NULL here");
|
||||
bool preventDefault;
|
||||
|
|
|
@ -96,12 +96,14 @@
|
|||
#include "nsEditorUtils.h"
|
||||
#include "nsWSRunObject.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIWidget.h"
|
||||
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIParserService.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
// Some utilities to handle annoying overloading of "A" tag for link and named anchor
|
||||
static char hrefText[] = "href";
|
||||
|
@ -6042,14 +6044,14 @@ nsHTMLEditor::IsAcceptableInputEvent(nsIDOMEvent* aEvent)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetPreferredIMEState(PRUint32 *aState)
|
||||
nsHTMLEditor::GetPreferredIMEState(IMEState *aState)
|
||||
{
|
||||
if (IsReadonly() || IsDisabled()) {
|
||||
*aState = nsIContent::IME_STATUS_DISABLE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// HTML editor don't prefer the CSS ime-mode because IE didn't do so too.
|
||||
*aState = nsIContent::IME_STATUS_ENABLE;
|
||||
aState->mOpen = IMEState::DONT_CHANGE_OPEN_STATE;
|
||||
if (IsReadonly() || IsDisabled()) {
|
||||
aState->mEnabled = IMEState::DISABLED;
|
||||
} else {
|
||||
aState->mEnabled = IMEState::ENABLED;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -84,6 +84,12 @@ class nsIRangeUtils;
|
|||
class nsILinkHandler;
|
||||
struct PropItem;
|
||||
|
||||
namespace mozilla {
|
||||
namespace widget {
|
||||
struct IMEState;
|
||||
} // namespace widget
|
||||
} // namespace mozilla
|
||||
|
||||
/**
|
||||
* The HTML editor implementation.<br>
|
||||
* Use to edit HTML document represented as a DOM tree.
|
||||
|
@ -161,7 +167,7 @@ public:
|
|||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
||||
|
||||
/* ------------ nsIEditorIMESupport overrides ------------ */
|
||||
NS_IMETHOD GetPreferredIMEState(PRUint32 *aState);
|
||||
NS_IMETHOD GetPreferredIMEState(mozilla::widget::IMEState *aState);
|
||||
|
||||
/* ------------ nsIHTMLEditor methods -------------- */
|
||||
|
||||
|
|
|
@ -90,6 +90,7 @@ _TEST_FILES = \
|
|||
test_bug674861.html \
|
||||
test_bug676401.html \
|
||||
test_bug677752.html \
|
||||
test_bug697842.html \
|
||||
test_CF_HTML_clipboard.html \
|
||||
test_contenteditable_focus.html \
|
||||
test_htmleditor_keyevent_handling.html \
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
<!DOCTYPE>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=697842
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 697842</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="display">
|
||||
<p id="editor" contenteditable style="min-height: 1.5em;"></p>
|
||||
</div>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<script class="testbody" type="application/javascript">
|
||||
|
||||
/** Test for Bug 697842 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(runTests);
|
||||
|
||||
function runTests()
|
||||
{
|
||||
var editor = document.getElementById("editor");
|
||||
editor.focus();
|
||||
|
||||
SimpleTest.executeSoon(function() {
|
||||
var composingString = "";
|
||||
|
||||
function handler(aEvent) {
|
||||
if (aEvent.type != "text") {
|
||||
is(aEvent.data, composingString, "mismatch composition string");
|
||||
}
|
||||
aEvent.stopPropagation();
|
||||
aEvent.preventDefault();
|
||||
}
|
||||
|
||||
editor.addEventListener("compositionstart", handler, true);
|
||||
editor.addEventListener("compositionend", handler, true);
|
||||
editor.addEventListener("compositionupdate", handler, true);
|
||||
editor.addEventListener("text", handler, true);
|
||||
|
||||
// start composition
|
||||
synthesizeComposition({ type: "compositionstart" });
|
||||
|
||||
// input first character
|
||||
composingString = "\u306B";
|
||||
synthesizeComposition({ type: "compositionupdate", data: composingString });
|
||||
synthesizeText(
|
||||
{ "composition":
|
||||
{ "string": composingString,
|
||||
"clauses":
|
||||
[
|
||||
{ "length": 1, "attr": COMPOSITION_ATTR_RAWINPUT }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 1, "length": 0 }
|
||||
});
|
||||
|
||||
// input second character
|
||||
composingString = "\u306B\u3085";
|
||||
synthesizeComposition({ type: "compositionupdate", data: composingString });
|
||||
synthesizeText(
|
||||
{ "composition":
|
||||
{ "string": composingString,
|
||||
"clauses":
|
||||
[
|
||||
{ "length": 2, "attr": COMPOSITION_ATTR_RAWINPUT }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 2, "length": 0 }
|
||||
});
|
||||
|
||||
// convert them
|
||||
synthesizeText(
|
||||
{ "composition":
|
||||
{ "string": composingString,
|
||||
"clauses":
|
||||
[
|
||||
{ "length": 2,
|
||||
"attr": COMPOSITION_ATTR_SELECTEDCONVERTEDTEXT }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 2, "length": 0 }
|
||||
});
|
||||
|
||||
// commit
|
||||
synthesizeText(
|
||||
{ "composition":
|
||||
{ "string": composingString,
|
||||
"clauses":
|
||||
[
|
||||
{ "length": 0, "attr": 0 }
|
||||
]
|
||||
},
|
||||
"caret": { "start": 2, "length": 0 }
|
||||
});
|
||||
|
||||
synthesizeComposition({ type: "compositionend", data: composingString });
|
||||
|
||||
is(editor.innerHTML, composingString,
|
||||
"editor has unexpected result");
|
||||
|
||||
editor.removeEventListener("compositionstart", handler, true);
|
||||
editor.removeEventListener("compositionend", handler, true);
|
||||
editor.removeEventListener("compositionupdate", handler, true);
|
||||
editor.removeEventListener("text", handler, true);
|
||||
|
||||
SimpleTest.finish();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -148,9 +148,9 @@ public class GeckoEvent {
|
|||
|
||||
if (s.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
|
||||
mType = ACCELERATION_EVENT;
|
||||
mX = s.values[0] / SensorManager.GRAVITY_EARTH;
|
||||
mY = s.values[1] / SensorManager.GRAVITY_EARTH;
|
||||
mZ = s.values[2] / SensorManager.GRAVITY_EARTH;
|
||||
mX = s.values[0];
|
||||
mY = s.values[1];
|
||||
mZ = s.values[2];
|
||||
}
|
||||
else {
|
||||
mType = ORIENTATION_EVENT;
|
||||
|
|
|
@ -45,8 +45,4 @@ include $(DEPTH)/config/autoconf.mk
|
|||
|
||||
DIRS = autoconfig
|
||||
|
||||
ifdef MOZ_ENABLE_GTK2
|
||||
DIRS += system-pref/src
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -42,10 +42,3 @@ add_makefiles "
|
|||
extensions/pref/autoconfig/public/Makefile
|
||||
extensions/pref/autoconfig/src/Makefile
|
||||
"
|
||||
|
||||
if [ "$MOZ_ENABLE_GTK2" ]; then
|
||||
add_makefiles "
|
||||
extensions/pref/system-pref/src/Makefile
|
||||
extensions/pref/system-pref/src/gconf/Makefile
|
||||
"
|
||||
fi
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
# ***** BEGIN LICENSE BLOCK *****
|
||||
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public License Version
|
||||
# 1.1 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
# http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
# for the specific language governing rights and limitations under the
|
||||
# License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Sun Microsystems, Inc.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2003
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Bolian Yin <bolian.yin@sun.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
# in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
# of those above. If you wish to allow use of your version of this file only
|
||||
# under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
# use your version of this file under the terms of the MPL, indicate your
|
||||
# decision by deleting the provisions above and replace them with the notice
|
||||
# and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
# the provisions above, a recipient may use your version of this file under
|
||||
# the terms of any one of the MPL, the GPL or the LGPL.
|
||||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
DEPTH = ../../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = system-pref
|
||||
LIBRARY_NAME = system-pref
|
||||
LIBXUL_LIBRARY = 1
|
||||
|
||||
|
||||
CPPSRCS = \
|
||||
nsSystemPrefService.cpp \
|
||||
nsSystemPrefFactory.cpp \
|
||||
$(NULL)
|
||||
|
||||
SHARED_LIBRARY_LIBS = ../libsystem-pref_s.a
|
||||
|
||||
EXPORT_LIBRARY = 1
|
||||
IS_COMPONENT = 1
|
||||
MODULE_NAME = nsSystemPrefModule
|
||||
|
||||
EXPORTS = \
|
||||
nsSystemPrefService.h \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
CFLAGS += $(MOZ_GTK2_CFLAGS)
|
||||
CXXFLAGS += $(MOZ_GTK2_CFLAGS)
|
||||
|
||||
LOCAL_INCLUDES = -I$(srcdir)/..
|
||||
|
||||
export::
|
||||
$(INSTALL) $(srcdir)/../nsSystemPrefFactory.cpp .
|
||||
|
||||
GARBAGE += nsSystemPrefFactory.cpp
|
|
@ -1,19 +0,0 @@
|
|||
/* This file is included as the content of an array
|
||||
*
|
||||
* the first column is the mozilla pref name, the second column is the
|
||||
* the related gconf pref name.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
{"network.proxy.http", "/system/http_proxy/host"},
|
||||
{"network.proxy.http_port", "/system/http_proxy/port"},
|
||||
{"network.proxy.ftp", "/system/proxy/ftp_host"},
|
||||
{"network.proxy.ftp_port", "/system/proxy/ftp_port"},
|
||||
{"network.proxy.ssl", "/system/proxy/secure_host"},
|
||||
{"network.proxy.ssl_port", "/system/proxy/secure_port"},
|
||||
{"network.proxy.socks", "/system/proxy/socks_host"},
|
||||
{"network.proxy.socks_port", "/system/proxy/socks_port"},
|
||||
{"network.proxy.no_proxies_on", "/system/http_proxy/ignore_hosts"},
|
||||
{"network.proxy.autoconfig_url", "/system/proxy/autoconfig_url"},
|
||||
{"network.proxy.type", "/system/proxy/mode"},
|
||||
{"config.use_system_prefs.accessibility", "/desktop/gnome/interface/accessibility"},
|
|
@ -1,915 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
|
||||
* Portions created by Sun Microsystems are Copyright (C) 2003 Sun
|
||||
* Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Original Author: Bolian Yin (bolian.yin@sun.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "plstr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
||||
#include "nsString.h"
|
||||
#include "nsSystemPrefLog.h"
|
||||
#include "nsSystemPrefService.h"
|
||||
|
||||
/*************************************************************************
|
||||
* The strange thing here is that we load the gconf library manually and
|
||||
* search the function pointers we need. If that process fails, no gconf
|
||||
* support is available in mozilla. The aim is to make mozilla independent
|
||||
* on gconf, in both compile time and run time.
|
||||
************************************************************************/
|
||||
|
||||
//gconf types
|
||||
extern "C" {
|
||||
|
||||
typedef enum {
|
||||
GCONF_VALUE_INVALID,
|
||||
GCONF_VALUE_STRING,
|
||||
GCONF_VALUE_INT,
|
||||
GCONF_VALUE_FLOAT,
|
||||
GCONF_VALUE_BOOL,
|
||||
GCONF_VALUE_SCHEMA,
|
||||
|
||||
GCONF_VALUE_LIST,
|
||||
GCONF_VALUE_PAIR
|
||||
|
||||
}GConfValueType;
|
||||
|
||||
typedef struct {
|
||||
GConfValueType type;
|
||||
}GConfValue;
|
||||
|
||||
typedef void * (*GConfClientGetDefaultType) (void);
|
||||
typedef bool (*GConfClientGetBoolType) (void *client, const gchar *key,
|
||||
GError **err);
|
||||
typedef gchar* (*GConfClientGetStringType) (void *client, const gchar *key,
|
||||
GError **err);
|
||||
typedef PRInt32 (*GConfClientGetIntType) (void *client, const gchar *key,
|
||||
GError **err);
|
||||
typedef GSList* (*GConfClientGetListType) (void *client, const gchar *key,
|
||||
GConfValueType list_type,
|
||||
GError **err);
|
||||
typedef void (*GConfClientNotifyFuncType) (void* client, guint cnxn_id,
|
||||
void *entry,
|
||||
gpointer user_data);
|
||||
typedef guint (*GConfClientNotifyAddType) (void* client,
|
||||
const gchar* namespace_section,
|
||||
GConfClientNotifyFuncType func,
|
||||
gpointer user_data,
|
||||
GFreeFunc destroy_notify,
|
||||
GError** err);
|
||||
typedef void (*GConfClientNotifyRemoveType) (void *client,
|
||||
guint cnxn);
|
||||
typedef void (*GConfClientAddDirType) (void *client,
|
||||
const gchar *dir,
|
||||
guint8 preload,
|
||||
GError **err);
|
||||
typedef void (*GConfClientRemoveDirType) (void *client,
|
||||
const gchar *dir,
|
||||
GError **err);
|
||||
|
||||
typedef const char* (*GConfEntryGetKeyType) (const void *entry);
|
||||
typedef GConfValue* (*GConfEntryGetValueType) (const void *entry);
|
||||
|
||||
typedef const char* (*GConfValueGetStringType) (const GConfValue *value);
|
||||
typedef PRInt32 (*GConfValueGetIntType) (const GConfValue *value);
|
||||
typedef bool (*GConfValueGetBoolType) (const GConfValue *value);
|
||||
|
||||
|
||||
static void gconf_key_listener (void* client, guint cnxn_id,
|
||||
void *entry, gpointer user_data);
|
||||
}
|
||||
|
||||
struct GConfCallbackData
|
||||
{
|
||||
GConfProxy *proxy;
|
||||
void * userData;
|
||||
PRUint32 atom;
|
||||
PRUint32 notifyId;
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// GConPrxoy is a thin wrapper for easy use of gconf funcs. It loads the
|
||||
// gconf library and initializes the func pointers for later use.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
class GConfProxy
|
||||
{
|
||||
public:
|
||||
GConfProxy(nsSystemPrefService* aSysPrefService);
|
||||
~GConfProxy();
|
||||
bool Init();
|
||||
|
||||
nsresult GetBoolPref(const char *aMozKey, bool *retval);
|
||||
nsresult GetCharPref(const char *aMozKey, char **retval);
|
||||
nsresult GetIntPref(const char *aMozKey, PRInt32 *retval);
|
||||
|
||||
nsresult NotifyAdd (PRUint32 aAtom, void *aUserData);
|
||||
nsresult NotifyRemove (PRUint32 aAtom, const void *aUserData);
|
||||
|
||||
nsresult GetAtomForMozKey(const char *aMozKey, PRUint32 *aAtom) {
|
||||
return GetAtom(aMozKey, 0, aAtom);
|
||||
}
|
||||
const char *GetMozKey(PRUint32 aAtom) {
|
||||
return GetKey(aAtom, 0);
|
||||
}
|
||||
|
||||
void OnNotify(void *aClient, void * aEntry, PRUint32 aNotifyId,
|
||||
GConfCallbackData *aData);
|
||||
|
||||
private:
|
||||
void *mGConfClient;
|
||||
PRLibrary *mGConfLib;
|
||||
bool mInitialized;
|
||||
nsSystemPrefService *mSysPrefService;
|
||||
|
||||
//listeners
|
||||
nsAutoVoidArray *mObservers;
|
||||
|
||||
void InitFuncPtrs();
|
||||
//gconf public func ptrs
|
||||
|
||||
//gconf client funcs
|
||||
GConfClientGetDefaultType GConfClientGetDefault;
|
||||
GConfClientGetBoolType GConfClientGetBool;
|
||||
GConfClientGetStringType GConfClientGetString;
|
||||
GConfClientGetIntType GConfClientGetInt;
|
||||
GConfClientGetListType GConfClientGetList;
|
||||
GConfClientNotifyAddType GConfClientNotifyAdd;
|
||||
GConfClientNotifyRemoveType GConfClientNotifyRemove;
|
||||
GConfClientAddDirType GConfClientAddDir;
|
||||
GConfClientRemoveDirType GConfClientRemoveDir;
|
||||
|
||||
//gconf entry funcs
|
||||
GConfEntryGetValueType GConfEntryGetValue;
|
||||
GConfEntryGetKeyType GConfEntryGetKey;
|
||||
|
||||
//gconf value funcs
|
||||
GConfValueGetBoolType GConfValueGetBool;
|
||||
GConfValueGetStringType GConfValueGetString;
|
||||
GConfValueGetIntType GConfValueGetInt;
|
||||
|
||||
//pref name translating stuff
|
||||
nsresult GetAtom(const char *aKey, PRUint8 aNameType, PRUint32 *aAtom);
|
||||
nsresult GetAtomForGConfKey(const char *aGConfKey, PRUint32 *aAtom) \
|
||||
{return GetAtom(aGConfKey, 1, aAtom);}
|
||||
const char *GetKey(PRUint32 aAtom, PRUint8 aNameType);
|
||||
const char *GetGConfKey(PRUint32 aAtom) \
|
||||
{return GetKey(aAtom, 1); }
|
||||
inline const char *MozKey2GConfKey(const char *aMozKey);
|
||||
|
||||
//const strings
|
||||
static const char sPrefGConfKey[];
|
||||
static const char sDefaultLibName1[];
|
||||
static const char sDefaultLibName2[];
|
||||
};
|
||||
|
||||
struct SysPrefCallbackData {
|
||||
nsISupports *observer;
|
||||
bool bIsWeakRef;
|
||||
PRUint32 prefAtom;
|
||||
};
|
||||
|
||||
bool
|
||||
sysPrefDeleteObserver(void *aElement, void *aData) {
|
||||
SysPrefCallbackData *pElement =
|
||||
static_cast<SysPrefCallbackData *>(aElement);
|
||||
NS_RELEASE(pElement->observer);
|
||||
nsMemory::Free(pElement);
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsSystemPrefService, nsIPrefBranch, nsIPrefBranch2)
|
||||
|
||||
/* public */
|
||||
nsSystemPrefService::nsSystemPrefService()
|
||||
:mInitialized(false),
|
||||
mGConf(nsnull),
|
||||
mObservers(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
nsSystemPrefService::~nsSystemPrefService()
|
||||
{
|
||||
mInitialized = false;
|
||||
|
||||
delete mGConf;
|
||||
if (mObservers) {
|
||||
(void)mObservers->EnumerateForwards(sysPrefDeleteObserver, nsnull);
|
||||
delete mObservers;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSystemPrefService::Init()
|
||||
{
|
||||
if (!gSysPrefLog) {
|
||||
gSysPrefLog = PR_NewLogModule("Syspref");
|
||||
if (!gSysPrefLog) return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
SYSPREF_LOG(("Init SystemPref Service\n"));
|
||||
if (mInitialized)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!mGConf) {
|
||||
mGConf = new GConfProxy(this);
|
||||
if (!mGConf->Init()) {
|
||||
delete mGConf;
|
||||
mGConf = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
mInitialized = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute string root; */
|
||||
NS_IMETHODIMP nsSystemPrefService::GetRoot(char * *aRoot)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* long getPrefType (in string aPrefName); */
|
||||
NS_IMETHODIMP nsSystemPrefService::GetPrefType(const char *aPrefName, PRInt32 *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* boolean getBoolPref (in string aPrefName); */
|
||||
NS_IMETHODIMP nsSystemPrefService::GetBoolPref(const char *aPrefName, bool *_retval)
|
||||
{
|
||||
return mInitialized ?
|
||||
mGConf->GetBoolPref(aPrefName, _retval) : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* void setBoolPref (in string aPrefName, in long aValue); */
|
||||
NS_IMETHODIMP nsSystemPrefService::SetBoolPref(const char *aPrefName, bool aValue)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* string getCharPref (in string aPrefName); */
|
||||
NS_IMETHODIMP nsSystemPrefService::GetCharPref(const char *aPrefName, char **_retval)
|
||||
{
|
||||
return mInitialized ?
|
||||
mGConf->GetCharPref(aPrefName, _retval) : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* void setCharPref (in string aPrefName, in string aValue); */
|
||||
NS_IMETHODIMP nsSystemPrefService::SetCharPref(const char *aPrefName, const char *aValue)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* long getIntPref (in string aPrefName); */
|
||||
NS_IMETHODIMP nsSystemPrefService::GetIntPref(const char *aPrefName, PRInt32 *_retval)
|
||||
{
|
||||
return mInitialized ?
|
||||
mGConf->GetIntPref(aPrefName, _retval) : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* void setIntPref (in string aPrefName, in long aValue); */
|
||||
NS_IMETHODIMP nsSystemPrefService::SetIntPref(const char *aPrefName, PRInt32 aValue)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void getComplexValue (in string aPrefName, in nsIIDRef aType, [iid_is (aType), retval] out nsQIResult aValue); */
|
||||
NS_IMETHODIMP nsSystemPrefService::GetComplexValue(const char *aPrefName, const nsIID & aType, void * *aValue)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void setComplexValue (in string aPrefName, in nsIIDRef aType, in nsISupports aValue); */
|
||||
NS_IMETHODIMP nsSystemPrefService::SetComplexValue(const char *aPrefName, const nsIID & aType, nsISupports *aValue)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void clearUserPref (in string aPrefName); */
|
||||
NS_IMETHODIMP nsSystemPrefService::ClearUserPref(const char *aPrefName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void lockPref (in string aPrefName); */
|
||||
NS_IMETHODIMP nsSystemPrefService::LockPref(const char *aPrefName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* boolean prefHasUserValue (in string aPrefName); */
|
||||
NS_IMETHODIMP nsSystemPrefService::PrefHasUserValue(const char *aPrefName, bool *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* boolean prefIsLocked (in string aPrefName); */
|
||||
NS_IMETHODIMP nsSystemPrefService::PrefIsLocked(const char *aPrefName, bool *_retval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void unlockPref (in string aPrefName); */
|
||||
NS_IMETHODIMP nsSystemPrefService::UnlockPref(const char *aPrefName)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void deleteBranch (in string aStartingAt); */
|
||||
NS_IMETHODIMP nsSystemPrefService::DeleteBranch(const char *aStartingAt)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void getChildList (in string aStartingAt, [optional] out unsigned long aCount, [array, size_is (aCount), retval] out string aChildArray); */
|
||||
NS_IMETHODIMP nsSystemPrefService::GetChildList(const char *aStartingAt, PRUint32 *aCount, char ***aChildArray)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void resetBranch (in string aStartingAt); */
|
||||
NS_IMETHODIMP nsSystemPrefService::ResetBranch(const char *aStartingAt)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/* void addObserver (in string aDomain, in nsIObserver aObserver, in boolean aHoldWeak); */
|
||||
NS_IMETHODIMP nsSystemPrefService::AddObserver(const char *aDomain, nsIObserver *aObserver, bool aHoldWeak)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aDomain);
|
||||
NS_ENSURE_ARG_POINTER(aObserver);
|
||||
|
||||
NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||||
|
||||
PRUint32 prefAtom;
|
||||
// make sure the pref name is supported
|
||||
rv = mGConf->GetAtomForMozKey(aDomain, &prefAtom);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!mObservers) {
|
||||
mObservers = new nsAutoVoidArray();
|
||||
if (mObservers == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
SysPrefCallbackData *pCallbackData = (SysPrefCallbackData *)
|
||||
nsMemory::Alloc(sizeof(SysPrefCallbackData));
|
||||
if (pCallbackData == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
pCallbackData->bIsWeakRef = aHoldWeak;
|
||||
pCallbackData->prefAtom = prefAtom;
|
||||
// hold a weak reference to the observer if so requested
|
||||
nsCOMPtr<nsISupports> observerRef;
|
||||
if (aHoldWeak) {
|
||||
nsCOMPtr<nsISupportsWeakReference> weakRefFactory =
|
||||
do_QueryInterface(aObserver);
|
||||
if (!weakRefFactory) {
|
||||
// the caller didn't give us a object that supports weak reference.
|
||||
// ... tell them
|
||||
nsMemory::Free(pCallbackData);
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
nsCOMPtr<nsIWeakReference> tmp = do_GetWeakReference(weakRefFactory);
|
||||
observerRef = tmp;
|
||||
} else {
|
||||
observerRef = aObserver;
|
||||
}
|
||||
|
||||
rv = mGConf->NotifyAdd(prefAtom, pCallbackData);
|
||||
if (NS_FAILED(rv)) {
|
||||
nsMemory::Free(pCallbackData);
|
||||
return rv;
|
||||
}
|
||||
|
||||
pCallbackData->observer = observerRef;
|
||||
NS_ADDREF(pCallbackData->observer);
|
||||
|
||||
mObservers->AppendElement(pCallbackData);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void removeObserver (in string aDomain, in nsIObserver aObserver); */
|
||||
NS_IMETHODIMP nsSystemPrefService::RemoveObserver(const char *aDomain, nsIObserver *aObserver)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
NS_ENSURE_ARG_POINTER(aDomain);
|
||||
NS_ENSURE_ARG_POINTER(aObserver);
|
||||
NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||||
|
||||
if (!mObservers)
|
||||
return NS_OK;
|
||||
|
||||
PRUint32 prefAtom;
|
||||
// make sure the pref name is supported
|
||||
rv = mGConf->GetAtomForMozKey(aDomain, &prefAtom);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// need to find the index of observer, so we can remove it
|
||||
PRIntn count = mObservers->Count();
|
||||
if (count <= 0)
|
||||
return NS_OK;
|
||||
|
||||
PRIntn i;
|
||||
SysPrefCallbackData *pCallbackData;
|
||||
for (i = 0; i < count; ++i) {
|
||||
pCallbackData = (SysPrefCallbackData *)mObservers->ElementAt(i);
|
||||
if (pCallbackData) {
|
||||
nsCOMPtr<nsISupports> observerRef;
|
||||
if (pCallbackData->bIsWeakRef) {
|
||||
nsCOMPtr<nsISupportsWeakReference> weakRefFactory =
|
||||
do_QueryInterface(aObserver);
|
||||
if (weakRefFactory) {
|
||||
nsCOMPtr<nsIWeakReference> tmp =
|
||||
do_GetWeakReference(aObserver);
|
||||
observerRef = tmp;
|
||||
}
|
||||
}
|
||||
if (!observerRef)
|
||||
observerRef = aObserver;
|
||||
|
||||
if (pCallbackData->observer == observerRef &&
|
||||
pCallbackData->prefAtom == prefAtom) {
|
||||
rv = mGConf->NotifyRemove(prefAtom, pCallbackData);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mObservers->RemoveElementAt(i);
|
||||
NS_RELEASE(pCallbackData->observer);
|
||||
nsMemory::Free(pCallbackData);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsSystemPrefService::OnPrefChange(PRUint32 aPrefAtom, void *aData)
|
||||
{
|
||||
if (!mInitialized)
|
||||
return;
|
||||
|
||||
SysPrefCallbackData *pData = (SysPrefCallbackData *)aData;
|
||||
if (pData->prefAtom != aPrefAtom)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIObserver> observer;
|
||||
if (pData->bIsWeakRef) {
|
||||
nsCOMPtr<nsIWeakReference> weakRef =
|
||||
do_QueryInterface(pData->observer);
|
||||
if(weakRef)
|
||||
observer = do_QueryReferent(weakRef);
|
||||
if (!observer) {
|
||||
// this weak referenced observer went away, remove it from the list
|
||||
nsresult rv = mGConf->NotifyRemove(aPrefAtom, pData);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mObservers->RemoveElement(pData);
|
||||
NS_RELEASE(pData->observer);
|
||||
nsMemory::Free(pData);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
observer = do_QueryInterface(pData->observer);
|
||||
|
||||
if (observer)
|
||||
observer->Observe(static_cast<nsIPrefBranch *>(this),
|
||||
NS_SYSTEMPREF_PREFCHANGE_TOPIC_ID,
|
||||
NS_ConvertUTF8toUTF16(mGConf->GetMozKey(aPrefAtom)).
|
||||
get());
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* GConfProxy
|
||||
*
|
||||
************************************************************/
|
||||
|
||||
struct GConfFuncListType {
|
||||
const char *FuncName;
|
||||
PRFuncPtr FuncPtr;
|
||||
};
|
||||
|
||||
struct PrefNamePair {
|
||||
const char *mozPrefName;
|
||||
const char *gconfPrefName;
|
||||
};
|
||||
|
||||
const char
|
||||
GConfProxy::sPrefGConfKey[] = "accessibility.unix.gconf2.shared-library";
|
||||
const char GConfProxy::sDefaultLibName1[] = "libgconf-2.so.4";
|
||||
const char GConfProxy::sDefaultLibName2[] = "libgconf-2.so";
|
||||
|
||||
#define GCONF_FUNCS_POINTER_BEGIN \
|
||||
static GConfFuncListType sGConfFuncList[] = {
|
||||
#define GCONF_FUNCS_POINTER_ADD(func_name) \
|
||||
{func_name, nsnull},
|
||||
#define GCONF_FUNCS_POINTER_END \
|
||||
{nsnull, nsnull}, };
|
||||
|
||||
GCONF_FUNCS_POINTER_BEGIN
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_client_get_default") // 0
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_client_get_bool") // 1
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_client_get_string") //2
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_client_get_int") //3
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_client_notify_add") //4
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_client_notify_remove") //5
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_client_add_dir") //6
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_client_remove_dir") //7
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_entry_get_value") //8
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_entry_get_key") //9
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_value_get_bool") //10
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_value_get_string") //11
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_value_get_int") //12
|
||||
GCONF_FUNCS_POINTER_ADD("gconf_client_get_list") //13
|
||||
GCONF_FUNCS_POINTER_END
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// the list is the mapping table, between mozilla prefs and gconf prefs
|
||||
// It is expected to include all the pref pairs that are related in mozilla
|
||||
// and gconf.
|
||||
//
|
||||
// Note: the prefs listed here are not neccessarily be read from gconf, they
|
||||
// are the prefs that could be read from gconf. Mozilla has another
|
||||
// list (see sSysPrefList in nsSystemPref.cpp) that decide which prefs
|
||||
// are really read.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const PrefNamePair sPrefNameMapping[] = {
|
||||
#include "gconf_pref_list.inc"
|
||||
{nsnull, nsnull},
|
||||
};
|
||||
|
||||
bool
|
||||
gconfDeleteObserver(void *aElement, void *aData) {
|
||||
nsMemory::Free(aElement);
|
||||
return true;
|
||||
}
|
||||
|
||||
GConfProxy::GConfProxy(nsSystemPrefService *aSysPrefService):
|
||||
mGConfClient(nsnull),
|
||||
mGConfLib(nsnull),
|
||||
mInitialized(false),
|
||||
mSysPrefService(aSysPrefService),
|
||||
mObservers(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
GConfProxy::~GConfProxy()
|
||||
{
|
||||
if (mGConfClient)
|
||||
g_object_unref(G_OBJECT(mGConfClient));
|
||||
|
||||
if (mObservers) {
|
||||
(void)mObservers->EnumerateForwards(gconfDeleteObserver, nsnull);
|
||||
delete mObservers;
|
||||
}
|
||||
|
||||
// bug 379666: can't unload GConf-2 since it registers atexit handlers
|
||||
//PR_UnloadLibrary(mGConfLib);
|
||||
}
|
||||
|
||||
bool
|
||||
GConfProxy::Init()
|
||||
{
|
||||
SYSPREF_LOG(("GConfProxy:: Init GConfProxy\n"));
|
||||
if (!mSysPrefService)
|
||||
return false;
|
||||
if (mInitialized)
|
||||
return true;
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> pref = do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
|
||||
if (!pref)
|
||||
return false;
|
||||
|
||||
nsXPIDLCString gconfLibName;
|
||||
nsresult rv;
|
||||
|
||||
//check if gconf-2 library is given in prefs
|
||||
rv = pref->GetCharPref(sPrefGConfKey, getter_Copies(gconfLibName));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
//use the library name in the preference
|
||||
SYSPREF_LOG(("GConf library in prefs is %s\n", gconfLibName.get()));
|
||||
mGConfLib = PR_LoadLibrary(gconfLibName.get());
|
||||
}
|
||||
else {
|
||||
SYSPREF_LOG(("GConf library not specified in prefs, try the default: "
|
||||
"%s and %s\n", sDefaultLibName1, sDefaultLibName2));
|
||||
mGConfLib = PR_LoadLibrary(sDefaultLibName1);
|
||||
if (!mGConfLib)
|
||||
mGConfLib = PR_LoadLibrary(sDefaultLibName2);
|
||||
}
|
||||
|
||||
if (!mGConfLib) {
|
||||
SYSPREF_LOG(("Fail to load GConf library\n"));
|
||||
return false;
|
||||
}
|
||||
|
||||
//check every func we need in the gconf library
|
||||
GConfFuncListType *funcList;
|
||||
PRFuncPtr func;
|
||||
for (funcList = sGConfFuncList; funcList->FuncName; ++funcList) {
|
||||
func = PR_FindFunctionSymbol(mGConfLib, funcList->FuncName);
|
||||
if (!func) {
|
||||
SYSPREF_LOG(("Check GConf Func Error: %s", funcList->FuncName));
|
||||
goto init_failed_unload;
|
||||
}
|
||||
funcList->FuncPtr = func;
|
||||
}
|
||||
|
||||
InitFuncPtrs();
|
||||
|
||||
mGConfClient = GConfClientGetDefault();
|
||||
|
||||
// Don't unload past this point, since GConf's initialization of ORBit
|
||||
// causes atexit handlers to be registered.
|
||||
|
||||
if (!mGConfClient) {
|
||||
SYSPREF_LOG(("Fail to Get default gconf client\n"));
|
||||
goto init_failed;
|
||||
}
|
||||
mInitialized = true;
|
||||
return true;
|
||||
|
||||
init_failed_unload:
|
||||
PR_UnloadLibrary(mGConfLib);
|
||||
init_failed:
|
||||
mGConfLib = nsnull;
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GConfProxy::GetBoolPref(const char *aMozKey, bool *retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||||
*retval = GConfClientGetBool(mGConfClient, MozKey2GConfKey(aMozKey), NULL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GConfProxy::GetCharPref(const char *aMozKey, char **retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||||
|
||||
const gchar *gconfkey = MozKey2GConfKey(aMozKey);
|
||||
|
||||
if (!strcmp (aMozKey, "network.proxy.no_proxies_on")) {
|
||||
GSList *s;
|
||||
nsCString noproxy;
|
||||
GSList *gslist = GConfClientGetList(mGConfClient, gconfkey,
|
||||
GCONF_VALUE_STRING, NULL);
|
||||
|
||||
for (s = gslist; s; s = g_slist_next(s)) {
|
||||
noproxy += (char *)s->data;
|
||||
noproxy += ", ";
|
||||
g_free ((char *)s->data);
|
||||
}
|
||||
g_slist_free (gslist);
|
||||
|
||||
*retval = PL_strdup(noproxy.get());
|
||||
} else {
|
||||
gchar *str = GConfClientGetString(mGConfClient, gconfkey, NULL);
|
||||
if (str) {
|
||||
*retval = PL_strdup(str);
|
||||
g_free (str);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GConfProxy::GetIntPref(const char *aMozKey, PRInt32 *retval)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||||
if (strcmp (aMozKey, "network.proxy.type") == 0) {
|
||||
gchar *str;
|
||||
|
||||
str = GConfClientGetString(mGConfClient,
|
||||
MozKey2GConfKey (aMozKey), NULL);
|
||||
|
||||
if (str) {
|
||||
if (strcmp (str, "manual") == 0)
|
||||
*retval = 1;
|
||||
else if (strcmp (str, "auto") == 0)
|
||||
*retval = 2;
|
||||
else
|
||||
*retval = 0;
|
||||
|
||||
g_free (str);
|
||||
} else
|
||||
*retval = 0;
|
||||
} else {
|
||||
*retval = GConfClientGetInt(mGConfClient,
|
||||
MozKey2GConfKey(aMozKey), NULL);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GConfProxy::NotifyAdd (PRUint32 aAtom, void *aUserData)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||||
|
||||
const char *gconfKey = GetGConfKey(aAtom);
|
||||
if (!gconfKey)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!mObservers) {
|
||||
mObservers = new nsAutoVoidArray();
|
||||
if (mObservers == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
GConfCallbackData *pData = (GConfCallbackData *)
|
||||
nsMemory::Alloc(sizeof(GConfCallbackData));
|
||||
NS_ENSURE_TRUE(pData, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
pData->proxy = this;
|
||||
pData->userData = aUserData;
|
||||
pData->atom = aAtom;
|
||||
mObservers->AppendElement(pData);
|
||||
|
||||
GConfClientAddDir(mGConfClient, gconfKey,
|
||||
0, // GCONF_CLIENT_PRELOAD_NONE, don't preload anything
|
||||
NULL);
|
||||
|
||||
pData->notifyId = GConfClientNotifyAdd(mGConfClient, gconfKey,
|
||||
gconf_key_listener, pData,
|
||||
NULL, NULL);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GConfProxy::NotifyRemove (PRUint32 aAtom, const void *aUserData)
|
||||
{
|
||||
NS_ENSURE_TRUE(mInitialized, NS_ERROR_FAILURE);
|
||||
|
||||
PRIntn count = mObservers->Count();
|
||||
if (count <= 0)
|
||||
return NS_OK;
|
||||
|
||||
PRIntn i;
|
||||
GConfCallbackData *pData;
|
||||
for (i = 0; i < count; ++i) {
|
||||
pData = (GConfCallbackData *)mObservers->ElementAt(i);
|
||||
if (pData && pData->atom == aAtom && pData->userData == aUserData) {
|
||||
GConfClientNotifyRemove(mGConfClient, pData->notifyId);
|
||||
GConfClientRemoveDir(mGConfClient,
|
||||
GetGConfKey(pData->atom), NULL);
|
||||
mObservers->RemoveElementAt(i);
|
||||
nsMemory::Free(pData);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GConfProxy::InitFuncPtrs()
|
||||
{
|
||||
//gconf client funcs
|
||||
GConfClientGetDefault =
|
||||
(GConfClientGetDefaultType) sGConfFuncList[0].FuncPtr;
|
||||
GConfClientGetBool =
|
||||
(GConfClientGetBoolType) sGConfFuncList[1].FuncPtr;
|
||||
GConfClientGetString =
|
||||
(GConfClientGetStringType) sGConfFuncList[2].FuncPtr;
|
||||
GConfClientGetInt =
|
||||
(GConfClientGetIntType) sGConfFuncList[3].FuncPtr;
|
||||
GConfClientNotifyAdd =
|
||||
(GConfClientNotifyAddType) sGConfFuncList[4].FuncPtr;
|
||||
GConfClientNotifyRemove =
|
||||
(GConfClientNotifyRemoveType) sGConfFuncList[5].FuncPtr;
|
||||
GConfClientAddDir =
|
||||
(GConfClientAddDirType) sGConfFuncList[6].FuncPtr;
|
||||
GConfClientRemoveDir =
|
||||
(GConfClientRemoveDirType) sGConfFuncList[7].FuncPtr;
|
||||
|
||||
//gconf entry funcs
|
||||
GConfEntryGetValue = (GConfEntryGetValueType) sGConfFuncList[8].FuncPtr;
|
||||
GConfEntryGetKey = (GConfEntryGetKeyType) sGConfFuncList[9].FuncPtr;
|
||||
|
||||
//gconf value funcs
|
||||
GConfValueGetBool = (GConfValueGetBoolType) sGConfFuncList[10].FuncPtr;
|
||||
GConfValueGetString = (GConfValueGetStringType) sGConfFuncList[11].FuncPtr;
|
||||
GConfValueGetInt = (GConfValueGetIntType) sGConfFuncList[12].FuncPtr;
|
||||
|
||||
//gconf client list func
|
||||
GConfClientGetList =
|
||||
(GConfClientGetListType) sGConfFuncList[13].FuncPtr;
|
||||
}
|
||||
|
||||
void
|
||||
GConfProxy::OnNotify(void *aClient, void * aEntry, PRUint32 aNotifyId,
|
||||
GConfCallbackData *aData)
|
||||
{
|
||||
if (!mInitialized || !aEntry || (mGConfClient != aClient) || !aData)
|
||||
return;
|
||||
|
||||
if (GConfEntryGetValue(aEntry) == NULL)
|
||||
return;
|
||||
|
||||
PRUint32 prefAtom;
|
||||
nsresult rv = GetAtomForGConfKey(GConfEntryGetKey(aEntry), &prefAtom);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
mSysPrefService->OnPrefChange(prefAtom, aData->userData);
|
||||
}
|
||||
|
||||
nsresult
|
||||
GConfProxy::GetAtom(const char *aKey, PRUint8 aNameType, PRUint32 *aAtom)
|
||||
{
|
||||
if (!aKey)
|
||||
return NS_ERROR_FAILURE;
|
||||
PRUint32 prefSize = sizeof(sPrefNameMapping) / sizeof(sPrefNameMapping[0]);
|
||||
for (PRUint32 index = 0; index < prefSize; ++index) {
|
||||
if (!strcmp((aNameType == 0) ? sPrefNameMapping[index].mozPrefName :
|
||||
sPrefNameMapping[index].gconfPrefName, aKey)) {
|
||||
*aAtom = index;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const char *
|
||||
GConfProxy::GetKey(PRUint32 aAtom, PRUint8 aNameType)
|
||||
{
|
||||
PRUint32 mapSize = sizeof(sPrefNameMapping) / sizeof(sPrefNameMapping[0]);
|
||||
if (aAtom >= 0 && aAtom < mapSize)
|
||||
return (aNameType == 0) ? sPrefNameMapping[aAtom].mozPrefName :
|
||||
sPrefNameMapping[aAtom].gconfPrefName;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline const char *
|
||||
GConfProxy::MozKey2GConfKey(const char *aMozKey)
|
||||
{
|
||||
PRUint32 atom;
|
||||
nsresult rv = GetAtomForMozKey(aMozKey, &atom);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return GetGConfKey(atom);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void gconf_key_listener (void* client, guint cnxn_id,
|
||||
void *entry, gpointer user_data)
|
||||
{
|
||||
SYSPREF_LOG(("...SYSPREF_LOG...key listener get called \n"));
|
||||
if (!user_data)
|
||||
return;
|
||||
GConfCallbackData *pData = reinterpret_cast<GConfCallbackData *>
|
||||
(user_data);
|
||||
pData->proxy->OnNotify(client, entry, cnxn_id, pData);
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
|
||||
* Portions created by Sun Microsystems are Copyright (C) 2003 Sun
|
||||
* Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Original Author: Bolian Yin (bolian.yin@sun.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __SYSTEM_PREF_SERVICE_H__
|
||||
#define __SYSTEM_PREF_SERVICE_H__
|
||||
|
||||
#include "prlink.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
|
||||
class GConfProxy;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// nsSystemPrefService provide a interface for read system prefs. It is
|
||||
// platform related. This directory (system-pref/gconf) impls it for gconf
|
||||
// on the gconf platform.
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsSystemPrefService : public nsIPrefBranch2
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPREFBRANCH
|
||||
NS_DECL_NSIPREFBRANCH2
|
||||
|
||||
nsSystemPrefService();
|
||||
virtual ~nsSystemPrefService();
|
||||
nsresult Init();
|
||||
|
||||
void OnPrefChange(PRUint32 aPrefAtom, void *aData);
|
||||
|
||||
private:
|
||||
bool mInitialized;
|
||||
GConfProxy *mGConf;
|
||||
|
||||
//listeners
|
||||
nsAutoVoidArray *mObservers;
|
||||
};
|
||||
|
||||
#define NS_SYSTEMPREF_SERVICE_CID \
|
||||
{ /* {94f1de09-d0e5-4ca8-94c2-98b049316b7f} */ \
|
||||
0x94f1de09, \
|
||||
0xd0e5, \
|
||||
0x4ca8, \
|
||||
{ 0x94, 0xc2, 0x98, 0xb0, 0x49, 0x31, 0x6b, 0x7f } \
|
||||
}
|
||||
|
||||
#define NS_SYSTEMPREF_SERVICE_CONTRACTID "@mozilla.org/system-preference-service;1"
|
||||
#define NS_SYSTEMPREF_SERVICE_CLASSNAME "System Preferences Service"
|
||||
|
||||
#define NS_SYSTEMPREF_PREFCHANGE_TOPIC_ID "nsSystemPrefService:pref-changed"
|
||||
|
||||
#endif /* __SYSTEM_PREF_SERVICE_H__ */
|
|
@ -1,474 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
|
||||
* Portions created by Sun Microsystems are Copyright (C) 2003 Sun
|
||||
* Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Original Author: Bolian Yin (bolian.yin@sun.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsSystemPref.h"
|
||||
#include "nsIObserverService.h"
|
||||
|
||||
#include "nsSystemPrefLog.h"
|
||||
#include "nsSystemPrefService.h"
|
||||
#include "nsString.h"
|
||||
|
||||
const char sSysPrefString[] = "config.use_system_prefs";
|
||||
union MozPrefValue {
|
||||
char * stringVal;
|
||||
PRInt32 intVal;
|
||||
bool boolVal;
|
||||
};
|
||||
|
||||
struct SysPrefItem {
|
||||
const char *prefName; // mozilla pref string name
|
||||
MozPrefValue defaultValue; // store the mozilla default value
|
||||
bool isLocked; // store the mozilla lock status
|
||||
SysPrefItem() {
|
||||
prefName = nsnull;
|
||||
defaultValue.intVal = 0;
|
||||
defaultValue.stringVal = nsnull;
|
||||
defaultValue.boolVal = false;
|
||||
isLocked = false;
|
||||
}
|
||||
void SetPrefName(const char *aPrefName) {
|
||||
prefName = aPrefName;
|
||||
}
|
||||
};
|
||||
|
||||
// all prefs that mozilla need to read from host system if they are available
|
||||
static const char *sSysPrefList[] = {
|
||||
"network.proxy.http",
|
||||
"network.proxy.http_port",
|
||||
"network.proxy.ftp",
|
||||
"network.proxy.ftp_port",
|
||||
"network.proxy.ssl",
|
||||
"network.proxy.ssl_port",
|
||||
"network.proxy.socks",
|
||||
"network.proxy.socks_port",
|
||||
"network.proxy.no_proxies_on",
|
||||
"network.proxy.autoconfig_url",
|
||||
"network.proxy.type",
|
||||
"config.use_system_prefs.accessibility",
|
||||
};
|
||||
|
||||
PRLogModuleInfo *gSysPrefLog = NULL;
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsSystemPref, nsIObserver, nsISupportsWeakReference)
|
||||
|
||||
nsSystemPref::nsSystemPref():
|
||||
mSysPrefService(nsnull),
|
||||
mEnabled(false),
|
||||
mSysPrefs(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
nsSystemPref::~nsSystemPref()
|
||||
{
|
||||
mSysPrefService = nsnull;
|
||||
mEnabled = false;
|
||||
delete [] mSysPrefs;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsSystemPref::Init
|
||||
// Setup log and listen on NS_PREFSERVICE_READ_TOPIC_ID from pref service
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
nsSystemPref::Init(void)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!gSysPrefLog) {
|
||||
gSysPrefLog = PR_NewLogModule("Syspref");
|
||||
if (!gSysPrefLog)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService("@mozilla.org/observer-service;1", &rv);
|
||||
|
||||
if (observerService) {
|
||||
rv = observerService->AddObserver(this, NS_PREFSERVICE_READ_TOPIC_ID,
|
||||
false);
|
||||
rv = observerService->AddObserver(this, "profile-before-change",
|
||||
false);
|
||||
SYSPREF_LOG(("Add Observer for %s\n", NS_PREFSERVICE_READ_TOPIC_ID));
|
||||
}
|
||||
return(rv);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsSystemPref::Observe
|
||||
// Observe notifications from mozilla pref system and system prefs (if enabled)
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
NS_IMETHODIMP
|
||||
nsSystemPref::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!aTopic)
|
||||
return NS_OK;
|
||||
|
||||
// if we are notified by pref service
|
||||
// check the system pref settings
|
||||
if (!nsCRT::strcmp(aTopic, NS_PREFSERVICE_READ_TOPIC_ID)) {
|
||||
SYSPREF_LOG(("Observed: %s\n", aTopic));
|
||||
|
||||
nsCOMPtr<nsIPrefBranch2> prefBranch =
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = prefBranch->GetBoolPref(sSysPrefString, &mEnabled);
|
||||
if (NS_FAILED(rv)) {
|
||||
SYSPREF_LOG(("...FAil to Get %s\n", sSysPrefString));
|
||||
return rv;
|
||||
}
|
||||
|
||||
// if there is no system pref service, assume nothing happen to us
|
||||
mSysPrefService = do_GetService(NS_SYSTEMPREF_SERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv) || !mSysPrefService) {
|
||||
SYSPREF_LOG(("...No System Pref Service\n"));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// listen on its changes
|
||||
rv = prefBranch->AddObserver(sSysPrefString, this, true);
|
||||
if (NS_FAILED(rv)) {
|
||||
SYSPREF_LOG(("...FAil to add observer for %s\n", sSysPrefString));
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!mEnabled) {
|
||||
SYSPREF_LOG(("%s is disabled\n", sSysPrefString));
|
||||
return NS_OK;
|
||||
}
|
||||
SYSPREF_LOG(("%s is enabled\n", sSysPrefString));
|
||||
rv = UseSystemPrefs();
|
||||
|
||||
}
|
||||
// sSysPrefString value was changed, update ...
|
||||
else if (!nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) &&
|
||||
NS_ConvertUTF8toUTF16(sSysPrefString).Equals(aData)) {
|
||||
SYSPREF_LOG(("++++++ Notify: topic=%s data=%s\n",
|
||||
aTopic, NS_ConvertUTF16toUTF8(aData).get()));
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch =
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
bool enabled = mEnabled;
|
||||
rv = prefBranch->GetBoolPref(sSysPrefString, &mEnabled);
|
||||
if (enabled != mEnabled) {
|
||||
if (mEnabled)
|
||||
//read prefs from system
|
||||
rv = UseSystemPrefs();
|
||||
else
|
||||
//roll back to mozilla prefs
|
||||
rv = UseMozillaPrefs();
|
||||
}
|
||||
}
|
||||
|
||||
// if the system pref notify us that some pref has been changed by user
|
||||
// outside mozilla. We need to read it again.
|
||||
else if (!nsCRT::strcmp(aTopic, NS_SYSTEMPREF_PREFCHANGE_TOPIC_ID) &&
|
||||
aData) {
|
||||
NS_ASSERTION(mEnabled, "Should not listen when disabled");
|
||||
SYSPREF_LOG(("====== System Pref Notify topic=%s data=%s\n",
|
||||
aTopic, (char*)aData));
|
||||
rv = ReadSystemPref(NS_LossyConvertUTF16toASCII(aData).get());
|
||||
return NS_OK;
|
||||
} else if (!nsCRT::strcmp(aTopic,"profile-before-change")) {
|
||||
//roll back to mozilla prefs
|
||||
if (mEnabled)
|
||||
UseMozillaPrefs();
|
||||
mEnabled = false;
|
||||
mSysPrefService = nsnull;
|
||||
delete [] mSysPrefs;
|
||||
mSysPrefs = nsnull;
|
||||
} else
|
||||
SYSPREF_LOG(("Not needed topic Received %s\n", aTopic));
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* private */
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// nsSystemPref::UseSystemPrefs
|
||||
// Read all the prefs in the table from system, listen for their
|
||||
// changes in system pref service.
|
||||
////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
nsSystemPref::UseSystemPrefs()
|
||||
{
|
||||
SYSPREF_LOG(("\n====Now Use system prefs==\n"));
|
||||
nsresult rv = NS_OK;
|
||||
if (!mSysPrefService) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
PRIntn sysPrefCount= sizeof(sSysPrefList) / sizeof(sSysPrefList[0]);
|
||||
|
||||
if (!mSysPrefs) {
|
||||
mSysPrefs = new SysPrefItem[sysPrefCount];
|
||||
if (!mSysPrefs)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
for (PRIntn index = 0; index < sysPrefCount; ++index)
|
||||
mSysPrefs[index].SetPrefName(sSysPrefList[index]);
|
||||
}
|
||||
|
||||
for (PRIntn index = 0; index < sysPrefCount; ++index) {
|
||||
// save mozilla prefs
|
||||
SaveMozDefaultPref(mSysPrefs[index].prefName,
|
||||
&mSysPrefs[index].defaultValue,
|
||||
&mSysPrefs[index].isLocked);
|
||||
|
||||
// get the system prefs
|
||||
ReadSystemPref(mSysPrefs[index].prefName);
|
||||
SYSPREF_LOG(("Add Listener on %s\n", mSysPrefs[index].prefName));
|
||||
mSysPrefService->AddObserver(mSysPrefs[index].prefName,
|
||||
this, true);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// nsSystemPref::ReadSystemPref
|
||||
// Read a pref value from system pref service, and lock it in mozilla.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
nsSystemPref::ReadSystemPref(const char *aPrefName)
|
||||
{
|
||||
if (!mSysPrefService)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch
|
||||
(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
SYSPREF_LOG(("about to read aPrefName %s\n", aPrefName));
|
||||
|
||||
prefBranch->UnlockPref(aPrefName);
|
||||
|
||||
PRInt32 prefType = nsIPrefBranch::PREF_INVALID;
|
||||
nsXPIDLCString strValue;
|
||||
PRInt32 intValue = 0;
|
||||
bool boolValue = false;
|
||||
|
||||
rv = prefBranch->GetPrefType(aPrefName, &prefType);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
switch (prefType) {
|
||||
case nsIPrefBranch::PREF_STRING:
|
||||
mSysPrefService->GetCharPref(aPrefName, getter_Copies(strValue));
|
||||
SYSPREF_LOG(("system value is %s\n", strValue.get()));
|
||||
|
||||
prefBranch->SetCharPref(aPrefName, strValue.get());
|
||||
break;
|
||||
case nsIPrefBranch::PREF_INT:
|
||||
mSysPrefService->GetIntPref(aPrefName, &intValue);
|
||||
SYSPREF_LOG(("system value is %d\n", intValue));
|
||||
|
||||
prefBranch->SetIntPref(aPrefName, intValue);
|
||||
break;
|
||||
case nsIPrefBranch::PREF_BOOL:
|
||||
mSysPrefService->GetBoolPref(aPrefName, &boolValue);
|
||||
SYSPREF_LOG(("system value is %s\n", boolValue ? "TRUE" : "FALSE"));
|
||||
|
||||
prefBranch->SetBoolPref(aPrefName, boolValue);
|
||||
break;
|
||||
default:
|
||||
SYSPREF_LOG(("Fail to system value for it\n"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
prefBranch->LockPref(aPrefName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// nsSystemPref::UseMozillaPrefs
|
||||
// Restore mozilla default prefs, remove system pref listeners
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
nsSystemPref::UseMozillaPrefs()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
SYSPREF_LOG(("\n====Now rollback to Mozilla prefs==\n"));
|
||||
|
||||
// if we did not use system prefs, do nothing
|
||||
if (!mSysPrefService)
|
||||
return NS_OK;
|
||||
|
||||
PRIntn sysPrefCount= sizeof(sSysPrefList) / sizeof(sSysPrefList[0]);
|
||||
for (PRIntn index = 0; index < sysPrefCount; ++index) {
|
||||
// restore mozilla default value and free string memory if needed
|
||||
RestoreMozDefaultPref(mSysPrefs[index].prefName,
|
||||
&mSysPrefs[index].defaultValue,
|
||||
mSysPrefs[index].isLocked);
|
||||
SYSPREF_LOG(("stop listening on %s\n", mSysPrefs[index].prefName));
|
||||
mSysPrefService->RemoveObserver(mSysPrefs[index].prefName,
|
||||
this);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// nsSystemPref::RestoreMozDefaultPref
|
||||
// Save the saved mozilla default value.
|
||||
// It is also responsible for allocate the string memory when needed, because
|
||||
// this method know what type of value is stored.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
nsSystemPref::SaveMozDefaultPref(const char *aPrefName,
|
||||
MozPrefValue *aPrefValue,
|
||||
bool *aLocked)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPrefName);
|
||||
NS_ENSURE_ARG_POINTER(aPrefValue);
|
||||
NS_ENSURE_ARG_POINTER(aLocked);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch =
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
SYSPREF_LOG(("Save Mozilla value for %s\n", aPrefName));
|
||||
|
||||
PRInt32 prefType = nsIPrefBranch::PREF_INVALID;
|
||||
nsXPIDLCString strValue;
|
||||
|
||||
rv = prefBranch->GetPrefType(aPrefName, &prefType);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
switch (prefType) {
|
||||
case nsIPrefBranch::PREF_STRING:
|
||||
prefBranch->GetCharPref(aPrefName,
|
||||
getter_Copies(strValue));
|
||||
SYSPREF_LOG(("Mozilla value is %s", strValue.get()));
|
||||
|
||||
if (aPrefValue->stringVal)
|
||||
PL_strfree(aPrefValue->stringVal);
|
||||
aPrefValue->stringVal = PL_strdup(strValue.get());
|
||||
break;
|
||||
case nsIPrefBranch::PREF_INT:
|
||||
prefBranch->GetIntPref(aPrefName, &aPrefValue->intVal);
|
||||
SYSPREF_LOG(("Mozilla value is %d\n", aPrefValue->intVal));
|
||||
|
||||
break;
|
||||
case nsIPrefBranch::PREF_BOOL:
|
||||
prefBranch->GetBoolPref(aPrefName, &aPrefValue->boolVal);
|
||||
SYSPREF_LOG(("Mozilla value is %s\n",
|
||||
aPrefValue->boolVal ? "TRUE" : "FALSE"));
|
||||
|
||||
break;
|
||||
default:
|
||||
SYSPREF_LOG(("Fail to Read Mozilla value for it\n"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
rv = prefBranch->PrefIsLocked(aPrefName, aLocked);
|
||||
SYSPREF_LOG((" (%s).\n", aLocked ? "Locked" : "NOT Locked"));
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// nsSystemPref::RestoreMozDefaultPref
|
||||
// Restore the saved mozilla default value to pref service.
|
||||
// It is also responsible for free the string memory when needed, because
|
||||
// this method know what type of value is stored.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
nsSystemPref::RestoreMozDefaultPref(const char *aPrefName,
|
||||
MozPrefValue *aPrefValue,
|
||||
bool aLocked)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPrefName);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch =
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
SYSPREF_LOG(("Restore Mozilla value for %s\n", aPrefName));
|
||||
|
||||
PRInt32 prefType = nsIPrefBranch::PREF_INVALID;
|
||||
rv = prefBranch->GetPrefType(aPrefName, &prefType);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
// unlock, if it is locked
|
||||
prefBranch->UnlockPref(aPrefName);
|
||||
|
||||
switch (prefType) {
|
||||
case nsIPrefBranch::PREF_STRING:
|
||||
prefBranch->SetCharPref(aPrefName,
|
||||
aPrefValue->stringVal);
|
||||
SYSPREF_LOG(("Mozilla value is %s\n", aPrefValue->stringVal));
|
||||
|
||||
PL_strfree(aPrefValue->stringVal);
|
||||
aPrefValue->stringVal = nsnull;
|
||||
|
||||
break;
|
||||
case nsIPrefBranch::PREF_INT:
|
||||
prefBranch->SetIntPref(aPrefName, aPrefValue->intVal);
|
||||
SYSPREF_LOG(("Mozilla value is %d\n", aPrefValue->intVal));
|
||||
|
||||
break;
|
||||
case nsIPrefBranch::PREF_BOOL:
|
||||
prefBranch->SetBoolPref(aPrefName, aPrefValue->boolVal);
|
||||
SYSPREF_LOG(("Mozilla value is %s\n",
|
||||
aPrefValue->boolVal ? "TRUE" : "FALSE"));
|
||||
|
||||
break;
|
||||
default:
|
||||
SYSPREF_LOG(("Fail to Restore Mozilla value for it\n"));
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// restore its old lock status
|
||||
if (aLocked)
|
||||
prefBranch->LockPref(aPrefName);
|
||||
return NS_OK;
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
|
||||
* Portions created by Sun Microsystems are Copyright (C) 2003 Sun
|
||||
* Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Original Author: Bolian Yin (bolian.yin@sun.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef __SYSTEM_PREF_H__
|
||||
#define __SYSTEM_PREF_H__
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIAppStartupNotifier.h"
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
|
||||
#include <nsIObserver.h>
|
||||
|
||||
union MozPrefValue;
|
||||
struct SysPrefItem;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// nsSystemPref, as an extension of mozilla pref service, reads some mozilla
|
||||
// prefs from host system when the feature is enabled ("config.system-pref").
|
||||
//
|
||||
// nsSystemPref listens on NS_PREFSERVICE_READ_TOPIC_ID. When notified,
|
||||
// nsSystemPref will start the nsSystemPrefService (platform specific) to
|
||||
// read all the interested prefs (listed in sSysPrefList table) from system
|
||||
// and lock these prefs from user's modification.
|
||||
//
|
||||
// This feature will make mozilla integrated better into host platforms. If
|
||||
// users want to change the prefs read from system, the system provided pref
|
||||
// editor (i.e. gconf-editor in gnome) should be used.
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsSystemPref : public nsIObserver,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
nsSystemPref();
|
||||
virtual ~nsSystemPref();
|
||||
nsresult Init(void);
|
||||
|
||||
private:
|
||||
// funcs used to load system prefs and save mozilla default prefs
|
||||
nsresult UseSystemPrefs();
|
||||
nsresult ReadSystemPref(const char *aPrefName);
|
||||
nsresult SaveMozDefaultPref(const char *aPrefName,
|
||||
MozPrefValue *aPrefVal,
|
||||
bool *aLocked);
|
||||
|
||||
// funcs used to load mozilla default prefs
|
||||
nsresult UseMozillaPrefs();
|
||||
nsresult RestoreMozDefaultPref(const char *aPrefName,
|
||||
MozPrefValue *aPrefVal,
|
||||
bool aLocked);
|
||||
|
||||
nsCOMPtr<nsIPrefBranch2> mSysPrefService;
|
||||
bool mEnabled; // system pref is enabled or not
|
||||
SysPrefItem *mSysPrefs;
|
||||
};
|
||||
|
||||
#define NS_SYSTEMPREF_CID \
|
||||
{ /* {549abb24-7c9d-4aba-915e-7ce0b716b32f} */ \
|
||||
0x549abb24, \
|
||||
0x7c9d, \
|
||||
0x4aba, \
|
||||
{ 0x91, 0x5e, 0x7c, 0xe0, 0xb7, 0x16, 0xb3, 0x2f } \
|
||||
}
|
||||
|
||||
#define NS_SYSTEMPREF_CONTRACTID "@mozilla.org/system-preferences;1"
|
||||
#define NS_SYSTEMPREF_CLASSNAME "System Preferences"
|
||||
|
||||
#endif /* __SYSTEM_PREF_H__ */
|
|
@ -1,77 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
|
||||
* Portions created by Sun Microsystems are Copyright (C) 2003 Sun
|
||||
* Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Original Author: Bolian Yin (bolian.yin@sun.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsICategoryManager.h"
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
#include "nsSystemPref.h"
|
||||
#include "nsSystemPrefService.h"
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemPref, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsSystemPrefService, Init)
|
||||
|
||||
NS_DEFINE_NAMED_CID(NS_SYSTEMPREF_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_SYSTEMPREF_SERVICE_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kSysPrefCIDs[] = {
|
||||
{ &kNS_SYSTEMPREF_CID, false, NULL, nsSystemPrefConstructor },
|
||||
{ &kNS_SYSTEMPREF_SERVICE_CID, false, NULL, nsSystemPrefServiceConstructor },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const mozilla::Module::ContractIDEntry kSysPrefContracts[] = {
|
||||
{ NS_SYSTEMPREF_CONTRACTID, &kNS_SYSTEMPREF_CID },
|
||||
{ NS_SYSTEMPREF_SERVICE_CONTRACTID, &kNS_SYSTEMPREF_SERVICE_CID },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const mozilla::Module::CategoryEntry kSysPrefCategories[] = {
|
||||
{ APPSTARTUP_CATEGORY, "SystemPref Module", NS_SYSTEMPREF_CONTRACTID },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const mozilla::Module kSysPrefModule = {
|
||||
mozilla::Module::kVersion,
|
||||
kSysPrefCIDs,
|
||||
kSysPrefContracts,
|
||||
kSysPrefCategories
|
||||
};
|
||||
|
||||
NSMODULE_DEFN(nsSystemPrefModule) = &kSysPrefModule;
|
|
@ -1,45 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim:expandtab:shiftwidth=4:tabstop=4:
|
||||
*/
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
|
||||
* Portions created by Sun Microsystems are Copyright (C) 2003 Sun
|
||||
* Microsystems, Inc. All Rights Reserved.
|
||||
*
|
||||
* Original Author: Bolian Yin (bolian.yin@sun.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "prlog.h"
|
||||
|
||||
extern PRLogModuleInfo *gSysPrefLog;
|
||||
#define SYSPREF_LOG(args) PR_LOG(gSysPrefLog, PR_LOG_DEBUG, args)
|
|
@ -95,14 +95,18 @@ NS_IMPL_CYCLE_COLLECTION_3(mozHunspell,
|
|||
mEncoder,
|
||||
mDecoder)
|
||||
|
||||
// Memory reporting stuff
|
||||
// Memory reporting stuff.
|
||||
static PRInt64 gHunspellAllocatedSize = 0;
|
||||
|
||||
void HunspellReportMemoryAllocation(void* ptr) {
|
||||
gHunspellAllocatedSize += moz_malloc_usable_size(ptr);
|
||||
// |computedSize| is zero because we don't know what it is.
|
||||
gHunspellAllocatedSize +=
|
||||
mozilla::MemoryReporterMallocSizeOfForCounterInc(ptr, 0);
|
||||
}
|
||||
void HunspellReportMemoryDeallocation(void* ptr) {
|
||||
gHunspellAllocatedSize -= moz_malloc_usable_size(ptr);
|
||||
// |computedSize| is zero because we don't know what it is.
|
||||
gHunspellAllocatedSize -=
|
||||
mozilla::MemoryReporterMallocSizeOfForCounterDec(ptr, 0);
|
||||
}
|
||||
static PRInt64 HunspellGetCurrentAllocatedSize() {
|
||||
return gHunspellAllocatedSize;
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "nsReadableUtils.h"
|
||||
#include "nsExpirationTracker.h"
|
||||
#include "nsILanguageAtomService.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
|
||||
#include "gfxFont.h"
|
||||
#include "gfxPlatform.h"
|
||||
|
@ -1182,8 +1183,8 @@ gfxFont::Draw(gfxTextRun *aTextRun, PRUint32 aStart, PRUint32 aEnd,
|
|||
|
||||
// synthetic-bold strikes are each offset one device pixel in run direction
|
||||
// (these values are only needed if IsSyntheticBold() is true)
|
||||
double synBoldOnePixelOffset;
|
||||
PRInt32 strikes;
|
||||
double synBoldOnePixelOffset = 0;
|
||||
PRInt32 strikes = 0;
|
||||
if (IsSyntheticBold()) {
|
||||
double xscale = CalcXScale(aContext);
|
||||
synBoldOnePixelOffset = direction * xscale;
|
||||
|
@ -4480,21 +4481,15 @@ gfxTextRun::ClusterIterator::ClusterAdvance(PropertyProvider *aProvider) const
|
|||
return mTextRun->GetAdvanceWidth(mCurrentChar, ClusterLength(), aProvider);
|
||||
}
|
||||
|
||||
PRUint64
|
||||
gfxTextRun::ComputeSize()
|
||||
size_t
|
||||
gfxTextRun::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf)
|
||||
{
|
||||
PRUint64 total = moz_malloc_usable_size(this);
|
||||
if (total == 0) {
|
||||
total = sizeof(gfxTextRun);
|
||||
}
|
||||
|
||||
PRUint64 glyphDataSize = moz_malloc_usable_size(mCharacterGlyphs);
|
||||
if (glyphDataSize == 0) {
|
||||
// calculate how much gfxTextRun::AllocateStorage would have allocated
|
||||
glyphDataSize = sizeof(CompressedGlyph) *
|
||||
GlyphStorageAllocCount(mCharacterCount, mFlags);
|
||||
}
|
||||
total += glyphDataSize;
|
||||
// The second arg is how much gfxTextRun::AllocateStorage would have
|
||||
// allocated.
|
||||
size_t total =
|
||||
aMallocSizeOf(mCharacterGlyphs,
|
||||
sizeof(CompressedGlyph) *
|
||||
GlyphStorageAllocCount(mCharacterCount, mFlags));
|
||||
|
||||
if (mDetailedGlyphs) {
|
||||
total += mDetailedGlyphs->SizeOf();
|
||||
|
@ -4505,6 +4500,13 @@ gfxTextRun::ComputeSize()
|
|||
return total;
|
||||
}
|
||||
|
||||
size_t
|
||||
gfxTextRun::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf)
|
||||
{
|
||||
return aMallocSizeOf(this, sizeof(gfxTextRun)) +
|
||||
SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
|
|
|
@ -2048,16 +2048,20 @@ public:
|
|||
|
||||
// return storage used by this run, for memory reporter;
|
||||
// nsTransformedTextRun needs to override this as it holds additional data
|
||||
virtual PRUint64 ComputeSize();
|
||||
virtual NS_MUST_OVERRIDE size_t
|
||||
SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf);
|
||||
virtual NS_MUST_OVERRIDE size_t
|
||||
SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf);
|
||||
|
||||
void AccountForSize(PRUint64* aTotal) {
|
||||
// Get the size, if it hasn't already been gotten, marking as it goes.
|
||||
size_t MaybeSizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) {
|
||||
if (mFlags & gfxTextRunFactory::TEXT_RUN_SIZE_ACCOUNTED) {
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
mFlags |= gfxTextRunFactory::TEXT_RUN_SIZE_ACCOUNTED;
|
||||
*aTotal += ComputeSize();
|
||||
return SizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
void ClearSizeAccounted() {
|
||||
void ResetSizeOfAccountingFlags() {
|
||||
mFlags &= ~gfxTextRunFactory::TEXT_RUN_SIZE_ACCOUNTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
#include "prtypes.h"
|
||||
#include "prlog.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsString.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
#include "gfxTypes.h"
|
||||
|
|
|
@ -135,7 +135,8 @@ public:
|
|||
#endif
|
||||
}
|
||||
|
||||
void ComputeStorage(PRUint64 *aTotal);
|
||||
size_t MaybeSizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf);
|
||||
void ResetSizeOfAccountingFlags();
|
||||
|
||||
#ifdef DEBUG
|
||||
PRUint32 mGeneration;
|
||||
|
@ -219,10 +220,10 @@ protected:
|
|||
PRUint32 aEnd, PRUint32 aHash);
|
||||
void Uninit();
|
||||
|
||||
static PLDHashOperator AccountForStorage(CacheHashEntry *aEntry,
|
||||
void *aUserData);
|
||||
static PLDHashOperator ClearSizeAccounted(CacheHashEntry *aEntry,
|
||||
void *aUserData);
|
||||
static PLDHashOperator MaybeSizeOfEntry(CacheHashEntry *aEntry,
|
||||
void *aUserData);
|
||||
static PLDHashOperator ResetSizeOfEntryAccountingFlags(CacheHashEntry *aEntry,
|
||||
void *aUserData);
|
||||
|
||||
nsTHashtable<CacheHashEntry> mCache;
|
||||
|
||||
|
@ -914,36 +915,48 @@ TextRunWordCache::RemoveTextRun(gfxTextRun *aTextRun)
|
|||
#endif
|
||||
}
|
||||
|
||||
struct SizeOfEntryData {
|
||||
nsMallocSizeOfFun mMallocSizeOf;
|
||||
size_t mTotal;
|
||||
SizeOfEntryData(nsMallocSizeOfFun mallocSizeOf)
|
||||
: mMallocSizeOf(mallocSizeOf), mTotal(0) { }
|
||||
};
|
||||
|
||||
/*static*/ PLDHashOperator
|
||||
TextRunWordCache::AccountForStorage(CacheHashEntry *aEntry, void *aUserData)
|
||||
TextRunWordCache::MaybeSizeOfEntry(CacheHashEntry *aEntry, void *aUserData)
|
||||
{
|
||||
gfxTextRun *run = aEntry->mTextRun;
|
||||
if (run) {
|
||||
PRUint64 *total = static_cast<PRUint64*>(aUserData);
|
||||
run->AccountForSize(total);
|
||||
SizeOfEntryData *data = static_cast<SizeOfEntryData*>(aUserData);
|
||||
data->mTotal += run->MaybeSizeOfIncludingThis(data->mMallocSizeOf);
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
/*static*/ PLDHashOperator
|
||||
TextRunWordCache::ClearSizeAccounted(CacheHashEntry *aEntry, void *)
|
||||
TextRunWordCache::ResetSizeOfEntryAccountingFlags(CacheHashEntry *aEntry, void *)
|
||||
{
|
||||
gfxTextRun *run = aEntry->mTextRun;
|
||||
if (run) {
|
||||
run->ClearSizeAccounted();
|
||||
run->ResetSizeOfAccountingFlags();
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
size_t
|
||||
TextRunWordCache::MaybeSizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf)
|
||||
{
|
||||
size_t total = mCache.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||
SizeOfEntryData data(aMallocSizeOf);
|
||||
mCache.EnumerateEntries(MaybeSizeOfEntry, &data);
|
||||
total += data.mTotal;
|
||||
return total;
|
||||
}
|
||||
|
||||
void
|
||||
TextRunWordCache::ComputeStorage(PRUint64 *aTotal)
|
||||
TextRunWordCache::ResetSizeOfAccountingFlags()
|
||||
{
|
||||
if (aTotal) {
|
||||
*aTotal += mCache.SizeOf();
|
||||
mCache.EnumerateEntries(AccountForStorage, aTotal);
|
||||
} else {
|
||||
mCache.EnumerateEntries(ClearSizeAccounted, nsnull);
|
||||
}
|
||||
mCache.EnumerateEntries(ResetSizeOfEntryAccountingFlags, nsnull);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -1101,12 +1114,20 @@ gfxTextRunWordCache::Flush()
|
|||
gTextRunWordCache->Flush();
|
||||
}
|
||||
|
||||
void
|
||||
gfxTextRunWordCache::ComputeStorage(PRUint64 *aTotal)
|
||||
size_t
|
||||
gfxTextRunWordCache::MaybeSizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf)
|
||||
{
|
||||
if (!gTextRunWordCache) {
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
return gTextRunWordCache->MaybeSizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
void
|
||||
gfxTextRunWordCache::ResetSizeOfAccountingFlags()
|
||||
{
|
||||
if (gTextRunWordCache) {
|
||||
gTextRunWordCache->ResetSizeOfAccountingFlags();
|
||||
}
|
||||
gTextRunWordCache->ComputeStorage(aTotal);
|
||||
}
|
||||
|
||||
|
|
|
@ -106,13 +106,16 @@ public:
|
|||
static void Flush();
|
||||
|
||||
/**
|
||||
* If aTotal is NULL, just clears the TEXT_RUN_MEMORY_ACCOUNTED flag
|
||||
* on each textRun found.
|
||||
* If aTotal is non-NULL, adds the storage used for each textRun to the
|
||||
* total, and sets the TEXT_RUN_MEMORY_ACCOUNTED flag to avoid double-
|
||||
* accounting. (Runs with this flag already set will be skipped.)
|
||||
* This adds the storage used for each textRun to the total, and sets the
|
||||
* TEXT_RUN_MEMORY_ACCOUNTED flag to avoid double- accounting. (Runs with
|
||||
* this flag already set will be skipped.)
|
||||
*/
|
||||
static void ComputeStorage(PRUint64 *aTotal);
|
||||
static size_t MaybeSizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf);
|
||||
|
||||
/**
|
||||
* This clears the TEXT_RUN_MEMORY_ACCOUNTED flag on each textRun found.
|
||||
*/
|
||||
static void ResetSizeOfAccountingFlags();
|
||||
|
||||
protected:
|
||||
friend class gfxPlatform;
|
||||
|
|
|
@ -399,10 +399,15 @@ nsBMPDecoder::WriteInternal(const char* aBuffer, PRUint32 aCount)
|
|||
break;
|
||||
case 2:
|
||||
mColors[colorNum].red = *aBuffer;
|
||||
colorNum++;
|
||||
// If there is no padding byte, increment the color index
|
||||
// since we're done with the current color.
|
||||
if (bytesPerColor == 3)
|
||||
colorNum++;
|
||||
break;
|
||||
case 3:
|
||||
// This is a padding byte
|
||||
// This is a padding byte only in Windows BMPs. Increment
|
||||
// the color index since we're done with the current color.
|
||||
colorNum++;
|
||||
break;
|
||||
}
|
||||
mPos++; aBuffer++; aCount--;
|
||||
|
|
|
@ -20,7 +20,8 @@ void NotifyEvent();
|
|||
namespace base {
|
||||
|
||||
MessagePumpForUI::MessagePumpForUI()
|
||||
: pump(*this)
|
||||
: state_(NULL)
|
||||
, pump(*this)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -653,14 +653,12 @@ class HashTable : private AllocPolicy
|
|||
return gen;
|
||||
}
|
||||
|
||||
/*
|
||||
* This counts the HashTable's |table| array. If |countMe| is true it also
|
||||
* counts the HashTable object itself.
|
||||
*/
|
||||
size_t sizeOf(JSUsableSizeFun usf, bool countMe) const {
|
||||
size_t usable = usf(table) + (countMe ? usf((void*)this) : 0);
|
||||
return usable ? usable
|
||||
: (capacity() * sizeof(Entry)) + (countMe ? sizeof(HashTable) : 0);
|
||||
size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const {
|
||||
return mallocSizeOf(table, capacity() * sizeof(Entry));
|
||||
}
|
||||
|
||||
size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const {
|
||||
return mallocSizeOf(this, sizeof(HashTable)) + sizeOfExcludingThis(mallocSizeOf);
|
||||
}
|
||||
|
||||
Ptr lookup(const Lookup &l) const {
|
||||
|
@ -1097,7 +1095,16 @@ class HashMap
|
|||
Range all() const { return impl.all(); }
|
||||
size_t count() const { return impl.count(); }
|
||||
size_t capacity() const { return impl.capacity(); }
|
||||
size_t sizeOf(JSUsableSizeFun usf, bool cm) const { return impl.sizeOf(usf, cm); }
|
||||
size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const {
|
||||
return impl.sizeOfExcludingThis(mallocSizeOf);
|
||||
}
|
||||
size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const {
|
||||
/*
|
||||
* Don't just call |impl.sizeOfExcludingThis()| because there's no
|
||||
* guarantee that |impl| is the first field in HashMap.
|
||||
*/
|
||||
return mallocSizeOf(this, sizeof(*this)) + impl.sizeOfExcludingThis(mallocSizeOf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Typedef for the enumeration class. An Enum may be used to examine and
|
||||
|
@ -1298,7 +1305,16 @@ class HashSet
|
|||
Range all() const { return impl.all(); }
|
||||
size_t count() const { return impl.count(); }
|
||||
size_t capacity() const { return impl.capacity(); }
|
||||
size_t sizeOf(JSUsableSizeFun usf, bool cm) const { return impl.sizeOf(usf, cm); }
|
||||
size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const {
|
||||
return impl.sizeOfExcludingThis(mallocSizeOf);
|
||||
}
|
||||
size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const {
|
||||
/*
|
||||
* Don't just call |impl.sizeOfExcludingThis()| because there's no
|
||||
* guarantee that |impl| is the first field in HashSet.
|
||||
*/
|
||||
return mallocSizeOf(this, sizeof(*this)) + impl.sizeOfExcludingThis(mallocSizeOf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Typedef for the enumeration class. An Enum may be used to examine and
|
||||
|
|
|
@ -895,11 +895,9 @@ RoundUpPow2(size_t x)
|
|||
#endif /* defined(__cplusplus) */
|
||||
|
||||
/*
|
||||
* This signature is for malloc_usable_size-like functions used to measure
|
||||
* memory usage. A return value of zero indicates that the size is unknown,
|
||||
* and so a fall-back computation should be done for the size.
|
||||
* This is SpiderMonkey's equivalent to |nsMallocSizeOfFun|.
|
||||
*/
|
||||
typedef size_t(*JSUsableSizeFun)(void *p);
|
||||
typedef size_t(*JSMallocSizeOfFun)(const void *p, size_t computedSize);
|
||||
|
||||
/* sixgill annotation defines */
|
||||
#ifndef HAVE_STATIC_ANNOTATIONS
|
||||
|
|
|
@ -8,6 +8,7 @@ builtin(include, build/autoconf/nspr.m4)dnl
|
|||
builtin(include, build/autoconf/altoptions.m4)dnl
|
||||
builtin(include, build/autoconf/moznbytetype.m4)dnl
|
||||
builtin(include, build/autoconf/mozprog.m4)dnl
|
||||
builtin(include, build/autoconf/mozheader.m4)dnl
|
||||
builtin(include, build/autoconf/acwinpaths.m4)dnl
|
||||
builtin(include, build/autoconf/lto.m4)dnl
|
||||
builtin(include, build/autoconf/gcc-pr49911.m4)dnl
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
dnl ***** BEGIN LICENSE BLOCK *****
|
||||
dnl Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
dnl
|
||||
dnl The contents of this file are subject to the Mozilla Public License Version
|
||||
dnl 1.1 (the "License"); you may not use this file except in compliance with
|
||||
dnl the License. You may obtain a copy of the License at
|
||||
dnl http://www.mozilla.org/MPL/
|
||||
dnl
|
||||
dnl Software distributed under the License is distributed on an "AS IS" basis,
|
||||
dnl WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
dnl for the specific language governing rights and limitations under the
|
||||
dnl License.
|
||||
dnl
|
||||
dnl The Original Code is mozilla.org code.
|
||||
dnl
|
||||
dnl The Initial Developer of the Original Code is the
|
||||
dnl Mozilla Foundation <http://www.mozilla.org>
|
||||
dnl
|
||||
dnl Portions created by the Initial Developer are Copyright (C) 2009
|
||||
dnl the Initial Developer. All Rights Reserved.
|
||||
dnl
|
||||
dnl Contributor(s):
|
||||
dnl Neil Rashbrook <neil@parkwaycc.co.uk>
|
||||
dnl
|
||||
dnl Alternatively, the contents of this file may be used under the terms of
|
||||
dnl either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
dnl or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
dnl in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
dnl of those above. If you wish to allow use of your version of this file only
|
||||
dnl under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
dnl use your version of this file under the terms of the MPL, indicate your
|
||||
dnl decision by deleting the provisions above and replace them with the notice
|
||||
dnl and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
dnl the provisions above, a recipient may use your version of this file under
|
||||
dnl the terms of any one of the MPL, the GPL or the LGPL.
|
||||
dnl
|
||||
dnl ***** END LICENSE BLOCK *****
|
||||
|
||||
dnl MOZ_CHECK_HEADER(HEADER-FILE, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]])
|
||||
AC_DEFUN([MOZ_CHECK_HEADER],
|
||||
[ dnl Do the transliteration at runtime so arg 1 can be a shell variable.
|
||||
ac_safe=`echo "$1" | sed 'y%./+-%__p_%'`
|
||||
AC_MSG_CHECKING([for $1])
|
||||
AC_CACHE_VAL(ac_cv_header_$ac_safe,
|
||||
[ AC_TRY_COMPILE([$4
|
||||
#include <$1>], ,
|
||||
eval "ac_cv_header_$ac_safe=yes",
|
||||
eval "ac_cv_header_$ac_safe=no") ])
|
||||
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
ifelse([$2], , :, [$2])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
ifelse([$3], , , [$3])
|
||||
fi
|
||||
])
|
||||
|
||||
dnl MOZ_CHECK_HEADERS(HEADER-FILE... [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, INCLUDES]]])
|
||||
AC_DEFUN([MOZ_CHECK_HEADERS],
|
||||
[ for ac_hdr in $1
|
||||
do
|
||||
MOZ_CHECK_HEADER($ac_hdr,
|
||||
[ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
|
||||
AC_DEFINE_UNQUOTED($ac_tr_hdr) $2], $3, [$4])
|
||||
done
|
||||
])
|
|
@ -803,7 +803,7 @@ case "$target" in
|
|||
# Identify which version of the SDK we're building with
|
||||
# Windows Server 2008 and newer SDKs have WinSDKVer.h, get the version
|
||||
# from there
|
||||
AC_CHECK_HEADERS([winsdkver.h])
|
||||
MOZ_CHECK_HEADERS([winsdkver.h])
|
||||
if test "$ac_cv_header_winsdkver_h" = "yes"; then
|
||||
# Get the highest _WIN32_WINNT and NTDDI versions supported
|
||||
# Take the higher of the two
|
||||
|
@ -830,7 +830,7 @@ EOF
|
|||
else
|
||||
# The Vista SDK is the only one to have sdkddkver.h but not
|
||||
# WinSDKVer.h
|
||||
AC_CHECK_HEADERS([sdkddkver.h])
|
||||
MOZ_CHECK_HEADERS([sdkddkver.h])
|
||||
if test "$ac_cv_header_sdkddkver_h" = "yes"; then
|
||||
MOZ_WINSDK_MAXVER=0x06000000
|
||||
else
|
||||
|
@ -1190,7 +1190,7 @@ tools are selected during the Xcode/Developer Tools installation.])
|
|||
CFLAGS="$CFLAGS -isysroot ${MACOS_SDK_DIR}"
|
||||
CXXFLAGS="$CXXFLAGS -isysroot ${MACOS_SDK_DIR}"
|
||||
|
||||
dnl CPP/CXXCPP needs to be set for AC_CHECK_HEADER.
|
||||
dnl CPP/CXXCPP needs to be set for MOZ_CHECK_HEADER.
|
||||
CPP="$CPP -isysroot ${MACOS_SDK_DIR}"
|
||||
CXXCPP="$CXXCPP -isysroot ${MACOS_SDK_DIR}"
|
||||
|
||||
|
@ -2164,7 +2164,7 @@ case "$target" in
|
|||
;;
|
||||
esac
|
||||
if test "$COMPILE_ENVIRONMENT"; then
|
||||
AC_CHECK_HEADERS(sys/inttypes.h)
|
||||
MOZ_CHECK_HEADERS(sys/inttypes.h)
|
||||
fi
|
||||
AC_DEFINE(JS_SYS_TYPES_H_DEFINES_EXACT_SIZE_TYPES)
|
||||
AC_DEFINE(NSCAP_DISABLE_DEBUG_PTR_TYPES)
|
||||
|
@ -2501,7 +2501,7 @@ ia64*-hpux*)
|
|||
CXXFLAGS="$CXXFLAGS -mstackrealign"
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS(mmintrin.h)
|
||||
MOZ_CHECK_HEADERS(mmintrin.h)
|
||||
AC_DEFINE(_X86_)
|
||||
;;
|
||||
x86_64-*)
|
||||
|
@ -2926,7 +2926,7 @@ dnl ========================================================
|
|||
dnl Once this is working, we can delete the code for int16_t,
|
||||
dnl etc. below.
|
||||
|
||||
AC_CHECK_HEADER(stdint.h)
|
||||
MOZ_CHECK_HEADER(stdint.h)
|
||||
if test "$ac_cv_header_stdint_h" = yes; then
|
||||
AC_DEFINE(JS_HAVE_STDINT_H)
|
||||
else
|
||||
|
@ -2954,12 +2954,12 @@ fi
|
|||
MOZ_ALIGN_OF_TYPE(JS_ALIGN_OF_POINTER, void*, 2 4 8 16)
|
||||
MOZ_SIZE_OF_TYPE(JS_BYTES_PER_DOUBLE, double, 6 8 10 12 14)
|
||||
|
||||
AC_CHECK_HEADERS(endian.h)
|
||||
MOZ_CHECK_HEADERS(endian.h)
|
||||
if test "$ac_cv_header_endian_h" = yes; then
|
||||
AC_DEFINE(JS_HAVE_ENDIAN_H)
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS(sys/isa_defs.h)
|
||||
MOZ_CHECK_HEADERS(sys/isa_defs.h)
|
||||
if test "$ac_cv_header_sys_isa_defs_h" = yes; then
|
||||
AC_DEFINE(JS_HAVE_SYS_ISA_DEFS_H)
|
||||
fi
|
||||
|
@ -3248,30 +3248,30 @@ freebsd*)
|
|||
CPPFLAGS="${CPPFLAGS} ${X_CFLAGS}"
|
||||
;;
|
||||
esac
|
||||
AC_CHECK_HEADERS(sys/byteorder.h compat.h getopt.h)
|
||||
AC_CHECK_HEADERS(sys/bitypes.h memory.h unistd.h)
|
||||
AC_CHECK_HEADERS(gnu/libc-version.h nl_types.h)
|
||||
AC_CHECK_HEADERS(malloc.h)
|
||||
AC_CHECK_HEADERS(X11/XKBlib.h)
|
||||
AC_CHECK_HEADERS(io.h)
|
||||
MOZ_CHECK_HEADERS(sys/byteorder.h compat.h getopt.h)
|
||||
MOZ_CHECK_HEADERS(sys/bitypes.h memory.h unistd.h)
|
||||
MOZ_CHECK_HEADERS(gnu/libc-version.h nl_types.h)
|
||||
MOZ_CHECK_HEADERS(malloc.h)
|
||||
MOZ_CHECK_HEADERS(X11/XKBlib.h)
|
||||
MOZ_CHECK_HEADERS(io.h)
|
||||
|
||||
dnl These are all the places some variant of statfs can be hiding.
|
||||
AC_CHECK_HEADERS(sys/statvfs.h sys/statfs.h sys/vfs.h sys/mount.h)
|
||||
MOZ_CHECK_HEADERS(sys/statvfs.h sys/statfs.h sys/vfs.h sys/mount.h)
|
||||
|
||||
dnl Quota support
|
||||
AC_CHECK_HEADERS(sys/quota.h)
|
||||
AC_CHECK_HEADERS(linux/quota.h)
|
||||
MOZ_CHECK_HEADERS(sys/quota.h)
|
||||
MOZ_CHECK_HEADERS(linux/quota.h)
|
||||
|
||||
dnl Try for MMX support
|
||||
dnl NB - later gcc versions require -mmmx for this header to be successfully
|
||||
dnl included (or another option which implies it, such as -march=pentium-mmx)
|
||||
AC_CHECK_HEADERS(mmintrin.h)
|
||||
MOZ_CHECK_HEADERS(mmintrin.h)
|
||||
|
||||
dnl Check whether the compiler supports the new-style C++ standard
|
||||
dnl library headers (i.e. <new>) or needs the old "new.h"
|
||||
AC_LANG_CPLUSPLUS
|
||||
NEW_H=new.h
|
||||
AC_CHECK_HEADER(new, [NEW_H=new])
|
||||
MOZ_CHECK_HEADER(new, [NEW_H=new])
|
||||
AC_DEFINE_UNQUOTED(NEW_H, <$NEW_H>)
|
||||
AC_LANG_C
|
||||
|
||||
|
@ -3279,7 +3279,7 @@ AC_ARG_ENABLE(dtrace,
|
|||
[ --enable-dtrace build with dtrace support if available (default=no)],
|
||||
[enable_dtrace="yes"],)
|
||||
if test "x$enable_dtrace" = "xyes"; then
|
||||
AC_CHECK_HEADER(sys/sdt.h, HAVE_DTRACE=1)
|
||||
MOZ_CHECK_HEADER(sys/sdt.h, HAVE_DTRACE=1)
|
||||
if test -n "$HAVE_DTRACE"; then
|
||||
AC_DEFINE(INCLUDE_MOZILLA_DTRACE)
|
||||
else
|
||||
|
@ -3292,12 +3292,12 @@ case $target in
|
|||
*-aix4.3*|*-aix5*)
|
||||
;;
|
||||
*)
|
||||
AC_CHECK_HEADERS(sys/cdefs.h)
|
||||
MOZ_CHECK_HEADERS(sys/cdefs.h)
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl Performance measurement headers.
|
||||
AC_CHECK_HEADER(linux/perf_event.h,
|
||||
MOZ_CHECK_HEADER(linux/perf_event.h,
|
||||
[AC_CACHE_CHECK(for perf_event_open system call,ac_cv_perf_event_open,
|
||||
[AC_TRY_COMPILE([#include <sys/syscall.h>],[return sizeof(__NR_perf_event_open);],
|
||||
ac_cv_perf_event_open=yes,
|
||||
|
@ -3332,7 +3332,7 @@ case $target in
|
|||
;;
|
||||
*)
|
||||
AC_SEARCH_LIBS(dlopen, dl,
|
||||
AC_CHECK_HEADER(dlfcn.h,
|
||||
MOZ_CHECK_HEADER(dlfcn.h,
|
||||
AC_DEFINE(HAVE_DLOPEN)))
|
||||
;;
|
||||
esac
|
||||
|
@ -3905,11 +3905,11 @@ fi
|
|||
dnl Check for the existence of various allocation headers/functions
|
||||
|
||||
MALLOC_H=
|
||||
AC_CHECK_HEADER(malloc.h, [MALLOC_H=malloc.h])
|
||||
MOZ_CHECK_HEADER(malloc.h, [MALLOC_H=malloc.h])
|
||||
if test "$MALLOC_H" = ""; then
|
||||
AC_CHECK_HEADER(malloc/malloc.h, [MALLOC_H=malloc/malloc.h])
|
||||
MOZ_CHECK_HEADER(malloc/malloc.h, [MALLOC_H=malloc/malloc.h])
|
||||
if test "$MALLOC_H" = ""; then
|
||||
AC_CHECK_HEADER(sys/malloc.h, [MALLOC_H=sys/malloc.h])
|
||||
MOZ_CHECK_HEADER(sys/malloc.h, [MALLOC_H=sys/malloc.h])
|
||||
fi
|
||||
fi
|
||||
if test "$MALLOC_H" != ""; then
|
||||
|
@ -4462,7 +4462,7 @@ MOZ_ARG_ENABLE_BOOL(valgrind,
|
|||
MOZ_VALGRIND=1,
|
||||
MOZ_VALGRIND= )
|
||||
if test -n "$MOZ_VALGRIND"; then
|
||||
AC_CHECK_HEADER([valgrind/valgrind.h], [],
|
||||
MOZ_CHECK_HEADER([valgrind/valgrind.h], [],
|
||||
AC_MSG_ERROR(
|
||||
[--enable-valgrind specified but Valgrind is not installed]))
|
||||
AC_DEFINE(MOZ_VALGRIND)
|
||||
|
@ -4667,7 +4667,7 @@ dnl ========================================================
|
|||
dnl = Support for gcc stack unwinding (from gcc 3.3)
|
||||
dnl ========================================================
|
||||
if test -z "$SKIP_LIBRARY_CHECKS"; then
|
||||
AC_CHECK_HEADER(unwind.h, AC_CHECK_FUNCS(_Unwind_Backtrace))
|
||||
MOZ_CHECK_HEADER(unwind.h, AC_CHECK_FUNCS(_Unwind_Backtrace))
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
|
|
|
@ -111,9 +111,8 @@ class BumpChunk
|
|||
void setNext(BumpChunk *succ) { next_ = succ; }
|
||||
|
||||
size_t used() const { return bump - bumpBase(); }
|
||||
size_t sizeOf(JSUsableSizeFun usf) {
|
||||
size_t usable = usf((void*)this);
|
||||
return usable ? usable : limit - headerBase();
|
||||
size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) {
|
||||
return mallocSizeOf(this, limit - headerBase());
|
||||
}
|
||||
|
||||
void resetBump() {
|
||||
|
@ -294,22 +293,23 @@ class LifoAlloc
|
|||
return accum;
|
||||
}
|
||||
|
||||
/* Get the total size of the arena chunks (including unused space), plus,
|
||||
* if |countMe| is true, the size of the LifoAlloc itself. */
|
||||
size_t sizeOf(JSUsableSizeFun usf, bool countMe) const {
|
||||
/* Get the total size of the arena chunks (including unused space). */
|
||||
size_t sizeOfExcludingThis(JSMallocSizeOfFun mallocSizeOf) const {
|
||||
size_t accum = 0;
|
||||
if (countMe) {
|
||||
size_t usable = usf((void*)this);
|
||||
accum += usable ? usable : sizeof(LifoAlloc);
|
||||
}
|
||||
BumpChunk *it = first;
|
||||
while (it) {
|
||||
accum += it->sizeOf(usf);
|
||||
accum += it->sizeOfIncludingThis(mallocSizeOf);
|
||||
it = it->next();
|
||||
}
|
||||
return accum;
|
||||
}
|
||||
|
||||
/* Like sizeOfExcludingThis(), but includes the size of the LifoAlloc itself. */
|
||||
size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const {
|
||||
return mallocSizeOf(this, sizeof(LifoAlloc)) +
|
||||
sizeOfExcludingThis(mallocSizeOf);
|
||||
}
|
||||
|
||||
/* Doesn't perform construction; useful for lazily-initialized POD types. */
|
||||
template <typename T>
|
||||
JS_ALWAYS_INLINE
|
||||
|
|
|
@ -5757,9 +5757,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
JSOp op;
|
||||
uint32 argc;
|
||||
EmitLevelManager elm(bce);
|
||||
#if JS_HAS_SHARP_VARS
|
||||
jsint sharpnum;
|
||||
#endif
|
||||
jsint sharpnum = -1;
|
||||
|
||||
JS_CHECK_RECURSION(cx, return JS_FALSE);
|
||||
|
||||
|
|
|
@ -116,12 +116,12 @@ typedef struct TypeInferenceMemoryStats
|
|||
extern JS_FRIEND_API(void)
|
||||
JS_GetTypeInferenceMemoryStats(JSContext *cx, JSCompartment *compartment,
|
||||
TypeInferenceMemoryStats *stats,
|
||||
JSUsableSizeFun usf);
|
||||
JSMallocSizeOfFun mallocSizeOf);
|
||||
|
||||
extern JS_FRIEND_API(void)
|
||||
JS_GetTypeInferenceObjectStats(/*TypeObject*/ void *object,
|
||||
TypeInferenceMemoryStats *stats,
|
||||
JSUsableSizeFun usf);
|
||||
JSMallocSizeOfFun mallocSizeOf);
|
||||
|
||||
extern JS_FRIEND_API(JSPrincipals *)
|
||||
JS_GetCompartmentPrincipals(JSCompartment *compartment);
|
||||
|
|
|
@ -1312,9 +1312,6 @@ typedef struct JSPtrTable {
|
|||
void **array;
|
||||
} JSPtrTable;
|
||||
|
||||
extern JSBool
|
||||
js_RegisterCloseableIterator(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern JSBool
|
||||
js_LockGCThingRT(JSRuntime *rt, void *thing);
|
||||
|
||||
|
|
|
@ -6150,8 +6150,8 @@ TypeSet::dynamicSize()
|
|||
{
|
||||
/*
|
||||
* This memory is allocated within the temp pool (but accounted for
|
||||
* elsewhere) so we can't use a JSUsableSizeFun to measure it. We must do
|
||||
* it analytically.
|
||||
* elsewhere) so we can't use a JSMallocSizeOfFun to measure it. We must
|
||||
* do it analytically.
|
||||
*/
|
||||
uint32 count = baseObjectCount();
|
||||
if (count >= 2)
|
||||
|
@ -6164,8 +6164,8 @@ TypeObject::dynamicSize()
|
|||
{
|
||||
/*
|
||||
* This memory is allocated within the temp pool (but accounted for
|
||||
* elsewhere) so we can't use a JSUsableSizeFun to measure it. We must do
|
||||
* it analytically.
|
||||
* elsewhere) so we can't use a JSMallocSizeOfFun to measure it. We must
|
||||
* do it analytically.
|
||||
*/
|
||||
size_t bytes = 0;
|
||||
|
||||
|
@ -6184,32 +6184,26 @@ TypeObject::dynamicSize()
|
|||
}
|
||||
|
||||
static void
|
||||
GetScriptMemoryStats(JSScript *script, TypeInferenceMemoryStats *stats, JSUsableSizeFun usf)
|
||||
GetScriptMemoryStats(JSScript *script, TypeInferenceMemoryStats *stats, JSMallocSizeOfFun mallocSizeOf)
|
||||
{
|
||||
TypeScript *typeScript = script->types;
|
||||
if (!typeScript)
|
||||
return;
|
||||
|
||||
size_t usable;
|
||||
|
||||
/* If TI is disabled, a single TypeScript is still present. */
|
||||
if (!script->compartment()->types.inferenceEnabled) {
|
||||
usable = usf(typeScript);
|
||||
stats->scripts += usable ? usable : sizeof(TypeScript);
|
||||
stats->scripts += mallocSizeOf(typeScript, sizeof(TypeScript));
|
||||
return;
|
||||
}
|
||||
|
||||
usable = usf(typeScript->nesting);
|
||||
stats->scripts += usable ? usable : sizeof(TypeScriptNesting);
|
||||
stats->scripts += mallocSizeOf(typeScript->nesting, sizeof(TypeScriptNesting));
|
||||
|
||||
unsigned count = TypeScript::NumTypeSets(script);
|
||||
usable = usf(typeScript);
|
||||
stats->scripts += usable ? usable : sizeof(TypeScript) + count * sizeof(TypeSet);
|
||||
stats->scripts += mallocSizeOf(typeScript, sizeof(TypeScript) + count * sizeof(TypeSet));
|
||||
|
||||
TypeResult *result = typeScript->dynamicList;
|
||||
while (result) {
|
||||
usable = usf(result);
|
||||
stats->scripts += usable ? usable : sizeof(TypeResult);
|
||||
stats->scripts += mallocSizeOf(result, sizeof(TypeResult));
|
||||
result = result->next;
|
||||
}
|
||||
|
||||
|
@ -6227,35 +6221,35 @@ GetScriptMemoryStats(JSScript *script, TypeInferenceMemoryStats *stats, JSUsable
|
|||
|
||||
JS_FRIEND_API(void)
|
||||
JS_GetTypeInferenceMemoryStats(JSContext *cx, JSCompartment *compartment,
|
||||
TypeInferenceMemoryStats *stats, JSUsableSizeFun usf)
|
||||
TypeInferenceMemoryStats *stats,
|
||||
JSMallocSizeOfFun mallocSizeOf)
|
||||
{
|
||||
/*
|
||||
* Note: not all data in the pool is temporary, and some will survive GCs
|
||||
* by being copied to the replacement pool. This memory will be counted
|
||||
* elsewhere and deducted from the amount of temporary data.
|
||||
*/
|
||||
stats->temporary += compartment->typeLifoAlloc.sizeOf(usf, /* countMe = */false);
|
||||
stats->temporary += compartment->typeLifoAlloc.sizeOfExcludingThis(mallocSizeOf);
|
||||
|
||||
/* Pending arrays are cleared on GC along with the analysis pool. */
|
||||
size_t usable = usf(compartment->types.pendingArray);
|
||||
stats->temporary +=
|
||||
usable ? usable
|
||||
: sizeof(TypeCompartment::PendingWork) * compartment->types.pendingCapacity;
|
||||
mallocSizeOf(compartment->types.pendingArray,
|
||||
sizeof(TypeCompartment::PendingWork) * compartment->types.pendingCapacity);
|
||||
|
||||
/* TypeCompartment::pendingRecompiles is non-NULL only while inference code is running. */
|
||||
JS_ASSERT(!compartment->types.pendingRecompiles);
|
||||
|
||||
for (gc::CellIter i(cx, compartment, gc::FINALIZE_SCRIPT); !i.done(); i.next())
|
||||
GetScriptMemoryStats(i.get<JSScript>(), stats, usf);
|
||||
GetScriptMemoryStats(i.get<JSScript>(), stats, mallocSizeOf);
|
||||
|
||||
if (compartment->types.allocationSiteTable)
|
||||
stats->tables += compartment->types.allocationSiteTable->sizeOf(usf, /* countMe = */true);
|
||||
stats->tables += compartment->types.allocationSiteTable->sizeOfIncludingThis(mallocSizeOf);
|
||||
|
||||
if (compartment->types.arrayTypeTable)
|
||||
stats->tables += compartment->types.arrayTypeTable->sizeOf(usf, /* countMe = */true);
|
||||
stats->tables += compartment->types.arrayTypeTable->sizeOfIncludingThis(mallocSizeOf);
|
||||
|
||||
if (compartment->types.objectTypeTable) {
|
||||
stats->tables += compartment->types.objectTypeTable->sizeOf(usf, /* countMe = */true);
|
||||
stats->tables += compartment->types.objectTypeTable->sizeOfIncludingThis(mallocSizeOf);
|
||||
|
||||
for (ObjectTypeTable::Enum e(*compartment->types.objectTypeTable);
|
||||
!e.empty();
|
||||
|
@ -6265,14 +6259,14 @@ JS_GetTypeInferenceMemoryStats(JSContext *cx, JSCompartment *compartment,
|
|||
const ObjectTableEntry &value = e.front().value;
|
||||
|
||||
/* key.ids and values.types have the same length. */
|
||||
usable = usf(key.ids) + usf(value.types);
|
||||
stats->tables += usable ? usable : key.nslots * (sizeof(jsid) + sizeof(Type));
|
||||
stats->tables += mallocSizeOf(key.ids, key.nslots * sizeof(jsid)) +
|
||||
mallocSizeOf(value.types, key.nslots * sizeof(Type));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
JS_GetTypeInferenceObjectStats(void *object_, TypeInferenceMemoryStats *stats, JSUsableSizeFun usf)
|
||||
JS_GetTypeInferenceObjectStats(void *object_, TypeInferenceMemoryStats *stats, JSMallocSizeOfFun mallocSizeOf)
|
||||
{
|
||||
TypeObject *object = (TypeObject *) object_;
|
||||
|
||||
|
@ -6288,23 +6282,19 @@ JS_GetTypeInferenceObjectStats(void *object_, TypeInferenceMemoryStats *stats, J
|
|||
|
||||
if (object->newScript) {
|
||||
/* The initializerList is tacked onto the end of the TypeNewScript. */
|
||||
size_t usable = usf(object->newScript);
|
||||
if (usable) {
|
||||
stats->objects += usable;
|
||||
} else {
|
||||
stats->objects += sizeof(TypeNewScript);
|
||||
for (TypeNewScript::Initializer *init = object->newScript->initializerList; ; init++) {
|
||||
stats->objects += sizeof(TypeNewScript::Initializer);
|
||||
if (init->kind == TypeNewScript::Initializer::DONE)
|
||||
break;
|
||||
}
|
||||
size_t computedSize = sizeof(TypeNewScript);
|
||||
for (TypeNewScript::Initializer *init = object->newScript->initializerList; ; init++) {
|
||||
computedSize += sizeof(TypeNewScript::Initializer);
|
||||
if (init->kind == TypeNewScript::Initializer::DONE)
|
||||
break;
|
||||
}
|
||||
stats->objects += mallocSizeOf(object->newScript, computedSize);
|
||||
}
|
||||
|
||||
if (object->emptyShapes) {
|
||||
size_t usable = usf(object->emptyShapes);
|
||||
stats->emptyShapes +=
|
||||
usable ? usable : sizeof(EmptyShape*) * gc::FINALIZE_OBJECT_LIMIT;
|
||||
mallocSizeOf(object->emptyShapes,
|
||||
sizeof(EmptyShape*) * gc::FINALIZE_OBJECT_LIMIT);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -2382,38 +2382,6 @@ END_CASE(JSOP_PICK)
|
|||
} \
|
||||
JS_END_MACRO
|
||||
|
||||
/*
|
||||
* Skip the JSOP_POP typically found after a JSOP_SET* opcode, where oplen is
|
||||
* the constant length of the SET opcode sequence, and spdec is the constant
|
||||
* by which to decrease the stack pointer to pop all of the SET op's operands.
|
||||
*
|
||||
* NB: unlike macros that could conceivably be replaced by functions (ignoring
|
||||
* goto error), where a call should not have to be braced in order to expand
|
||||
* correctly (e.g., in if (cond) FOO(); else BAR()), these three macros lack
|
||||
* JS_{BEGIN,END}_MACRO brackets. They are also indented so as to align with
|
||||
* nearby opcode code.
|
||||
*/
|
||||
#define SKIP_POP_AFTER_SET(oplen,spdec) \
|
||||
if (regs.pc[oplen] == JSOP_POP) { \
|
||||
regs.sp -= spdec; \
|
||||
regs.pc += oplen + JSOP_POP_LENGTH; \
|
||||
op = (JSOp) *regs.pc; \
|
||||
DO_OP(); \
|
||||
}
|
||||
|
||||
#define END_SET_CASE(OP) \
|
||||
SKIP_POP_AFTER_SET(OP##_LENGTH, 1); \
|
||||
END_CASE(OP)
|
||||
|
||||
#define END_SET_CASE_STORE_RVAL(OP,spdec) \
|
||||
SKIP_POP_AFTER_SET(OP##_LENGTH, spdec); \
|
||||
{ \
|
||||
Value *newsp = regs.sp - ((spdec) - 1); \
|
||||
newsp[-1] = regs.sp[-1]; \
|
||||
regs.sp = newsp; \
|
||||
} \
|
||||
END_CASE(OP)
|
||||
|
||||
BEGIN_CASE(JSOP_SETCONST)
|
||||
{
|
||||
JSAtom *atom;
|
||||
|
@ -2426,7 +2394,7 @@ BEGIN_CASE(JSOP_SETCONST)
|
|||
goto error;
|
||||
}
|
||||
}
|
||||
END_SET_CASE(JSOP_SETCONST);
|
||||
END_CASE(JSOP_SETCONST);
|
||||
|
||||
#if JS_HAS_DESTRUCTURING
|
||||
BEGIN_CASE(JSOP_ENUMCONSTELEM)
|
||||
|
@ -2935,17 +2903,23 @@ END_CASE(JSOP_DELELEM)
|
|||
BEGIN_CASE(JSOP_TOID)
|
||||
{
|
||||
/*
|
||||
* Increment or decrement requires use to lookup the same property twice, but we need to avoid
|
||||
* the oberservable stringification the second time.
|
||||
* There must be an object value below the id, which will not be popped
|
||||
* but is necessary in interning the id for XML.
|
||||
*/
|
||||
JSObject *obj;
|
||||
FETCH_OBJECT(cx, -2, obj);
|
||||
|
||||
jsid id;
|
||||
FETCH_ELEMENT_ID(obj, -1, id);
|
||||
|
||||
if (!regs.sp[-1].isInt32())
|
||||
|
||||
Value &idval = regs.sp[-1];
|
||||
if (!idval.isInt32()) {
|
||||
JSObject *obj;
|
||||
FETCH_OBJECT(cx, -2, obj);
|
||||
|
||||
jsid dummy;
|
||||
if (!js_InternNonIntElementId(cx, obj, idval, &dummy, &idval))
|
||||
goto error;
|
||||
|
||||
TypeScript::MonitorUnknown(cx, script, regs.pc);
|
||||
}
|
||||
}
|
||||
END_CASE(JSOP_TOID)
|
||||
|
||||
|
@ -3176,7 +3150,6 @@ BEGIN_CASE(JSOP_LOCALINC)
|
|||
if (JS_LIKELY(vp->isInt32() && CanIncDecWithoutOverflow(tmp = vp->toInt32()))) {
|
||||
vp->getInt32Ref() = tmp + incr;
|
||||
JS_ASSERT(JSOP_INCARG_LENGTH == js_CodeSpec[op].length);
|
||||
SKIP_POP_AFTER_SET(JSOP_INCARG_LENGTH, 0);
|
||||
PUSH_INT32(tmp + incr2);
|
||||
} else {
|
||||
PUSH_COPY(*vp);
|
||||
|
@ -3549,8 +3522,11 @@ BEGIN_CASE(JSOP_SETMETHOD)
|
|||
goto error;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
regs.sp[-2] = regs.sp[-1];
|
||||
regs.sp--;
|
||||
}
|
||||
END_SET_CASE_STORE_RVAL(JSOP_SETPROP, 2);
|
||||
END_CASE(JSOP_SETPROP)
|
||||
|
||||
BEGIN_CASE(JSOP_GETELEM)
|
||||
{
|
||||
|
@ -3695,9 +3671,11 @@ BEGIN_CASE(JSOP_SETELEM)
|
|||
rval = regs.sp[-1];
|
||||
if (!obj->setGeneric(cx, id, &rval, script->strictModeCode))
|
||||
goto error;
|
||||
end_setelem:;
|
||||
end_setelem:
|
||||
regs.sp[-3] = regs.sp[-1];
|
||||
regs.sp -= 2;
|
||||
}
|
||||
END_SET_CASE_STORE_RVAL(JSOP_SETELEM, 3)
|
||||
END_CASE(JSOP_SETELEM)
|
||||
|
||||
BEGIN_CASE(JSOP_ENUMELEM)
|
||||
{
|
||||
|
@ -4213,7 +4191,7 @@ BEGIN_CASE(JSOP_SETARG)
|
|||
JS_ASSERT(slot < regs.fp()->numFormalArgs());
|
||||
argv[slot] = regs.sp[-1];
|
||||
}
|
||||
END_SET_CASE(JSOP_SETARG)
|
||||
END_CASE(JSOP_SETARG)
|
||||
|
||||
BEGIN_CASE(JSOP_GETLOCAL)
|
||||
{
|
||||
|
@ -4249,7 +4227,7 @@ BEGIN_CASE(JSOP_SETLOCAL)
|
|||
JS_ASSERT(slot < script->nslots);
|
||||
regs.fp()->slots()[slot] = regs.sp[-1];
|
||||
}
|
||||
END_SET_CASE(JSOP_SETLOCAL)
|
||||
END_CASE(JSOP_SETLOCAL)
|
||||
|
||||
BEGIN_CASE(JSOP_GETFCSLOT)
|
||||
BEGIN_CASE(JSOP_CALLFCSLOT)
|
||||
|
|
|
@ -2708,12 +2708,11 @@ obj_preventExtensions(JSContext *cx, uintN argc, Value *vp)
|
|||
}
|
||||
|
||||
size_t
|
||||
JSObject::sizeOfSlotsArray(JSUsableSizeFun usf)
|
||||
JSObject::sizeOfSlotsArray(JSMallocSizeOfFun mallocSizeOf)
|
||||
{
|
||||
if (!hasSlotsArray())
|
||||
return 0;
|
||||
size_t usable = usf((void *)slots);
|
||||
return usable ? usable : numSlots() * sizeof(js::Value);
|
||||
return mallocSizeOf(slots, numDynamicSlots(numSlots()) * sizeof(js::Value));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -4559,10 +4558,16 @@ JSObject::shrinkSlots(JSContext *cx, size_t newcap)
|
|||
}
|
||||
|
||||
uint32 fill = newcap;
|
||||
newcap = Max(newcap, size_t(SLOT_CAPACITY_MIN));
|
||||
newcap = Max(newcap, numFixedSlots());
|
||||
if (isDenseArray()) {
|
||||
newcap = Max(newcap, size_t(SLOT_CAPACITY_MIN));
|
||||
newcap = Max(newcap, numFixedSlots());
|
||||
} else {
|
||||
newcap = Max(newcap, numFixedSlots() + SLOT_CAPACITY_MIN);
|
||||
}
|
||||
|
||||
HeapValue *tmpslots = (HeapValue*) cx->realloc_(slots, newcap * sizeof(HeapValue));
|
||||
uint32 allocCount = numDynamicSlots(newcap);
|
||||
|
||||
HeapValue *tmpslots = (HeapValue*) cx->realloc_(slots, allocCount * sizeof(Value));
|
||||
if (!tmpslots)
|
||||
return; /* Leave slots at its old size. */
|
||||
|
||||
|
|
|
@ -486,7 +486,7 @@ struct JSObject : js::gc::Cell {
|
|||
|
||||
jsuword &initializedLength() { return *newType.unsafeGetUnioned(); }
|
||||
|
||||
JS_FRIEND_API(size_t) sizeOfSlotsArray(JSUsableSizeFun usf);
|
||||
JS_FRIEND_API(size_t) sizeOfSlotsArray(JSMallocSizeOfFun mallocSizeOf);
|
||||
|
||||
js::HeapPtrObject parent; /* object's parent */
|
||||
void *privateData; /* private data */
|
||||
|
|
|
@ -257,9 +257,9 @@ struct PropertyTable {
|
|||
* This counts the PropertyTable object itself (which must be
|
||||
* heap-allocated) and its |entries| array.
|
||||
*/
|
||||
size_t sizeOf(JSUsableSizeFun usf) const {
|
||||
size_t usable = usf((void*)this) + usf(entries);
|
||||
return usable ? usable : sizeOfEntries(capacity()) + sizeof(PropertyTable);
|
||||
size_t sizeOfIncludingThis(JSMallocSizeOfFun mallocSizeOf) const {
|
||||
return mallocSizeOf(this, sizeof(PropertyTable)) +
|
||||
mallocSizeOf(entries, sizeOfEntries(capacity()));
|
||||
}
|
||||
|
||||
/* Whether we need to grow. We want to do this if the load factor is >= 0.75 */
|
||||
|
@ -449,15 +449,14 @@ struct Shape : public js::gc::Cell
|
|||
return table;
|
||||
}
|
||||
|
||||
size_t sizeOfPropertyTable(JSUsableSizeFun usf) const {
|
||||
return hasTable() ? getTable()->sizeOf(usf) : 0;
|
||||
size_t sizeOfPropertyTableIncludingThis(JSMallocSizeOfFun mallocSizeOf) const {
|
||||
return hasTable() ? getTable()->sizeOfIncludingThis(mallocSizeOf) : 0;
|
||||
}
|
||||
|
||||
size_t sizeOfKids(JSUsableSizeFun usf) const {
|
||||
/* Nb: |countMe| is true because the kids HashTable is on the heap. */
|
||||
size_t sizeOfKidsIncludingThis(JSMallocSizeOfFun mallocSizeOf) const {
|
||||
JS_ASSERT(!inDictionary());
|
||||
return kids.isHash()
|
||||
? kids.toHash()->sizeOf(usf, /* countMe */true)
|
||||
? kids.toHash()->sizeOfIncludingThis(mallocSizeOf)
|
||||
: 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1273,15 +1273,14 @@ JSScript::dataSize()
|
|||
}
|
||||
|
||||
size_t
|
||||
JSScript::dataSize(JSUsableSizeFun usf)
|
||||
JSScript::dataSize(JSMallocSizeOfFun mallocSizeOf)
|
||||
{
|
||||
#if JS_SCRIPT_INLINE_DATA_LIMIT
|
||||
if (data == inlineData)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
size_t usable = usf(data);
|
||||
return usable ? usable : dataSize();
|
||||
return mallocSizeOf(data, dataSize());
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -660,7 +660,7 @@ struct JSScript : public js::gc::Cell {
|
|||
}
|
||||
|
||||
/* Size of the JITScript and all sections. (This method is implemented in MethodJIT.h.) */
|
||||
JS_FRIEND_API(size_t) jitDataSize(JSUsableSizeFun usf);
|
||||
JS_FRIEND_API(size_t) jitDataSize(JSMallocSizeOfFun mallocSizeOf);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -682,9 +682,9 @@ struct JSScript : public js::gc::Cell {
|
|||
* second is the size of the block allocated to hold all the data sections
|
||||
* (which can be larger than the in-use size).
|
||||
*/
|
||||
JS_FRIEND_API(size_t) dataSize(); /* Size of all data sections */
|
||||
JS_FRIEND_API(size_t) dataSize(JSUsableSizeFun usf); /* Size of all data sections */
|
||||
uint32 numNotes(); /* Number of srcnote slots in the srcnotes section */
|
||||
JS_FRIEND_API(size_t) dataSize(); /* Size of all data sections */
|
||||
JS_FRIEND_API(size_t) dataSize(JSMallocSizeOfFun mallocSizeOf); /* Size of all data sections */
|
||||
uint32 numNotes(); /* Number of srcnote slots in the srcnotes section */
|
||||
|
||||
/* Script notes are allocated right after the code. */
|
||||
jssrcnote *notes() { return (jssrcnote *)(code + length); }
|
||||
|
|
|
@ -1302,22 +1302,21 @@ mjit::JITScript::~JITScript()
|
|||
}
|
||||
|
||||
size_t
|
||||
JSScript::jitDataSize(JSUsableSizeFun usf)
|
||||
JSScript::jitDataSize(JSMallocSizeOfFun mallocSizeOf)
|
||||
{
|
||||
size_t n = 0;
|
||||
if (jitNormal)
|
||||
n += jitNormal->scriptDataSize(usf);
|
||||
n += jitNormal->scriptDataSize(mallocSizeOf);
|
||||
if (jitCtor)
|
||||
n += jitCtor->scriptDataSize(usf);
|
||||
n += jitCtor->scriptDataSize(mallocSizeOf);
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Please keep in sync with Compiler::finishThisUp! */
|
||||
size_t
|
||||
mjit::JITScript::scriptDataSize(JSUsableSizeFun usf)
|
||||
mjit::JITScript::scriptDataSize(JSMallocSizeOfFun mallocSizeOf)
|
||||
{
|
||||
size_t usable = usf ? usf(this) : 0;
|
||||
return usable ? usable :
|
||||
size_t computedSize =
|
||||
sizeof(JITScript) +
|
||||
sizeof(NativeMapEntry) * nNmapPairs +
|
||||
sizeof(InlineFrame) * nInlineFrames +
|
||||
|
@ -1334,6 +1333,8 @@ mjit::JITScript::scriptDataSize(JSUsableSizeFun usf)
|
|||
sizeof(ic::SetElementIC) * nSetElems +
|
||||
#endif
|
||||
0;
|
||||
/* |mallocSizeOf| can be null here. */
|
||||
return mallocSizeOf ? mallocSizeOf(this, computedSize) : computedSize;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -682,8 +682,8 @@ struct JITScript {
|
|||
|
||||
void nukeScriptDependentICs();
|
||||
|
||||
/* |usf| can be NULL here, in which case the fallback size computation will be used. */
|
||||
size_t scriptDataSize(JSUsableSizeFun usf);
|
||||
/* |mallocSizeOf| can be NULL here, in which case the fallback size computation will be used. */
|
||||
size_t scriptDataSize(JSMallocSizeOfFun mallocSizeOf);
|
||||
|
||||
jsbytecode *nativeToPC(void *returnAddress, CallSite **pinline) const;
|
||||
|
||||
|
|
|
@ -3829,9 +3829,9 @@ MJitCodeStats(JSContext *cx, uintN argc, jsval *vp)
|
|||
#ifdef JS_METHODJIT
|
||||
|
||||
static size_t
|
||||
zero_usable_size(void *p)
|
||||
computedSize(const void *p, size_t size)
|
||||
{
|
||||
return 0;
|
||||
return size;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -3842,10 +3842,10 @@ SumJitDataSizeCallback(JSContext *cx, void *data, void *thing,
|
|||
JS_ASSERT(traceKind == JSTRACE_SCRIPT);
|
||||
JSScript *script = static_cast<JSScript *>(thing);
|
||||
/*
|
||||
* Passing in zero_usable_size causes jitDataSize to fall back to its
|
||||
* Passing in |computedSize| causes jitDataSize to fall back to its
|
||||
* secondary size computation.
|
||||
*/
|
||||
*sump += script->jitDataSize(zero_usable_size);
|
||||
*sump += script->jitDataSize(computedSize);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -87,7 +87,7 @@ JSLinearString::mark(JSTracer *)
|
|||
}
|
||||
|
||||
size_t
|
||||
JSString::charsHeapSize(JSUsableSizeFun usf)
|
||||
JSString::charsHeapSize(JSMallocSizeOfFun mallocSizeOf)
|
||||
{
|
||||
/* JSRope: do nothing, we'll count all children chars when we hit the leaf strings. */
|
||||
if (isRope())
|
||||
|
@ -104,8 +104,7 @@ JSString::charsHeapSize(JSUsableSizeFun usf)
|
|||
/* JSExtensibleString: count the full capacity, not just the used space. */
|
||||
if (isExtensible()) {
|
||||
JSExtensibleString &extensible = asExtensible();
|
||||
size_t usable = usf((void *)extensible.chars());
|
||||
return usable ? usable : asExtensible().capacity() * sizeof(jschar);
|
||||
return mallocSizeOf(extensible.chars(), asExtensible().capacity() * sizeof(jschar));
|
||||
}
|
||||
|
||||
JS_ASSERT(isFixed());
|
||||
|
@ -118,10 +117,9 @@ JSString::charsHeapSize(JSUsableSizeFun usf)
|
|||
if (isInline())
|
||||
return 0;
|
||||
|
||||
/* JSAtom, JSFixedString: count the chars. */
|
||||
/* JSAtom, JSFixedString: count the chars. +1 for the null char. */
|
||||
JSFixedString &fixed = asFixed();
|
||||
size_t usable = usf((void *)fixed.chars());
|
||||
return usable ? usable : length() * sizeof(jschar);
|
||||
return mallocSizeOf(fixed.chars(), (length() + 1) * sizeof(jschar));
|
||||
}
|
||||
|
||||
static JS_ALWAYS_INLINE bool
|
||||
|
|
|
@ -407,7 +407,7 @@ class JSString : public js::gc::Cell
|
|||
|
||||
/* Gets the number of bytes that the chars take on the heap. */
|
||||
|
||||
JS_FRIEND_API(size_t) charsHeapSize(JSUsableSizeFun usf);
|
||||
JS_FRIEND_API(size_t) charsHeapSize(JSMallocSizeOfFun mallocSizeOf);
|
||||
|
||||
/* Offsets for direct field from jit code. */
|
||||
|
||||
|
|
|
@ -1046,39 +1046,10 @@ public:
|
|||
return JSRegExpErrorNoMatch;
|
||||
}
|
||||
|
||||
void lookupForBeginChars()
|
||||
{
|
||||
int character;
|
||||
bool firstSingleCharFound;
|
||||
|
||||
while (true) {
|
||||
if (input.isNotAvailableInput(2))
|
||||
return;
|
||||
|
||||
firstSingleCharFound = false;
|
||||
|
||||
character = input.readPair();
|
||||
|
||||
for (unsigned i = 0; i < pattern->m_beginChars.size(); ++i) {
|
||||
BeginChar bc = pattern->m_beginChars[i];
|
||||
|
||||
if (!firstSingleCharFound && bc.value <= 0xFFFF) {
|
||||
firstSingleCharFound = true;
|
||||
character &= 0xFFFF;
|
||||
}
|
||||
|
||||
if ((character | bc.mask) == bc.value)
|
||||
return;
|
||||
}
|
||||
|
||||
input.next();
|
||||
}
|
||||
}
|
||||
|
||||
#define MATCH_NEXT() { ++context->term; goto matchAgain; }
|
||||
#define BACKTRACK() { --context->term; goto backtrack; }
|
||||
#define currentTerm() (disjunction->terms[context->term])
|
||||
JSRegExpResult matchDisjunction(ByteDisjunction* disjunction, DisjunctionContext* context, bool btrack = false, bool isBody = false)
|
||||
JSRegExpResult matchDisjunction(ByteDisjunction* disjunction, DisjunctionContext* context, bool btrack = false)
|
||||
{
|
||||
if (!--remainingMatchCount)
|
||||
return JSRegExpErrorHitLimit;
|
||||
|
@ -1086,9 +1057,6 @@ public:
|
|||
if (btrack)
|
||||
BACKTRACK();
|
||||
|
||||
if (pattern->m_containsBeginChars && isBody)
|
||||
lookupForBeginChars();
|
||||
|
||||
context->matchBegin = input.getPos();
|
||||
context->term = 0;
|
||||
|
||||
|
@ -1266,9 +1234,6 @@ public:
|
|||
|
||||
input.next();
|
||||
|
||||
if (pattern->m_containsBeginChars && isBody)
|
||||
lookupForBeginChars();
|
||||
|
||||
context->matchBegin = input.getPos();
|
||||
|
||||
if (currentTerm().alternative.onceThrough)
|
||||
|
@ -1397,7 +1362,7 @@ public:
|
|||
|
||||
DisjunctionContext* context = allocDisjunctionContext(pattern->m_body.get());
|
||||
|
||||
JSRegExpResult result = matchDisjunction(pattern->m_body.get(), context, false, true);
|
||||
JSRegExpResult result = matchDisjunction(pattern->m_body.get(), context, false);
|
||||
if (result == JSRegExpMatch) {
|
||||
output[0] = context->matchBegin;
|
||||
output[1] = context->matchEnd;
|
||||
|
|
|
@ -335,7 +335,6 @@ public:
|
|||
: m_body(body)
|
||||
, m_ignoreCase(pattern.m_ignoreCase)
|
||||
, m_multiline(pattern.m_multiline)
|
||||
, m_containsBeginChars(pattern.m_containsBeginChars)
|
||||
, m_allocator(allocator)
|
||||
{
|
||||
newlineCharacterClass = pattern.newlineCharacterClass();
|
||||
|
@ -347,8 +346,6 @@ public:
|
|||
// array, so that it won't delete them on destruction. We'll
|
||||
// take responsibility for that.
|
||||
pattern.m_userCharacterClasses.clear();
|
||||
|
||||
m_beginChars.append(pattern.m_beginChars);
|
||||
}
|
||||
|
||||
~BytecodePattern()
|
||||
|
@ -360,7 +357,6 @@ public:
|
|||
OwnPtr<ByteDisjunction> m_body;
|
||||
bool m_ignoreCase;
|
||||
bool m_multiline;
|
||||
bool m_containsBeginChars;
|
||||
// Each BytecodePattern is associated with a RegExp, each RegExp is associated
|
||||
// with a JSGlobalData. Cache a pointer to out JSGlobalData's m_regExpAllocator.
|
||||
BumpPointerAllocator* m_allocator;
|
||||
|
@ -368,8 +364,6 @@ public:
|
|||
CharacterClass* newlineCharacterClass;
|
||||
CharacterClass* wordcharCharacterClass;
|
||||
|
||||
Vector<BeginChar> m_beginChars;
|
||||
|
||||
private:
|
||||
Vector<ByteDisjunction*> m_allParenthesesInfo;
|
||||
Vector<CharacterClass*> m_userCharacterClasses;
|
||||
|
|
|
@ -242,117 +242,11 @@ private:
|
|||
Vector<CharacterRange> m_rangesUnicode;
|
||||
};
|
||||
|
||||
struct BeginCharHelper {
|
||||
BeginCharHelper(Vector<BeginChar>* beginChars, bool isCaseInsensitive = false)
|
||||
: m_beginChars(beginChars)
|
||||
, m_isCaseInsensitive(isCaseInsensitive)
|
||||
{}
|
||||
|
||||
void addBeginChar(BeginChar beginChar, Vector<TermChain>* hotTerms, QuantifierType quantityType, unsigned quantityCount)
|
||||
{
|
||||
if (quantityType == QuantifierFixedCount && quantityCount > 1) {
|
||||
// We duplicate the first found character if the quantity of the term is more than one. eg.: /a{3}/
|
||||
beginChar.value |= beginChar.value << 16;
|
||||
beginChar.mask |= beginChar.mask << 16;
|
||||
addCharacter(beginChar);
|
||||
} else if (quantityType == QuantifierFixedCount && quantityCount == 1 && hotTerms->size())
|
||||
// In case of characters with fixed quantifier we should check the next character as well.
|
||||
linkHotTerms(beginChar, hotTerms);
|
||||
else
|
||||
// In case of greedy matching the next character checking is unnecessary therefore we just store
|
||||
// the first character.
|
||||
addCharacter(beginChar);
|
||||
}
|
||||
|
||||
// Merge two following BeginChars in the vector to reduce the number of character checks.
|
||||
void merge(unsigned size)
|
||||
{
|
||||
for (unsigned i = 0; i < size; i++) {
|
||||
BeginChar* curr = &m_beginChars->at(i);
|
||||
BeginChar* next = &m_beginChars->at(i + 1);
|
||||
|
||||
// If the current and the next size of value is different we should skip the merge process
|
||||
// because the 16bit and 32bit values are unmergable.
|
||||
if (curr->value <= 0xFFFF && next->value > 0xFFFF)
|
||||
continue;
|
||||
|
||||
unsigned diff = curr->value ^ next->value;
|
||||
|
||||
curr->mask |= diff;
|
||||
curr->value |= curr->mask;
|
||||
|
||||
m_beginChars->remove(i + 1);
|
||||
size--;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void addCharacter(BeginChar beginChar)
|
||||
{
|
||||
unsigned pos = 0;
|
||||
unsigned range = m_beginChars->size();
|
||||
|
||||
// binary chop, find position to insert char.
|
||||
while (range) {
|
||||
unsigned index = range >> 1;
|
||||
|
||||
int val = m_beginChars->at(pos+index).value - beginChar.value;
|
||||
if (!val)
|
||||
return;
|
||||
if (val < 0)
|
||||
range = index;
|
||||
else {
|
||||
pos += (index+1);
|
||||
range -= (index+1);
|
||||
}
|
||||
}
|
||||
|
||||
if (pos == m_beginChars->size())
|
||||
m_beginChars->append(beginChar);
|
||||
else
|
||||
m_beginChars->insert(pos, beginChar);
|
||||
}
|
||||
|
||||
// Create BeginChar objects by appending each terms from a hotTerms vector to an existing BeginChar object.
|
||||
void linkHotTerms(BeginChar beginChar, Vector<TermChain>* hotTerms)
|
||||
{
|
||||
for (unsigned i = 0; i < hotTerms->size(); i++) {
|
||||
PatternTerm hotTerm = hotTerms->at(i).term;
|
||||
ASSERT(hotTerm.type == PatternTerm::TypePatternCharacter);
|
||||
|
||||
UChar characterNext = hotTerm.patternCharacter;
|
||||
|
||||
// Append a character to an existing BeginChar object.
|
||||
if (characterNext <= 0x7f) {
|
||||
unsigned mask = 0;
|
||||
|
||||
if (m_isCaseInsensitive && isASCIIAlpha(characterNext)) {
|
||||
mask = 32;
|
||||
characterNext = toASCIILower(characterNext);
|
||||
}
|
||||
|
||||
addCharacter(BeginChar(beginChar.value | (characterNext << 16), beginChar.mask | (mask << 16)));
|
||||
} else {
|
||||
UChar upper, lower;
|
||||
if (m_isCaseInsensitive && ((upper = Unicode::toUpper(characterNext)) != (lower = Unicode::toLower(characterNext)))) {
|
||||
addCharacter(BeginChar(beginChar.value | (upper << 16), beginChar.mask));
|
||||
addCharacter(BeginChar(beginChar.value | (lower << 16), beginChar.mask));
|
||||
} else
|
||||
addCharacter(BeginChar(beginChar.value | (characterNext << 16), beginChar.mask));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector<BeginChar>* m_beginChars;
|
||||
bool m_isCaseInsensitive;
|
||||
};
|
||||
|
||||
class YarrPatternConstructor {
|
||||
public:
|
||||
YarrPatternConstructor(YarrPattern& pattern)
|
||||
: m_pattern(pattern)
|
||||
, m_characterClassConstructor(pattern.m_ignoreCase)
|
||||
, m_beginCharHelper(&pattern.m_beginChars, pattern.m_ignoreCase)
|
||||
, m_invertParentheticalAssertion(false)
|
||||
{
|
||||
m_pattern.m_body = js::OffTheBooks::new_<PatternDisjunction>();
|
||||
|
@ -789,144 +683,10 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// This function collects the terms which are potentially matching the first number of depth characters in the result.
|
||||
// If this function returns false then it found at least one term which makes the beginning character
|
||||
// look-up optimization inefficient.
|
||||
bool setupDisjunctionBeginTerms(PatternDisjunction* disjunction, Vector<TermChain>* beginTerms, unsigned depth)
|
||||
{
|
||||
for (unsigned alt = 0; alt < disjunction->m_alternatives.size(); ++alt) {
|
||||
PatternAlternative* alternative = disjunction->m_alternatives[alt];
|
||||
|
||||
if (!setupAlternativeBeginTerms(alternative, beginTerms, 0, depth))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool setupAlternativeBeginTerms(PatternAlternative* alternative, Vector<TermChain>* beginTerms, unsigned termIndex, unsigned depth)
|
||||
{
|
||||
bool checkNext = true;
|
||||
unsigned numTerms = alternative->m_terms.size();
|
||||
|
||||
while (checkNext && termIndex < numTerms) {
|
||||
PatternTerm term = alternative->m_terms[termIndex];
|
||||
checkNext = false;
|
||||
|
||||
switch (term.type) {
|
||||
case PatternTerm::TypeAssertionBOL:
|
||||
case PatternTerm::TypeAssertionEOL:
|
||||
case PatternTerm::TypeAssertionWordBoundary:
|
||||
return false;
|
||||
|
||||
case PatternTerm::TypeBackReference:
|
||||
case PatternTerm::TypeForwardReference:
|
||||
return false;
|
||||
|
||||
case PatternTerm::TypePatternCharacter:
|
||||
if (termIndex != numTerms - 1) {
|
||||
beginTerms->append(TermChain(term));
|
||||
termIndex++;
|
||||
checkNext = true;
|
||||
} else if (term.quantityType == QuantifierFixedCount) {
|
||||
beginTerms->append(TermChain(term));
|
||||
if (depth < 2 && termIndex < numTerms - 1 && term.quantityCount == 1)
|
||||
if (!setupAlternativeBeginTerms(alternative, &beginTerms->last().hotTerms, termIndex + 1, depth + 1))
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PatternTerm::TypeCharacterClass:
|
||||
return false;
|
||||
|
||||
case PatternTerm::TypeParentheticalAssertion:
|
||||
if (term.invert())
|
||||
return false;
|
||||
|
||||
case PatternTerm::TypeParenthesesSubpattern:
|
||||
if (term.quantityType != QuantifierFixedCount) {
|
||||
if (termIndex == numTerms - 1)
|
||||
break;
|
||||
|
||||
termIndex++;
|
||||
checkNext = true;
|
||||
}
|
||||
|
||||
if (!setupDisjunctionBeginTerms(term.parentheses.disjunction, beginTerms, depth))
|
||||
return false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void setupBeginChars()
|
||||
{
|
||||
Vector<TermChain> beginTerms;
|
||||
bool containsFixedCharacter = false;
|
||||
|
||||
if ((!m_pattern.m_body->m_hasFixedSize || m_pattern.m_body->m_alternatives.size() > 1)
|
||||
&& setupDisjunctionBeginTerms(m_pattern.m_body, &beginTerms, 0)) {
|
||||
unsigned size = beginTerms.size();
|
||||
|
||||
// If we haven't collected any terms we should abort the preparation of beginning character look-up optimization.
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
m_pattern.m_containsBeginChars = true;
|
||||
|
||||
for (unsigned i = 0; i < size; i++) {
|
||||
PatternTerm term = beginTerms[i].term;
|
||||
|
||||
// We have just collected PatternCharacter terms, other terms are not allowed.
|
||||
ASSERT(term.type == PatternTerm::TypePatternCharacter);
|
||||
|
||||
if (term.quantityType == QuantifierFixedCount)
|
||||
containsFixedCharacter = true;
|
||||
|
||||
UChar character = term.patternCharacter;
|
||||
unsigned mask = 0;
|
||||
|
||||
if (character <= 0x7f) {
|
||||
if (m_pattern.m_ignoreCase && isASCIIAlpha(character)) {
|
||||
mask = 32;
|
||||
character = toASCIILower(character);
|
||||
}
|
||||
|
||||
m_beginCharHelper.addBeginChar(BeginChar(character, mask), &beginTerms[i].hotTerms, term.quantityType, term.quantityCount);
|
||||
} else {
|
||||
UChar upper, lower;
|
||||
if (m_pattern.m_ignoreCase && ((upper = Unicode::toUpper(character)) != (lower = Unicode::toLower(character)))) {
|
||||
m_beginCharHelper.addBeginChar(BeginChar(upper, mask), &beginTerms[i].hotTerms, term.quantityType, term.quantityCount);
|
||||
m_beginCharHelper.addBeginChar(BeginChar(lower, mask), &beginTerms[i].hotTerms, term.quantityType, term.quantityCount);
|
||||
} else
|
||||
m_beginCharHelper.addBeginChar(BeginChar(character, mask), &beginTerms[i].hotTerms, term.quantityType, term.quantityCount);
|
||||
}
|
||||
}
|
||||
|
||||
// If the pattern doesn't contain terms with fixed quantifiers then the beginning character look-up optimization is inefficient.
|
||||
if (!containsFixedCharacter) {
|
||||
m_pattern.m_containsBeginChars = false;
|
||||
return;
|
||||
}
|
||||
|
||||
size = m_pattern.m_beginChars.size();
|
||||
|
||||
if (size > 2)
|
||||
m_beginCharHelper.merge(size - 1);
|
||||
else if (size <= 1)
|
||||
m_pattern.m_containsBeginChars = false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
YarrPattern& m_pattern;
|
||||
PatternAlternative* m_alternative;
|
||||
CharacterClassConstructor m_characterClassConstructor;
|
||||
BeginCharHelper m_beginCharHelper;
|
||||
bool m_invertCharacterClass;
|
||||
bool m_invertParentheticalAssertion;
|
||||
};
|
||||
|
@ -959,7 +719,6 @@ ErrorCode YarrPattern::compile(const UString& patternString)
|
|||
constructor.optimizeBOL();
|
||||
|
||||
constructor.setupOffsets();
|
||||
constructor.setupBeginChars();
|
||||
|
||||
return NoError;
|
||||
}
|
||||
|
@ -968,7 +727,6 @@ YarrPattern::YarrPattern(const UString& pattern, bool ignoreCase, bool multiline
|
|||
: m_ignoreCase(ignoreCase)
|
||||
, m_multiline(multiline)
|
||||
, m_containsBackreferences(false)
|
||||
, m_containsBeginChars(false)
|
||||
, m_containsBOL(false)
|
||||
, m_numSubpatterns(0)
|
||||
, m_maxBackReference(0)
|
||||
|
|
|
@ -332,21 +332,6 @@ struct TermChain {
|
|||
Vector<TermChain> hotTerms;
|
||||
};
|
||||
|
||||
struct BeginChar {
|
||||
BeginChar()
|
||||
: value(0)
|
||||
, mask(0)
|
||||
{}
|
||||
|
||||
BeginChar(unsigned value, unsigned mask)
|
||||
: value(value)
|
||||
, mask(mask)
|
||||
{}
|
||||
|
||||
unsigned value;
|
||||
unsigned mask;
|
||||
};
|
||||
|
||||
struct YarrPattern {
|
||||
YarrPattern(const UString& pattern, bool ignoreCase, bool multiline, ErrorCode* error);
|
||||
|
||||
|
@ -362,7 +347,6 @@ struct YarrPattern {
|
|||
m_maxBackReference = 0;
|
||||
|
||||
m_containsBackreferences = false;
|
||||
m_containsBeginChars = false;
|
||||
m_containsBOL = false;
|
||||
|
||||
newlineCached = 0;
|
||||
|
@ -377,7 +361,6 @@ struct YarrPattern {
|
|||
m_disjunctions.clear();
|
||||
deleteAllValues(m_userCharacterClasses);
|
||||
m_userCharacterClasses.clear();
|
||||
m_beginChars.clear();
|
||||
}
|
||||
|
||||
bool containsIllegalBackReference()
|
||||
|
@ -431,14 +414,12 @@ struct YarrPattern {
|
|||
bool m_ignoreCase : 1;
|
||||
bool m_multiline : 1;
|
||||
bool m_containsBackreferences : 1;
|
||||
bool m_containsBeginChars : 1;
|
||||
bool m_containsBOL : 1;
|
||||
unsigned m_numSubpatterns;
|
||||
unsigned m_maxBackReference;
|
||||
PatternDisjunction* m_body;
|
||||
Vector<PatternDisjunction*, 4> m_disjunctions;
|
||||
Vector<CharacterClass*> m_userCharacterClasses;
|
||||
Vector<BeginChar> m_beginChars;
|
||||
|
||||
private:
|
||||
ErrorCode compile(const UString& patternString);
|
||||
|
|
|
@ -1233,7 +1233,7 @@ CompartmentCallback(JSContext *cx, void *vdata, JSCompartment *compartment)
|
|||
curr->mjitCodeUnused = unused;
|
||||
#endif
|
||||
JS_GetTypeInferenceMemoryStats(cx, compartment, &curr->typeInferenceMemory,
|
||||
moz_malloc_usable_size);
|
||||
MemoryReporterMallocSizeOf);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1278,14 +1278,14 @@ CellCallback(JSContext *cx, void *vdata, void *thing, JSGCTraceKind traceKind,
|
|||
} else {
|
||||
curr->gcHeapObjectsNonFunction += thingSize;
|
||||
}
|
||||
curr->objectSlots += obj->sizeOfSlotsArray(moz_malloc_usable_size);
|
||||
curr->objectSlots += obj->sizeOfSlotsArray(MemoryReporterMallocSizeOf);
|
||||
break;
|
||||
}
|
||||
case JSTRACE_STRING:
|
||||
{
|
||||
JSString *str = static_cast<JSString *>(thing);
|
||||
curr->gcHeapStrings += thingSize;
|
||||
curr->stringChars += str->charsHeapSize(moz_malloc_usable_size);
|
||||
curr->stringChars += str->charsHeapSize(MemoryReporterMallocSizeOf);
|
||||
break;
|
||||
}
|
||||
case JSTRACE_SHAPE:
|
||||
|
@ -1293,11 +1293,14 @@ CellCallback(JSContext *cx, void *vdata, void *thing, JSGCTraceKind traceKind,
|
|||
js::Shape *shape = static_cast<js::Shape *>(thing);
|
||||
if (shape->inDictionary()) {
|
||||
curr->gcHeapShapesDict += thingSize;
|
||||
curr->shapesExtraDictTables += shape->sizeOfPropertyTable(moz_malloc_usable_size);
|
||||
curr->shapesExtraDictTables +=
|
||||
shape->sizeOfPropertyTableIncludingThis(MemoryReporterMallocSizeOf);
|
||||
} else {
|
||||
curr->gcHeapShapesTree += thingSize;
|
||||
curr->shapesExtraTreeTables += shape->sizeOfPropertyTable(moz_malloc_usable_size);
|
||||
curr->shapesExtraTreeShapeKids += shape->sizeOfKids(moz_malloc_usable_size);
|
||||
curr->shapesExtraTreeTables +=
|
||||
shape->sizeOfPropertyTableIncludingThis(MemoryReporterMallocSizeOf);
|
||||
curr->shapesExtraTreeShapeKids +=
|
||||
shape->sizeOfKidsIncludingThis(MemoryReporterMallocSizeOf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1305,9 +1308,9 @@ CellCallback(JSContext *cx, void *vdata, void *thing, JSGCTraceKind traceKind,
|
|||
{
|
||||
JSScript *script = static_cast<JSScript *>(thing);
|
||||
curr->gcHeapScripts += thingSize;
|
||||
curr->scriptData += script->dataSize(moz_malloc_usable_size);
|
||||
curr->scriptData += script->dataSize(MemoryReporterMallocSizeOf);
|
||||
#ifdef JS_METHODJIT
|
||||
curr->mjitData += script->jitDataSize(moz_malloc_usable_size);
|
||||
curr->mjitData += script->jitDataSize(MemoryReporterMallocSizeOf);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
@ -1315,7 +1318,8 @@ CellCallback(JSContext *cx, void *vdata, void *thing, JSGCTraceKind traceKind,
|
|||
{
|
||||
js::types::TypeObject *obj = static_cast<js::types::TypeObject *>(thing);
|
||||
curr->gcHeapTypeObjects += thingSize;
|
||||
JS_GetTypeInferenceObjectStats(obj, &curr->typeInferenceMemory, moz_malloc_usable_size);
|
||||
JS_GetTypeInferenceObjectStats(obj, &curr->typeInferenceMemory,
|
||||
MemoryReporterMallocSizeOf);
|
||||
break;
|
||||
}
|
||||
case JSTRACE_XML:
|
||||
|
@ -1530,13 +1534,12 @@ CollectCompartmentStatsForRuntime(JSRuntime *rt, IterateData *data)
|
|||
for (js::ThreadDataIter i(rt); !i.empty(); i.popFront())
|
||||
data->stackSize += i.threadData()->stackSpace.committedSize();
|
||||
|
||||
size_t usable = moz_malloc_usable_size(rt);
|
||||
data->runtimeObjectSize = usable ? usable : sizeof(JSRuntime);
|
||||
data->runtimeObjectSize = MemoryReporterMallocSizeOf(rt, sizeof(JSRuntime));
|
||||
|
||||
// Nb: |countMe| is false because atomState.atoms is within JSRuntime,
|
||||
// and so counted when JSRuntime is counted.
|
||||
// Nb: we use sizeOfExcludingThis() because atomState.atoms is within
|
||||
// JSRuntime, and so counted when JSRuntime is counted.
|
||||
data->atomsTableSize =
|
||||
rt->atomState.atoms.sizeOf(moz_malloc_usable_size, /* countMe */false);
|
||||
rt->atomState.atoms.sizeOfExcludingThis(MemoryReporterMallocSizeOf);
|
||||
}
|
||||
|
||||
JS_DestroyContextNoGC(cx);
|
||||
|
|
|
@ -217,7 +217,19 @@ members = [
|
|||
# Quick stubs handle the shadowing the same as XPConnect.
|
||||
'nsIDOMHTMLCollection.length',
|
||||
'nsIDOMHTMLCommandElement.*',
|
||||
'nsIDOMHTMLDocument.*',
|
||||
'nsIDOMHTMLDocument.body',
|
||||
'nsIDOMHTMLDocument.getElementsByName',
|
||||
'nsIDOMHTMLDocument.anchors',
|
||||
'nsIDOMHTMLDocument.links',
|
||||
'nsIDOMHTMLDocument.URL',
|
||||
'nsIDOMHTMLDocument.forms',
|
||||
'nsIDOMHTMLDocument.cookie',
|
||||
'nsIDOMHTMLDocument.images',
|
||||
'nsIDOMHTMLDocument.write',
|
||||
'nsIDOMHTMLDocument.writeln',
|
||||
'nsIDOMHTMLDocument.domain',
|
||||
'nsIDOMHTMLDocument.getSelection',
|
||||
'nsIDOMHTMLDocument.designMode',
|
||||
'nsIDOMHTMLElement.*',
|
||||
'nsIDOMHTMLFormElement.elements',
|
||||
'nsIDOMHTMLFormElement.name',
|
||||
|
|
|
@ -4295,25 +4295,29 @@ nsLayoutUtils::GetFontFacesForText(nsIFrame* aFrame,
|
|||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsLayoutUtils::GetTextRunMemoryForFrames(nsIFrame* aFrame, PRUint64* aTotal)
|
||||
size_t
|
||||
nsLayoutUtils::SizeOfTextRunsForFrames(nsIFrame* aFrame,
|
||||
nsMallocSizeOfFun aMallocSizeOf,
|
||||
bool clear)
|
||||
{
|
||||
NS_PRECONDITION(aFrame, "NULL frame pointer");
|
||||
|
||||
size_t total = 0;
|
||||
|
||||
if (aFrame->GetType() == nsGkAtoms::textFrame) {
|
||||
nsTextFrame* textFrame = static_cast<nsTextFrame*>(aFrame);
|
||||
for (PRUint32 i = 0; i < 2; ++i) {
|
||||
gfxTextRun *run = textFrame->GetTextRun(
|
||||
(i != 0) ? nsTextFrame::eInflated : nsTextFrame::eNotInflated);
|
||||
if (run) {
|
||||
if (aTotal) {
|
||||
run->AccountForSize(aTotal);
|
||||
if (clear) {
|
||||
run->ResetSizeOfAccountingFlags();
|
||||
} else {
|
||||
run->ClearSizeAccounted();
|
||||
total += run->MaybeSizeOfIncludingThis(aMallocSizeOf);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
return total;
|
||||
}
|
||||
|
||||
nsAutoTArray<nsIFrame::ChildList,4> childListArray;
|
||||
|
@ -4323,11 +4327,10 @@ nsLayoutUtils::GetTextRunMemoryForFrames(nsIFrame* aFrame, PRUint64* aTotal)
|
|||
!childLists.IsDone(); childLists.Next()) {
|
||||
for (nsFrameList::Enumerator e(childLists.CurrentList());
|
||||
!e.AtEnd(); e.Next()) {
|
||||
GetTextRunMemoryForFrames(e.get(), aTotal);
|
||||
total += SizeOfTextRunsForFrames(e.get(), aMallocSizeOf, clear);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return total;
|
||||
}
|
||||
|
||||
/* static */
|
||||
|
|
|
@ -1438,17 +1438,18 @@ public:
|
|||
|
||||
/**
|
||||
* Walks the frame tree starting at aFrame looking for textRuns.
|
||||
* If aTotal is NULL, just clears the TEXT_RUN_MEMORY_ACCOUNTED flag
|
||||
* on each textRun found.
|
||||
* If aTotal is non-NULL, adds the storage used for each textRun to the
|
||||
* If |clear| is true, just clears the TEXT_RUN_MEMORY_ACCOUNTED flag
|
||||
* on each textRun found (and |aMallocSizeOf| is not used).
|
||||
* If |clear| is false, adds the storage used for each textRun to the
|
||||
* total, and sets the TEXT_RUN_MEMORY_ACCOUNTED flag to avoid double-
|
||||
* accounting. (Runs with this flag already set will be skipped.)
|
||||
* Expected usage pattern is therefore to call twice:
|
||||
* rv = GetTextRunMemoryForFrames(rootFrame, NULL);
|
||||
* rv = GetTextRunMemoryForFrames(rootFrame, &total);
|
||||
* (void)SizeOfTextRunsForFrames(rootFrame, nsnull, true);
|
||||
* total = SizeOfTextRunsForFrames(rootFrame, mallocSizeOf, false);
|
||||
*/
|
||||
static nsresult GetTextRunMemoryForFrames(nsIFrame* aFrame,
|
||||
PRUint64* aTotal);
|
||||
static size_t SizeOfTextRunsForFrames(nsIFrame* aFrame,
|
||||
nsMallocSizeOfFun aMallocSizeOf,
|
||||
bool clear);
|
||||
|
||||
/**
|
||||
* Checks if CSS 3D transforms are currently enabled.
|
||||
|
|
|
@ -661,8 +661,7 @@ PresShell::MemoryReporter::SizeEnumerator(PresShellPtrKey *aEntry,
|
|||
PRUint32 styleSize;
|
||||
styleSize = aShell->StyleSet()->SizeOf();
|
||||
|
||||
PRUint64 textRunsSize;
|
||||
textRunsSize = aShell->ComputeTextRunMemoryUsed();
|
||||
PRInt64 textRunsSize = aShell->SizeOfTextRuns(MemoryReporterMallocSizeOf);
|
||||
|
||||
data->callback->
|
||||
Callback(EmptyCString(), arenaPath, nsIMemoryReporter::KIND_HEAP,
|
||||
|
@ -693,7 +692,7 @@ PresShell::MemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
|||
data.closure = aClosure;
|
||||
|
||||
// clear TEXT_RUN_SIZE_ACCOUNTED flag on cached runs
|
||||
gfxTextRunWordCache::ComputeStorage(nsnull);
|
||||
gfxTextRunWordCache::ResetSizeOfAccountingFlags();
|
||||
|
||||
sLiveShells->EnumerateEntries(SizeEnumerator, &data);
|
||||
|
||||
|
@ -704,8 +703,8 @@ PresShell::MemoryReporter::CollectReports(nsIMemoryMultiReporterCallback* aCb,
|
|||
"not owned by a PresShell's frame tree.");
|
||||
|
||||
// now total up cached runs that aren't otherwise accounted for
|
||||
PRUint64 textRunWordCacheSize = 0;
|
||||
gfxTextRunWordCache::ComputeStorage(&textRunWordCacheSize);
|
||||
PRInt64 textRunWordCacheSize =
|
||||
gfxTextRunWordCache::MaybeSizeOfExcludingThis(MemoryReporterMallocSizeOf);
|
||||
|
||||
aCb->Callback(EmptyCString(), kTextRunWordCachePath,
|
||||
nsIMemoryReporter::KIND_HEAP, nsIMemoryReporter::UNITS_BYTES,
|
||||
|
@ -8808,8 +8807,8 @@ PresShell::GetRootPresShell()
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
PRUint64
|
||||
PresShell::ComputeTextRunMemoryUsed()
|
||||
size_t
|
||||
PresShell::SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf)
|
||||
{
|
||||
nsIFrame* rootFrame = FrameManager()->GetRootFrame();
|
||||
if (!rootFrame) {
|
||||
|
@ -8817,12 +8816,11 @@ PresShell::ComputeTextRunMemoryUsed()
|
|||
}
|
||||
|
||||
// clear the TEXT_RUN_MEMORY_ACCOUNTED flags
|
||||
nsLayoutUtils::GetTextRunMemoryForFrames(rootFrame, nsnull);
|
||||
nsLayoutUtils::SizeOfTextRunsForFrames(rootFrame, nsnull,
|
||||
/* clear = */true);
|
||||
|
||||
// collect the total memory in use for textruns
|
||||
PRUint64 total = 0;
|
||||
nsLayoutUtils::GetTextRunMemoryForFrames(rootFrame, &total);
|
||||
|
||||
return total;
|
||||
return nsLayoutUtils::SizeOfTextRunsForFrames(rootFrame, aMallocSizeOf,
|
||||
/* clear = */false);
|
||||
}
|
||||
|
||||
|
|
|
@ -890,7 +890,7 @@ public:
|
|||
return result;
|
||||
}
|
||||
|
||||
PRUint64 ComputeTextRunMemoryUsed();
|
||||
size_t SizeOfTextRuns(nsMallocSizeOfFun aMallocSizeOf);
|
||||
|
||||
class MemoryReporter : public nsIMemoryMultiReporter
|
||||
{
|
||||
|
|
|
@ -99,28 +99,28 @@ nsTransformedTextRun::SetPotentialLineBreaks(PRUint32 aStart, PRUint32 aLength,
|
|||
return changed;
|
||||
}
|
||||
|
||||
PRUint64
|
||||
nsTransformedTextRun::ComputeSize()
|
||||
size_t
|
||||
nsTransformedTextRun::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf)
|
||||
{
|
||||
PRUint32 total = gfxTextRun::ComputeSize();
|
||||
if (moz_malloc_usable_size(this) == 0) {
|
||||
total += sizeof(nsTransformedTextRun) - sizeof(gfxTextRun);
|
||||
}
|
||||
size_t total = gfxTextRun::SizeOfExcludingThis(aMallocSizeOf);
|
||||
total += mStyles.SizeOf();
|
||||
total += mCapitalize.SizeOf();
|
||||
if (mOwnsFactory) {
|
||||
PRUint32 factorySize = moz_malloc_usable_size(mFactory);
|
||||
if (factorySize == 0) {
|
||||
// this may not quite account for everything
|
||||
// (e.g. nsCaseTransformTextRunFactory adds a couple of members)
|
||||
// but I'm not sure it's worth the effort to track more precisely
|
||||
factorySize = sizeof(nsTransformingTextRunFactory);
|
||||
}
|
||||
total += factorySize;
|
||||
// It's not worth the effort to get all the sub-class cases right for a
|
||||
// small size in the fallback case. So we use a |computedSize| of 0, which
|
||||
// disables any usable vs. computedSize checking done by aMallocSizeOf.
|
||||
total += aMallocSizeOf(mFactory, 0);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
size_t
|
||||
nsTransformedTextRun::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf)
|
||||
{
|
||||
return aMallocSizeOf(this, sizeof(nsTransformedTextRun)) +
|
||||
SizeOfExcludingThis(aMallocSizeOf);
|
||||
}
|
||||
|
||||
nsTransformedTextRun*
|
||||
nsTransformingTextRunFactory::MakeTextRun(const PRUnichar* aString, PRUint32 aLength,
|
||||
const gfxTextRunFactory::Parameters* aParams,
|
||||
|
|
|
@ -132,8 +132,9 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// override the gfxTextRun impl to account for additional members here
|
||||
virtual PRUint64 ComputeSize();
|
||||
// override the gfxTextRun impls to account for additional members here
|
||||
virtual NS_MUST_OVERRIDE size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf);
|
||||
virtual NS_MUST_OVERRIDE size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf);
|
||||
|
||||
nsTransformingTextRunFactory *mFactory;
|
||||
nsTArray<nsRefPtr<nsStyleContext> > mStyles;
|
||||
|
|
|
@ -301,7 +301,7 @@ fails-if(Android) != 192767-17.xul 192767-37.xul
|
|||
== 283686-3.html about:blank
|
||||
== 289384-1.xhtml 289384-ref.xhtml
|
||||
fails-if(Android) random-if(d2d) HTTP == 289480.html#top 289480-ref.html # basically-verbatim acid2 test, HTTP for a 404 page -- bug 578114 for the d2d failures
|
||||
asserts(1) == 290129-1.html 290129-1-ref.html # bug 315549/460637
|
||||
== 290129-1.html 290129-1-ref.html
|
||||
== 291078-1.html 291078-1-ref.html
|
||||
== 291078-2.html 291078-2-ref.html
|
||||
== 291262-1.html 291262-1-ref.html
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head><script type="text/javascript">
|
||||
<![CDATA[
|
||||
|
||||
function boom() {
|
||||
var HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
var r = document.documentElement; while(r.firstChild) { r.removeChild(r.firstChild); }
|
||||
var table = document.createElementNS(HTML_NS, "table");
|
||||
table.setAttribute("border", "1");
|
||||
var text = document.createTextNode("\n ");
|
||||
table.appendChild(text);
|
||||
var tr1 = document.createElementNS(HTML_NS, "tr");
|
||||
table.appendChild(tr1);
|
||||
var tr2 = document.createElementNS(HTML_NS, "tr");
|
||||
var input = document.createElementNS(HTML_NS, "input");
|
||||
tr2.appendChild(input);
|
||||
table.appendChild(tr2);
|
||||
document.documentElement.appendChild(table);
|
||||
var tr3 = document.createElementNS(HTML_NS, 'tr');
|
||||
table.insertBefore(tr3, text);
|
||||
var td = document.createElementNS(HTML_NS, 'td');
|
||||
td.setAttribute('rowspan', 0);
|
||||
tr3.insertBefore(td, null);
|
||||
table.removeAttribute('border');
|
||||
var caption = document.createElementNS(HTML_NS, 'caption');
|
||||
table.insertBefore(caption, tr2);
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
function ol(e) {
|
||||
window.removeEventListener("load", ol, false);
|
||||
setTimeout(boom, 400);
|
||||
}
|
||||
|
||||
window.addEventListener("load", ol, false);
|
||||
|
||||
]]></script>
|
||||
</head>
|
||||
|
||||
<body></body>
|
||||
</html>
|
|
@ -0,0 +1,24 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head><script type="text/javascript">
|
||||
<![CDATA[
|
||||
|
||||
function boom() {
|
||||
var tr = document.getElementById('tr');
|
||||
th = document.createElementNS("http://www.w3.org/1999/xhtml", 'th');
|
||||
th.setAttribute('rowspan', 9);
|
||||
tr.appendChild(th);
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
|
||||
function ol(e) {
|
||||
window.removeEventListener("load", ol, false);
|
||||
setTimeout(boom, 400);
|
||||
}
|
||||
|
||||
window.addEventListener("load", ol, false);
|
||||
|
||||
]]></script>
|
||||
</head>
|
||||
<body><table style="border-collapse: collapse;"><tbody><tr id="tr"></tr></tbody></table></body>
|
||||
</html>
|
|
@ -0,0 +1,26 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
|
||||
<head><script type="text/javascript">
|
||||
<![CDATA[
|
||||
|
||||
function boom() {
|
||||
const HTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
var tr4 = document.createElementNS(HTML_NS, 'tr');
|
||||
document.getElementById('tbody1').appendChild(tr4);
|
||||
var span1 = document.createElementNS(HTML_NS, 'td');
|
||||
tr4.insertBefore(span1, null);
|
||||
document.documentElement.removeAttribute("class");
|
||||
}
|
||||
|
||||
function ol(e) {
|
||||
window.removeEventListener("load", ol, false);
|
||||
setTimeout(boom, 400);
|
||||
}
|
||||
|
||||
window.addEventListener("load", ol, false);
|
||||
|
||||
]]>
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body><table><tbody id="tbody1"><tr><td rowspan="0"></td></tr></tbody></table></body>
|
||||
</html>
|
|
@ -96,6 +96,9 @@ load 448988-1.xhtml
|
|||
load 450311-1.html
|
||||
load 456041.html
|
||||
load 457115.html
|
||||
load 460637-1.xhtml
|
||||
load 460637-2.xhtml
|
||||
load 460637-3.xhtml
|
||||
load 467141-1.html
|
||||
load 488388-1.html
|
||||
load 512749-1.html
|
||||
|
|
|
@ -41,6 +41,24 @@
|
|||
#include "nsTableCellFrame.h"
|
||||
#include "nsTableRowGroupFrame.h"
|
||||
|
||||
|
||||
static void
|
||||
SetDamageArea(PRInt32 aXOrigin,
|
||||
PRInt32 aYOrigin,
|
||||
PRInt32 aWidth,
|
||||
PRInt32 aHeight,
|
||||
nsRect& aDamageArea)
|
||||
{
|
||||
NS_ASSERTION(aXOrigin >= 0, "negative col index");
|
||||
NS_ASSERTION(aYOrigin >= 0, "negative row index");
|
||||
NS_ASSERTION(aWidth >= 0, "negative horizontal damage");
|
||||
NS_ASSERTION(aHeight >= 0, "negative vertical damage");
|
||||
aDamageArea.x = aXOrigin;
|
||||
aDamageArea.y = aYOrigin;
|
||||
aDamageArea.width = aWidth;
|
||||
aDamageArea.height = aHeight;
|
||||
}
|
||||
|
||||
// Empty static array used for SafeElementAt() calls on mRows.
|
||||
static nsCellMap::CellDataArray * sEmptyRow;
|
||||
|
||||
|
@ -479,13 +497,13 @@ nsTableCellMap::InsertRows(nsTableRowGroupFrame* aParent,
|
|||
if ((numNewRows <= 0) || (aFirstRowIndex < 0)) ABORT0();
|
||||
|
||||
PRInt32 rowIndex = aFirstRowIndex;
|
||||
PRInt32 rgStartRowIndex = 0;
|
||||
nsCellMap* cellMap = mFirstMap;
|
||||
while (cellMap) {
|
||||
nsTableRowGroupFrame* rg = cellMap->GetRowGroup();
|
||||
if (rg == aParent) {
|
||||
cellMap->InsertRows(*this, aRows, rowIndex, aConsiderSpans, aDamageArea);
|
||||
aDamageArea.y = NS_MIN(aFirstRowIndex, aDamageArea.y);
|
||||
aDamageArea.height = NS_MAX(0, GetRowCount() - aDamageArea.y);
|
||||
cellMap->InsertRows(*this, aRows, rowIndex, aConsiderSpans,
|
||||
rgStartRowIndex, aDamageArea);
|
||||
#ifdef DEBUG_TABLE_CELLMAP
|
||||
Dump("after InsertRows");
|
||||
#endif
|
||||
|
@ -507,7 +525,9 @@ nsTableCellMap::InsertRows(nsTableRowGroupFrame* aParent,
|
|||
}
|
||||
return;
|
||||
}
|
||||
rowIndex -= cellMap->GetRowCount();
|
||||
PRInt32 rowCount = cellMap->GetRowCount();
|
||||
rgStartRowIndex += rowCount;
|
||||
rowIndex -= rowCount;
|
||||
cellMap = cellMap->GetNextSibling();
|
||||
}
|
||||
|
||||
|
@ -521,13 +541,13 @@ nsTableCellMap::RemoveRows(PRInt32 aFirstRowIndex,
|
|||
nsRect& aDamageArea)
|
||||
{
|
||||
PRInt32 rowIndex = aFirstRowIndex;
|
||||
PRInt32 rgStartRowIndex = 0;
|
||||
nsCellMap* cellMap = mFirstMap;
|
||||
while (cellMap) {
|
||||
if (cellMap->GetRowCount() > rowIndex) {
|
||||
cellMap->RemoveRows(*this, rowIndex, aNumRowsToRemove, aConsiderSpans, aDamageArea);
|
||||
nsTableRowGroupFrame* rg = cellMap->GetRowGroup();
|
||||
aDamageArea.y += (rg) ? rg->GetStartRowIndex() : 0;
|
||||
aDamageArea.height = NS_MAX(0, GetRowCount() - aFirstRowIndex);
|
||||
PRInt32 rowCount = cellMap->GetRowCount();
|
||||
if (rowCount > rowIndex) {
|
||||
cellMap->RemoveRows(*this, rowIndex, aNumRowsToRemove, aConsiderSpans,
|
||||
rgStartRowIndex, aDamageArea);
|
||||
if (mBCInfo) {
|
||||
for (PRInt32 rowX = aFirstRowIndex + aNumRowsToRemove - 1; rowX >= aFirstRowIndex; rowX--) {
|
||||
if (PRUint32(rowX) < mBCInfo->mRightBorders.Length()) {
|
||||
|
@ -537,7 +557,8 @@ nsTableCellMap::RemoveRows(PRInt32 aFirstRowIndex,
|
|||
}
|
||||
break;
|
||||
}
|
||||
rowIndex -= cellMap->GetRowCount();
|
||||
rgStartRowIndex += rowCount;
|
||||
rowIndex -= rowCount;
|
||||
cellMap = cellMap->GetNextSibling();
|
||||
}
|
||||
#ifdef DEBUG_TABLE_CELLMAP
|
||||
|
@ -561,15 +582,18 @@ nsTableCellMap::AppendCell(nsTableCellFrame& aCellFrame,
|
|||
|
||||
CellData* result = nsnull;
|
||||
PRInt32 rowIndex = aRowIndex;
|
||||
PRInt32 rgStartRowIndex = 0;
|
||||
nsCellMap* cellMap = mFirstMap;
|
||||
while (cellMap) {
|
||||
if (cellMap->GetRowGroup() == rgFrame) {
|
||||
result = cellMap->AppendCell(*this, &aCellFrame, rowIndex, aRebuildIfNecessary, aDamageArea);
|
||||
nsTableRowGroupFrame* rg = cellMap->GetRowGroup();
|
||||
aDamageArea.y += (rg) ? rg->GetStartRowIndex() : 0;
|
||||
result = cellMap->AppendCell(*this, &aCellFrame, rowIndex,
|
||||
aRebuildIfNecessary, rgStartRowIndex,
|
||||
aDamageArea);
|
||||
break;
|
||||
}
|
||||
rowIndex -= cellMap->GetRowCount();
|
||||
PRInt32 rowCount = cellMap->GetRowCount();
|
||||
rgStartRowIndex += rowCount;
|
||||
rowIndex -= rowCount;
|
||||
cellMap = cellMap->GetNextSibling();
|
||||
}
|
||||
#ifdef DEBUG_TABLE_CELLMAP
|
||||
|
@ -586,16 +610,17 @@ nsTableCellMap::InsertCells(nsTArray<nsTableCellFrame*>& aCellFrames,
|
|||
nsRect& aDamageArea)
|
||||
{
|
||||
PRInt32 rowIndex = aRowIndex;
|
||||
PRInt32 rgStartRowIndex = 0;
|
||||
nsCellMap* cellMap = mFirstMap;
|
||||
while (cellMap) {
|
||||
if (cellMap->GetRowCount() > rowIndex) {
|
||||
cellMap->InsertCells(*this, aCellFrames, rowIndex, aColIndexBefore, aDamageArea);
|
||||
nsTableRowGroupFrame* rg = cellMap->GetRowGroup();
|
||||
aDamageArea.y += (rg) ? rg->GetStartRowIndex() : 0;
|
||||
aDamageArea.width = NS_MAX(0, GetColCount() - aColIndexBefore - 1);
|
||||
PRInt32 rowCount = cellMap->GetRowCount();
|
||||
if (rowCount > rowIndex) {
|
||||
cellMap->InsertCells(*this, aCellFrames, rowIndex, aColIndexBefore,
|
||||
rgStartRowIndex, aDamageArea);
|
||||
break;
|
||||
}
|
||||
rowIndex -= cellMap->GetRowCount();
|
||||
rgStartRowIndex += rowCount;
|
||||
rowIndex -= rowCount;
|
||||
cellMap = cellMap->GetNextSibling();
|
||||
}
|
||||
#ifdef DEBUG_TABLE_CELLMAP
|
||||
|
@ -613,21 +638,20 @@ nsTableCellMap::RemoveCell(nsTableCellFrame* aCellFrame,
|
|||
NS_ASSERTION(aCellFrame == (nsTableCellFrame *)aCellFrame->GetFirstInFlow(),
|
||||
"invalid call on continuing frame");
|
||||
PRInt32 rowIndex = aRowIndex;
|
||||
PRInt32 rgStartRowIndex = 0;
|
||||
nsCellMap* cellMap = mFirstMap;
|
||||
while (cellMap) {
|
||||
if (cellMap->GetRowCount() > rowIndex) {
|
||||
cellMap->RemoveCell(*this, aCellFrame, rowIndex, aDamageArea);
|
||||
nsTableRowGroupFrame* rg = cellMap->GetRowGroup();
|
||||
aDamageArea.y += (rg) ? rg->GetStartRowIndex() : 0;
|
||||
PRInt32 colIndex;
|
||||
aCellFrame->GetColIndex(colIndex);
|
||||
aDamageArea.width = NS_MAX(0, GetColCount() - colIndex - 1);
|
||||
PRInt32 rowCount = cellMap->GetRowCount();
|
||||
if (rowCount > rowIndex) {
|
||||
cellMap->RemoveCell(*this, aCellFrame, rowIndex, rgStartRowIndex,
|
||||
aDamageArea);
|
||||
#ifdef DEBUG_TABLE_CELLMAP
|
||||
Dump("after RemoveCell");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
rowIndex -= cellMap->GetRowCount();
|
||||
rgStartRowIndex += rowCount;
|
||||
rowIndex -= rowCount;
|
||||
cellMap = cellMap->GetNextSibling();
|
||||
}
|
||||
// if we reach this point - the cell did not get removed, the caller of this routine
|
||||
|
@ -637,19 +661,6 @@ nsTableCellMap::RemoveCell(nsTableCellFrame* aCellFrame,
|
|||
NS_ERROR("nsTableCellMap::RemoveCell - could not remove cell");
|
||||
}
|
||||
|
||||
void
|
||||
SetDamageArea(PRInt32 aXOrigin,
|
||||
PRInt32 aYOrigin,
|
||||
PRInt32 aWidth,
|
||||
PRInt32 aHeight,
|
||||
nsRect& aDamageArea)
|
||||
{
|
||||
aDamageArea.x = aXOrigin;
|
||||
aDamageArea.y = aYOrigin;
|
||||
aDamageArea.width = NS_MAX(1, aWidth);
|
||||
aDamageArea.height = NS_MAX(1, aHeight);
|
||||
}
|
||||
|
||||
void
|
||||
nsTableCellMap::RebuildConsideringCells(nsCellMap* aCellMap,
|
||||
nsTArray<nsTableCellFrame*>* aCellFrames,
|
||||
|
@ -664,11 +675,12 @@ nsTableCellMap::RebuildConsideringCells(nsCellMap* aCellMap,
|
|||
PRInt32 rowCount = 0;
|
||||
while (cellMap) {
|
||||
if (cellMap == aCellMap) {
|
||||
cellMap->RebuildConsideringCells(*this, numOrigCols, aCellFrames, aRowIndex, aColIndex, aInsert, aDamageArea);
|
||||
|
||||
cellMap->RebuildConsideringCells(*this, numOrigCols, aCellFrames,
|
||||
aRowIndex, aColIndex, aInsert);
|
||||
}
|
||||
else {
|
||||
cellMap->RebuildConsideringCells(*this, numOrigCols, nsnull, -1, 0, false, aDamageArea);
|
||||
cellMap->RebuildConsideringCells(*this, numOrigCols, nsnull, -1, 0,
|
||||
false);
|
||||
}
|
||||
rowCount += cellMap->GetRowCount();
|
||||
cellMap = cellMap->GetNextSibling();
|
||||
|
@ -692,10 +704,12 @@ nsTableCellMap::RebuildConsideringRows(nsCellMap* aCellMap,
|
|||
PRInt32 rowCount = 0;
|
||||
while (cellMap) {
|
||||
if (cellMap == aCellMap) {
|
||||
cellMap->RebuildConsideringRows(*this, aStartRowIndex, aRowsToInsert, aNumRowsToRemove, aDamageArea);
|
||||
cellMap->RebuildConsideringRows(*this, aStartRowIndex, aRowsToInsert,
|
||||
aNumRowsToRemove);
|
||||
}
|
||||
else {
|
||||
cellMap->RebuildConsideringCells(*this, numOrigCols, nsnull, -1, 0, false, aDamageArea);
|
||||
cellMap->RebuildConsideringCells(*this, numOrigCols, nsnull, -1, 0,
|
||||
false);
|
||||
}
|
||||
rowCount += cellMap->GetRowCount();
|
||||
cellMap = cellMap->GetNextSibling();
|
||||
|
@ -1015,7 +1029,9 @@ nsTableCellMap::SetBCBorderEdge(mozilla::css::Side aSide,
|
|||
PRInt32 numRgRows = aCellMap.GetRowCount();
|
||||
if (yPos < numRgRows) { // add a dead cell data
|
||||
nsRect damageArea;
|
||||
cellData = (BCCellData*)aCellMap.AppendCell(*this, nsnull, rgYPos, false, damageArea); if (!cellData) ABORT0();
|
||||
cellData = (BCCellData*)aCellMap.AppendCell(*this, nsnull, rgYPos,
|
||||
false, 0, damageArea);
|
||||
if (!cellData) ABORT0();
|
||||
}
|
||||
else {
|
||||
NS_ASSERTION(aSide == NS_SIDE_BOTTOM, "program error");
|
||||
|
@ -1028,7 +1044,9 @@ nsTableCellMap::SetBCBorderEdge(mozilla::css::Side aSide,
|
|||
cellData = (BCCellData*)cellMap->GetDataAt(0, xIndex);
|
||||
if (!cellData) { // add a dead cell
|
||||
nsRect damageArea;
|
||||
cellData = (BCCellData*)cellMap->AppendCell(*this, nsnull, 0, false, damageArea);
|
||||
cellData = (BCCellData*)cellMap->AppendCell(*this, nsnull, 0,
|
||||
false, 0,
|
||||
damageArea);
|
||||
}
|
||||
}
|
||||
else { // must be at the end of the table
|
||||
|
@ -1121,7 +1139,8 @@ nsTableCellMap::SetBCBorderCorner(Corner aCorner,
|
|||
PRInt32 numRgRows = aCellMap.GetRowCount();
|
||||
if (yPos < numRgRows) { // add a dead cell data
|
||||
nsRect damageArea;
|
||||
cellData = (BCCellData*)aCellMap.AppendCell(*this, nsnull, rgYPos, false, damageArea);
|
||||
cellData = (BCCellData*)aCellMap.AppendCell(*this, nsnull, rgYPos,
|
||||
false, 0, damageArea);
|
||||
}
|
||||
else {
|
||||
// try the next non empty row group
|
||||
|
@ -1133,7 +1152,8 @@ nsTableCellMap::SetBCBorderCorner(Corner aCorner,
|
|||
cellData = (BCCellData*)cellMap->GetDataAt(0, xPos);
|
||||
if (!cellData) { // add a dead cell
|
||||
nsRect damageArea;
|
||||
cellData = (BCCellData*)cellMap->AppendCell(*this, nsnull, 0, false, damageArea);
|
||||
cellData = (BCCellData*)cellMap->AppendCell(*this, nsnull, 0,
|
||||
false, 0, damageArea);
|
||||
}
|
||||
}
|
||||
else { // must be at the bottom of the table
|
||||
|
@ -1337,6 +1357,7 @@ nsCellMap::InsertRows(nsTableCellMap& aMap,
|
|||
nsTArray<nsTableRowFrame*>& aRows,
|
||||
PRInt32 aFirstRowIndex,
|
||||
bool aConsiderSpans,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea)
|
||||
{
|
||||
PRInt32 numCols = aMap.GetColCount();
|
||||
|
@ -1352,7 +1373,7 @@ nsCellMap::InsertRows(nsTableCellMap& aMap,
|
|||
if (!aConsiderSpans) {
|
||||
// update mContentRowCount, since non-empty rows will be added
|
||||
mContentRowCount = NS_MAX(aFirstRowIndex, mContentRowCount);
|
||||
ExpandWithRows(aMap, aRows, aFirstRowIndex, aDamageArea);
|
||||
ExpandWithRows(aMap, aRows, aFirstRowIndex, aRgFirstRowIndex, aDamageArea);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1368,12 +1389,11 @@ nsCellMap::InsertRows(nsTableCellMap& aMap,
|
|||
if (!spansCauseRebuild && (PRUint32(aFirstRowIndex) < mRows.Length())) {
|
||||
spansCauseRebuild = CellsSpanOut(aRows);
|
||||
}
|
||||
|
||||
if (spansCauseRebuild) {
|
||||
aMap.RebuildConsideringRows(this, aFirstRowIndex, &aRows, 0, aDamageArea);
|
||||
}
|
||||
else {
|
||||
ExpandWithRows(aMap, aRows, aFirstRowIndex, aDamageArea);
|
||||
ExpandWithRows(aMap, aRows, aFirstRowIndex, aRgFirstRowIndex, aDamageArea);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1382,6 +1402,7 @@ nsCellMap::RemoveRows(nsTableCellMap& aMap,
|
|||
PRInt32 aFirstRowIndex,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
bool aConsiderSpans,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea)
|
||||
{
|
||||
PRInt32 numRows = mRows.Length();
|
||||
|
@ -1395,7 +1416,8 @@ nsCellMap::RemoveRows(nsTableCellMap& aMap,
|
|||
return;
|
||||
}
|
||||
if (!aConsiderSpans) {
|
||||
ShrinkWithoutRows(aMap, aFirstRowIndex, aNumRowsToRemove, aDamageArea);
|
||||
ShrinkWithoutRows(aMap, aFirstRowIndex, aNumRowsToRemove, aRgFirstRowIndex,
|
||||
aDamageArea);
|
||||
return;
|
||||
}
|
||||
PRInt32 endRowIndex = aFirstRowIndex + aNumRowsToRemove - 1;
|
||||
|
@ -1405,12 +1427,13 @@ nsCellMap::RemoveRows(nsTableCellMap& aMap,
|
|||
}
|
||||
bool spansCauseRebuild = CellsSpanInOrOut(aFirstRowIndex, endRowIndex,
|
||||
0, numCols - 1);
|
||||
|
||||
if (spansCauseRebuild) {
|
||||
aMap.RebuildConsideringRows(this, aFirstRowIndex, nsnull, aNumRowsToRemove, aDamageArea);
|
||||
aMap.RebuildConsideringRows(this, aFirstRowIndex, nsnull, aNumRowsToRemove,
|
||||
aDamageArea);
|
||||
}
|
||||
else {
|
||||
ShrinkWithoutRows(aMap, aFirstRowIndex, aNumRowsToRemove, aDamageArea);
|
||||
ShrinkWithoutRows(aMap, aFirstRowIndex, aNumRowsToRemove, aRgFirstRowIndex,
|
||||
aDamageArea);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1422,6 +1445,7 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
|
|||
nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
bool aRebuildIfNecessary,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea,
|
||||
PRInt32* aColToBeginSearch)
|
||||
{
|
||||
|
@ -1514,7 +1538,15 @@ nsCellMap::AppendCell(nsTableCellMap& aMap,
|
|||
SetDataAt(aMap, *origData, aRowIndex, startColIndex);
|
||||
}
|
||||
|
||||
SetDamageArea(startColIndex, aRowIndex, 1 + endColIndex - startColIndex, 1 + endRowIndex - aRowIndex, aDamageArea);
|
||||
if (aRebuildIfNecessary) {
|
||||
//the caller depends on the damageArea
|
||||
// The special case for zeroRowSpan is to adjust for the '2' in
|
||||
// GetRowSpanForNewCell.
|
||||
PRUint32 height = zeroRowSpan ? endRowIndex - aRowIndex :
|
||||
1 + endRowIndex - aRowIndex;
|
||||
SetDamageArea(startColIndex, aRgFirstRowIndex + aRowIndex,
|
||||
1 + endColIndex - startColIndex, height, aDamageArea);
|
||||
}
|
||||
|
||||
if (!aCellFrame) {
|
||||
return origData;
|
||||
|
@ -1723,6 +1755,7 @@ void nsCellMap::InsertCells(nsTableCellMap& aMap,
|
|||
nsTArray<nsTableCellFrame*>& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndexBefore,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea)
|
||||
{
|
||||
if (aCellFrames.Length() == 0) return;
|
||||
|
@ -1779,12 +1812,13 @@ void nsCellMap::InsertCells(nsTableCellMap& aMap,
|
|||
spansCauseRebuild = CellsSpanInOrOut(aRowIndex, aRowIndex + rowSpan - 1,
|
||||
startColIndex, numCols - 1);
|
||||
}
|
||||
|
||||
if (spansCauseRebuild) {
|
||||
aMap.RebuildConsideringCells(this, &aCellFrames, aRowIndex, startColIndex, true, aDamageArea);
|
||||
aMap.RebuildConsideringCells(this, &aCellFrames, aRowIndex, startColIndex,
|
||||
true, aDamageArea);
|
||||
}
|
||||
else {
|
||||
ExpandWithCells(aMap, aCellFrames, aRowIndex, startColIndex, rowSpan, zeroRowSpan, aDamageArea);
|
||||
ExpandWithCells(aMap, aCellFrames, aRowIndex, startColIndex, rowSpan,
|
||||
zeroRowSpan, aRgFirstRowIndex, aDamageArea);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1792,6 +1826,7 @@ void
|
|||
nsCellMap::ExpandWithRows(nsTableCellMap& aMap,
|
||||
nsTArray<nsTableRowFrame*>& aRowFrames,
|
||||
PRInt32 aStartRowIndexIn,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea)
|
||||
{
|
||||
PRInt32 startRowIndex = (aStartRowIndexIn >= 0) ? aStartRowIndexIn : 0;
|
||||
|
@ -1818,14 +1853,15 @@ nsCellMap::ExpandWithRows(nsTableCellMap& aMap,
|
|||
while (cFrame) {
|
||||
nsTableCellFrame *cellFrame = do_QueryFrame(cFrame);
|
||||
if (cellFrame) {
|
||||
AppendCell(aMap, cellFrame, rowX, false, aDamageArea, &colIndex);
|
||||
AppendCell(aMap, cellFrame, rowX, false, aRgFirstRowIndex, aDamageArea,
|
||||
&colIndex);
|
||||
}
|
||||
cFrame = cFrame->GetNextSibling();
|
||||
}
|
||||
newRowIndex++;
|
||||
}
|
||||
|
||||
SetDamageArea(0, startRowIndex, aMap.GetColCount(), 1 + endRowIndex - startRowIndex, aDamageArea);
|
||||
SetDamageArea(0, aRgFirstRowIndex + startRowIndex, aMap.GetColCount(),
|
||||
1 + endRowIndex - startRowIndex, aDamageArea);
|
||||
}
|
||||
|
||||
void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
|
||||
|
@ -1834,6 +1870,7 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
|
|||
PRInt32 aColIndex,
|
||||
PRInt32 aRowSpan, // same for all cells
|
||||
bool aRowSpanIsZero,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea)
|
||||
{
|
||||
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
|
||||
|
@ -1908,8 +1945,10 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
|
|||
}
|
||||
cellFrame->SetColIndex(startColIndex);
|
||||
}
|
||||
PRInt32 damageHeight = NS_MIN(GetRowGroup()->GetRowCount() - aRowIndex, aRowSpan);
|
||||
SetDamageArea(aColIndex, aRowIndex, 1 + endColIndex - aColIndex, damageHeight, aDamageArea);
|
||||
PRInt32 damageHeight = NS_MIN(GetRowGroup()->GetRowCount() - aRowIndex,
|
||||
aRowSpan);
|
||||
SetDamageArea(aColIndex, aRgFirstRowIndex + aRowIndex,
|
||||
1 + endColIndex - aColIndex, damageHeight, aDamageArea);
|
||||
|
||||
PRInt32 rowX;
|
||||
|
||||
|
@ -1951,6 +1990,7 @@ void nsCellMap::ExpandWithCells(nsTableCellMap& aMap,
|
|||
void nsCellMap::ShrinkWithoutRows(nsTableCellMap& aMap,
|
||||
PRInt32 aStartRowIndex,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea)
|
||||
{
|
||||
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
|
||||
|
@ -1988,8 +2028,8 @@ void nsCellMap::ShrinkWithoutRows(nsTableCellMap& aMap,
|
|||
mContentRowCount--;
|
||||
}
|
||||
aMap.RemoveColsAtEnd();
|
||||
|
||||
SetDamageArea(0, aStartRowIndex, aMap.GetColCount(), 0, aDamageArea);
|
||||
SetDamageArea(0, aRgFirstRowIndex + aStartRowIndex, aMap.GetColCount(), 0,
|
||||
aDamageArea);
|
||||
}
|
||||
|
||||
PRInt32 nsCellMap::GetColSpanForNewCell(nsTableCellFrame& aCellFrameToAdd,
|
||||
|
@ -2127,6 +2167,7 @@ void nsCellMap::ShrinkWithoutCell(nsTableCellMap& aMap,
|
|||
nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea)
|
||||
{
|
||||
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
|
||||
|
@ -2139,8 +2180,9 @@ void nsCellMap::ShrinkWithoutCell(nsTableCellMap& aMap,
|
|||
PRUint32 colSpan = GetEffectiveColSpan(aMap, aRowIndex, aColIndex, zeroColSpan);
|
||||
PRUint32 endRowIndex = aRowIndex + rowSpan - 1;
|
||||
PRUint32 endColIndex = aColIndex + colSpan - 1;
|
||||
|
||||
SetDamageArea(aColIndex, aRowIndex, 1 + endColIndex - aColIndex, 1 + endRowIndex - aRowIndex, aDamageArea);
|
||||
SetDamageArea(aColIndex, aRgFirstRowIndex + aRowIndex,
|
||||
NS_MAX(0, aMap.GetColCount() - aColIndex - 1),
|
||||
1 + endRowIndex - aRowIndex, aDamageArea);
|
||||
|
||||
if (aMap.mTableFrame.HasZeroColSpans()) {
|
||||
aMap.mTableFrame.SetNeedColSpanExpansion(true);
|
||||
|
@ -2217,8 +2259,7 @@ void
|
|||
nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
|
||||
PRInt32 aStartRowIndex,
|
||||
nsTArray<nsTableRowFrame*>* aRowsToInsert,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
nsRect& aDamageArea)
|
||||
PRInt32 aNumRowsToRemove)
|
||||
{
|
||||
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
|
||||
// copy the old cell map into a new array
|
||||
|
@ -2252,7 +2293,7 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
|
|||
// rowX keeps track of where we are in mRows while setting up the
|
||||
// new cellmap.
|
||||
PRUint32 rowX = 0;
|
||||
|
||||
nsRect damageArea;
|
||||
// put back the rows before the affected ones just as before. Note that we
|
||||
// can't just copy the old rows in bit-for-bit, because they might be
|
||||
// spanning out into the rows we're adding/removing.
|
||||
|
@ -2263,7 +2304,7 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
|
|||
// put in the original cell from the cell map
|
||||
const CellData* data = row.ElementAt(colX);
|
||||
if (data && data->IsOrig()) {
|
||||
AppendCell(aMap, data->GetCellFrame(), rowX, false, aDamageArea);
|
||||
AppendCell(aMap, data->GetCellFrame(), rowX, false, 0, damageArea);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2280,7 +2321,7 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
|
|||
while (cFrame) {
|
||||
nsTableCellFrame *cellFrame = do_QueryFrame(cFrame);
|
||||
if (cellFrame) {
|
||||
AppendCell(aMap, cellFrame, rowX, false, aDamageArea);
|
||||
AppendCell(aMap, cellFrame, rowX, false, 0, damageArea);
|
||||
}
|
||||
cFrame = cFrame->GetNextSibling();
|
||||
}
|
||||
|
@ -2303,7 +2344,7 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
|
|||
// put in the original cell from the cell map
|
||||
CellData* data = row.ElementAt(colX);
|
||||
if (data && data->IsOrig()) {
|
||||
AppendCell(aMap, data->GetCellFrame(), rowX, false, aDamageArea);
|
||||
AppendCell(aMap, data->GetCellFrame(), rowX, false, 0, damageArea);
|
||||
}
|
||||
}
|
||||
rowX++;
|
||||
|
@ -2317,8 +2358,6 @@ nsCellMap::RebuildConsideringRows(nsTableCellMap& aMap,
|
|||
DestroyCellData(row[colX]);
|
||||
}
|
||||
}
|
||||
|
||||
SetDamageArea(0, 0, aMap.GetColCount(), GetRowCount(), aDamageArea);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2327,8 +2366,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
|
|||
nsTArray<nsTableCellFrame*>* aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
bool aInsert,
|
||||
nsRect& aDamageArea)
|
||||
bool aInsert)
|
||||
{
|
||||
NS_ASSERTION(!!aMap.mBCInfo == mIsBC, "BC state mismatch");
|
||||
// copy the old cell map into a new array
|
||||
|
@ -2345,6 +2383,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
|
|||
// build the new cell map. Hard to say what, if anything, we can preallocate
|
||||
// here... Should come back to that sometime, perhaps.
|
||||
PRInt32 rowX;
|
||||
nsRect damageArea;
|
||||
for (rowX = 0; rowX < numOrigRows; rowX++) {
|
||||
const CellDataArray& row = origRows[rowX];
|
||||
for (PRInt32 colX = 0; colX < numCols; colX++) {
|
||||
|
@ -2353,7 +2392,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
|
|||
for (PRInt32 cellX = 0; cellX < numNewCells; cellX++) {
|
||||
nsTableCellFrame* cell = aCellFrames->ElementAt(cellX);
|
||||
if (cell) {
|
||||
AppendCell(aMap, cell, rowX, false, aDamageArea);
|
||||
AppendCell(aMap, cell, rowX, false, 0, damageArea);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2364,7 +2403,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
|
|||
// put in the original cell from the cell map
|
||||
CellData* data = row.SafeElementAt(colX);
|
||||
if (data && data->IsOrig()) {
|
||||
AppendCell(aMap, data->GetCellFrame(), rowX, false, aDamageArea);
|
||||
AppendCell(aMap, data->GetCellFrame(), rowX, false, 0, damageArea);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2373,7 +2412,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
|
|||
for (PRInt32 cellX = 0; cellX < numNewCells; cellX++) {
|
||||
nsTableCellFrame* cell = aCellFrames->ElementAt(cellX);
|
||||
if (cell) {
|
||||
AppendCell(aMap, cell, aRowIndex, false, aDamageArea);
|
||||
AppendCell(aMap, cell, aRowIndex, false, 0, damageArea);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2396,6 +2435,7 @@ nsCellMap::RebuildConsideringCells(nsTableCellMap& aMap,
|
|||
void nsCellMap::RemoveCell(nsTableCellMap& aMap,
|
||||
nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea)
|
||||
{
|
||||
PRUint32 numRows = mRows.Length();
|
||||
|
@ -2429,10 +2469,12 @@ void nsCellMap::RemoveCell(nsTableCellMap& aMap,
|
|||
spansCauseRebuild = true;
|
||||
|
||||
if (spansCauseRebuild) {
|
||||
aMap.RebuildConsideringCells(this, nsnull, aRowIndex, startColIndex, false, aDamageArea);
|
||||
aMap.RebuildConsideringCells(this, nsnull, aRowIndex, startColIndex, false,
|
||||
aDamageArea);
|
||||
}
|
||||
else {
|
||||
ShrinkWithoutCell(aMap, *aCellFrame, aRowIndex, startColIndex, aDamageArea);
|
||||
ShrinkWithoutCell(aMap, *aCellFrame, aRowIndex, startColIndex,
|
||||
aRgFirstRowIndex, aDamageArea);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -378,6 +378,7 @@ public:
|
|||
nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
bool aRebuildIfNecessary,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea,
|
||||
PRInt32* aBeginSearchAtCol = nsnull);
|
||||
|
||||
|
@ -401,23 +402,27 @@ public:
|
|||
nsTArray<nsTableCellFrame*>& aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndexBefore,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RemoveCell(nsTableCellMap& aMap,
|
||||
nsTableCellFrame* aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void InsertRows(nsTableCellMap& aMap,
|
||||
nsTArray<nsTableRowFrame*>& aRows,
|
||||
PRInt32 aFirstRowIndex,
|
||||
bool aConsiderSpans,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void RemoveRows(nsTableCellMap& aMap,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
bool aConsiderSpans,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
|
||||
|
@ -499,6 +504,7 @@ protected:
|
|||
void ExpandWithRows(nsTableCellMap& aMap,
|
||||
nsTArray<nsTableRowFrame*>& aRowFrames,
|
||||
PRInt32 aStartRowIndex,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void ExpandWithCells(nsTableCellMap& aMap,
|
||||
|
@ -507,17 +513,20 @@ protected:
|
|||
PRInt32 aColIndex,
|
||||
PRInt32 aRowSpan,
|
||||
bool aRowSpanIsZero,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void ShrinkWithoutRows(nsTableCellMap& aMap,
|
||||
PRInt32 aFirstRowIndex,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
void ShrinkWithoutCell(nsTableCellMap& aMap,
|
||||
nsTableCellFrame& aCellFrame,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
PRInt32 aRgFirstRowIndex,
|
||||
nsRect& aDamageArea);
|
||||
|
||||
/**
|
||||
|
@ -531,16 +540,14 @@ protected:
|
|||
void RebuildConsideringRows(nsTableCellMap& aMap,
|
||||
PRInt32 aStartRowIndex,
|
||||
nsTArray<nsTableRowFrame*>* aRowsToInsert,
|
||||
PRInt32 aNumRowsToRemove,
|
||||
nsRect& aDamageArea);
|
||||
PRInt32 aNumRowsToRemove);
|
||||
|
||||
void RebuildConsideringCells(nsTableCellMap& aMap,
|
||||
PRInt32 aNumOrigCols,
|
||||
nsTArray<nsTableCellFrame*>* aCellFrames,
|
||||
PRInt32 aRowIndex,
|
||||
PRInt32 aColIndex,
|
||||
bool aInsert,
|
||||
nsRect& aDamageArea);
|
||||
bool aInsert);
|
||||
|
||||
bool CellsSpanOut(nsTArray<nsTableRowFrame*>& aNewRows) const;
|
||||
|
||||
|
|
|
@ -256,7 +256,7 @@ nsTableCellFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
|||
GetColIndex(colIndex);
|
||||
GetRowIndex(rowIndex);
|
||||
nsRect damageArea(colIndex, rowIndex, GetColSpan(), GetRowSpan());
|
||||
tableFrame->SetBCDamageArea(damageArea);
|
||||
tableFrame->AddBCDamageArea(damageArea);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ nsTableColFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
|||
if (tableFrame->IsBorderCollapse() &&
|
||||
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
|
||||
nsRect damageArea = nsRect(GetColIndex(), 0, 1, tableFrame->GetRowCount());
|
||||
tableFrame->SetBCDamageArea(damageArea);
|
||||
tableFrame->AddBCDamageArea(damageArea);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -205,7 +205,7 @@ nsTableColGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
|||
return; // this is a degenerated colgroup
|
||||
nsRect damageArea(GetFirstColumn()->GetColIndex(), 0, colCount,
|
||||
tableFrame->GetRowCount());
|
||||
tableFrame->SetBCDamageArea(damageArea);
|
||||
tableFrame->AddBCDamageArea(damageArea);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -148,11 +148,10 @@ struct nsTableReflowState {
|
|||
|
||||
struct BCPropertyData
|
||||
{
|
||||
BCPropertyData() { mDamageArea.x = mDamageArea.y = mDamageArea.width =
|
||||
mDamageArea.height = mTopBorderWidth = mRightBorderWidth =
|
||||
mBottomBorderWidth = mLeftBorderWidth =
|
||||
mLeftCellBorderWidth = mRightCellBorderWidth = 0; }
|
||||
nsRect mDamageArea;
|
||||
BCPropertyData() : mTopBorderWidth(0), mRightBorderWidth(0),
|
||||
mBottomBorderWidth(0), mLeftBorderWidth(0),
|
||||
mLeftCellBorderWidth(0), mRightCellBorderWidth(0) {}
|
||||
nsRect mDamageArea;
|
||||
BCPixelSize mTopBorderWidth;
|
||||
BCPixelSize mRightBorderWidth;
|
||||
BCPixelSize mBottomBorderWidth;
|
||||
|
@ -351,8 +350,7 @@ nsTableFrame::SetInitialChildList(ChildListID aListID,
|
|||
InsertRowGroups(mFrames);
|
||||
// calc collapsing borders
|
||||
if (IsBorderCollapse()) {
|
||||
nsRect damageArea(0, 0, GetColCount(), GetRowCount());
|
||||
SetBCDamageArea(damageArea);
|
||||
SetFullBCDamageArea();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -604,8 +602,8 @@ void nsTableFrame::InsertCol(nsTableColFrame& aColFrame,
|
|||
}
|
||||
// for now, just bail and recalc all of the collapsing borders
|
||||
if (IsBorderCollapse()) {
|
||||
nsRect damageArea(0, 0, NS_MAX(1, GetColCount()), NS_MAX(1, GetRowCount()));
|
||||
SetBCDamageArea(damageArea);
|
||||
nsRect damageArea(aColIndex, 0, 1, GetRowCount());
|
||||
AddBCDamageArea(damageArea);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -626,7 +624,7 @@ void nsTableFrame::RemoveCol(nsTableColGroupFrame* aColGroupFrame,
|
|||
// for now, just bail and recalc all of the collapsing borders
|
||||
if (IsBorderCollapse()) {
|
||||
nsRect damageArea(0, 0, GetColCount(), GetRowCount());
|
||||
SetBCDamageArea(damageArea);
|
||||
AddBCDamageArea(damageArea);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -799,7 +797,7 @@ nsTableFrame::AppendCell(nsTableCellFrame& aCellFrame,
|
|||
cellMap->AppendCell(aCellFrame, aRowIndex, true, damageArea);
|
||||
MatchCellMapToColCache(cellMap);
|
||||
if (IsBorderCollapse()) {
|
||||
SetBCDamageArea(damageArea);
|
||||
AddBCDamageArea(damageArea);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -814,7 +812,7 @@ void nsTableFrame::InsertCells(nsTArray<nsTableCellFrame*>& aCellFrames,
|
|||
cellMap->InsertCells(aCellFrames, aRowIndex, aColIndexBefore, damageArea);
|
||||
MatchCellMapToColCache(cellMap);
|
||||
if (IsBorderCollapse()) {
|
||||
SetBCDamageArea(damageArea);
|
||||
AddBCDamageArea(damageArea);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -854,7 +852,7 @@ void nsTableFrame::RemoveCell(nsTableCellFrame* aCellFrame,
|
|||
cellMap->RemoveCell(aCellFrame, aRowIndex, damageArea);
|
||||
MatchCellMapToColCache(cellMap);
|
||||
if (IsBorderCollapse()) {
|
||||
SetBCDamageArea(damageArea);
|
||||
AddBCDamageArea(damageArea);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -919,7 +917,7 @@ nsTableFrame::InsertRows(nsTableRowGroupFrame* aRowGroupFrame,
|
|||
rowFrame->SetRowIndex(aRowIndex + rowY);
|
||||
}
|
||||
if (IsBorderCollapse()) {
|
||||
SetBCDamageArea(damageArea);
|
||||
AddBCDamageArea(damageArea);
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_TABLE_CELLMAP
|
||||
|
@ -962,7 +960,7 @@ void nsTableFrame::RemoveRows(nsTableRowFrame& aFirstRowFrame,
|
|||
cellMap->RemoveRows(firstRowIndex, aNumRowsToRemove, aConsiderSpans, damageArea);
|
||||
MatchCellMapToColCache(cellMap);
|
||||
if (IsBorderCollapse()) {
|
||||
SetBCDamageArea(damageArea);
|
||||
AddBCDamageArea(damageArea);
|
||||
}
|
||||
}
|
||||
AdjustRowIndices(firstRowIndex, -aNumRowsToRemove);
|
||||
|
@ -2049,8 +2047,7 @@ nsTableFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
|||
|
||||
if (IsBorderCollapse() &&
|
||||
BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
|
||||
nsRect damageArea(0, 0, GetColCount(), GetRowCount());
|
||||
SetBCDamageArea(damageArea);
|
||||
SetFullBCDamageArea();
|
||||
}
|
||||
|
||||
//avoid this on init or nextinflow
|
||||
|
@ -2309,8 +2306,7 @@ nsTableFrame::RemoveFrame(ChildListID aListID,
|
|||
// for now, just bail and recalc all of the collapsing borders
|
||||
// as the cellmap changes we need to recalc
|
||||
if (IsBorderCollapse()) {
|
||||
nsRect damageArea(0, 0, NS_MAX(1, GetColCount()), NS_MAX(1, GetRowCount()));
|
||||
SetBCDamageArea(damageArea);
|
||||
SetFullBCDamageArea();
|
||||
}
|
||||
PresContext()->PresShell()->FrameNeedsReflow(this, nsIPresShell::eTreeChange,
|
||||
NS_FRAME_HAS_DIRTY_CHILDREN);
|
||||
|
@ -2357,6 +2353,20 @@ DestroyBCProperty(void* aPropertyValue)
|
|||
|
||||
NS_DECLARE_FRAME_PROPERTY(TableBCProperty, DestroyBCProperty)
|
||||
|
||||
BCPropertyData*
|
||||
nsTableFrame::GetBCProperty(bool aCreateIfNecessary) const
|
||||
{
|
||||
FrameProperties props = Properties();
|
||||
BCPropertyData* value = static_cast<BCPropertyData*>
|
||||
(props.Get(TableBCProperty()));
|
||||
if (!value && aCreateIfNecessary) {
|
||||
value = new BCPropertyData();
|
||||
props.Set(TableBCProperty(), value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static void
|
||||
DivideBCBorderSize(BCPixelSize aPixelSize,
|
||||
BCPixelSize& aSmallHalf,
|
||||
|
@ -2374,8 +2384,7 @@ nsTableFrame::GetOuterBCBorder() const
|
|||
|
||||
nsMargin border(0, 0, 0, 0);
|
||||
PRInt32 p2t = nsPresContext::AppUnitsPerCSSPixel();
|
||||
BCPropertyData* propData = static_cast<BCPropertyData*>
|
||||
(Properties().Get(TableBCProperty()));
|
||||
BCPropertyData* propData = GetBCProperty();
|
||||
if (propData) {
|
||||
border.top = BC_BORDER_TOP_HALF_COORD(p2t, propData->mTopBorderWidth);
|
||||
border.right = BC_BORDER_RIGHT_HALF_COORD(p2t, propData->mRightBorderWidth);
|
||||
|
@ -2393,8 +2402,7 @@ nsTableFrame::GetIncludedOuterBCBorder() const
|
|||
|
||||
nsMargin border(0, 0, 0, 0);
|
||||
PRInt32 p2t = nsPresContext::AppUnitsPerCSSPixel();
|
||||
BCPropertyData* propData = static_cast<BCPropertyData*>
|
||||
(Properties().Get(TableBCProperty()));
|
||||
BCPropertyData* propData = GetBCProperty();
|
||||
if (propData) {
|
||||
border.top += BC_BORDER_TOP_HALF_COORD(p2t, propData->mTopBorderWidth);
|
||||
border.right += BC_BORDER_RIGHT_HALF_COORD(p2t, propData->mRightCellBorderWidth);
|
||||
|
@ -3767,22 +3775,6 @@ nsTableFrame::ColumnHasCellSpacingBefore(PRInt32 aColIndex) const
|
|||
return cellMap->GetNumCellsOriginatingInCol(aColIndex) > 0;
|
||||
}
|
||||
|
||||
static void
|
||||
CheckFixDamageArea(PRInt32 aNumRows,
|
||||
PRInt32 aNumCols,
|
||||
nsRect& aDamageArea)
|
||||
{
|
||||
if (((aDamageArea.XMost() > aNumCols) && (aDamageArea.width != 1) && (aNumCols != 0)) ||
|
||||
((aDamageArea.YMost() > aNumRows) && (aDamageArea.height != 1) && (aNumRows != 0))) {
|
||||
// the damage area was set incorrectly, just be safe and make it the entire table
|
||||
NS_ASSERTION(false, "invalid BC damage area");
|
||||
aDamageArea.x = 0;
|
||||
aDamageArea.y = 0;
|
||||
aDamageArea.width = aNumCols;
|
||||
aDamageArea.height = aNumRows;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Collapsing Borders
|
||||
*
|
||||
|
@ -3796,31 +3788,77 @@ CheckFixDamageArea(PRInt32 aNumRows,
|
|||
* 5) if all border styles are NONE, then that's the computed border style.
|
||||
*******************************************************************************/
|
||||
|
||||
void
|
||||
nsTableFrame::SetBCDamageArea(const nsRect& aValue)
|
||||
{
|
||||
nsRect newRect(aValue);
|
||||
newRect.width = NS_MAX(1, newRect.width);
|
||||
newRect.height = NS_MAX(1, newRect.height);
|
||||
#ifdef DEBUG
|
||||
#define VerifyNonNegativeDamageRect(r) \
|
||||
NS_ASSERTION((r).x >= 0, "negative col index"); \
|
||||
NS_ASSERTION((r).y >= 0, "negative row index"); \
|
||||
NS_ASSERTION((r).width >= 0, "negative horizontal damage"); \
|
||||
NS_ASSERTION((r).height >= 0, "negative vertical damage");
|
||||
#define VerifyDamageRect(r) \
|
||||
VerifyNonNegativeDamageRect(r); \
|
||||
NS_ASSERTION((r).XMost() <= GetColCount(), \
|
||||
"horizontal damage extends outside table"); \
|
||||
NS_ASSERTION((r).YMost() <= GetRowCount(), \
|
||||
"vertical damage extends outside table");
|
||||
#endif
|
||||
|
||||
void
|
||||
nsTableFrame::AddBCDamageArea(const nsRect& aValue)
|
||||
{
|
||||
NS_ASSERTION(IsBorderCollapse(), "invalid AddBCDamageArea call");
|
||||
#ifdef DEBUG
|
||||
VerifyDamageRect(aValue);
|
||||
#endif
|
||||
|
||||
if (!IsBorderCollapse()) {
|
||||
NS_ASSERTION(false, "invalid call - not border collapse model");
|
||||
return;
|
||||
}
|
||||
SetNeedToCalcBCBorders(true);
|
||||
// Get the property
|
||||
FrameProperties props = Properties();
|
||||
BCPropertyData* value = static_cast<BCPropertyData*>
|
||||
(props.Get(TableBCProperty()));
|
||||
if (!value) {
|
||||
value = new BCPropertyData();
|
||||
props.Set(TableBCProperty(), value);
|
||||
BCPropertyData* value = GetBCProperty(true);
|
||||
if (value) {
|
||||
#ifdef DEBUG
|
||||
VerifyNonNegativeDamageRect(value->mDamageArea);
|
||||
#endif
|
||||
// Clamp the old damage area to the current table area in case it shrunk.
|
||||
PRInt32 cols = GetColCount();
|
||||
if (value->mDamageArea.XMost() > cols) {
|
||||
if (value->mDamageArea.x > cols) {
|
||||
value->mDamageArea.x = cols;
|
||||
value->mDamageArea.width = 0;
|
||||
}
|
||||
else {
|
||||
value->mDamageArea.width = cols - value->mDamageArea.x;
|
||||
}
|
||||
}
|
||||
PRInt32 rows = GetRowCount();
|
||||
if (value->mDamageArea.YMost() > rows) {
|
||||
if (value->mDamageArea.y > rows) {
|
||||
value->mDamageArea.y = rows;
|
||||
value->mDamageArea.height = 0;
|
||||
}
|
||||
else {
|
||||
value->mDamageArea.height = rows - value->mDamageArea.y;
|
||||
}
|
||||
}
|
||||
|
||||
// Construct a union of the new and old damage areas.
|
||||
value->mDamageArea.UnionRect(value->mDamageArea, aValue);
|
||||
}
|
||||
// for now just construct a union of the new and old damage areas
|
||||
value->mDamageArea.UnionRect(value->mDamageArea, newRect);
|
||||
CheckFixDamageArea(GetRowCount(), GetColCount(), value->mDamageArea);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsTableFrame::SetFullBCDamageArea()
|
||||
{
|
||||
NS_ASSERTION(IsBorderCollapse(), "invalid SetFullBCDamageArea call");
|
||||
|
||||
SetNeedToCalcBCBorders(true);
|
||||
|
||||
BCPropertyData* value = GetBCProperty(true);
|
||||
if (value) {
|
||||
value->mDamageArea = nsRect(0, 0, GetColCount(), GetRowCount());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* BCCellBorder represents a border segment which can be either a horizontal
|
||||
* or a vertical segment. For each segment we need to know the color, width,
|
||||
* style, who owns it and how long it is in cellmap coordinates.
|
||||
|
@ -4216,7 +4254,9 @@ BCMapCellIterator::SetNewRow(nsTableRowFrame* aRow)
|
|||
CellData* cellData = row.SafeElementAt(mColIndex);
|
||||
if (!cellData) { // add a dead cell data
|
||||
nsRect damageArea;
|
||||
cellData = mCellMap->AppendCell(*mTableCellMap, nsnull, rgRowIndex, false, damageArea); if (!cellData) ABORT1(false);
|
||||
cellData = mCellMap->AppendCell(*mTableCellMap, nsnull, rgRowIndex,
|
||||
false, 0, damageArea);
|
||||
if (!cellData) ABORT1(false);
|
||||
}
|
||||
if (cellData && (cellData->IsOrig() || cellData->IsDead())) {
|
||||
break;
|
||||
|
@ -4312,7 +4352,7 @@ BCMapCellIterator::Next(BCMapCellInfo& aMapInfo)
|
|||
nsRect damageArea;
|
||||
cellData =
|
||||
static_cast<BCCellData*>(mCellMap->AppendCell(*mTableCellMap, nsnull,
|
||||
rgRowIndex, false,
|
||||
rgRowIndex, false, 0,
|
||||
damageArea));
|
||||
if (!cellData) ABORT0();
|
||||
}
|
||||
|
@ -4347,7 +4387,7 @@ BCMapCellIterator::PeekRight(BCMapCellInfo& aRefInfo,
|
|||
nsRect damageArea;
|
||||
cellData =
|
||||
static_cast<BCCellData*>(mCellMap->AppendCell(*mTableCellMap, nsnull,
|
||||
rgRowIndex, false,
|
||||
rgRowIndex, false, 0,
|
||||
damageArea));
|
||||
if (!cellData) ABORT0();
|
||||
}
|
||||
|
@ -4405,7 +4445,7 @@ BCMapCellIterator::PeekBottom(BCMapCellInfo& aRefInfo,
|
|||
nsRect damageArea;
|
||||
cellData =
|
||||
static_cast<BCCellData*>(cellMap->AppendCell(*mTableCellMap, nsnull,
|
||||
rgRowIndex, false,
|
||||
rgRowIndex, false, 0,
|
||||
damageArea));
|
||||
if (!cellData) ABORT0();
|
||||
}
|
||||
|
@ -5469,13 +5509,11 @@ nsTableFrame::CalcBCBorders()
|
|||
return; // nothing to do
|
||||
|
||||
// Get the property holding the table damage area and border widths
|
||||
BCPropertyData* propData = static_cast<BCPropertyData*>
|
||||
(Properties().Get(TableBCProperty()));
|
||||
BCPropertyData* propData = GetBCProperty();
|
||||
if (!propData) ABORT0();
|
||||
|
||||
|
||||
|
||||
CheckFixDamageArea(numRows, numCols, propData->mDamageArea);
|
||||
// calculate an expanded damage area
|
||||
nsRect damageArea(propData->mDamageArea);
|
||||
ExpandBCDamageArea(damageArea);
|
||||
|
|
|
@ -58,6 +58,7 @@ class nsStyleContext;
|
|||
|
||||
struct nsTableReflowState;
|
||||
struct nsStylePosition;
|
||||
struct BCPropertyData;
|
||||
|
||||
static inline bool IS_TABLE_CELL(nsIAtom* frameType) {
|
||||
return nsGkAtoms::tableCellFrame == frameType ||
|
||||
|
@ -291,7 +292,7 @@ public:
|
|||
|
||||
friend class nsDelayedCalcBCBorders;
|
||||
|
||||
void SetBCDamageArea(const nsRect& aValue);
|
||||
void AddBCDamageArea(const nsRect& aValue);
|
||||
bool BCRecalcNeeded(nsStyleContext* aOldStyleContext,
|
||||
nsStyleContext* aNewStyleContext);
|
||||
void PaintBCBorders(nsRenderingContext& aRenderingContext,
|
||||
|
@ -688,10 +689,13 @@ public:
|
|||
|
||||
nsTArray<nsTableColFrame*>& GetColCache();
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
void SetBorderCollapse(bool aValue);
|
||||
|
||||
BCPropertyData* GetBCProperty(bool aCreateIfNecessary = false) const;
|
||||
void SetFullBCDamageArea();
|
||||
void CalcBCBorders();
|
||||
|
||||
void ExpandBCDamageArea(nsRect& aRect) const;
|
||||
|
|
|
@ -195,7 +195,7 @@ nsTableRowFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
|||
if (tableFrame->IsBorderCollapse() &&
|
||||
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
|
||||
nsRect damageArea(0, GetRowIndex(), tableFrame->GetColCount(), 1);
|
||||
tableFrame->SetBCDamageArea(damageArea);
|
||||
tableFrame->AddBCDamageArea(damageArea);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1389,7 +1389,7 @@ nsTableRowGroupFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
|||
tableFrame->BCRecalcNeeded(aOldStyleContext, GetStyleContext())) {
|
||||
nsRect damageArea(0, GetStartRowIndex(), tableFrame->GetColCount(),
|
||||
GetRowCount());
|
||||
tableFrame->SetBCDamageArea(damageArea);
|
||||
tableFrame->AddBCDamageArea(damageArea);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -268,6 +268,12 @@ moz_malloc_usable_size(void *ptr)
|
|||
#endif
|
||||
}
|
||||
|
||||
size_t moz_malloc_size_of(const void *ptr, size_t computedSize)
|
||||
{
|
||||
size_t usable = moz_malloc_usable_size((void *)ptr);
|
||||
return usable ? usable : computedSize;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
const fallible_t fallible = fallible_t();
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
#include "xpcom-config.h"
|
||||
|
||||
#define MOZALLOC_HAVE_XMALLOC
|
||||
#define MOZALLOC_HAVE_MALLOC_USABLE_SIZE
|
||||
|
||||
#if defined(MOZALLOC_EXPORT)
|
||||
/* do nothing: it's been defined to __declspec(dllexport) by
|
||||
|
@ -136,6 +135,8 @@ MOZALLOC_EXPORT char* moz_strdup(const char* str)
|
|||
|
||||
MOZALLOC_EXPORT size_t moz_malloc_usable_size(void *ptr);
|
||||
|
||||
MOZALLOC_EXPORT size_t moz_malloc_size_of(const void *ptr, size_t computedSize);
|
||||
|
||||
#if defined(HAVE_STRNDUP)
|
||||
MOZALLOC_EXPORT char* moz_xstrndup(const char* str, size_t strsize)
|
||||
NS_ATTR_MALLOC NS_WARN_UNUSED_RESULT;
|
||||
|
|
|
@ -401,11 +401,11 @@ Preferences::ReadUserPrefs(nsIFile *aFile)
|
|||
nsresult rv;
|
||||
|
||||
if (nsnull == aFile) {
|
||||
rv = UseDefaultPrefFile();
|
||||
UseUserPrefFile();
|
||||
|
||||
NotifyServiceObservers(NS_PREFSERVICE_READ_TOPIC_ID);
|
||||
|
||||
rv = UseDefaultPrefFile();
|
||||
UseUserPrefFile();
|
||||
} else {
|
||||
rv = ReadAndOwnUserPrefFile(aFile);
|
||||
}
|
||||
|
|
|
@ -169,8 +169,8 @@ nsDiskCacheMap::Open(nsILocalFile * cacheDirectory)
|
|||
{
|
||||
// extra scope so the compiler doesn't barf on the above gotos jumping
|
||||
// past this declaration down here
|
||||
PRUint32 overhead = moz_malloc_usable_size(mRecordArray);
|
||||
overhead = overhead ? overhead : mHeader.mRecordCount * sizeof(nsDiskCacheRecord);
|
||||
PRUint32 overhead =
|
||||
moz_malloc_size_of(mRecordArray, mHeader.mRecordCount * sizeof(nsDiskCacheRecord));
|
||||
mozilla::Telemetry::Accumulate(mozilla::Telemetry::HTTP_DISK_CACHE_OVERHEAD,
|
||||
overhead);
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче