1998-04-13 20:24:54 +00:00
|
|
|
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
|
* The contents of this file are subject to the Netscape 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/NPL/
|
1998-04-13 20:24:54 +00:00
|
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
|
* 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.
|
1998-04-13 20:24:54 +00:00
|
|
|
|
*
|
1999-11-06 03:40:37 +00:00
|
|
|
|
* The Original Code is mozilla.org code.
|
|
|
|
|
*
|
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
1998-04-13 20:24:54 +00:00
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
1999-11-06 03:40:37 +00:00
|
|
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
|
|
|
* Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s):
|
2001-04-18 06:06:31 +00:00
|
|
|
|
* Steve Clark <buster@netscape.com>
|
|
|
|
|
* H<EFBFBD>kan Waara <hwaara@chello.se>
|
|
|
|
|
* Dan Rosen <dr@netscape.com>
|
2000-05-15 03:37:21 +00:00
|
|
|
|
*
|
|
|
|
|
* IBM Corporation
|
|
|
|
|
*
|
|
|
|
|
* This Original Code has been modified by IBM Corporation.
|
|
|
|
|
* Modifications made by IBM described herein are
|
|
|
|
|
* Copyright (c) International Business Machines
|
|
|
|
|
* Corporation, 2000
|
|
|
|
|
*
|
|
|
|
|
* Modifications to Mozilla code or documentation
|
|
|
|
|
* identified per MPL Section 3.3
|
|
|
|
|
*
|
|
|
|
|
* Date Modified by Description of modification
|
|
|
|
|
* 05/03/2000 IBM Corp. Observer events for reflow states
|
1999-09-10 18:29:37 +00:00
|
|
|
|
*/
|
2001-04-18 06:06:31 +00:00
|
|
|
|
|
1999-12-07 04:36:08 +00:00
|
|
|
|
#define PL_ARENA_CONST_ALIGN_MASK 3
|
1998-04-13 20:24:54 +00:00
|
|
|
|
#include "nsIPresShell.h"
|
2000-03-22 23:19:10 +00:00
|
|
|
|
#include "nsISpaceManager.h"
|
1999-12-04 23:49:50 +00:00
|
|
|
|
#include "nsIPresContext.h"
|
1998-04-13 20:24:54 +00:00
|
|
|
|
#include "nsIContent.h"
|
|
|
|
|
#include "nsIDocument.h"
|
1998-06-03 15:46:54 +00:00
|
|
|
|
#include "nsIDocumentObserver.h"
|
1998-04-13 20:24:54 +00:00
|
|
|
|
#include "nsIStyleSet.h"
|
1998-11-26 01:34:53 +00:00
|
|
|
|
#include "nsICSSStyleSheet.h" // XXX for UA sheet loading hack, can this go away please?
|
2000-10-11 08:33:01 +00:00
|
|
|
|
#include "nsIDOMCSSStyleSheet.h" // for Pref-related rule management (bugs 22963,20760,31816)
|
|
|
|
|
#include "nsINameSpaceManager.h" // for Pref-related rule management (bugs 22963,20760,31816)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
#include "nsIStyleContext.h"
|
1999-08-05 20:17:44 +00:00
|
|
|
|
#include "nsIServiceManager.h"
|
1998-05-20 16:24:54 +00:00
|
|
|
|
#include "nsFrame.h"
|
1998-06-09 04:51:44 +00:00
|
|
|
|
#include "nsIReflowCommand.h"
|
1998-04-13 20:24:54 +00:00
|
|
|
|
#include "nsIViewManager.h"
|
|
|
|
|
#include "nsCRT.h"
|
1998-06-03 15:46:54 +00:00
|
|
|
|
#include "prlog.h"
|
2000-04-01 08:35:40 +00:00
|
|
|
|
#include "prmem.h"
|
1998-12-12 19:21:05 +00:00
|
|
|
|
#include "prinrval.h"
|
1998-06-09 04:51:44 +00:00
|
|
|
|
#include "nsVoidArray.h"
|
2000-10-09 03:08:41 +00:00
|
|
|
|
#include "nsHashtable.h"
|
1998-07-31 05:54:59 +00:00
|
|
|
|
#include "nsIPref.h"
|
1998-08-28 02:54:06 +00:00
|
|
|
|
#include "nsIViewObserver.h"
|
1998-09-19 03:24:26 +00:00
|
|
|
|
#include "nsContainerFrame.h"
|
1998-10-01 04:46:11 +00:00
|
|
|
|
#include "nsHTMLIIDs.h"
|
1998-10-02 01:12:39 +00:00
|
|
|
|
#include "nsIDeviceContext.h"
|
1998-11-18 05:25:26 +00:00
|
|
|
|
#include "nsIEventStateManager.h"
|
2000-12-30 19:22:22 +00:00
|
|
|
|
#include "nsIDOMEvent.h"
|
1998-11-17 02:14:38 +00:00
|
|
|
|
#include "nsHTMLParts.h"
|
2000-09-14 11:45:01 +00:00
|
|
|
|
#include "nsISelection.h"
|
1999-12-02 21:45:21 +00:00
|
|
|
|
#include "nsISelectionController.h"
|
1998-12-08 18:26:06 +00:00
|
|
|
|
#include "nsLayoutCID.h"
|
2000-03-22 23:19:10 +00:00
|
|
|
|
#include "nsLayoutAtoms.h"
|
1998-12-14 18:34:14 +00:00
|
|
|
|
#include "nsIDOMRange.h"
|
|
|
|
|
#include "nsIDOMDocument.h"
|
|
|
|
|
#include "nsIDOMNode.h"
|
2000-09-14 11:45:01 +00:00
|
|
|
|
#include "nsIDOMNodeList.h"
|
1998-12-14 18:34:14 +00:00
|
|
|
|
#include "nsIDOMElement.h"
|
1999-01-07 04:47:43 +00:00
|
|
|
|
#include "nsHTMLAtoms.h"
|
1999-01-22 18:58:14 +00:00
|
|
|
|
#include "nsCOMPtr.h"
|
1999-08-25 10:51:55 +00:00
|
|
|
|
#include "nsWeakReference.h"
|
2000-01-04 20:24:09 +00:00
|
|
|
|
#include "nsIPageSequenceFrame.h"
|
1999-02-12 00:02:56 +00:00
|
|
|
|
#include "nsICaret.h"
|
1999-02-12 05:39:33 +00:00
|
|
|
|
#include "nsIDOMHTMLDocument.h"
|
1999-03-20 01:51:00 +00:00
|
|
|
|
#include "nsIXMLDocument.h"
|
1999-02-12 05:39:33 +00:00
|
|
|
|
#include "nsIScrollableView.h"
|
1999-03-01 19:21:01 +00:00
|
|
|
|
#include "nsIParser.h"
|
|
|
|
|
#include "nsParserCIID.h"
|
1999-03-12 00:17:14 +00:00
|
|
|
|
#include "nsIFrameSelection.h"
|
2000-06-14 02:57:26 +00:00
|
|
|
|
#include "nsIDOMNSHTMLInputElement.h" //optimization for ::DoXXX commands
|
2000-06-29 22:33:36 +00:00
|
|
|
|
#include "nsIDOMNSHTMLTextAreaElement.h"
|
1999-04-03 18:58:04 +00:00
|
|
|
|
#include "nsViewsCID.h"
|
1999-08-04 04:02:40 +00:00
|
|
|
|
#include "nsIFrameManager.h"
|
1999-08-25 08:35:06 +00:00
|
|
|
|
#include "nsISupportsPrimitives.h"
|
1999-08-30 22:38:58 +00:00
|
|
|
|
#include "nsILayoutHistoryState.h"
|
1999-10-15 04:29:30 +00:00
|
|
|
|
#include "nsIScrollPositionListener.h"
|
|
|
|
|
#include "nsICompositeListener.h"
|
2001-01-10 02:43:00 +00:00
|
|
|
|
#include "nsILineIterator.h" // for ScrollFrameIntoView
|
1999-11-10 03:41:09 +00:00
|
|
|
|
#include "nsTimer.h"
|
1999-11-09 03:23:26 +00:00
|
|
|
|
#include "nsWeakPtr.h"
|
1999-12-07 04:36:08 +00:00
|
|
|
|
#include "plarena.h"
|
2000-03-23 00:34:54 +00:00
|
|
|
|
#include "nsCSSAtoms.h"
|
2000-05-15 03:37:21 +00:00
|
|
|
|
#include "nsIObserverService.h" // for reflow observation
|
2000-08-30 00:35:43 +00:00
|
|
|
|
#include "nsIDocShell.h" // for reflow observation
|
2001-03-27 23:59:56 +00:00
|
|
|
|
#include "nsIDOMRange.h"
|
1999-10-19 22:27:20 +00:00
|
|
|
|
#ifdef MOZ_PERF_METRICS
|
1999-09-20 08:23:33 +00:00
|
|
|
|
#include "nsITimeRecorder.h"
|
|
|
|
|
#endif
|
1999-11-01 22:12:45 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
|
#include "nsIFrameDebug.h"
|
|
|
|
|
#endif
|
1999-02-19 23:47:36 +00:00
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
#ifdef MOZ_REFLOW_PERF_DSP
|
|
|
|
|
#include "nsIRenderingContext.h"
|
|
|
|
|
#include "nsIFontMetrics.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-07-13 23:00:59 +00:00
|
|
|
|
#include "nsIReflowCallback.h"
|
|
|
|
|
|
2000-02-13 06:07:38 +00:00
|
|
|
|
#include "nsIScriptGlobalObject.h"
|
2000-09-01 01:54:35 +00:00
|
|
|
|
#include "nsIDOMWindowInternal.h"
|
2000-02-13 06:07:38 +00:00
|
|
|
|
#include "nsPIDOMWindow.h"
|
2000-11-04 08:21:20 +00:00
|
|
|
|
#include "nsIFocusController.h"
|
2000-02-13 06:07:38 +00:00
|
|
|
|
|
1999-03-23 21:32:48 +00:00
|
|
|
|
// Drag & Drop, Clipboard
|
|
|
|
|
#include "nsWidgetsCID.h"
|
|
|
|
|
#include "nsIClipboard.h"
|
1999-12-18 02:09:29 +00:00
|
|
|
|
#include "nsIDocShellTreeItem.h"
|
1999-11-09 03:23:26 +00:00
|
|
|
|
#include "nsIURI.h"
|
|
|
|
|
#include "nsIEventQueue.h"
|
|
|
|
|
#include "nsIEventQueueService.h"
|
1999-12-07 05:28:32 +00:00
|
|
|
|
#include "nsIScrollableFrame.h"
|
1999-12-23 02:02:33 +00:00
|
|
|
|
#include "prtime.h"
|
|
|
|
|
#include "prlong.h"
|
2000-06-14 23:18:54 +00:00
|
|
|
|
#include "nsIDragService.h"
|
2001-02-15 13:22:26 +00:00
|
|
|
|
#include "nsCopySupport.h"
|
2001-04-18 06:06:31 +00:00
|
|
|
|
#include "nsIDOMHTMLAnchorElement.h"
|
|
|
|
|
#include "nsIDOMHTMLImageElement.h"
|
2001-04-17 23:25:21 +00:00
|
|
|
|
#include "nsITimer.h"
|
2000-06-14 23:18:54 +00:00
|
|
|
|
|
2000-09-12 00:35:11 +00:00
|
|
|
|
// Dummy layout request
|
|
|
|
|
#include "nsIChannel.h"
|
|
|
|
|
#include "nsILoadGroup.h"
|
|
|
|
|
#include "nsNetUtil.h"
|
2000-06-14 23:18:54 +00:00
|
|
|
|
|
2000-03-03 23:15:29 +00:00
|
|
|
|
// SubShell map
|
|
|
|
|
#include "nsDST.h"
|
|
|
|
|
|
2001-03-09 03:29:00 +00:00
|
|
|
|
#ifdef IBMBIDI
|
|
|
|
|
#include "nsIBidiKeyboard.h"
|
|
|
|
|
#endif // IBMBIDI
|
|
|
|
|
|
2001-02-19 21:50:04 +00:00
|
|
|
|
#include "nsContentCID.h"
|
|
|
|
|
static NS_DEFINE_CID(kCSSStyleSheetCID, NS_CSS_STYLESHEET_CID);
|
|
|
|
|
static NS_DEFINE_CID(kStyleSetCID, NS_STYLESET_CID);
|
2001-03-27 23:59:56 +00:00
|
|
|
|
static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
|
2001-02-19 21:50:04 +00:00
|
|
|
|
|
2000-10-11 08:33:01 +00:00
|
|
|
|
// supporting bugs 31816, 20760, 22963
|
|
|
|
|
// define USE_OVERRIDE to put prefs in as an override stylesheet
|
|
|
|
|
// otherwise they go in as a Backstop stylesheets
|
|
|
|
|
// - OVERRIDE is better for text and bg colors, but bad for link colors,
|
|
|
|
|
// so eventually, we should probably have a backstop and an override and
|
|
|
|
|
// put the link colors in the backstop and the text and bg colors in the override,
|
|
|
|
|
// but using the backstop stylesheet with !important rules solves 95% of the
|
|
|
|
|
// problem and should suffice for RTM
|
|
|
|
|
//
|
|
|
|
|
// XXX: use backstop stylesheet of link colors and link underline,
|
|
|
|
|
// user override stylesheet for forcing background and text colors, post RTM
|
|
|
|
|
//
|
|
|
|
|
// #define PREFS_USE_OVERRIDE
|
|
|
|
|
|
|
|
|
|
// convert a color value to a string, in the CSS format #RRGGBB
|
|
|
|
|
// * - initially created for bugs 31816, 20760, 22963
|
|
|
|
|
static void ColorToString(nscolor aColor, nsAutoString &aString);
|
|
|
|
|
|
|
|
|
|
|
2000-02-11 01:21:05 +00:00
|
|
|
|
// local management of the style watch:
|
|
|
|
|
// aCtlValue should be set to all actions desired (bitwise OR'd together)
|
|
|
|
|
// aStyleSet cannot be null
|
|
|
|
|
// NOTE: implementation is noop unless MOZ_PERF_METRICS is defined
|
|
|
|
|
static nsresult CtlStyleWatch(PRUint32 aCtlValue, nsIStyleSet *aStyleSet);
|
|
|
|
|
#define kStyleWatchEnable 1
|
|
|
|
|
#define kStyleWatchDisable 2
|
|
|
|
|
#define kStyleWatchPrint 4
|
|
|
|
|
#define kStyleWatchStart 8
|
|
|
|
|
#define kStyleWatchStop 16
|
|
|
|
|
#define kStyleWatchReset 32
|
1999-11-09 03:23:26 +00:00
|
|
|
|
|
2000-01-04 20:24:09 +00:00
|
|
|
|
// Class ID's
|
|
|
|
|
static NS_DEFINE_CID(kFrameSelectionCID, NS_FRAMESELECTION_CID);
|
|
|
|
|
static NS_DEFINE_CID(kCRangeCID, NS_RANGE_CID);
|
|
|
|
|
static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
|
|
|
|
|
static NS_DEFINE_CID(kViewCID, NS_VIEW_CID);
|
|
|
|
|
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
1999-03-23 21:32:48 +00:00
|
|
|
|
|
|
|
|
|
// Drag & Drop, Clipboard Support
|
1999-05-04 14:55:24 +00:00
|
|
|
|
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
1999-05-13 21:53:57 +00:00
|
|
|
|
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
|
Checking in for bug 50742, this change removes the use of XIF in mozilla and replaces the XIF converter with a HTML (and XML) serializer.
Contextual information added to HTML copy and intelligence added to HTML paste in the editor (fixes bugs 47014, 50568 and 46554, and partly (at least) fixes bug 53188).
Code written by vidur, jfrancis, jst, akkana. Tested by jfrancis, akkana, vidur, jst, kin. Reviwed (and super reviewed) by waterson, vidur, kin, jfrancis, jst
2000-10-07 10:57:30 +00:00
|
|
|
|
static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
|
|
|
|
#undef NOISY
|
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
//========================================================================
|
|
|
|
|
//========================================================================
|
2000-04-26 21:01:57 +00:00
|
|
|
|
//========================================================================
|
|
|
|
|
#ifdef MOZ_REFLOW_PERF
|
|
|
|
|
class ReflowCountMgr;
|
|
|
|
|
|
|
|
|
|
static const char * kGrandTotalsStr = "Grand Totals";
|
|
|
|
|
#define NUM_REFLOW_TYPES 5
|
|
|
|
|
|
|
|
|
|
// Counting Class
|
|
|
|
|
class ReflowCounter {
|
|
|
|
|
public:
|
2001-02-22 13:58:17 +00:00
|
|
|
|
ReflowCounter(ReflowCountMgr * aMgr = nsnull);
|
2000-04-26 21:01:57 +00:00
|
|
|
|
~ReflowCounter();
|
|
|
|
|
|
|
|
|
|
void ClearTotals();
|
|
|
|
|
void DisplayTotals(const char * aStr);
|
2000-04-28 23:32:04 +00:00
|
|
|
|
void DisplayDiffTotals(const char * aStr);
|
2000-04-26 21:01:57 +00:00
|
|
|
|
void DisplayHTMLTotals(const char * aStr);
|
|
|
|
|
|
2000-04-28 23:32:04 +00:00
|
|
|
|
void Add(nsReflowReason aType) { mTotals[aType]++; }
|
|
|
|
|
void Add(nsReflowReason aType, PRUint32 aTotal) { mTotals[aType] += aTotal; }
|
|
|
|
|
|
|
|
|
|
void CalcDiffInTotals();
|
|
|
|
|
void SetTotalsCache();
|
|
|
|
|
|
|
|
|
|
void SetMgr(ReflowCountMgr * aMgr) { mMgr = aMgr; }
|
2000-04-26 21:01:57 +00:00
|
|
|
|
|
2001-02-22 13:58:17 +00:00
|
|
|
|
PRUint32 GetTotalByType(nsReflowReason aType) { if (aType >= eReflowReason_Initial && aType <= eReflowReason_Dirty) return mTotals[aType]; else return 0; }
|
|
|
|
|
|
2000-04-26 21:01:57 +00:00
|
|
|
|
protected:
|
|
|
|
|
void DisplayTotals(PRUint32 * aArray, const char * aTitle);
|
|
|
|
|
void DisplayHTMLTotals(PRUint32 * aArray, const char * aTitle);
|
|
|
|
|
|
|
|
|
|
PRUint32 mTotals[NUM_REFLOW_TYPES];
|
2000-04-28 23:32:04 +00:00
|
|
|
|
PRUint32 mCacheTotals[NUM_REFLOW_TYPES];
|
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
ReflowCountMgr * mMgr; // weak reference (don't delete)
|
2000-04-26 21:01:57 +00:00
|
|
|
|
};
|
|
|
|
|
|
2001-02-22 13:58:17 +00:00
|
|
|
|
// Counting Class
|
|
|
|
|
class IndiReflowCounter {
|
|
|
|
|
public:
|
2001-03-13 01:47:22 +00:00
|
|
|
|
IndiReflowCounter(ReflowCountMgr * aMgr = nsnull):mMgr(aMgr),mCounter(aMgr),mFrame(nsnull), mCount(0), mHasBeenOutput(PR_FALSE) {}
|
2001-02-22 13:58:17 +00:00
|
|
|
|
virtual ~IndiReflowCounter() {}
|
|
|
|
|
|
|
|
|
|
nsAutoString mName;
|
2001-03-13 01:47:22 +00:00
|
|
|
|
nsIFrame * mFrame; // weak reference (don't delete)
|
2001-02-22 13:58:17 +00:00
|
|
|
|
PRInt32 mCount;
|
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
ReflowCountMgr * mMgr; // weak reference (don't delete)
|
2001-02-22 13:58:17 +00:00
|
|
|
|
|
|
|
|
|
ReflowCounter mCounter;
|
|
|
|
|
PRBool mHasBeenOutput;
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
//--------------------
|
2000-04-26 21:01:57 +00:00
|
|
|
|
// Manager Class
|
2001-03-13 01:47:22 +00:00
|
|
|
|
//--------------------
|
2000-04-26 21:01:57 +00:00
|
|
|
|
class ReflowCountMgr {
|
|
|
|
|
public:
|
|
|
|
|
ReflowCountMgr();
|
2001-03-13 01:47:22 +00:00
|
|
|
|
virtual ~ReflowCountMgr();
|
2000-04-26 21:01:57 +00:00
|
|
|
|
|
|
|
|
|
void ClearTotals();
|
2000-04-28 23:32:04 +00:00
|
|
|
|
void ClearGrandTotals();
|
2000-04-26 21:01:57 +00:00
|
|
|
|
void DisplayTotals(const char * aStr);
|
|
|
|
|
void DisplayHTMLTotals(const char * aStr);
|
2000-04-28 23:32:04 +00:00
|
|
|
|
void DisplayDiffsInTotals(const char * aStr);
|
2000-04-26 21:01:57 +00:00
|
|
|
|
|
2001-02-22 13:58:17 +00:00
|
|
|
|
void Add(const char * aName, nsReflowReason aType, nsIFrame * aFrame);
|
2000-04-26 21:01:57 +00:00
|
|
|
|
ReflowCounter * LookUp(const char * aName);
|
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
void PaintCount(const char * aName, nsIRenderingContext* aRenderingContext, nsIPresContext* aPresContext, nsIFrame * aFrame, PRUint32 aColor);
|
|
|
|
|
|
2000-04-26 21:01:57 +00:00
|
|
|
|
FILE * GetOutFile() { return mFD; }
|
|
|
|
|
|
2001-02-22 13:58:17 +00:00
|
|
|
|
PLHashTable * GetIndiFrameHT() { return mIndiFrameCounts; }
|
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
void SetPresContext(nsIPresContext * aPresContext) { mPresContext = aPresContext; } // weak reference
|
|
|
|
|
void SetPresShell(nsIPresShell* aPresShell) { mPresShell= aPresShell; } // weak reference
|
|
|
|
|
|
|
|
|
|
void SetDumpFrameCounts(PRBool aVal) { mDumpFrameCounts = aVal; }
|
|
|
|
|
void SetDumpFrameByFrameCounts(PRBool aVal) { mDumpFrameByFrameCounts = aVal; }
|
|
|
|
|
void SetPaintFrameCounts(PRBool aVal) { mPaintFrameByFrameCounts = aVal; }
|
2001-02-22 13:58:17 +00:00
|
|
|
|
|
2000-04-26 21:01:57 +00:00
|
|
|
|
protected:
|
|
|
|
|
void DisplayTotals(PRUint32 * aArray, PRUint32 * aDupArray, char * aTitle);
|
|
|
|
|
void DisplayHTMLTotals(PRUint32 * aArray, PRUint32 * aDupArray, char * aTitle);
|
|
|
|
|
|
2001-03-14 23:57:37 +00:00
|
|
|
|
PR_STATIC_CALLBACK(PRIntn) RemoveItems(PLHashEntry *he, PRIntn i, void *arg);
|
|
|
|
|
PR_STATIC_CALLBACK(PRIntn) RemoveIndiItems(PLHashEntry *he, PRIntn i, void *arg);
|
2000-04-26 21:01:57 +00:00
|
|
|
|
void CleanUp();
|
|
|
|
|
|
|
|
|
|
// stdout Output Methods
|
2001-03-14 23:57:37 +00:00
|
|
|
|
PR_STATIC_CALLBACK(PRIntn) DoSingleTotal(PLHashEntry *he, PRIntn i, void *arg);
|
|
|
|
|
PR_STATIC_CALLBACK(PRIntn) DoSingleIndi(PLHashEntry *he, PRIntn i, void *arg);
|
2001-02-22 13:58:17 +00:00
|
|
|
|
|
2000-04-26 21:01:57 +00:00
|
|
|
|
void DoGrandTotals();
|
2001-02-22 13:58:17 +00:00
|
|
|
|
void DoIndiTotalsTree();
|
2000-04-26 21:01:57 +00:00
|
|
|
|
|
|
|
|
|
// HTML Output Methods
|
2001-03-14 23:57:37 +00:00
|
|
|
|
PR_STATIC_CALLBACK(PRIntn) DoSingleHTMLTotal(PLHashEntry *he, PRIntn i, void *arg);
|
2000-04-26 21:01:57 +00:00
|
|
|
|
void DoGrandHTMLTotals();
|
|
|
|
|
|
2000-04-28 23:32:04 +00:00
|
|
|
|
// Zero Out the Totals
|
2001-03-14 23:57:37 +00:00
|
|
|
|
PR_STATIC_CALLBACK(PRIntn) DoClearTotals(PLHashEntry *he, PRIntn i, void *arg);
|
2000-04-28 23:32:04 +00:00
|
|
|
|
|
|
|
|
|
// Displays the Diff Totals
|
2001-03-14 23:57:37 +00:00
|
|
|
|
PR_STATIC_CALLBACK(PRIntn) DoDisplayDiffTotals(PLHashEntry *he, PRIntn i, void *arg);
|
2000-04-28 23:32:04 +00:00
|
|
|
|
|
2000-04-26 21:01:57 +00:00
|
|
|
|
PLHashTable * mCounts;
|
2001-02-22 13:58:17 +00:00
|
|
|
|
PLHashTable * mIndiFrameCounts;
|
2000-04-26 21:01:57 +00:00
|
|
|
|
FILE * mFD;
|
2001-02-22 13:58:17 +00:00
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
PRBool mDumpFrameCounts;
|
|
|
|
|
PRBool mDumpFrameByFrameCounts;
|
|
|
|
|
PRBool mPaintFrameByFrameCounts;
|
|
|
|
|
|
2000-04-28 23:32:04 +00:00
|
|
|
|
PRBool mCycledOnce;
|
|
|
|
|
|
2001-02-22 13:58:17 +00:00
|
|
|
|
// Root Frame for Individual Tracking
|
|
|
|
|
nsIPresContext * mPresContext;
|
|
|
|
|
nsIPresShell* mPresShell;
|
|
|
|
|
|
2000-04-26 21:01:57 +00:00
|
|
|
|
// ReflowCountMgr gReflowCountMgr;
|
|
|
|
|
};
|
|
|
|
|
#endif
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
1999-02-12 00:02:56 +00:00
|
|
|
|
// comment out to hide caret
|
1999-03-02 04:26:49 +00:00
|
|
|
|
#define SHOW_CARET
|
1999-02-12 00:02:56 +00:00
|
|
|
|
|
1999-12-23 02:02:33 +00:00
|
|
|
|
// The upper bound on the amount of time to spend reflowing. When this bound is exceeded
|
|
|
|
|
// and reflow commands are still queued up, a reflow event is posted. The idea is for reflow
|
|
|
|
|
// to not hog the processor beyond the time specifed in gMaxRCProcessingTime.
|
|
|
|
|
// This data member is initialized from the layout.reflow.timeslice pref.
|
|
|
|
|
#define NS_MAX_REFLOW_TIME 1000000
|
1999-12-23 03:47:02 +00:00
|
|
|
|
static PRInt32 gMaxRCProcessingTime = -1;
|
1999-12-23 02:02:33 +00:00
|
|
|
|
|
2000-09-12 08:59:01 +00:00
|
|
|
|
// Set to true to enable async reflow during document load.
|
|
|
|
|
// This flag is initialized from the layout.reflow.async.duringDocLoad pref.
|
|
|
|
|
static PRBool gAsyncReflowDuringDocLoad = PR_FALSE;
|
|
|
|
|
|
1999-12-07 04:36:08 +00:00
|
|
|
|
// Largest chunk size we recycle
|
2000-03-31 07:02:06 +00:00
|
|
|
|
static const size_t gMaxRecycledSize = 400;
|
1999-12-07 04:36:08 +00:00
|
|
|
|
|
2000-03-31 07:02:06 +00:00
|
|
|
|
#define MARK_INCREMENT 50
|
|
|
|
|
#define BLOCK_INCREMENT 2048
|
|
|
|
|
|
|
|
|
|
/**A block of memory that the stack will
|
|
|
|
|
* chop up and hand out
|
|
|
|
|
*/
|
|
|
|
|
struct StackBlock {
|
|
|
|
|
|
|
|
|
|
// a block of memory
|
|
|
|
|
void* mBlock;
|
|
|
|
|
|
|
|
|
|
// another block of memory that would only be created
|
|
|
|
|
// if our stack overflowed. Yes we have the ability
|
|
|
|
|
// to grow on a stack overflow
|
|
|
|
|
StackBlock* mNext;
|
|
|
|
|
StackBlock()
|
|
|
|
|
{
|
2000-04-01 08:35:40 +00:00
|
|
|
|
mBlock = PR_Malloc(BLOCK_INCREMENT);
|
2000-03-31 07:02:06 +00:00
|
|
|
|
mNext = nsnull;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~StackBlock()
|
|
|
|
|
{
|
2000-04-01 08:35:40 +00:00
|
|
|
|
PR_Free(mBlock);
|
2000-03-31 07:02:06 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* we hold an array of marks. A push pushes a mark on the stack
|
|
|
|
|
* a pop pops it off.
|
|
|
|
|
*/
|
|
|
|
|
struct StackMark {
|
|
|
|
|
// the block of memory we are currently handing out chunks of
|
|
|
|
|
StackBlock* mBlock;
|
|
|
|
|
|
|
|
|
|
// our current position in the memory
|
|
|
|
|
size_t mPos;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* A stack arena allows a stack based interface to a block of memory.
|
|
|
|
|
* It should be used when you need to allocate some temporary memory that
|
|
|
|
|
* you will immediately return.
|
|
|
|
|
*/
|
|
|
|
|
class StackArena {
|
|
|
|
|
public:
|
|
|
|
|
StackArena();
|
|
|
|
|
~StackArena();
|
|
|
|
|
|
|
|
|
|
// Memory management functions
|
|
|
|
|
nsresult Allocate(size_t aSize, void** aResult);
|
|
|
|
|
nsresult Push();
|
|
|
|
|
nsresult Pop();
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// our current position in memory
|
|
|
|
|
size_t mPos;
|
|
|
|
|
|
|
|
|
|
// a list of memory block. Usually there is only one
|
|
|
|
|
// but if we overrun our stack size we can get more memory.
|
|
|
|
|
StackBlock* mBlocks;
|
|
|
|
|
|
|
|
|
|
// the current block of memory we are passing our chucks of
|
|
|
|
|
StackBlock* mCurBlock;
|
|
|
|
|
|
|
|
|
|
// our stack of mark where push has been called
|
|
|
|
|
StackMark* mMarks;
|
|
|
|
|
|
|
|
|
|
// the current top of the the mark list
|
|
|
|
|
PRUint32 mStackTop;
|
|
|
|
|
|
|
|
|
|
// the size of the mark array
|
|
|
|
|
PRUint32 mMarkLength;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StackArena::StackArena()
|
|
|
|
|
{
|
|
|
|
|
// allocate the marks array
|
|
|
|
|
mMarkLength = MARK_INCREMENT;
|
|
|
|
|
mMarks = new StackMark[mMarkLength];
|
|
|
|
|
|
|
|
|
|
// allocate our stack memory
|
|
|
|
|
mBlocks = new StackBlock();
|
|
|
|
|
mCurBlock = mBlocks;
|
|
|
|
|
|
|
|
|
|
mStackTop = 0;
|
|
|
|
|
mPos = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StackArena::~StackArena()
|
|
|
|
|
{
|
|
|
|
|
// free up our data
|
|
|
|
|
delete[] mMarks;
|
|
|
|
|
while(mBlocks)
|
|
|
|
|
{
|
|
|
|
|
StackBlock* toDelete = mBlocks;
|
|
|
|
|
mBlocks = mBlocks->mNext;
|
|
|
|
|
delete toDelete;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
StackArena::Push()
|
|
|
|
|
{
|
|
|
|
|
// if the we overrun our mark array. Resize it.
|
|
|
|
|
if (mStackTop + 1 >= mMarkLength)
|
|
|
|
|
{
|
|
|
|
|
StackMark* oldMarks = mMarks;
|
|
|
|
|
PRUint32 oldLength = mMarkLength;
|
|
|
|
|
mMarkLength += MARK_INCREMENT;
|
|
|
|
|
mMarks = new StackMark[mMarkLength];
|
|
|
|
|
nsCRT::memcpy(mMarks, oldMarks, sizeof(StackMark)*oldLength);
|
|
|
|
|
|
|
|
|
|
delete[] oldMarks;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// set a mark at the top
|
|
|
|
|
mMarks[mStackTop].mBlock = mCurBlock;
|
|
|
|
|
mMarks[mStackTop].mPos = mPos;
|
|
|
|
|
|
|
|
|
|
mStackTop++;
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
StackArena::Allocate(size_t aSize, void** aResult)
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(mStackTop > 0, "Error allocate called before push!!!");
|
|
|
|
|
|
|
|
|
|
// make sure we are aligned. Beard said 8 was safer then 4.
|
|
|
|
|
// Round size to multiple of 8
|
|
|
|
|
aSize = PR_ROUNDUP(aSize, 8);
|
|
|
|
|
|
|
|
|
|
// if the size makes the stack overflow. Grab another block for the stack
|
|
|
|
|
if (mPos + aSize >= BLOCK_INCREMENT)
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(aSize <= BLOCK_INCREMENT,"Requested memory is greater that our block size!!");
|
|
|
|
|
if (mCurBlock->mNext == nsnull)
|
|
|
|
|
mCurBlock->mNext = new StackBlock();
|
|
|
|
|
|
|
|
|
|
mCurBlock = mCurBlock->mNext;
|
|
|
|
|
mPos = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// return the chunk they need.
|
|
|
|
|
*aResult = ((char*)mCurBlock->mBlock) + mPos;
|
|
|
|
|
mPos += aSize;
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
StackArena::Pop()
|
|
|
|
|
{
|
|
|
|
|
// pop off the mark
|
|
|
|
|
NS_ASSERTION(mStackTop > 0, "Error Pop called 1 too many times");
|
|
|
|
|
mStackTop--;
|
|
|
|
|
mCurBlock = mMarks[mStackTop].mBlock;
|
|
|
|
|
mPos = mMarks[mStackTop].mPos;
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1999-12-07 04:36:08 +00:00
|
|
|
|
// Memory is allocated 4-byte aligned. We have recyclers for chunks up to
|
|
|
|
|
// 200 bytes
|
|
|
|
|
class FrameArena {
|
|
|
|
|
public:
|
2000-03-31 04:11:28 +00:00
|
|
|
|
FrameArena(PRUint32 aArenaSize = 4096);
|
1999-12-07 04:36:08 +00:00
|
|
|
|
~FrameArena();
|
|
|
|
|
|
|
|
|
|
// Memory management functions
|
|
|
|
|
nsresult AllocateFrame(size_t aSize, void** aResult);
|
|
|
|
|
nsresult FreeFrame(size_t aSize, void* aPtr);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// Underlying arena pool
|
|
|
|
|
PLArenaPool mPool;
|
|
|
|
|
|
|
|
|
|
// The recycler array is sparse with the indices being multiples of 4,
|
|
|
|
|
// i.e., 0, 4, 8, 12, 16, 20, ...
|
|
|
|
|
void* mRecyclers[gMaxRecycledSize >> 2];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
FrameArena::FrameArena(PRUint32 aArenaSize)
|
|
|
|
|
{
|
|
|
|
|
// Initialize the arena pool
|
|
|
|
|
PL_INIT_ARENA_POOL(&mPool, "FrameArena", aArenaSize);
|
|
|
|
|
|
|
|
|
|
// Zero out the recyclers array
|
|
|
|
|
nsCRT::memset(mRecyclers, 0, sizeof(mRecyclers));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FrameArena::~FrameArena()
|
|
|
|
|
{
|
|
|
|
|
// Free the arena in the pool and finish using it
|
|
|
|
|
PL_FinishArenaPool(&mPool);
|
2000-03-31 07:02:06 +00:00
|
|
|
|
}
|
1999-12-07 04:36:08 +00:00
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
FrameArena::AllocateFrame(size_t aSize, void** aResult)
|
|
|
|
|
{
|
|
|
|
|
void* result = nsnull;
|
|
|
|
|
|
|
|
|
|
// Round size to multiple of 4
|
2000-01-04 03:04:56 +00:00
|
|
|
|
aSize = PR_ROUNDUP(aSize, 4);
|
1999-12-07 04:36:08 +00:00
|
|
|
|
|
|
|
|
|
// Check recyclers first
|
|
|
|
|
if (aSize < gMaxRecycledSize) {
|
|
|
|
|
const int index = aSize >> 2;
|
|
|
|
|
|
|
|
|
|
result = mRecyclers[index];
|
|
|
|
|
if (result) {
|
|
|
|
|
// Need to move to the next object
|
|
|
|
|
void* next = *((void**)result);
|
|
|
|
|
mRecyclers[index] = next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!result) {
|
|
|
|
|
// Allocate a new chunk from the arena
|
|
|
|
|
PL_ARENA_ALLOCATE(result, &mPool, aSize);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*aResult = result;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
FrameArena::FreeFrame(size_t aSize, void* aPtr)
|
|
|
|
|
{
|
|
|
|
|
// Round size to multiple of 4
|
2000-01-04 03:09:32 +00:00
|
|
|
|
aSize = PR_ROUNDUP(aSize, 4);
|
1999-12-07 04:36:08 +00:00
|
|
|
|
|
|
|
|
|
// See if it's a size that we recycle
|
|
|
|
|
if (aSize < gMaxRecycledSize) {
|
|
|
|
|
const int index = aSize >> 2;
|
|
|
|
|
void* currentTop = mRecyclers[index];
|
|
|
|
|
mRecyclers[index] = aPtr;
|
|
|
|
|
*((void**)aPtr) = currentTop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
1999-10-15 04:29:30 +00:00
|
|
|
|
class PresShellViewEventListener : public nsIScrollPositionListener,
|
|
|
|
|
public nsICompositeListener
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
PresShellViewEventListener();
|
|
|
|
|
virtual ~PresShellViewEventListener();
|
|
|
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
|
|
// nsIScrollPositionListener methods
|
|
|
|
|
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView *aView, nscoord aX, nscoord aY);
|
|
|
|
|
NS_IMETHOD ScrollPositionDidChange(nsIScrollableView *aView, nscoord aX, nscoord aY);
|
|
|
|
|
|
|
|
|
|
// nsICompositeListener methods
|
|
|
|
|
NS_IMETHOD WillRefreshRegion(nsIViewManager *aViewManager,
|
|
|
|
|
nsIView *aView,
|
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
|
nsIRegion *aRegion,
|
|
|
|
|
PRUint32 aUpdateFlags);
|
|
|
|
|
|
|
|
|
|
NS_IMETHOD DidRefreshRegion(nsIViewManager *aViewManager,
|
|
|
|
|
nsIView *aView,
|
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
|
nsIRegion *aRegion,
|
|
|
|
|
PRUint32 aUpdateFlags);
|
|
|
|
|
|
|
|
|
|
NS_IMETHOD WillRefreshRect(nsIViewManager *aViewManager,
|
|
|
|
|
nsIView *aView,
|
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
|
const nsRect *aRect,
|
|
|
|
|
PRUint32 aUpdateFlags);
|
|
|
|
|
|
|
|
|
|
NS_IMETHOD DidRefreshRect(nsIViewManager *aViewManager,
|
|
|
|
|
nsIView *aView,
|
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
|
const nsRect *aRect,
|
|
|
|
|
PRUint32 aUpdateFlags);
|
|
|
|
|
|
|
|
|
|
nsresult SetPresShell(nsIPresShell *aPresShell);
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
nsresult HideCaret();
|
|
|
|
|
nsresult RestoreCaretVisibility();
|
|
|
|
|
|
|
|
|
|
nsIPresShell *mPresShell;
|
|
|
|
|
PRBool mWasVisible;
|
|
|
|
|
PRInt32 mCallCount;
|
|
|
|
|
};
|
|
|
|
|
|
2000-06-23 05:15:04 +00:00
|
|
|
|
struct nsDOMEventRequest
|
|
|
|
|
{
|
|
|
|
|
nsIContent* content;
|
|
|
|
|
nsEvent* event;
|
|
|
|
|
nsDOMEventRequest* next;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct nsAttributeChangeRequest
|
|
|
|
|
{
|
|
|
|
|
nsIContent* content;
|
|
|
|
|
PRInt32 nameSpaceID;
|
|
|
|
|
nsIAtom* name;
|
|
|
|
|
nsAutoString value;
|
|
|
|
|
PRBool notify;
|
|
|
|
|
nsAttributeChangeType type;
|
|
|
|
|
nsAttributeChangeRequest* next;
|
|
|
|
|
};
|
|
|
|
|
|
2000-07-13 23:00:59 +00:00
|
|
|
|
struct nsCallbackEventRequest
|
|
|
|
|
{
|
|
|
|
|
nsIReflowCallback* callback;
|
|
|
|
|
nsCallbackEventRequest* next;
|
|
|
|
|
};
|
|
|
|
|
|
2000-09-12 00:35:11 +00:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// DummyLayoutRequest
|
|
|
|
|
//
|
|
|
|
|
// This is a dummy request implementation that we add to the document's load
|
|
|
|
|
// group. It ensures that EndDocumentLoad() in the docshell doesn't fire
|
|
|
|
|
// before we've finished all of layout.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
class DummyLayoutRequest : public nsIChannel
|
|
|
|
|
{
|
|
|
|
|
protected:
|
2000-09-20 07:20:23 +00:00
|
|
|
|
DummyLayoutRequest(nsIPresShell* aPresShell);
|
2000-09-12 00:35:11 +00:00
|
|
|
|
virtual ~DummyLayoutRequest();
|
|
|
|
|
|
|
|
|
|
static PRInt32 gRefCnt;
|
|
|
|
|
static nsIURI* gURI;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsILoadGroup> mLoadGroup;
|
2000-09-20 07:20:23 +00:00
|
|
|
|
nsWeakPtr mPresShell;
|
2000-09-12 00:35:11 +00:00
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
static nsresult
|
2001-02-21 20:38:08 +00:00
|
|
|
|
Create(nsIRequest** aResult, nsIPresShell* aPresShell);
|
2000-09-12 00:35:11 +00:00
|
|
|
|
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
|
|
// nsIRequest
|
|
|
|
|
NS_IMETHOD GetName(PRUnichar* *result) {
|
2001-04-13 23:24:25 +00:00
|
|
|
|
*result = ToNewUnicode(NS_LITERAL_STRING("about:layout-dummy-request"));
|
|
|
|
|
return NS_OK;
|
2000-09-12 00:35:11 +00:00
|
|
|
|
}
|
|
|
|
|
NS_IMETHOD IsPending(PRBool *_retval) { *_retval = PR_TRUE; return NS_OK; }
|
|
|
|
|
NS_IMETHOD GetStatus(nsresult *status) { *status = NS_OK; return NS_OK; }
|
|
|
|
|
NS_IMETHOD Cancel(nsresult status);
|
|
|
|
|
NS_IMETHOD Suspend(void) { return NS_OK; }
|
|
|
|
|
NS_IMETHOD Resume(void) { return NS_OK; }
|
|
|
|
|
|
2001-02-21 20:38:08 +00:00
|
|
|
|
// nsIChannel
|
2000-09-12 00:35:11 +00:00
|
|
|
|
NS_IMETHOD GetOriginalURI(nsIURI* *aOriginalURI) { *aOriginalURI = gURI; NS_ADDREF(*aOriginalURI); return NS_OK; }
|
|
|
|
|
NS_IMETHOD SetOriginalURI(nsIURI* aOriginalURI) { gURI = aOriginalURI; NS_ADDREF(gURI); return NS_OK; }
|
|
|
|
|
NS_IMETHOD GetURI(nsIURI* *aURI) { *aURI = gURI; NS_ADDREF(*aURI); return NS_OK; }
|
|
|
|
|
NS_IMETHOD SetURI(nsIURI* aURI) { gURI = aURI; NS_ADDREF(gURI); return NS_OK; }
|
2001-02-21 20:38:08 +00:00
|
|
|
|
NS_IMETHOD Open(nsIInputStream **_retval) { *_retval = nsnull; return NS_OK; }
|
|
|
|
|
NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt) { return NS_OK; }
|
2001-04-10 06:01:08 +00:00
|
|
|
|
NS_IMETHOD GetLoadFlags(nsLoadFlags *aLoadFlags) { *aLoadFlags = nsIRequest::LOAD_NORMAL; return NS_OK; }
|
|
|
|
|
NS_IMETHOD SetLoadFlags(nsLoadFlags aLoadFlags) { return NS_OK; }
|
2001-02-21 20:38:08 +00:00
|
|
|
|
NS_IMETHOD GetOwner(nsISupports * *aOwner) { *aOwner = nsnull; return NS_OK; }
|
|
|
|
|
NS_IMETHOD SetOwner(nsISupports * aOwner) { return NS_OK; }
|
|
|
|
|
NS_IMETHOD GetLoadGroup(nsILoadGroup * *aLoadGroup) { *aLoadGroup = mLoadGroup; NS_IF_ADDREF(*aLoadGroup); return NS_OK; }
|
|
|
|
|
NS_IMETHOD SetLoadGroup(nsILoadGroup * aLoadGroup) { mLoadGroup = aLoadGroup; return NS_OK; }
|
|
|
|
|
NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor * *aNotificationCallbacks) { *aNotificationCallbacks = nsnull; return NS_OK; }
|
|
|
|
|
NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor * aNotificationCallbacks) { return NS_OK; }
|
|
|
|
|
NS_IMETHOD GetSecurityInfo(nsISupports * *aSecurityInfo) { *aSecurityInfo = nsnull; return NS_OK; }
|
|
|
|
|
NS_IMETHOD GetContentType(char * *aContentType) { *aContentType = nsnull; return NS_OK; }
|
|
|
|
|
NS_IMETHOD SetContentType(const char * aContentType) { return NS_OK; }
|
|
|
|
|
NS_IMETHOD GetContentLength(PRInt32 *aContentLength) { return NS_OK; }
|
|
|
|
|
NS_IMETHOD SetContentLength(PRInt32 aContentLength) { return NS_OK; }
|
|
|
|
|
|
2000-09-12 00:35:11 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
PRInt32 DummyLayoutRequest::gRefCnt;
|
|
|
|
|
nsIURI* DummyLayoutRequest::gURI;
|
|
|
|
|
|
|
|
|
|
NS_IMPL_ADDREF(DummyLayoutRequest);
|
|
|
|
|
NS_IMPL_RELEASE(DummyLayoutRequest);
|
|
|
|
|
NS_IMPL_QUERY_INTERFACE2(DummyLayoutRequest, nsIRequest, nsIChannel);
|
|
|
|
|
|
|
|
|
|
nsresult
|
2001-02-21 20:38:08 +00:00
|
|
|
|
DummyLayoutRequest::Create(nsIRequest** aResult, nsIPresShell* aPresShell)
|
2000-09-12 00:35:11 +00:00
|
|
|
|
{
|
2000-09-20 07:20:23 +00:00
|
|
|
|
DummyLayoutRequest* request = new DummyLayoutRequest(aPresShell);
|
2000-09-12 00:35:11 +00:00
|
|
|
|
if (!request)
|
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
2001-02-21 20:38:08 +00:00
|
|
|
|
return request->QueryInterface(NS_GET_IID(nsIRequest), (void**) aResult);
|
2000-09-12 00:35:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-09-20 07:20:23 +00:00
|
|
|
|
DummyLayoutRequest::DummyLayoutRequest(nsIPresShell* aPresShell)
|
2000-09-12 00:35:11 +00:00
|
|
|
|
{
|
|
|
|
|
NS_INIT_REFCNT();
|
|
|
|
|
|
|
|
|
|
if (gRefCnt++ == 0) {
|
|
|
|
|
nsresult rv;
|
|
|
|
|
rv = NS_NewURI(&gURI, "about:layout-dummy-request", nsnull);
|
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "unable to create about:layout-dummy-request");
|
|
|
|
|
}
|
2000-09-20 07:20:23 +00:00
|
|
|
|
|
|
|
|
|
mPresShell = getter_AddRefs(NS_GetWeakReference(aPresShell));
|
2000-09-12 00:35:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DummyLayoutRequest::~DummyLayoutRequest()
|
|
|
|
|
{
|
|
|
|
|
if (--gRefCnt == 0) {
|
|
|
|
|
NS_IF_RELEASE(gURI);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
DummyLayoutRequest::Cancel(nsresult status)
|
|
|
|
|
{
|
2000-09-20 07:20:23 +00:00
|
|
|
|
// Cancel layout
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
|
|
|
|
|
if (presShell) {
|
|
|
|
|
rv = presShell->CancelAllReflowCommands();
|
|
|
|
|
}
|
|
|
|
|
return rv;
|
2000-09-12 00:35:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
|
1998-08-28 02:54:06 +00:00
|
|
|
|
class PresShell : public nsIPresShell, public nsIViewObserver,
|
1999-02-19 23:47:36 +00:00
|
|
|
|
private nsIDocumentObserver, public nsIFocusTracker,
|
1999-12-02 21:45:21 +00:00
|
|
|
|
public nsISelectionController,
|
1999-10-22 00:19:18 +00:00
|
|
|
|
public nsSupportsWeakReference
|
1998-08-28 02:54:06 +00:00
|
|
|
|
{
|
1998-04-13 20:24:54 +00:00
|
|
|
|
public:
|
|
|
|
|
PresShell();
|
|
|
|
|
|
1999-02-26 20:02:06 +00:00
|
|
|
|
NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
|
1999-02-26 17:08:48 +00:00
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
|
// nsISupports
|
|
|
|
|
NS_DECL_ISUPPORTS
|
|
|
|
|
|
|
|
|
|
// nsIPresShell
|
1998-06-03 15:46:54 +00:00
|
|
|
|
NS_IMETHOD Init(nsIDocument* aDocument,
|
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
|
nsIViewManager* aViewManager,
|
|
|
|
|
nsIStyleSet* aStyleSet);
|
1999-12-04 23:49:50 +00:00
|
|
|
|
|
|
|
|
|
NS_IMETHOD AllocateFrame(size_t aSize, void** aResult);
|
|
|
|
|
NS_IMETHOD FreeFrame(size_t aSize, void* aFreeChunk);
|
2000-03-31 07:02:06 +00:00
|
|
|
|
|
|
|
|
|
// Dynamic stack memory allocation
|
|
|
|
|
NS_IMETHOD PushStackMemory();
|
|
|
|
|
NS_IMETHOD PopStackMemory();
|
|
|
|
|
NS_IMETHOD AllocateStackMemory(size_t aSize, void** aResult);
|
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_IMETHOD GetDocument(nsIDocument** aResult);
|
|
|
|
|
NS_IMETHOD GetPresContext(nsIPresContext** aResult);
|
|
|
|
|
NS_IMETHOD GetViewManager(nsIViewManager** aResult);
|
|
|
|
|
NS_IMETHOD GetStyleSet(nsIStyleSet** aResult);
|
1999-01-23 07:03:46 +00:00
|
|
|
|
NS_IMETHOD GetActiveAlternateStyleSheet(nsString& aSheetTitle);
|
|
|
|
|
NS_IMETHOD SelectAlternateStyleSheet(const nsString& aSheetTitle);
|
|
|
|
|
NS_IMETHOD ListAlternateStyleSheets(nsStringArray& aTitleList);
|
2000-12-15 23:48:55 +00:00
|
|
|
|
NS_IMETHOD SetPreferenceStyleRules(PRBool aForceReflow);
|
2000-10-11 08:33:01 +00:00
|
|
|
|
NS_IMETHOD EnablePrefStyleRules(PRBool aEnable, PRUint8 aPrefType=0xFF);
|
|
|
|
|
NS_IMETHOD ArePrefStyleRulesEnabled(PRBool& aEnabled);
|
2000-04-27 07:37:12 +00:00
|
|
|
|
|
2000-04-28 06:21:31 +00:00
|
|
|
|
NS_IMETHOD SetDisplaySelection(PRInt16 aToggle);
|
|
|
|
|
NS_IMETHOD GetDisplaySelection(PRInt16 *aToggle);
|
2000-09-14 11:45:01 +00:00
|
|
|
|
NS_IMETHOD GetSelection(SelectionType aType, nsISelection** aSelection);
|
1999-08-30 21:54:40 +00:00
|
|
|
|
NS_IMETHOD ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion);
|
|
|
|
|
NS_IMETHOD RepaintSelection(SelectionType aType);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
NS_IMETHOD GetFrameSelection(nsIFrameSelection** aSelection);
|
1999-11-09 03:23:26 +00:00
|
|
|
|
|
1998-12-29 04:56:31 +00:00
|
|
|
|
NS_IMETHOD BeginObservingDocument();
|
|
|
|
|
NS_IMETHOD EndObservingDocument();
|
1998-09-10 19:32:14 +00:00
|
|
|
|
NS_IMETHOD InitialReflow(nscoord aWidth, nscoord aHeight);
|
1998-08-28 02:54:06 +00:00
|
|
|
|
NS_IMETHOD ResizeReflow(nscoord aWidth, nscoord aHeight);
|
1998-11-06 16:16:01 +00:00
|
|
|
|
NS_IMETHOD StyleChangeReflow();
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_IMETHOD GetRootFrame(nsIFrame** aFrame) const;
|
|
|
|
|
NS_IMETHOD GetPageSequenceFrame(nsIPageSequenceFrame** aResult) const;
|
|
|
|
|
NS_IMETHOD GetPrimaryFrameFor(nsIContent* aContent,
|
|
|
|
|
nsIFrame** aPrimaryFrame) const;
|
1999-02-25 19:55:06 +00:00
|
|
|
|
NS_IMETHOD GetStyleContextFor(nsIFrame* aFrame,
|
|
|
|
|
nsIStyleContext** aStyleContext) const;
|
1999-02-10 23:21:22 +00:00
|
|
|
|
NS_IMETHOD GetLayoutObjectFor(nsIContent* aContent,
|
|
|
|
|
nsISupports** aResult) const;
|
2000-03-03 23:15:29 +00:00
|
|
|
|
NS_IMETHOD GetSubShellFor(nsIContent* aContent,
|
|
|
|
|
nsISupports** aResult) const;
|
|
|
|
|
NS_IMETHOD SetSubShellFor(nsIContent* aContent,
|
|
|
|
|
nsISupports* aSubShell);
|
1998-12-29 03:38:16 +00:00
|
|
|
|
NS_IMETHOD GetPlaceholderFrameFor(nsIFrame* aFrame,
|
1999-02-12 17:45:58 +00:00
|
|
|
|
nsIFrame** aPlaceholderFrame) const;
|
1998-12-29 04:56:31 +00:00
|
|
|
|
NS_IMETHOD AppendReflowCommand(nsIReflowCommand* aReflowCommand);
|
2001-03-13 06:38:59 +00:00
|
|
|
|
NS_IMETHOD AppendReflowCommandInternal(nsIReflowCommand* aReflowCommand,
|
|
|
|
|
nsVoidArray& aQueue);
|
|
|
|
|
NS_IMETHOD CancelReflowCommand(nsIFrame* aTargetFrame,
|
|
|
|
|
nsIReflowCommand::ReflowType* aCmdType);
|
|
|
|
|
NS_IMETHOD CancelReflowCommandInternal(nsIFrame* aTargetFrame,
|
|
|
|
|
nsIReflowCommand::ReflowType* aCmdType,
|
|
|
|
|
nsVoidArray& aQueue);
|
2000-09-20 07:20:23 +00:00
|
|
|
|
NS_IMETHOD CancelAllReflowCommands();
|
2000-10-17 05:07:39 +00:00
|
|
|
|
NS_IMETHOD IsSafeToFlush(PRBool& aIsSafeToFlush);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
NS_IMETHOD FlushPendingNotifications();
|
|
|
|
|
|
2000-06-23 05:15:04 +00:00
|
|
|
|
/**
|
|
|
|
|
* Post a request to handle a DOM event after Reflow has finished.
|
|
|
|
|
*/
|
|
|
|
|
NS_IMETHOD PostDOMEvent(nsIContent* aContent, nsEvent* aEvent);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Post a request to set and attribute after reflow has finished.
|
|
|
|
|
*/
|
|
|
|
|
NS_IMETHOD PostAttributeChange(nsIContent* aContent,
|
|
|
|
|
PRInt32 aNameSpaceID,
|
|
|
|
|
nsIAtom* aName,
|
|
|
|
|
const nsString& aValue,
|
|
|
|
|
PRBool aNotify,
|
|
|
|
|
nsAttributeChangeType aType);
|
2000-07-13 23:00:59 +00:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Post a callback that should be handled after reflow has finished.
|
|
|
|
|
*/
|
|
|
|
|
NS_IMETHOD PostReflowCallback(nsIReflowCallback* aCallback);
|
2000-10-07 00:49:08 +00:00
|
|
|
|
NS_IMETHOD CancelReflowCallback(nsIReflowCallback* aCallback);
|
2000-07-13 23:00:59 +00:00
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
/**
|
|
|
|
|
* Reflow batching
|
|
|
|
|
*/
|
|
|
|
|
NS_IMETHOD BeginReflowBatching();
|
|
|
|
|
NS_IMETHOD EndReflowBatching(PRBool aFlushPendingReflows);
|
|
|
|
|
NS_IMETHOD GetReflowBatchingStatus(PRBool* aBatch);
|
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_IMETHOD ClearFrameRefs(nsIFrame* aFrame);
|
|
|
|
|
NS_IMETHOD CreateRenderingContext(nsIFrame *aFrame,
|
|
|
|
|
nsIRenderingContext** aContext);
|
1999-02-05 18:25:29 +00:00
|
|
|
|
NS_IMETHOD CantRenderReplacedElement(nsIPresContext* aPresContext,
|
|
|
|
|
nsIFrame* aFrame);
|
2001-03-27 23:59:56 +00:00
|
|
|
|
NS_IMETHOD GoToAnchor(const nsString& aAnchorName);
|
1998-08-28 02:54:06 +00:00
|
|
|
|
|
1999-02-18 22:52:21 +00:00
|
|
|
|
NS_IMETHOD ScrollFrameIntoView(nsIFrame *aFrame,
|
1999-07-19 18:38:33 +00:00
|
|
|
|
PRIntn aVPercent,
|
|
|
|
|
PRIntn aHPercent) const;
|
1999-04-07 03:56:07 +00:00
|
|
|
|
|
1999-07-16 23:27:46 +00:00
|
|
|
|
NS_IMETHOD NotifyDestroyingFrame(nsIFrame* aFrame);
|
1999-08-04 04:02:40 +00:00
|
|
|
|
|
|
|
|
|
NS_IMETHOD GetFrameManager(nsIFrameManager** aFrameManager) const;
|
1999-07-16 23:27:46 +00:00
|
|
|
|
|
1999-04-07 03:56:07 +00:00
|
|
|
|
NS_IMETHOD DoCopy();
|
2001-04-18 06:06:31 +00:00
|
|
|
|
NS_IMETHOD DoCopyLinkLocation(nsIDOMNode* aNode);
|
|
|
|
|
NS_IMETHOD DoCopyImageLocation(nsIDOMNode* aNode);
|
|
|
|
|
NS_IMETHOD DoCopyImageContents(nsIDOMNode* aNode);
|
1999-08-31 14:35:50 +00:00
|
|
|
|
|
2000-06-15 00:35:46 +00:00
|
|
|
|
NS_IMETHOD CaptureHistoryState(nsILayoutHistoryState** aLayoutHistoryState, PRBool aLeavingPage);
|
1999-08-30 22:38:58 +00:00
|
|
|
|
NS_IMETHOD GetHistoryState(nsILayoutHistoryState** aLayoutHistoryState);
|
1999-09-15 00:43:53 +00:00
|
|
|
|
NS_IMETHOD SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState);
|
1999-08-30 22:38:58 +00:00
|
|
|
|
|
2000-03-23 00:34:54 +00:00
|
|
|
|
NS_IMETHOD GetGeneratedContentIterator(nsIContent* aContent,
|
|
|
|
|
GeneratedContentType aType,
|
|
|
|
|
nsIContentIterator** aIterator) const;
|
2000-04-24 04:41:27 +00:00
|
|
|
|
|
2000-10-09 03:08:41 +00:00
|
|
|
|
NS_IMETHOD SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements);
|
|
|
|
|
NS_IMETHOD GetAnonymousContentFor(nsIContent* aContent, nsISupportsArray** aAnonymousElements);
|
|
|
|
|
NS_IMETHOD ReleaseAnonymousContent();
|
|
|
|
|
|
2001-04-25 19:52:49 +00:00
|
|
|
|
NS_IMETHOD IsPaintingSuppressed(PRBool* aResult);
|
|
|
|
|
NS_IMETHOD UnsuppressPainting(PRBool aCancelTimer);
|
|
|
|
|
|
2000-09-19 21:47:04 +00:00
|
|
|
|
NS_IMETHOD HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame, nsIContent* aContent, PRUint32 aFlags, nsEventStatus* aStatus);
|
2000-06-24 03:58:13 +00:00
|
|
|
|
NS_IMETHOD GetEventTargetFrame(nsIFrame** aFrame);
|
2000-03-23 00:34:54 +00:00
|
|
|
|
|
2000-02-09 15:48:01 +00:00
|
|
|
|
NS_IMETHOD IsReflowLocked(PRBool* aIsLocked);
|
2001-03-09 03:29:00 +00:00
|
|
|
|
#ifdef IBMBIDI
|
|
|
|
|
NS_IMETHOD SetCursorBidiLevel(PRUint8 aLevel);
|
|
|
|
|
NS_IMETHOD GetCursorBidiLevel(PRUint8 *aOutLevel);
|
|
|
|
|
NS_IMETHOD UndefineCursorBidiLevel();
|
|
|
|
|
NS_IMETHOD BidiStyleChangeReflow();
|
|
|
|
|
#endif
|
2000-01-28 00:48:02 +00:00
|
|
|
|
|
1998-08-28 02:54:06 +00:00
|
|
|
|
//nsIViewObserver interface
|
|
|
|
|
|
|
|
|
|
NS_IMETHOD Paint(nsIView *aView,
|
|
|
|
|
nsIRenderingContext& aRenderingContext,
|
|
|
|
|
const nsRect& aDirtyRect);
|
|
|
|
|
NS_IMETHOD HandleEvent(nsIView* aView,
|
|
|
|
|
nsGUIEvent* aEvent,
|
2000-03-22 02:43:08 +00:00
|
|
|
|
nsEventStatus* aEventStatus,
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
|
PRBool aForceHandle,
|
2000-03-22 02:43:08 +00:00
|
|
|
|
PRBool& aHandled);
|
2000-06-29 02:02:43 +00:00
|
|
|
|
NS_IMETHOD HandleDOMEventWithTarget(nsIContent* aTargetContent,
|
|
|
|
|
nsEvent* aEvent,
|
|
|
|
|
nsEventStatus* aStatus);
|
1998-08-28 02:54:06 +00:00
|
|
|
|
NS_IMETHOD Scrolled(nsIView *aView);
|
|
|
|
|
NS_IMETHOD ResizeReflow(nsIView *aView, nscoord aWidth, nscoord aHeight);
|
|
|
|
|
|
1998-12-14 18:34:14 +00:00
|
|
|
|
//nsIFocusTracker interface
|
1999-02-21 03:49:32 +00:00
|
|
|
|
NS_IMETHOD ScrollFrameIntoView(nsIFrame *aFrame);
|
1999-02-13 04:45:44 +00:00
|
|
|
|
// caret handling
|
1999-08-04 20:46:16 +00:00
|
|
|
|
NS_IMETHOD GetCaret(nsICaret **aOutCaret);
|
2000-05-11 04:25:43 +00:00
|
|
|
|
NS_IMETHOD SetCaretEnabled(PRBool aInEnable);
|
2000-07-28 22:12:45 +00:00
|
|
|
|
NS_IMETHOD SetCaretWidth(PRInt16 twips);
|
2000-05-11 04:25:43 +00:00
|
|
|
|
NS_IMETHOD SetCaretReadOnly(PRBool aReadOnly);
|
1999-08-04 20:46:16 +00:00
|
|
|
|
NS_IMETHOD GetCaretEnabled(PRBool *aOutEnabled);
|
1999-02-13 04:45:44 +00:00
|
|
|
|
|
2000-05-11 04:25:43 +00:00
|
|
|
|
NS_IMETHOD SetDisplayNonTextSelection(PRBool aInEnable);
|
1999-08-04 20:46:16 +00:00
|
|
|
|
NS_IMETHOD GetDisplayNonTextSelection(PRBool *aOutEnable);
|
1999-05-17 00:21:18 +00:00
|
|
|
|
|
1999-12-02 21:45:21 +00:00
|
|
|
|
// nsISelectionController
|
1999-10-22 00:19:18 +00:00
|
|
|
|
|
|
|
|
|
NS_IMETHOD CharacterMove(PRBool aForward, PRBool aExtend);
|
|
|
|
|
NS_IMETHOD WordMove(PRBool aForward, PRBool aExtend);
|
|
|
|
|
NS_IMETHOD LineMove(PRBool aForward, PRBool aExtend);
|
|
|
|
|
NS_IMETHOD IntraLineMove(PRBool aForward, PRBool aExtend);
|
|
|
|
|
NS_IMETHOD PageMove(PRBool aForward, PRBool aExtend);
|
|
|
|
|
NS_IMETHOD ScrollPage(PRBool aForward);
|
1999-12-15 03:54:52 +00:00
|
|
|
|
NS_IMETHOD ScrollLine(PRBool aForward);
|
|
|
|
|
NS_IMETHOD ScrollHorizontal(PRBool aLeft);
|
1999-12-11 00:02:08 +00:00
|
|
|
|
NS_IMETHOD CompleteScroll(PRBool aForward);
|
|
|
|
|
NS_IMETHOD CompleteMove(PRBool aForward, PRBool aExtend);
|
1999-10-22 00:19:18 +00:00
|
|
|
|
NS_IMETHOD SelectAll();
|
2000-07-26 11:31:12 +00:00
|
|
|
|
NS_IMETHOD CheckVisibility(nsIDOMNode *node, PRInt16 startOffset, PRInt16 EndOffset, PRBool *_retval);
|
1999-02-13 04:45:44 +00:00
|
|
|
|
|
1999-07-14 17:30:07 +00:00
|
|
|
|
// nsIDocumentObserver
|
|
|
|
|
NS_IMETHOD BeginUpdate(nsIDocument *aDocument);
|
|
|
|
|
NS_IMETHOD EndUpdate(nsIDocument *aDocument);
|
|
|
|
|
NS_IMETHOD BeginLoad(nsIDocument *aDocument);
|
|
|
|
|
NS_IMETHOD EndLoad(nsIDocument *aDocument);
|
|
|
|
|
NS_IMETHOD BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell);
|
|
|
|
|
NS_IMETHOD EndReflow(nsIDocument *aDocument, nsIPresShell* aShell);
|
|
|
|
|
NS_IMETHOD ContentChanged(nsIDocument *aDocument,
|
|
|
|
|
nsIContent* aContent,
|
|
|
|
|
nsISupports* aSubContent);
|
|
|
|
|
NS_IMETHOD ContentStatesChanged(nsIDocument* aDocument,
|
|
|
|
|
nsIContent* aContent1,
|
|
|
|
|
nsIContent* aContent2);
|
|
|
|
|
NS_IMETHOD AttributeChanged(nsIDocument *aDocument,
|
|
|
|
|
nsIContent* aContent,
|
1999-10-15 23:16:45 +00:00
|
|
|
|
PRInt32 aNameSpaceID,
|
1999-07-14 17:30:07 +00:00
|
|
|
|
nsIAtom* aAttribute,
|
|
|
|
|
PRInt32 aHint);
|
|
|
|
|
NS_IMETHOD ContentAppended(nsIDocument *aDocument,
|
|
|
|
|
nsIContent* aContainer,
|
|
|
|
|
PRInt32 aNewIndexInContainer);
|
|
|
|
|
NS_IMETHOD ContentInserted(nsIDocument *aDocument,
|
|
|
|
|
nsIContent* aContainer,
|
|
|
|
|
nsIContent* aChild,
|
|
|
|
|
PRInt32 aIndexInContainer);
|
|
|
|
|
NS_IMETHOD ContentReplaced(nsIDocument *aDocument,
|
|
|
|
|
nsIContent* aContainer,
|
|
|
|
|
nsIContent* aOldChild,
|
|
|
|
|
nsIContent* aNewChild,
|
|
|
|
|
PRInt32 aIndexInContainer);
|
|
|
|
|
NS_IMETHOD ContentRemoved(nsIDocument *aDocument,
|
|
|
|
|
nsIContent* aContainer,
|
|
|
|
|
nsIContent* aChild,
|
|
|
|
|
PRInt32 aIndexInContainer);
|
|
|
|
|
NS_IMETHOD StyleSheetAdded(nsIDocument *aDocument,
|
|
|
|
|
nsIStyleSheet* aStyleSheet);
|
|
|
|
|
NS_IMETHOD StyleSheetRemoved(nsIDocument *aDocument,
|
|
|
|
|
nsIStyleSheet* aStyleSheet);
|
|
|
|
|
NS_IMETHOD StyleSheetDisabledStateChanged(nsIDocument *aDocument,
|
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
|
PRBool aDisabled);
|
|
|
|
|
NS_IMETHOD StyleRuleChanged(nsIDocument *aDocument,
|
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
|
nsIStyleRule* aStyleRule,
|
|
|
|
|
PRInt32 aHint);
|
|
|
|
|
NS_IMETHOD StyleRuleAdded(nsIDocument *aDocument,
|
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
|
nsIStyleRule* aStyleRule);
|
|
|
|
|
NS_IMETHOD StyleRuleRemoved(nsIDocument *aDocument,
|
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
|
nsIStyleRule* aStyleRule);
|
|
|
|
|
NS_IMETHOD DocumentWillBeDestroyed(nsIDocument *aDocument);
|
1999-12-23 02:02:33 +00:00
|
|
|
|
|
2001-03-13 06:38:59 +00:00
|
|
|
|
NS_IMETHOD SendInterruptNotificationTo(nsIFrame* aFrame,
|
|
|
|
|
nsIPresShell::InterruptType aInterruptType);
|
|
|
|
|
NS_IMETHOD CancelInterruptNotificationTo(nsIFrame* aFrame,
|
|
|
|
|
nsIPresShell::InterruptType aInterruptType);
|
2000-04-21 14:59:47 +00:00
|
|
|
|
#ifdef MOZ_REFLOW_PERF
|
2000-04-28 23:32:04 +00:00
|
|
|
|
NS_IMETHOD DumpReflows();
|
2001-02-22 13:58:17 +00:00
|
|
|
|
NS_IMETHOD CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame);
|
2001-03-13 01:47:22 +00:00
|
|
|
|
NS_IMETHOD PaintCount(const char * aName, nsIRenderingContext* aRenderingContext, nsIPresContext* aPresContext, nsIFrame * aFrame, PRUint32 aColor);
|
|
|
|
|
|
|
|
|
|
NS_IMETHOD SetPaintFrameCount(PRBool aOn);
|
|
|
|
|
|
2000-04-21 14:59:47 +00:00
|
|
|
|
#endif
|
|
|
|
|
|
2001-04-11 03:07:50 +00:00
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
|
static PRLogModuleInfo* gLog;
|
|
|
|
|
#endif
|
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
|
protected:
|
1999-02-12 17:45:58 +00:00
|
|
|
|
virtual ~PresShell();
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
2000-06-23 05:15:04 +00:00
|
|
|
|
void HandlePostedDOMEvents();
|
|
|
|
|
void HandlePostedAttributeChanges();
|
2000-07-13 23:00:59 +00:00
|
|
|
|
void HandlePostedReflowCallbacks();
|
2000-06-23 05:15:04 +00:00
|
|
|
|
|
2001-04-25 19:52:49 +00:00
|
|
|
|
void UnsuppressAndInvalidate();
|
|
|
|
|
|
2000-05-15 03:37:21 +00:00
|
|
|
|
/** notify all external reflow observers that reflow of type "aData" is about
|
|
|
|
|
* to begin.
|
|
|
|
|
*/
|
|
|
|
|
nsresult NotifyReflowObservers(const char *aData);
|
|
|
|
|
|
2000-09-12 00:35:11 +00:00
|
|
|
|
nsresult ReflowCommandAdded(nsIReflowCommand* aRC);
|
|
|
|
|
nsresult ReflowCommandRemoved(nsIReflowCommand* aRC);
|
2000-09-20 07:20:23 +00:00
|
|
|
|
|
2001-03-14 07:47:00 +00:00
|
|
|
|
// This method should be called after a reflow commands have been
|
|
|
|
|
// removed from the queue, but after the state in the presshell is
|
|
|
|
|
// such that it's safe to flush (i.e. mIsReflowing == PR_FALSE)
|
|
|
|
|
void DoneRemovingReflowCommands();
|
|
|
|
|
|
2000-09-12 00:35:11 +00:00
|
|
|
|
nsresult AddDummyLayoutRequest(void);
|
|
|
|
|
nsresult RemoveDummyLayoutRequest(void);
|
|
|
|
|
|
1998-11-26 01:34:53 +00:00
|
|
|
|
nsresult ReconstructFrames(void);
|
1999-04-03 18:58:04 +00:00
|
|
|
|
nsresult CloneStyleSet(nsIStyleSet* aSet, nsIStyleSet** aResult);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
nsresult WillCauseReflow();
|
|
|
|
|
nsresult DidCauseReflow();
|
2001-03-13 06:38:59 +00:00
|
|
|
|
void ProcessReflowCommand(nsVoidArray& aQueue,
|
|
|
|
|
PRBool aAccumulateTime,
|
|
|
|
|
nsHTMLReflowMetrics& aDesiredSize,
|
|
|
|
|
nsSize& aMaxSize,
|
|
|
|
|
nsIRenderingContext& aRenderingContext);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
nsresult ProcessReflowCommands(PRBool aInterruptible);
|
|
|
|
|
nsresult GetReflowEventStatus(PRBool* aPending);
|
|
|
|
|
nsresult SetReflowEventStatus(PRBool aPending);
|
|
|
|
|
void PostReflowEvent();
|
2001-03-13 06:38:59 +00:00
|
|
|
|
PRBool AlreadyInQueue(nsIReflowCommand* aReflowCommand,
|
|
|
|
|
nsVoidArray& aQueue);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
friend struct ReflowEvent;
|
1999-11-01 22:12:45 +00:00
|
|
|
|
|
2000-06-14 23:18:54 +00:00
|
|
|
|
// utility to determine if we're in the middle of a drag
|
|
|
|
|
PRBool IsDragInProgress ( ) const ;
|
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
PRBool mCaretEnabled;
|
2001-03-09 03:29:00 +00:00
|
|
|
|
#ifdef IBMBIDI
|
|
|
|
|
PRUint8 mBidiLevel; // The Bidi level of the cursor
|
|
|
|
|
nsCOMPtr<nsIBidiKeyboard> mBidiKeyboard;
|
|
|
|
|
#endif // IBMBIDI
|
1999-11-01 22:12:45 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
1999-09-10 18:49:23 +00:00
|
|
|
|
PRBool VerifyIncrementalReflow();
|
1998-11-26 18:11:02 +00:00
|
|
|
|
PRBool mInVerifyReflow;
|
1998-07-13 19:49:42 +00:00
|
|
|
|
#endif
|
1998-05-20 16:24:54 +00:00
|
|
|
|
|
2000-10-11 08:33:01 +00:00
|
|
|
|
/**
|
|
|
|
|
* methods that manage rules that are used to implement the associated preferences
|
|
|
|
|
* - initially created for bugs 31816, 20760, 22963
|
|
|
|
|
*/
|
|
|
|
|
nsresult ClearPreferenceStyleRules(void);
|
|
|
|
|
nsresult CreatePreferenceStyleSheet(void);
|
|
|
|
|
nsresult SetPrefColorRules(void);
|
|
|
|
|
nsresult SetPrefLinkRules(void);
|
2001-04-09 22:17:11 +00:00
|
|
|
|
nsresult SetPrefFocusRules(void);
|
2000-10-11 08:33:01 +00:00
|
|
|
|
|
2001-03-27 23:59:56 +00:00
|
|
|
|
nsresult SelectContent(nsIContent *aContent);
|
|
|
|
|
|
1999-04-30 09:04:36 +00:00
|
|
|
|
// IMPORTANT: The ownership implicit in the following member variables has been
|
|
|
|
|
// explicitly checked and set using nsCOMPtr for owning pointers and raw COM interface
|
|
|
|
|
// pointers for weak (ie, non owning) references. If you add any members to this
|
|
|
|
|
// class, please make the ownership explicit (pinkerton, scc).
|
1999-05-04 23:27:42 +00:00
|
|
|
|
|
|
|
|
|
// these are the same Document and PresContext owned by the DocViewer.
|
|
|
|
|
// we must share ownership.
|
|
|
|
|
nsCOMPtr<nsIDocument> mDocument;
|
|
|
|
|
nsCOMPtr<nsIPresContext> mPresContext;
|
1999-04-30 09:04:36 +00:00
|
|
|
|
nsCOMPtr<nsIStyleSet> mStyleSet;
|
2000-10-11 08:33:01 +00:00
|
|
|
|
nsICSSStyleSheet* mPrefStyleSheet; // mStyleSet owns it but we maintaina ref, may be null
|
|
|
|
|
PRPackedBool mEnablePrefStyleSheet;
|
1999-04-30 09:04:36 +00:00
|
|
|
|
nsIViewManager* mViewManager; // [WEAK] docViewer owns it so I don't have to
|
1999-08-31 14:35:50 +00:00
|
|
|
|
nsILayoutHistoryState* mHistoryState; // [WEAK] session history owns this
|
1998-04-13 20:24:54 +00:00
|
|
|
|
PRUint32 mUpdateCount;
|
2001-03-13 06:38:59 +00:00
|
|
|
|
// normal reflow commands
|
|
|
|
|
nsVoidArray mReflowCommands;
|
|
|
|
|
// reflow commands targeted at each aFrame who calls SendInterruptNotificationTo(aFrame, Timeout);
|
|
|
|
|
nsVoidArray mTimeoutReflowCommands;
|
|
|
|
|
|
2000-05-16 01:11:29 +00:00
|
|
|
|
PRPackedBool mDocumentLoading;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
PRPackedBool mIsReflowing;
|
|
|
|
|
PRPackedBool mIsDestroying;
|
1998-11-21 00:19:36 +00:00
|
|
|
|
nsIFrame* mCurrentEventFrame;
|
1999-06-15 03:14:28 +00:00
|
|
|
|
nsIContent* mCurrentEventContent;
|
1999-09-02 18:14:01 +00:00
|
|
|
|
nsVoidArray mCurrentEventFrameStack;
|
2000-04-24 04:41:27 +00:00
|
|
|
|
nsVoidArray mCurrentEventContentStack;
|
2000-10-09 03:08:41 +00:00
|
|
|
|
nsSupportsHashtable* mAnonymousContentTable;
|
2000-04-24 04:41:27 +00:00
|
|
|
|
|
2000-02-03 02:49:58 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
|
nsRect mCurrentTargetRect;
|
|
|
|
|
nsIView* mCurrentTargetView;
|
|
|
|
|
#endif
|
1999-02-12 00:02:56 +00:00
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIFrameSelection> mSelection;
|
|
|
|
|
nsCOMPtr<nsICaret> mCaret;
|
1999-05-17 00:21:18 +00:00
|
|
|
|
PRBool mDisplayNonTextSelection;
|
1999-02-21 19:43:40 +00:00
|
|
|
|
PRBool mScrollingEnabled; //used to disable programmable scrolling from outside
|
1999-08-05 03:23:39 +00:00
|
|
|
|
nsIFrameManager* mFrameManager; // we hold a reference
|
1999-10-15 04:29:30 +00:00
|
|
|
|
PresShellViewEventListener *mViewEventListener;
|
1999-11-09 03:23:26 +00:00
|
|
|
|
PRBool mPendingReflowEvent;
|
|
|
|
|
nsCOMPtr<nsIEventQueue> mEventQueue;
|
1999-12-07 04:36:08 +00:00
|
|
|
|
FrameArena mFrameArena;
|
2000-03-31 07:02:06 +00:00
|
|
|
|
StackArena* mStackArena;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
PRInt32 mAccumulatedReflowTime; // Time spent in reflow command processing so far
|
|
|
|
|
PRPackedBool mBatchReflows; // When set to true, the pres shell batches reflow commands.
|
2000-05-15 03:37:21 +00:00
|
|
|
|
nsCOMPtr<nsIObserverService> mObserverService; // Observer service for reflow events
|
2000-06-14 23:18:54 +00:00
|
|
|
|
nsCOMPtr<nsIDragService> mDragService;
|
2000-09-12 00:35:11 +00:00
|
|
|
|
PRInt32 mRCCreatedDuringLoad; // Counter to keep track of reflow commands created during doc
|
2001-02-21 20:38:08 +00:00
|
|
|
|
nsCOMPtr<nsIRequest> mDummyLayoutRequest;
|
2000-06-23 05:15:04 +00:00
|
|
|
|
|
|
|
|
|
// used for list of posted events and attribute changes. To be done
|
|
|
|
|
// after reflow.
|
|
|
|
|
nsDOMEventRequest* mFirstDOMEventRequest;
|
|
|
|
|
nsDOMEventRequest* mLastDOMEventRequest;
|
|
|
|
|
nsAttributeChangeRequest* mFirstAttributeRequest;
|
|
|
|
|
nsAttributeChangeRequest* mLastAttributeRequest;
|
2000-07-13 23:00:59 +00:00
|
|
|
|
nsCallbackEventRequest* mFirstCallbackEventRequest;
|
|
|
|
|
nsCallbackEventRequest* mLastCallbackEventRequest;
|
2000-06-23 05:15:04 +00:00
|
|
|
|
|
2001-04-25 19:52:49 +00:00
|
|
|
|
PRBool mPaintingSuppressed; // For all documents we initially lock down painting.
|
|
|
|
|
// We will refuse to paint the document until either
|
|
|
|
|
// (a) our timer fires or (b) all frames are constructed.
|
|
|
|
|
PRBool mShouldUnsuppressPainting; // Indicates that it is safe to unlock painting once all pending
|
|
|
|
|
// reflows have been processed.
|
|
|
|
|
nsCOMPtr<nsITimer> mPaintSuppressionTimer; // This timer controls painting suppression. Until it fires
|
|
|
|
|
// or all frames are constructed, we won't paint anything but
|
|
|
|
|
// our <body> background and scrollbars.
|
|
|
|
|
#define PAINTLOCK_EVENT_DELAY 1200 // 1200 ms. This is actually pref-controlled, but we use this
|
|
|
|
|
// value if we fail to get the pref for any reason.
|
|
|
|
|
|
|
|
|
|
static void sPaintSuppressionCallback(nsITimer* aTimer, void* aPresShell); // A callback for the timer.
|
|
|
|
|
|
2000-03-03 23:15:29 +00:00
|
|
|
|
// subshell map
|
|
|
|
|
nsDST* mSubShellMap; // map of content/subshell pairs
|
|
|
|
|
nsDST::NodeArena* mDSTNodeArena; // weak link. DST owns (mSubShellMap object)
|
1999-11-09 03:23:26 +00:00
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
MOZ_TIMER_DECLARE(mReflowWatch) // Used for measuring time spent in reflow
|
|
|
|
|
MOZ_TIMER_DECLARE(mFrameCreationWatch) // Used for measuring time spent in frame creation
|
1999-12-23 02:02:33 +00:00
|
|
|
|
|
2000-04-21 14:59:47 +00:00
|
|
|
|
#ifdef MOZ_REFLOW_PERF
|
|
|
|
|
ReflowCountMgr * mReflowCountMgr;
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-04-18 06:06:31 +00:00
|
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
// copy string to clipboard methods
|
|
|
|
|
static nsresult CopyStringToClipboard(nsString& aString,
|
|
|
|
|
PRInt32 aClipboardID);
|
|
|
|
|
static nsresult CopyStringToClipboard(nsString& aString);
|
|
|
|
|
|
2000-03-31 07:02:06 +00:00
|
|
|
|
void FreeDynamicStack();
|
|
|
|
|
|
1999-02-21 19:43:40 +00:00
|
|
|
|
//helper funcs for disabing autoscrolling
|
|
|
|
|
void DisableScrolling(){mScrollingEnabled = PR_FALSE;}
|
|
|
|
|
void EnableScrolling(){mScrollingEnabled = PR_TRUE;}
|
|
|
|
|
PRBool IsScrollingEnabled(){return mScrollingEnabled;}
|
1999-09-02 18:14:01 +00:00
|
|
|
|
|
|
|
|
|
//helper funcs for event handling
|
1999-06-15 03:14:28 +00:00
|
|
|
|
nsIFrame* GetCurrentEventFrame();
|
2000-04-24 04:41:27 +00:00
|
|
|
|
void PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent);
|
|
|
|
|
void PopCurrentEventInfo();
|
2000-09-19 21:47:04 +00:00
|
|
|
|
nsresult HandleEventInternal(nsEvent* aEvent, nsIView* aView, PRUint32 aFlags, nsEventStatus *aStatus);
|
2001-04-17 23:25:21 +00:00
|
|
|
|
|
|
|
|
|
//help funcs for resize events
|
|
|
|
|
void CreateResizeEventTimer();
|
|
|
|
|
void KillResizeEventTimer();
|
|
|
|
|
void FireResizeEvent();
|
|
|
|
|
static void sResizeEventCallback(nsITimer* aTimer, void* aPresShell) ;
|
|
|
|
|
nsCOMPtr<nsITimer> mResizeEventTimer;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
};
|
|
|
|
|
|
2001-04-11 03:07:50 +00:00
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
|
PRLogModuleInfo* PresShell::gLog;
|
|
|
|
|
#endif
|
|
|
|
|
|
1999-09-21 07:53:49 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
|
static void
|
2000-01-22 01:16:50 +00:00
|
|
|
|
VerifyStyleTree(nsIPresContext* aPresContext, nsIFrameManager* aFrameManager)
|
1999-09-21 07:53:49 +00:00
|
|
|
|
{
|
1999-11-01 22:12:45 +00:00
|
|
|
|
if (aFrameManager && nsIFrameDebug::GetVerifyStyleTreeEnable()) {
|
1999-10-18 22:20:37 +00:00
|
|
|
|
nsIFrame* rootFrame;
|
|
|
|
|
|
|
|
|
|
aFrameManager->GetRootFrame(&rootFrame);
|
2000-01-22 01:16:50 +00:00
|
|
|
|
aFrameManager->DebugVerifyStyleTree(aPresContext, rootFrame);
|
1999-09-21 07:53:49 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2000-01-22 01:16:50 +00:00
|
|
|
|
#define VERIFY_STYLE_TREE VerifyStyleTree(mPresContext, mFrameManager)
|
1999-09-21 07:53:49 +00:00
|
|
|
|
#else
|
|
|
|
|
#define VERIFY_STYLE_TREE
|
|
|
|
|
#endif
|
|
|
|
|
|
1998-07-13 19:49:42 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
|
/**
|
|
|
|
|
* Note: the log module is created during library initialization which
|
|
|
|
|
* means that you cannot perform logging before then.
|
|
|
|
|
*/
|
1999-02-26 17:08:48 +00:00
|
|
|
|
static PRLogModuleInfo* gLogModule;
|
1999-09-10 18:49:23 +00:00
|
|
|
|
static PRUint32 gVerifyReflowFlags;
|
1999-04-27 22:14:17 +00:00
|
|
|
|
#endif
|
1998-07-13 19:49:42 +00:00
|
|
|
|
|
1999-09-10 18:49:23 +00:00
|
|
|
|
static PRBool gVerifyReflowEnabled;
|
|
|
|
|
|
1998-07-13 19:49:42 +00:00
|
|
|
|
NS_LAYOUT PRBool
|
|
|
|
|
nsIPresShell::GetVerifyReflowEnable()
|
|
|
|
|
{
|
|
|
|
|
#ifdef NS_DEBUG
|
1999-09-10 18:49:23 +00:00
|
|
|
|
static PRBool firstTime = PR_TRUE;
|
|
|
|
|
if (firstTime) {
|
|
|
|
|
firstTime = PR_FALSE;
|
1999-02-26 17:08:48 +00:00
|
|
|
|
gLogModule = PR_NewLogModule("verifyreflow");
|
1999-09-10 18:49:23 +00:00
|
|
|
|
gVerifyReflowFlags = gLogModule->level;
|
|
|
|
|
if (VERIFY_REFLOW_ON & gVerifyReflowFlags) {
|
|
|
|
|
gVerifyReflowEnabled = PR_TRUE;
|
1998-11-25 18:41:02 +00:00
|
|
|
|
}
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("Note: verifyreflow is %sabled",
|
1999-09-10 18:49:23 +00:00
|
|
|
|
gVerifyReflowEnabled ? "en" : "dis");
|
|
|
|
|
if (VERIFY_REFLOW_NOISY & gVerifyReflowFlags) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf(" (noisy)");
|
1998-11-25 18:41:02 +00:00
|
|
|
|
}
|
1999-09-10 18:49:23 +00:00
|
|
|
|
if (VERIFY_REFLOW_ALL & gVerifyReflowFlags) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf(" (all)");
|
1998-11-25 18:41:02 +00:00
|
|
|
|
}
|
1999-09-15 00:27:05 +00:00
|
|
|
|
if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf(" (show reflow commands)");
|
1999-09-15 00:27:05 +00:00
|
|
|
|
}
|
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf(" (noisy reflow commands)");
|
1999-10-05 14:51:12 +00:00
|
|
|
|
if (VERIFY_REFLOW_REALLY_NOISY_RC & gVerifyReflowFlags) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf(" (REALLY noisy reflow commands)");
|
1999-10-05 14:51:12 +00:00
|
|
|
|
}
|
1999-09-15 00:27:05 +00:00
|
|
|
|
}
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("\n");
|
1998-07-13 19:49:42 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
1999-09-10 18:49:23 +00:00
|
|
|
|
return gVerifyReflowEnabled;
|
1998-07-13 19:49:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_LAYOUT void
|
|
|
|
|
nsIPresShell::SetVerifyReflowEnable(PRBool aEnabled)
|
|
|
|
|
{
|
1999-09-10 18:49:23 +00:00
|
|
|
|
gVerifyReflowEnabled = aEnabled;
|
1998-07-13 19:49:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-03-22 23:19:10 +00:00
|
|
|
|
NS_LAYOUT PRInt32
|
|
|
|
|
nsIPresShell::GetVerifyReflowFlags()
|
|
|
|
|
{
|
2000-03-23 00:10:26 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
2000-03-22 23:19:10 +00:00
|
|
|
|
return gVerifyReflowFlags;
|
2000-03-23 00:10:26 +00:00
|
|
|
|
#else
|
|
|
|
|
return 0;
|
|
|
|
|
#endif
|
2000-03-22 23:19:10 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
|
//----------------------------------------------------------------------
|
|
|
|
|
|
1998-07-13 19:49:42 +00:00
|
|
|
|
NS_LAYOUT nsresult
|
|
|
|
|
NS_NewPresShell(nsIPresShell** aInstancePtrResult)
|
|
|
|
|
{
|
|
|
|
|
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
|
|
|
|
if (nsnull == aInstancePtrResult) {
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
PresShell* it = new PresShell();
|
|
|
|
|
if (nsnull == it) {
|
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
}
|
2000-01-04 20:24:09 +00:00
|
|
|
|
return it->QueryInterface(NS_GET_IID(nsIPresShell),
|
|
|
|
|
(void **) aInstancePtrResult);
|
1998-07-13 19:49:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-12-30 19:22:22 +00:00
|
|
|
|
PresShell::PresShell():mAnonymousContentTable(nsnull),
|
|
|
|
|
mStackArena(nsnull),
|
2000-06-23 05:15:04 +00:00
|
|
|
|
mFirstDOMEventRequest(nsnull),
|
|
|
|
|
mLastDOMEventRequest(nsnull),
|
|
|
|
|
mFirstAttributeRequest(nsnull),
|
2000-07-13 23:00:59 +00:00
|
|
|
|
mLastAttributeRequest(nsnull),
|
|
|
|
|
mFirstCallbackEventRequest(nsnull),
|
2001-04-25 19:52:49 +00:00
|
|
|
|
mLastCallbackEventRequest(nsnull),
|
|
|
|
|
mPaintingSuppressed(PR_FALSE),
|
|
|
|
|
mShouldUnsuppressPainting(PR_FALSE)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
2000-03-05 21:26:01 +00:00
|
|
|
|
NS_INIT_REFCNT();
|
1998-11-18 05:25:26 +00:00
|
|
|
|
mIsDestroying = PR_FALSE;
|
1999-04-01 23:58:11 +00:00
|
|
|
|
mCaretEnabled = PR_FALSE;
|
1999-05-17 00:21:18 +00:00
|
|
|
|
mDisplayNonTextSelection = PR_FALSE;
|
1999-06-15 03:14:28 +00:00
|
|
|
|
mCurrentEventContent = nsnull;
|
1999-09-02 18:14:01 +00:00
|
|
|
|
mCurrentEventFrame = nsnull;
|
1999-02-21 19:43:40 +00:00
|
|
|
|
EnableScrolling();
|
2000-02-03 02:49:58 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
|
mCurrentTargetView = nsnull;
|
|
|
|
|
#endif
|
2000-04-17 07:13:57 +00:00
|
|
|
|
mPendingReflowEvent = PR_FALSE;
|
2000-01-28 00:48:02 +00:00
|
|
|
|
mBatchReflows = PR_FALSE;
|
2000-05-16 01:11:29 +00:00
|
|
|
|
mDocumentLoading = PR_FALSE;
|
2000-03-03 23:15:29 +00:00
|
|
|
|
mSubShellMap = nsnull;
|
2000-09-12 00:35:11 +00:00
|
|
|
|
mRCCreatedDuringLoad = 0;
|
|
|
|
|
mDummyLayoutRequest = nsnull;
|
2000-10-11 08:33:01 +00:00
|
|
|
|
mPrefStyleSheet = nsnull;
|
|
|
|
|
mEnablePrefStyleSheet = PR_TRUE;
|
2000-04-21 14:59:47 +00:00
|
|
|
|
|
|
|
|
|
#ifdef MOZ_REFLOW_PERF
|
|
|
|
|
mReflowCountMgr = new ReflowCountMgr();
|
2001-02-22 13:58:17 +00:00
|
|
|
|
mReflowCountMgr->SetPresContext(mPresContext);
|
|
|
|
|
mReflowCountMgr->SetPresShell(this);
|
2000-04-21 14:59:47 +00:00
|
|
|
|
#endif
|
2001-03-09 03:29:00 +00:00
|
|
|
|
#ifdef IBMBIDI
|
|
|
|
|
mBidiLevel = BIDI_LEVEL_UNDEFINED;
|
|
|
|
|
#endif
|
2001-04-11 03:07:50 +00:00
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
|
if (! gLog)
|
|
|
|
|
gLog = PR_NewLogModule("PresShell");
|
|
|
|
|
#endif
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-09-12 19:33:48 +00:00
|
|
|
|
NS_IMPL_ADDREF(PresShell)
|
|
|
|
|
NS_IMPL_RELEASE(PresShell)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
1998-05-09 03:22:41 +00:00
|
|
|
|
nsresult
|
|
|
|
|
PresShell::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (!aInstancePtr) {
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (aIID.Equals(NS_GET_IID(nsIPresShell))) {
|
1998-09-12 19:33:48 +00:00
|
|
|
|
nsIPresShell* tmp = this;
|
|
|
|
|
*aInstancePtr = (void*) tmp;
|
2000-01-04 20:24:09 +00:00
|
|
|
|
} else if (aIID.Equals(NS_GET_IID(nsIDocumentObserver))) {
|
1998-09-12 19:33:48 +00:00
|
|
|
|
nsIDocumentObserver* tmp = this;
|
|
|
|
|
*aInstancePtr = (void*) tmp;
|
2000-01-04 20:24:09 +00:00
|
|
|
|
} else if (aIID.Equals(NS_GET_IID(nsIViewObserver))) {
|
1998-09-12 19:33:48 +00:00
|
|
|
|
nsIViewObserver* tmp = this;
|
|
|
|
|
*aInstancePtr = (void*) tmp;
|
2000-01-04 20:24:09 +00:00
|
|
|
|
} else if (aIID.Equals(NS_GET_IID(nsIFocusTracker))) {
|
1998-12-14 18:34:14 +00:00
|
|
|
|
nsIFocusTracker* tmp = this;
|
|
|
|
|
*aInstancePtr = (void*) tmp;
|
2000-01-04 20:24:09 +00:00
|
|
|
|
} else if (aIID.Equals(NS_GET_IID(nsISelectionController))) {
|
1999-12-02 21:45:21 +00:00
|
|
|
|
nsISelectionController* tmp = this;
|
1999-02-19 23:47:36 +00:00
|
|
|
|
*aInstancePtr = (void*) tmp;
|
2000-01-04 20:24:09 +00:00
|
|
|
|
} else if (aIID.Equals(NS_GET_IID(nsISupportsWeakReference))) {
|
1999-08-25 10:51:55 +00:00
|
|
|
|
nsISupportsWeakReference* tmp = this;
|
|
|
|
|
*aInstancePtr = (void*) tmp;
|
2000-01-04 20:24:09 +00:00
|
|
|
|
} else if (aIID.Equals(NS_GET_IID(nsISupports))) {
|
1998-09-12 19:33:48 +00:00
|
|
|
|
nsIPresShell* tmp = this;
|
|
|
|
|
nsISupports* tmp2 = tmp;
|
|
|
|
|
*aInstancePtr = (void*) tmp2;
|
2000-01-04 20:24:09 +00:00
|
|
|
|
} else {
|
|
|
|
|
*aInstancePtr = nsnull;
|
|
|
|
|
|
|
|
|
|
return NS_NOINTERFACE;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
2000-01-04 20:24:09 +00:00
|
|
|
|
|
|
|
|
|
NS_ADDREF_THIS();
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PresShell::~PresShell()
|
|
|
|
|
{
|
2000-04-21 14:59:47 +00:00
|
|
|
|
#ifdef MOZ_REFLOW_PERF
|
2000-04-28 23:32:04 +00:00
|
|
|
|
DumpReflows();
|
|
|
|
|
if (mReflowCountMgr) {
|
|
|
|
|
delete mReflowCountMgr;
|
|
|
|
|
mReflowCountMgr = nsnull;
|
2000-04-21 14:59:47 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2001-04-25 19:52:49 +00:00
|
|
|
|
// If our paint suppression timer is still active, kill it.
|
|
|
|
|
if (mPaintSuppressionTimer) {
|
|
|
|
|
mPaintSuppressionTimer->Cancel();
|
|
|
|
|
mPaintSuppressionTimer = nsnull;
|
|
|
|
|
}
|
|
|
|
|
|
2000-10-11 08:33:01 +00:00
|
|
|
|
// release our pref style sheet, if we have one still
|
|
|
|
|
ClearPreferenceStyleRules();
|
|
|
|
|
|
2000-03-31 07:02:06 +00:00
|
|
|
|
// if we allocated any stack memory free it.
|
|
|
|
|
FreeDynamicStack();
|
|
|
|
|
|
2000-10-09 03:08:41 +00:00
|
|
|
|
// free our table of anonymous content
|
|
|
|
|
ReleaseAnonymousContent();
|
|
|
|
|
|
1998-11-18 05:25:26 +00:00
|
|
|
|
mIsDestroying = PR_TRUE;
|
1999-06-15 03:14:28 +00:00
|
|
|
|
|
1999-10-07 00:31:21 +00:00
|
|
|
|
// Clobber weak leaks in case of re-entrancy during tear down
|
|
|
|
|
mHistoryState = nsnull;
|
|
|
|
|
|
2000-03-03 23:15:29 +00:00
|
|
|
|
// kill subshell map, if any. It holds only weak references
|
|
|
|
|
if (mSubShellMap)
|
|
|
|
|
{
|
|
|
|
|
delete mSubShellMap;
|
|
|
|
|
mSubShellMap = nsnull;
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-24 04:41:27 +00:00
|
|
|
|
// release current event content and any content on event stack
|
1999-06-15 03:14:28 +00:00
|
|
|
|
NS_IF_RELEASE(mCurrentEventContent);
|
1999-10-07 00:31:21 +00:00
|
|
|
|
|
2000-04-24 04:41:27 +00:00
|
|
|
|
PRInt32 i, count = mCurrentEventContentStack.Count();
|
|
|
|
|
nsIContent* currentEventContent;
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
|
currentEventContent = (nsIContent*)mCurrentEventContentStack.ElementAt(i);
|
|
|
|
|
NS_IF_RELEASE(currentEventContent);
|
|
|
|
|
}
|
|
|
|
|
|
1999-04-30 00:08:17 +00:00
|
|
|
|
if (mViewManager) {
|
|
|
|
|
// Disable paints during tear down of the frame tree
|
|
|
|
|
mViewManager->DisableRefresh();
|
1999-10-07 00:31:21 +00:00
|
|
|
|
mViewManager = nsnull;
|
1999-04-30 00:08:17 +00:00
|
|
|
|
}
|
1999-10-07 00:31:21 +00:00
|
|
|
|
|
1999-10-18 22:20:37 +00:00
|
|
|
|
// Destroy the frame manager. This will destroy the frame hierarchy
|
2001-03-06 01:46:03 +00:00
|
|
|
|
if (mFrameManager) {
|
|
|
|
|
mFrameManager->Destroy();
|
|
|
|
|
NS_RELEASE(mFrameManager);
|
|
|
|
|
}
|
1999-10-07 00:31:21 +00:00
|
|
|
|
|
|
|
|
|
if (mDocument) {
|
1998-09-23 17:16:51 +00:00
|
|
|
|
mDocument->DeleteShell(this);
|
1999-10-07 00:31:21 +00:00
|
|
|
|
}
|
1999-10-18 19:00:49 +00:00
|
|
|
|
|
|
|
|
|
// We hold a reference to the pres context, and it holds a weak link back
|
|
|
|
|
// to us. To avoid the pres context having a dangling reference, set its
|
|
|
|
|
// pres shell to NULL
|
|
|
|
|
if (mPresContext) {
|
|
|
|
|
mPresContext->SetShell(nsnull);
|
|
|
|
|
}
|
1999-10-15 04:29:30 +00:00
|
|
|
|
|
|
|
|
|
if (mViewEventListener) {
|
|
|
|
|
mViewEventListener->SetPresShell((nsIPresShell*)nsnull);
|
|
|
|
|
NS_RELEASE(mViewEventListener);
|
|
|
|
|
}
|
2000-02-10 07:27:43 +00:00
|
|
|
|
|
|
|
|
|
// Revoke pending reflow events
|
|
|
|
|
if (mPendingReflowEvent) {
|
|
|
|
|
mPendingReflowEvent = PR_FALSE;
|
|
|
|
|
mEventQueue->RevokeEvents(this);
|
|
|
|
|
}
|
2000-04-21 14:59:47 +00:00
|
|
|
|
|
2001-04-17 23:25:21 +00:00
|
|
|
|
KillResizeEventTimer();
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Initialize the presentation shell. Create view manager and style
|
|
|
|
|
* manager.
|
|
|
|
|
*/
|
1998-05-09 03:22:41 +00:00
|
|
|
|
nsresult
|
|
|
|
|
PresShell::Init(nsIDocument* aDocument,
|
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
|
nsIViewManager* aViewManager,
|
|
|
|
|
nsIStyleSet* aStyleSet)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
|
|
|
|
NS_PRECONDITION(nsnull != aDocument, "null ptr");
|
|
|
|
|
NS_PRECONDITION(nsnull != aPresContext, "null ptr");
|
|
|
|
|
NS_PRECONDITION(nsnull != aViewManager, "null ptr");
|
1999-12-04 23:49:50 +00:00
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
|
if ((nsnull == aDocument) || (nsnull == aPresContext) ||
|
|
|
|
|
(nsnull == aViewManager)) {
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
1999-05-04 23:27:42 +00:00
|
|
|
|
if (mDocument) {
|
1998-04-13 20:24:54 +00:00
|
|
|
|
return NS_ERROR_ALREADY_INITIALIZED;
|
|
|
|
|
}
|
|
|
|
|
|
1999-05-04 23:27:42 +00:00
|
|
|
|
mDocument = dont_QueryInterface(aDocument);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
mViewManager = aViewManager;
|
|
|
|
|
|
1998-08-28 02:54:06 +00:00
|
|
|
|
//doesn't add a ref since we own it... MMP
|
|
|
|
|
mViewManager->SetViewObserver((nsIViewObserver *)this);
|
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
|
// Bind the context to the presentation shell.
|
1999-05-04 23:27:42 +00:00
|
|
|
|
mPresContext = dont_QueryInterface(aPresContext);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
aPresContext->SetShell(this);
|
|
|
|
|
|
1999-04-30 09:04:36 +00:00
|
|
|
|
mStyleSet = dont_QueryInterface(aStyleSet);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
1999-08-31 14:35:50 +00:00
|
|
|
|
mHistoryState = nsnull;
|
|
|
|
|
|
1999-07-18 02:27:19 +00:00
|
|
|
|
nsresult result = nsComponentManager::CreateInstance(kFrameSelectionCID, nsnull,
|
2000-01-04 20:24:09 +00:00
|
|
|
|
NS_GET_IID(nsIFrameSelection),
|
1999-07-18 02:27:19 +00:00
|
|
|
|
getter_AddRefs(mSelection));
|
1998-12-14 18:34:14 +00:00
|
|
|
|
if (!NS_SUCCEEDED(result))
|
|
|
|
|
return result;
|
1999-04-26 04:02:04 +00:00
|
|
|
|
|
1999-08-04 04:02:40 +00:00
|
|
|
|
// Create and initialize the frame manager
|
|
|
|
|
result = NS_NewFrameManager(&mFrameManager);
|
|
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
1999-10-18 22:20:37 +00:00
|
|
|
|
result = mFrameManager->Init(this, mStyleSet);
|
|
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
1999-08-04 04:02:40 +00:00
|
|
|
|
|
2000-05-02 03:45:01 +00:00
|
|
|
|
result = mSelection->Init((nsIFocusTracker *) this, nsnull);
|
1999-04-26 04:02:04 +00:00
|
|
|
|
if (!NS_SUCCEEDED(result))
|
|
|
|
|
return result;
|
1999-02-12 00:02:56 +00:00
|
|
|
|
// Important: this has to happen after the selection has been set up
|
|
|
|
|
#ifdef SHOW_CARET
|
|
|
|
|
// make the caret
|
|
|
|
|
nsresult err = NS_NewCaret(getter_AddRefs(mCaret));
|
|
|
|
|
if (NS_SUCCEEDED(err))
|
1999-04-01 23:58:11 +00:00
|
|
|
|
{
|
1999-07-14 22:18:29 +00:00
|
|
|
|
mCaret->Init(this);
|
1999-04-01 23:58:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//SetCaretEnabled(PR_TRUE); // make it show in browser windows
|
1999-02-12 00:02:56 +00:00
|
|
|
|
#endif
|
1999-04-29 20:24:21 +00:00
|
|
|
|
//set up selection to be displayed in document
|
|
|
|
|
nsCOMPtr<nsISupports> container;
|
|
|
|
|
result = aPresContext->GetContainer(getter_AddRefs(container));
|
|
|
|
|
if (NS_SUCCEEDED(result) && container) {
|
1999-12-18 02:09:29 +00:00
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> docShell(do_QueryInterface(container, &result));
|
|
|
|
|
if (NS_SUCCEEDED(result) && docShell){
|
|
|
|
|
PRInt32 docShellType;
|
|
|
|
|
result = docShell->GetItemType(&docShellType);
|
1999-04-29 20:24:21 +00:00
|
|
|
|
if (NS_SUCCEEDED(result)){
|
1999-12-18 02:09:29 +00:00
|
|
|
|
if (nsIDocShellTreeItem::typeContent == docShellType){
|
2000-04-28 06:21:31 +00:00
|
|
|
|
SetDisplaySelection(nsISelectionController::SELECTION_ON);
|
1999-04-29 20:24:21 +00:00
|
|
|
|
}
|
1999-11-09 03:23:26 +00:00
|
|
|
|
}
|
1999-04-29 20:24:21 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1999-11-30 00:32:43 +00:00
|
|
|
|
|
1999-11-09 03:23:26 +00:00
|
|
|
|
// Cache the event queue of the current UI thread
|
|
|
|
|
NS_WITH_SERVICE(nsIEventQueueService, eventService, kEventQueueServiceCID, &result);
|
1999-11-30 00:32:43 +00:00
|
|
|
|
if (NS_SUCCEEDED(result)) // XXX this implies that the UI is the current thread.
|
|
|
|
|
result = eventService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(mEventQueue));
|
1999-11-09 03:23:26 +00:00
|
|
|
|
|
1999-12-23 02:02:33 +00:00
|
|
|
|
|
1999-12-23 03:47:02 +00:00
|
|
|
|
if (gMaxRCProcessingTime == -1) {
|
1999-12-23 02:02:33 +00:00
|
|
|
|
// First, set the defaults
|
2000-09-12 08:59:01 +00:00
|
|
|
|
gMaxRCProcessingTime = NS_MAX_REFLOW_TIME;
|
2000-09-20 07:20:23 +00:00
|
|
|
|
gAsyncReflowDuringDocLoad = PR_TRUE;
|
1999-12-23 02:02:33 +00:00
|
|
|
|
|
|
|
|
|
// Get the prefs service
|
|
|
|
|
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &result);
|
2000-02-02 00:19:52 +00:00
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
2000-09-12 08:59:01 +00:00
|
|
|
|
prefs->GetIntPref("layout.reflow.timeslice", &gMaxRCProcessingTime);
|
|
|
|
|
prefs->GetBoolPref("layout.reflow.async.duringDocLoad", &gAsyncReflowDuringDocLoad);
|
1999-12-23 02:02:33 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-05-15 03:37:21 +00:00
|
|
|
|
// cache the observation service
|
2000-09-13 23:57:52 +00:00
|
|
|
|
mObserverService = do_GetService(NS_OBSERVERSERVICE_CONTRACTID,
|
2000-05-15 03:37:21 +00:00
|
|
|
|
&result);
|
|
|
|
|
if (NS_FAILED(result)) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2000-06-14 23:18:54 +00:00
|
|
|
|
// cache the drag service so we can check it during reflows
|
2000-09-13 23:57:52 +00:00
|
|
|
|
mDragService = do_GetService("@mozilla.org/widget/dragservice;1");
|
2000-06-14 23:18:54 +00:00
|
|
|
|
|
2001-03-09 03:29:00 +00:00
|
|
|
|
#ifdef IBMBIDI
|
|
|
|
|
mBidiKeyboard = do_GetService("@mozilla.org/widget/bidikeyboard;1");
|
|
|
|
|
#endif
|
2000-10-11 08:33:01 +00:00
|
|
|
|
// setup the preference style rules up (no forced reflow)
|
|
|
|
|
SetPreferenceStyleRules(PR_FALSE);
|
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
#ifdef MOZ_REFLOW_PERF
|
|
|
|
|
// Get the prefs service
|
|
|
|
|
NS_WITH_SERVICE(nsIPref, prefs, kPrefServiceCID, &result);
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
if (mReflowCountMgr != nsnull) {
|
2001-03-14 01:03:31 +00:00
|
|
|
|
PRBool paintFrameCounts = PR_FALSE;
|
|
|
|
|
PRBool dumpFrameCounts = PR_FALSE;
|
|
|
|
|
PRBool dumpFrameByFrameCounts = PR_FALSE;
|
2001-03-13 01:47:22 +00:00
|
|
|
|
prefs->GetBoolPref("layout.reflow.showframecounts", &paintFrameCounts);
|
|
|
|
|
prefs->GetBoolPref("layout.reflow.dumpframecounts", &dumpFrameCounts);
|
|
|
|
|
prefs->GetBoolPref("layout.reflow.dumpframebyframecounts", &dumpFrameByFrameCounts);
|
|
|
|
|
|
|
|
|
|
mReflowCountMgr->SetDumpFrameCounts(dumpFrameCounts);
|
|
|
|
|
mReflowCountMgr->SetDumpFrameByFrameCounts(dumpFrameByFrameCounts);
|
|
|
|
|
mReflowCountMgr->SetPaintFrameCounts(paintFrameCounts);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2000-03-31 07:02:06 +00:00
|
|
|
|
// Dynamic stack memory allocation
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::PushStackMemory()
|
|
|
|
|
{
|
|
|
|
|
if (nsnull == mStackArena)
|
|
|
|
|
mStackArena = new StackArena();
|
|
|
|
|
|
|
|
|
|
return mStackArena->Push();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::PopStackMemory()
|
|
|
|
|
{
|
|
|
|
|
if (nsnull == mStackArena)
|
|
|
|
|
mStackArena = new StackArena();
|
|
|
|
|
|
|
|
|
|
return mStackArena->Pop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::AllocateStackMemory(size_t aSize, void** aResult)
|
|
|
|
|
{
|
|
|
|
|
if (nsnull == mStackArena)
|
|
|
|
|
mStackArena = new StackArena();
|
|
|
|
|
|
|
|
|
|
return mStackArena->Allocate(aSize, aResult);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
PresShell::FreeDynamicStack()
|
|
|
|
|
{
|
|
|
|
|
if (mStackArena) {
|
|
|
|
|
delete mStackArena;
|
|
|
|
|
mStackArena = nsnull;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1999-12-04 23:49:50 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::FreeFrame(size_t aSize, void* aPtr)
|
|
|
|
|
{
|
1999-12-07 04:36:08 +00:00
|
|
|
|
mFrameArena.FreeFrame(aSize, aPtr);
|
1999-12-04 23:49:50 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::AllocateFrame(size_t aSize, void** aResult)
|
|
|
|
|
{
|
1999-12-07 04:36:08 +00:00
|
|
|
|
return mFrameArena.AllocateFrame(aSize, aResult);
|
1999-12-04 23:49:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetDocument(nsIDocument** aResult)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
*aResult = mDocument;
|
1999-05-04 23:27:42 +00:00
|
|
|
|
NS_IF_ADDREF(*aResult);
|
1999-02-12 17:45:58 +00:00
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetPresContext(nsIPresContext** aResult)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
*aResult = mPresContext;
|
1999-05-04 23:27:42 +00:00
|
|
|
|
NS_IF_ADDREF(*aResult);
|
1999-02-12 17:45:58 +00:00
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetViewManager(nsIViewManager** aResult)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
*aResult = mViewManager;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
NS_IF_ADDREF(mViewManager);
|
1999-02-12 17:45:58 +00:00
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetStyleSet(nsIStyleSet** aResult)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
*aResult = mStyleSet;
|
1999-04-30 09:04:36 +00:00
|
|
|
|
NS_IF_ADDREF(*aResult);
|
1999-02-12 17:45:58 +00:00
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-01-23 07:03:46 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetActiveAlternateStyleSheet(nsString& aSheetTitle)
|
|
|
|
|
{ // first non-html sheet in style set that has title
|
1999-04-30 09:04:36 +00:00
|
|
|
|
if (mStyleSet) {
|
1999-01-23 07:03:46 +00:00
|
|
|
|
PRInt32 count = mStyleSet->GetNumberOfDocStyleSheets();
|
|
|
|
|
PRInt32 index;
|
2000-04-03 11:39:09 +00:00
|
|
|
|
nsAutoString textHtml; textHtml.AssignWithConversion("text/html");
|
1999-01-23 07:03:46 +00:00
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
|
nsIStyleSheet* sheet = mStyleSet->GetDocStyleSheetAt(index);
|
|
|
|
|
if (nsnull != sheet) {
|
|
|
|
|
nsAutoString type;
|
|
|
|
|
sheet->GetType(type);
|
|
|
|
|
if (PR_FALSE == type.Equals(textHtml)) {
|
|
|
|
|
nsAutoString title;
|
|
|
|
|
sheet->GetTitle(title);
|
|
|
|
|
if (0 < title.Length()) {
|
|
|
|
|
aSheetTitle = title;
|
|
|
|
|
index = count; // stop looking
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
NS_RELEASE(sheet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::SelectAlternateStyleSheet(const nsString& aSheetTitle)
|
|
|
|
|
{
|
1999-05-04 23:27:42 +00:00
|
|
|
|
if (mDocument && mStyleSet) {
|
1999-01-23 07:03:46 +00:00
|
|
|
|
PRInt32 count = mDocument->GetNumberOfStyleSheets();
|
|
|
|
|
PRInt32 index;
|
2000-04-03 11:39:09 +00:00
|
|
|
|
nsAutoString textHtml; textHtml.AssignWithConversion("text/html");
|
1999-01-23 07:03:46 +00:00
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
|
nsIStyleSheet* sheet = mDocument->GetStyleSheetAt(index);
|
|
|
|
|
if (nsnull != sheet) {
|
|
|
|
|
nsAutoString type;
|
|
|
|
|
sheet->GetType(type);
|
|
|
|
|
if (PR_FALSE == type.Equals(textHtml)) {
|
|
|
|
|
nsAutoString title;
|
|
|
|
|
sheet->GetTitle(title);
|
|
|
|
|
if (0 < title.Length()) {
|
|
|
|
|
if (title.EqualsIgnoreCase(aSheetTitle)) {
|
|
|
|
|
mStyleSet->AddDocStyleSheet(sheet, mDocument);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mStyleSet->RemoveDocStyleSheet(sheet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
NS_RELEASE(sheet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ReconstructFrames();
|
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::ListAlternateStyleSheets(nsStringArray& aTitleList)
|
|
|
|
|
{
|
1999-05-04 23:27:42 +00:00
|
|
|
|
if (mDocument) {
|
1999-01-23 07:03:46 +00:00
|
|
|
|
PRInt32 count = mDocument->GetNumberOfStyleSheets();
|
|
|
|
|
PRInt32 index;
|
2000-04-03 11:39:09 +00:00
|
|
|
|
nsAutoString textHtml; textHtml.AssignWithConversion("text/html");
|
1999-01-23 07:03:46 +00:00
|
|
|
|
for (index = 0; index < count; index++) {
|
|
|
|
|
nsIStyleSheet* sheet = mDocument->GetStyleSheetAt(index);
|
|
|
|
|
if (nsnull != sheet) {
|
|
|
|
|
nsAutoString type;
|
|
|
|
|
sheet->GetType(type);
|
|
|
|
|
if (PR_FALSE == type.Equals(textHtml)) {
|
|
|
|
|
nsAutoString title;
|
|
|
|
|
sheet->GetTitle(title);
|
|
|
|
|
if (0 < title.Length()) {
|
|
|
|
|
if (-1 == aTitleList.IndexOfIgnoreCase(title)) {
|
|
|
|
|
aTitleList.AppendString(title);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
NS_RELEASE(sheet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
1998-12-08 18:26:06 +00:00
|
|
|
|
|
2000-10-11 08:33:01 +00:00
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::EnablePrefStyleRules(PRBool aEnable, PRUint8 aPrefType/*=0xFF*/)
|
|
|
|
|
{
|
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
|
|
// capture change in state
|
|
|
|
|
PRBool bChanging = (mEnablePrefStyleSheet != aEnable) ? PR_TRUE : PR_FALSE;
|
|
|
|
|
// set to desired state
|
|
|
|
|
mEnablePrefStyleSheet = aEnable;
|
|
|
|
|
|
2000-11-13 08:27:01 +00:00
|
|
|
|
#ifdef DEBUG_attinasi
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("PrefStyleSheet %s %s\n",
|
|
|
|
|
mEnablePrefStyleSheet ? "ENABLED" : "DISABLED",
|
|
|
|
|
bChanging ? "(state toggled)" : "(state unchanged)");
|
|
|
|
|
#endif
|
2000-10-11 08:33:01 +00:00
|
|
|
|
|
|
|
|
|
// deal with changing state
|
|
|
|
|
if(bChanging){
|
|
|
|
|
switch (mEnablePrefStyleSheet){
|
|
|
|
|
case PR_TRUE:
|
|
|
|
|
// was off, now on, so create the rules
|
|
|
|
|
result = SetPreferenceStyleRules(PR_TRUE);
|
|
|
|
|
break;
|
|
|
|
|
default :
|
|
|
|
|
// was on, now off, so clear the rules
|
|
|
|
|
result = ClearPreferenceStyleRules();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::ArePrefStyleRulesEnabled(PRBool& aEnabled)
|
|
|
|
|
{
|
|
|
|
|
aEnabled = mEnablePrefStyleSheet;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::SetPreferenceStyleRules(PRBool aForceReflow)
|
|
|
|
|
{
|
|
|
|
|
NS_PRECONDITION(mPresContext, "presContext cannot be null");
|
|
|
|
|
if (mPresContext) {
|
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
|
|
// zeroth, make sure this feature is enabled
|
|
|
|
|
// XXX: may get more granularity later
|
|
|
|
|
// (i.e. each pref may be controlled independently)
|
|
|
|
|
if (!mEnablePrefStyleSheet) {
|
2000-11-13 08:27:01 +00:00
|
|
|
|
#ifdef DEBUG_attinasi
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("PrefStyleSheet disabled\n");
|
|
|
|
|
#endif
|
2000-10-11 08:33:01 +00:00
|
|
|
|
return PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// first, make sure this is not a chrome shell
|
|
|
|
|
nsCOMPtr<nsISupports> container;
|
|
|
|
|
result = mPresContext->GetContainer(getter_AddRefs(container));
|
|
|
|
|
if (NS_SUCCEEDED(result) && container) {
|
|
|
|
|
nsCOMPtr<nsIDocShellTreeItem> docShell(do_QueryInterface(container, &result));
|
|
|
|
|
if (NS_SUCCEEDED(result) && docShell){
|
|
|
|
|
PRInt32 docShellType;
|
|
|
|
|
result = docShell->GetItemType(&docShellType);
|
|
|
|
|
if (NS_SUCCEEDED(result)){
|
|
|
|
|
if (nsIDocShellTreeItem::typeChrome == docShellType){
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
|
2000-11-13 08:27:01 +00:00
|
|
|
|
#ifdef DEBUG_attinasi
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("Setting Preference Style Rules:\n");
|
|
|
|
|
#endif
|
2000-10-11 08:33:01 +00:00
|
|
|
|
// if here, we need to create rules for the prefs
|
|
|
|
|
// - this includes the background-color, the text-color,
|
|
|
|
|
// the link color, the visited link color and the link-underlining
|
|
|
|
|
|
|
|
|
|
// first clear any exising rules
|
|
|
|
|
result = ClearPreferenceStyleRules();
|
|
|
|
|
|
|
|
|
|
// now do the color rules
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
result = SetPrefColorRules();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// now the link rules (must come after the color rules, or links will not be correct color!)
|
|
|
|
|
// XXX - when there is both an override and backstop pref stylesheet this won't matter,
|
|
|
|
|
// as the color rules will be overrides and the links rules will be backstop
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
result = SetPrefLinkRules();
|
|
|
|
|
}
|
2001-04-09 22:17:11 +00:00
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
result = SetPrefFocusRules();
|
|
|
|
|
}
|
|
|
|
|
|
2000-10-11 08:33:01 +00:00
|
|
|
|
|
|
|
|
|
// update the styleset now that we are done inserting our rules
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
if (mStyleSet) {
|
|
|
|
|
mStyleSet->NotifyStyleSheetStateChanged(PR_FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-11-13 08:27:01 +00:00
|
|
|
|
#ifdef DEBUG_attinasi
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf( "Preference Style Rules set: error=%ld\n", (long)result);
|
|
|
|
|
#endif
|
2000-10-11 08:33:01 +00:00
|
|
|
|
|
|
|
|
|
if (aForceReflow){
|
2000-10-28 22:17:53 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
|
printf( "*** Forcing reframe! ***\n");
|
|
|
|
|
#endif
|
2000-10-11 08:33:01 +00:00
|
|
|
|
// this is harsh, but without it the new colors don't appear on the current page
|
|
|
|
|
// Fortunately, it only happens when the prefs change, a rare event.
|
|
|
|
|
// XXX - determine why the normal PresContext::RemapStyleAndReflow doesn't cut it
|
|
|
|
|
ReconstructFrames();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult PresShell::ClearPreferenceStyleRules(void)
|
|
|
|
|
{
|
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
if (mPrefStyleSheet) {
|
|
|
|
|
NS_ASSERTION(mStyleSet, "null styleset entirely unexpected!");
|
|
|
|
|
if (mStyleSet) {
|
|
|
|
|
// remove the sheet from the styleset:
|
|
|
|
|
// - note that we have to check for success by comparing the count before and after...
|
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
|
#ifdef PREFS_USE_OVERRIDE
|
|
|
|
|
PRInt32 numBefore = mStyleSet->GetNumberOfOverrideStyleSheets();
|
|
|
|
|
#else
|
|
|
|
|
PRInt32 numBefore = mStyleSet->GetNumberOfBackstopStyleSheets();
|
|
|
|
|
#endif
|
|
|
|
|
NS_ASSERTION(numBefore > 0, "no override stylesheets in styleset, but we have one!");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifdef PREFS_USE_OVERRIDE
|
|
|
|
|
mStyleSet->RemoveOverrideStyleSheet(mPrefStyleSheet);
|
|
|
|
|
#else
|
|
|
|
|
mStyleSet->RemoveBackstopStyleSheet(mPrefStyleSheet);
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-11-13 08:27:01 +00:00
|
|
|
|
#ifdef DEBUG_attinasi
|
2000-10-11 08:33:01 +00:00
|
|
|
|
#ifdef PREFS_USE_OVERRIDE
|
|
|
|
|
NS_ASSERTION((numBefore - 1) == mStyleSet->GetNumberOfOverrideStyleSheets(),
|
|
|
|
|
"Pref stylesheet was not removed");
|
|
|
|
|
#else
|
|
|
|
|
NS_ASSERTION((numBefore - 1) == mStyleSet->GetNumberOfBackstopStyleSheets(),
|
|
|
|
|
"Pref stylesheet was not removed");
|
|
|
|
|
#endif
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("PrefStyleSheet removed\n");
|
|
|
|
|
#endif
|
2000-10-11 08:33:01 +00:00
|
|
|
|
// clear the sheet pointer: it is strictly historical now
|
|
|
|
|
NS_IF_RELEASE(mPrefStyleSheet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult PresShell::CreatePreferenceStyleSheet(void)
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(mPrefStyleSheet==nsnull, "prefStyleSheet already exists");
|
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
2001-02-19 21:50:04 +00:00
|
|
|
|
result = nsComponentManager::CreateInstance(kCSSStyleSheetCID,nsnull,NS_GET_IID(nsICSSStyleSheet),(void**)&mPrefStyleSheet);
|
2000-10-11 08:33:01 +00:00
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
NS_ASSERTION(mPrefStyleSheet, "null but no error");
|
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
|
result = NS_NewURI(getter_AddRefs(uri), "about:PreferenceStyleSheet", nsnull);
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
NS_ASSERTION(uri, "null but no error");
|
|
|
|
|
result = mPrefStyleSheet->Init(uri);
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
mPrefStyleSheet->SetDefaultNameSpaceID(kNameSpaceID_HTML);
|
|
|
|
|
#ifdef PREFS_USE_OVERRIDE
|
|
|
|
|
mStyleSet->AppendOverrideStyleSheet(mPrefStyleSheet);
|
|
|
|
|
#else
|
|
|
|
|
mStyleSet->AppendBackstopStyleSheet(mPrefStyleSheet);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
result = NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
2000-11-13 08:27:01 +00:00
|
|
|
|
#ifdef DEBUG_attinasi
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("CreatePrefStyleSheet completed: error=%ld\n",(long)result);
|
|
|
|
|
#endif
|
2000-10-11 08:33:01 +00:00
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult PresShell::SetPrefColorRules(void)
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(mPresContext,"null prescontext not allowed");
|
|
|
|
|
if (mPresContext) {
|
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
PRBool useDocColors = PR_TRUE;
|
|
|
|
|
|
|
|
|
|
// see if we need to create the rules first
|
|
|
|
|
if (NS_SUCCEEDED(mPresContext->GetCachedBoolPref(kPresContext_UseDocumentColors, useDocColors))) {
|
|
|
|
|
if (!useDocColors) {
|
|
|
|
|
|
2000-11-13 08:27:01 +00:00
|
|
|
|
#ifdef DEBUG_attinasi
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf(" - Creating rules for document colors\n");
|
|
|
|
|
#endif
|
2000-10-11 08:33:01 +00:00
|
|
|
|
|
|
|
|
|
// OK, not using document colors, so we have to force the user's colors via style rules
|
|
|
|
|
if (!mPrefStyleSheet) {
|
|
|
|
|
result = CreatePreferenceStyleSheet();
|
|
|
|
|
}
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
NS_ASSERTION(mPrefStyleSheet, "prefstylesheet should not be null");
|
|
|
|
|
|
|
|
|
|
nscolor bgColor;
|
|
|
|
|
nscolor textColor;
|
|
|
|
|
result = mPresContext->GetDefaultColor(&textColor);
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
result = mPresContext->GetDefaultBackgroundColor(&bgColor);
|
|
|
|
|
}
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
// get the DOM interface to the stylesheet
|
|
|
|
|
nsCOMPtr<nsIDOMCSSStyleSheet> sheet(do_QueryInterface(mPrefStyleSheet,&result));
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
PRUint32 index = 0;
|
|
|
|
|
nsAutoString strRule,strColor;
|
|
|
|
|
|
|
|
|
|
// create a rule for each color and add it to the style sheet
|
|
|
|
|
// - the rules are !important so they override all but author
|
|
|
|
|
// important rules (when put into a backstop stylesheet) and
|
|
|
|
|
// all (even author important) when put into an override stylesheet
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
2000-10-30 22:27:37 +00:00
|
|
|
|
// - default color: ':root {color:#RRGGBB !important;}'
|
2000-10-11 08:33:01 +00:00
|
|
|
|
ColorToString(textColor,strColor);
|
2000-10-30 22:27:37 +00:00
|
|
|
|
strRule.Append(NS_LITERAL_STRING(":root {color:"));
|
2000-10-11 08:33:01 +00:00
|
|
|
|
strRule.Append(strColor);
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING(" !important;} "));
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
2000-10-30 22:27:37 +00:00
|
|
|
|
// - default background color: ':root {background:#RRGGBB !important;}'
|
2000-10-11 08:33:01 +00:00
|
|
|
|
ColorToString(bgColor,strColor);
|
2000-10-30 22:27:37 +00:00
|
|
|
|
strRule.Append(NS_LITERAL_STRING(":root {background:"));
|
2000-10-11 08:33:01 +00:00
|
|
|
|
strRule.Append(strColor);
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING(" !important;} "));
|
|
|
|
|
|
2000-10-30 22:27:37 +00:00
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
|
// - everything else inherits the color, and has transparent background
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING("* {color: inherit !important; background: transparent !important;} "));
|
|
|
|
|
|
2000-10-11 08:33:01 +00:00
|
|
|
|
// now insert the rule
|
|
|
|
|
result = sheet->InsertRule(strRule,0,&index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
} else {
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult PresShell::SetPrefLinkRules(void)
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(mPresContext,"null prescontext not allowed");
|
|
|
|
|
if (mPresContext) {
|
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
|
|
if (!mPrefStyleSheet) {
|
|
|
|
|
result = CreatePreferenceStyleSheet();
|
|
|
|
|
}
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
NS_ASSERTION(mPrefStyleSheet, "prefstylesheet should not be null");
|
|
|
|
|
|
|
|
|
|
// get the DOM interface to the stylesheet
|
|
|
|
|
nsCOMPtr<nsIDOMCSSStyleSheet> sheet(do_QueryInterface(mPrefStyleSheet,&result));
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
|
2000-11-13 08:27:01 +00:00
|
|
|
|
#ifdef DEBUG_attinasi
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf(" - Creating rules for link and visited colors\n");
|
|
|
|
|
#endif
|
2000-10-11 08:33:01 +00:00
|
|
|
|
|
|
|
|
|
// support default link colors:
|
|
|
|
|
// this means the link colors need to be overridable,
|
|
|
|
|
// which they are if we put them in the backstop stylesheet,
|
|
|
|
|
// though if using an override sheet this will cause authors grief still
|
2000-10-11 22:25:57 +00:00
|
|
|
|
// In the backstop stylesheet, they are !important when we are ignoring document colors
|
2000-10-11 08:33:01 +00:00
|
|
|
|
//
|
|
|
|
|
// XXX: do active links and visited links get another color?
|
|
|
|
|
// They were red in the html.css rules
|
|
|
|
|
|
|
|
|
|
nscolor linkColor, visitedColor;
|
|
|
|
|
result = mPresContext->GetDefaultLinkColor(&linkColor);
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
result = mPresContext->GetDefaultVisitedLinkColor(&visitedColor);
|
|
|
|
|
}
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
// insert a rule to make links the preferred color
|
|
|
|
|
PRUint32 index = 0;
|
|
|
|
|
nsAutoString strRule, strColor;
|
2000-10-11 22:25:57 +00:00
|
|
|
|
PRBool useDocColors = PR_TRUE;
|
|
|
|
|
|
|
|
|
|
// see if we need to create the rules first
|
|
|
|
|
mPresContext->GetCachedBoolPref(kPresContext_UseDocumentColors, useDocColors);
|
2000-10-11 08:33:01 +00:00
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
2000-10-11 22:25:57 +00:00
|
|
|
|
// - links: '*:link, *:link:active {color: #RRGGBB [!important];}'
|
2000-10-11 08:33:01 +00:00
|
|
|
|
ColorToString(linkColor,strColor);
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING("*:link, *:link:active {color:"));
|
|
|
|
|
strRule.Append(strColor);
|
2000-10-11 22:25:57 +00:00
|
|
|
|
if (!useDocColors) {
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING(" !important;} "));
|
|
|
|
|
} else {
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING(";} "));
|
|
|
|
|
}
|
2000-10-11 08:33:01 +00:00
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
2000-10-11 22:25:57 +00:00
|
|
|
|
// - visited links '*:visited, *:visited:active {color: #RRGGBB [!important];}'
|
2000-10-11 08:33:01 +00:00
|
|
|
|
ColorToString(visitedColor,strColor);
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING("*:visited, *:visited:active {color:"));
|
|
|
|
|
strRule.Append(strColor);
|
2000-10-11 22:25:57 +00:00
|
|
|
|
if (!useDocColors) {
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING(" !important;} "));
|
|
|
|
|
} else {
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING(";} "));
|
|
|
|
|
}
|
2000-10-11 08:33:01 +00:00
|
|
|
|
|
|
|
|
|
// insert the rules
|
|
|
|
|
result = sheet->InsertRule(strRule,0,&index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
PRBool underlineLinks = PR_TRUE;
|
|
|
|
|
result = mPresContext->GetCachedBoolPref(kPresContext_UnderlineLinks,underlineLinks);
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
// create a rule for underline: on or off
|
|
|
|
|
PRUint32 index = 0;
|
|
|
|
|
nsAutoString strRule;
|
|
|
|
|
if (underlineLinks) {
|
|
|
|
|
// create a rule to make underlining happen
|
|
|
|
|
// ':link, :visited {text-decoration:[underline|none];}'
|
|
|
|
|
// no need for important, we want these to be overridable
|
|
|
|
|
// NOTE: these must go in the backstop stylesheet or they cannot be
|
|
|
|
|
// overridden by authors
|
2000-11-13 08:27:01 +00:00
|
|
|
|
#ifdef DEBUG_attinasi
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf (" - Creating rules for enabling link underlines\n");
|
|
|
|
|
#endif
|
2000-10-11 08:33:01 +00:00
|
|
|
|
// make a rule to make text-decoration: underline happen for links
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING(":link, :visited {text-decoration:underline;}"));
|
|
|
|
|
} else {
|
2000-11-13 08:27:01 +00:00
|
|
|
|
#ifdef DEBUG_attinasi
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf (" - Creating rules for disabling link underlines\n");
|
|
|
|
|
#endif
|
2000-10-11 08:33:01 +00:00
|
|
|
|
// make a rule to make text-decoration: none happen for links
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING(":link, :visited {text-decoration:none;}"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ...now insert the rule
|
|
|
|
|
result = sheet->InsertRule(strRule,0,&index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
} else {
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-09 22:17:11 +00:00
|
|
|
|
nsresult PresShell::SetPrefFocusRules(void)
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(mPresContext,"null prescontext not allowed");
|
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
|
|
if (!mPresContext)
|
|
|
|
|
result = NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(result) && !mPrefStyleSheet)
|
|
|
|
|
result = CreatePreferenceStyleSheet();
|
|
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
NS_ASSERTION(mPrefStyleSheet, "prefstylesheet should not be null");
|
|
|
|
|
|
|
|
|
|
// get the DOM interface to the stylesheet
|
|
|
|
|
nsCOMPtr<nsIDOMCSSStyleSheet> sheet(do_QueryInterface(mPrefStyleSheet,&result));
|
|
|
|
|
if (NS_SUCCEEDED(result)) {
|
|
|
|
|
PRBool useFocusColors;
|
|
|
|
|
mPresContext->GetUseFocusColors(useFocusColors);
|
|
|
|
|
nscolor focusBackground, focusText;
|
|
|
|
|
result = mPresContext->GetFocusBackgroundColor(&focusBackground);
|
|
|
|
|
nsresult result2 = mPresContext->GetFocusTextColor(&focusText);
|
|
|
|
|
if (useFocusColors && NS_SUCCEEDED(result) && NS_SUCCEEDED(result2)) {
|
|
|
|
|
// insert a rule to make focus the preferred color
|
|
|
|
|
PRUint32 index = 0;
|
|
|
|
|
nsAutoString strRule, strColor;
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
|
|
|
// - focus: '*:focus
|
|
|
|
|
ColorToString(focusText,strColor);
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING("*:focus,*:focus>font {color: "));
|
|
|
|
|
strRule.Append(strColor);
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING(" !important; background-color: "));
|
|
|
|
|
ColorToString(focusBackground,strColor);
|
|
|
|
|
strRule.Append(strColor);
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING(" !important; } "));
|
|
|
|
|
// insert the rules
|
|
|
|
|
result = sheet->InsertRule(strRule,0,&index);
|
|
|
|
|
}
|
|
|
|
|
PRUint8 focusRingWidth = 1;
|
|
|
|
|
result = mPresContext->GetFocusRingWidth(&focusRingWidth);
|
|
|
|
|
PRBool focusRingOnAnything;
|
|
|
|
|
mPresContext->GetFocusRingOnAnything(focusRingOnAnything);
|
|
|
|
|
|
|
|
|
|
if ((NS_SUCCEEDED(result) && focusRingWidth != 1 && focusRingWidth <= 4 ) || focusRingOnAnything) {
|
|
|
|
|
PRUint32 index = 0;
|
|
|
|
|
nsAutoString strRule;
|
|
|
|
|
if (!focusRingOnAnything)
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING(":link:focus, :visited")); // If we only want focus rings on the normal things like links
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING(":focus {-moz-outline: ")); // For example 3px dotted WindowText (maximum 4)
|
|
|
|
|
strRule.AppendInt(focusRingWidth);
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING("px dotted WindowText !important; } ")); // For example 3px dotted WindowText
|
|
|
|
|
// insert the rules
|
|
|
|
|
if (focusRingWidth != 1) {
|
|
|
|
|
// If the focus ring width is different from the default, fix buttons with rings
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING("button:-moz-focus-inner, input[type=\"reset\"]:-moz-focus-inner,"));
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING("input[type=\"button\"]:-moz-focus-inner, "));
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING("input[type=\"submit\"]:-moz-focus-inner { padding: 1px 2px 1px 2px; border: "));
|
|
|
|
|
strRule.AppendInt(focusRingWidth);
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING("px dotted transparent !important; } "));
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING("button:focus:-moz-focus-inner, input[type=\"reset\"]:focus:-moz-focus-inner,"));
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING("input[type=\"button\"]:focus:-moz-focus-inner, input[type=\"submit\"]:focus:-moz-focus-inner {"));
|
|
|
|
|
strRule.Append(NS_LITERAL_STRING("border-color: ButtonText !important; }"));
|
|
|
|
|
}
|
|
|
|
|
result = sheet->InsertRule(strRule,0,&index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-04-28 06:21:31 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::SetDisplaySelection(PRInt16 aToggle)
|
|
|
|
|
{
|
|
|
|
|
return mSelection->SetDisplaySelection(aToggle);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetDisplaySelection(PRInt16 *aToggle)
|
|
|
|
|
{
|
|
|
|
|
return mSelection->GetDisplaySelection(aToggle);
|
|
|
|
|
}
|
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_IMETHODIMP
|
2000-09-14 11:45:01 +00:00
|
|
|
|
PresShell::GetSelection(SelectionType aType, nsISelection **aSelection)
|
1998-12-08 18:26:06 +00:00
|
|
|
|
{
|
|
|
|
|
if (!aSelection || !mSelection)
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1999-07-18 02:27:19 +00:00
|
|
|
|
return mSelection->GetSelection(aType, aSelection);
|
1998-12-08 18:26:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-08-30 21:54:40 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::ScrollSelectionIntoView(SelectionType aType, SelectionRegion aRegion)
|
|
|
|
|
{
|
|
|
|
|
if (!mSelection)
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
|
|
return mSelection->ScrollSelectionIntoView(aType, aRegion);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::RepaintSelection(SelectionType aType)
|
|
|
|
|
{
|
|
|
|
|
if (!mSelection)
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
1999-10-26 04:44:41 +00:00
|
|
|
|
return mSelection->RepaintSelection(mPresContext, aType);
|
1999-08-30 21:54:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-07-18 02:27:19 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetFrameSelection(nsIFrameSelection** aSelection)
|
|
|
|
|
{
|
|
|
|
|
if (!aSelection || !mSelection)
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
*aSelection = mSelection;
|
|
|
|
|
(*aSelection)->AddRef();
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
1998-12-08 18:26:06 +00:00
|
|
|
|
|
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
|
// Make shell be a document observer
|
1998-12-29 04:56:31 +00:00
|
|
|
|
NS_IMETHODIMP
|
1998-05-09 03:22:41 +00:00
|
|
|
|
PresShell::BeginObservingDocument()
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
1999-05-04 23:27:42 +00:00
|
|
|
|
if (mDocument) {
|
1998-04-13 20:24:54 +00:00
|
|
|
|
mDocument->AddObserver(this);
|
|
|
|
|
}
|
1998-12-29 04:56:31 +00:00
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Make shell stop being a document observer
|
1998-12-29 04:56:31 +00:00
|
|
|
|
NS_IMETHODIMP
|
1998-05-09 03:22:41 +00:00
|
|
|
|
PresShell::EndObservingDocument()
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
1999-05-04 23:27:42 +00:00
|
|
|
|
if (mDocument) {
|
1998-04-13 20:24:54 +00:00
|
|
|
|
mDocument->RemoveObserver(this);
|
|
|
|
|
}
|
1999-02-19 23:47:36 +00:00
|
|
|
|
if (mSelection){
|
2000-09-14 11:45:01 +00:00
|
|
|
|
nsCOMPtr<nsISelection> domselection;
|
1999-02-19 23:47:36 +00:00
|
|
|
|
nsresult result;
|
2000-04-27 07:37:12 +00:00
|
|
|
|
result = mSelection->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domselection));
|
1999-02-19 23:47:36 +00:00
|
|
|
|
if (NS_FAILED(result))
|
|
|
|
|
return result;
|
|
|
|
|
if (!domselection)
|
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
1999-04-26 04:02:04 +00:00
|
|
|
|
mSelection->ShutDown();
|
1999-02-19 23:47:36 +00:00
|
|
|
|
}
|
1998-12-29 04:56:31 +00:00
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-08-27 21:50:37 +00:00
|
|
|
|
#ifdef DEBUG_kipp
|
|
|
|
|
char* nsPresShell_ReflowStackPointerTop;
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-02-13 06:07:38 +00:00
|
|
|
|
static void CheckForFocus(nsIDocument* aDocument)
|
|
|
|
|
{
|
|
|
|
|
// Now that we have a root frame, set focus in to the presshell, but
|
|
|
|
|
// only do this if our window is currently focused
|
|
|
|
|
// Restore focus if we're the active window or a parent of a previously
|
|
|
|
|
// active window.
|
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
|
|
|
aDocument->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
|
|
|
|
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(globalObject);
|
2000-11-04 08:21:20 +00:00
|
|
|
|
nsCOMPtr<nsIFocusController> focusController;
|
|
|
|
|
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
|
|
|
|
|
|
|
|
|
|
if (focusController) {
|
|
|
|
|
// Suppress the command dispatcher.
|
2001-04-18 01:41:20 +00:00
|
|
|
|
focusController->SetSuppressFocus(PR_TRUE, "PresShell suppression on Web page loads");
|
2000-11-04 08:21:20 +00:00
|
|
|
|
nsCOMPtr<nsIDOMWindowInternal> focusedWindow;
|
|
|
|
|
focusController->GetFocusedWindow(getter_AddRefs(focusedWindow));
|
|
|
|
|
|
|
|
|
|
// See if the command dispatcher is holding on to an orphan window.
|
|
|
|
|
// This happens when you move from an inner frame to an outer frame
|
|
|
|
|
// (e.g., _parent, _top)
|
|
|
|
|
if (focusedWindow) {
|
|
|
|
|
nsCOMPtr<nsIDOMDocument> domDoc;
|
|
|
|
|
focusedWindow->GetDocument(getter_AddRefs(domDoc));
|
|
|
|
|
if (!domDoc) {
|
|
|
|
|
// We're pointing to garbage. Go ahead and let this
|
|
|
|
|
// presshell take the focus.
|
|
|
|
|
focusedWindow = do_QueryInterface(ourWindow);
|
|
|
|
|
focusController->SetFocusedWindow(focusedWindow);
|
2000-02-13 06:07:38 +00:00
|
|
|
|
}
|
2000-11-04 08:21:20 +00:00
|
|
|
|
}
|
2000-02-13 06:07:38 +00:00
|
|
|
|
|
2000-11-04 08:21:20 +00:00
|
|
|
|
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(ourWindow);
|
|
|
|
|
if (domWindow == focusedWindow) {
|
|
|
|
|
PRBool active;
|
|
|
|
|
focusController->GetActive(&active);
|
|
|
|
|
focusController->SetFocusedElement(nsnull);
|
|
|
|
|
if(active) {
|
|
|
|
|
// We need to restore focus and make sure we null
|
|
|
|
|
// out the focused element.
|
|
|
|
|
domWindow->Focus();
|
2000-02-13 06:07:38 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-04-18 01:41:20 +00:00
|
|
|
|
focusController->SetSuppressFocus(PR_FALSE, "PresShell suppression on Web page loads");
|
2000-02-13 06:07:38 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2000-05-15 03:37:21 +00:00
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
PresShell::NotifyReflowObservers(const char *aData)
|
|
|
|
|
{
|
|
|
|
|
if (!aData) { return NS_ERROR_NULL_POINTER; }
|
|
|
|
|
|
2000-08-30 00:35:43 +00:00
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
nsCOMPtr<nsISupports> pContainer;
|
|
|
|
|
nsCOMPtr<nsIDocShell> pDocShell;
|
2000-05-15 03:37:21 +00:00
|
|
|
|
nsAutoString sTopic,
|
|
|
|
|
sData;
|
2000-08-30 00:35:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
result = mPresContext->GetContainer( getter_AddRefs( pContainer ) );
|
|
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED( result ) && pContainer) {
|
|
|
|
|
pDocShell = do_QueryInterface( pContainer,
|
|
|
|
|
&result );
|
|
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED( result ) && pDocShell && mObserverService) {
|
2000-05-15 03:37:21 +00:00
|
|
|
|
sTopic.AssignWithConversion( NS_PRESSHELL_REFLOW_TOPIC );
|
|
|
|
|
sData.AssignWithConversion( aData );
|
2000-08-30 00:35:43 +00:00
|
|
|
|
result = mObserverService->Notify( pDocShell,
|
|
|
|
|
sTopic.GetUnicode( ),
|
|
|
|
|
sData.GetUnicode( ) );
|
2000-05-15 03:37:21 +00:00
|
|
|
|
// notice that we don't really care what the observer service returns
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2000-06-15 00:35:46 +00:00
|
|
|
|
static nsresult
|
|
|
|
|
GetRootScrollFrame(nsIPresContext* aPresContext, nsIFrame* aRootFrame, nsIFrame** aScrollFrame) {
|
|
|
|
|
|
|
|
|
|
// Frames: viewport->scroll->scrollport (Gfx) or viewport->scroll (Native)
|
|
|
|
|
// Types: viewport->scroll->sroll viewport->scroll
|
|
|
|
|
|
|
|
|
|
// Ensure root frame is a viewport frame
|
|
|
|
|
*aScrollFrame = nsnull;
|
|
|
|
|
nsIFrame* theFrame = nsnull;
|
|
|
|
|
if (aRootFrame) {
|
|
|
|
|
nsCOMPtr<nsIAtom> fType;
|
|
|
|
|
aRootFrame->GetFrameType(getter_AddRefs(fType));
|
|
|
|
|
if (fType && (nsLayoutAtoms::viewportFrame == fType.get())) {
|
|
|
|
|
|
|
|
|
|
// If child is scrollframe keep it (native)
|
|
|
|
|
aRootFrame->FirstChild(aPresContext, nsnull, &theFrame);
|
|
|
|
|
if (theFrame) {
|
|
|
|
|
theFrame->GetFrameType(getter_AddRefs(fType));
|
|
|
|
|
if (nsLayoutAtoms::scrollFrame == fType.get()) {
|
|
|
|
|
*aScrollFrame = theFrame;
|
|
|
|
|
|
|
|
|
|
// If the first child of that is scrollframe, use it instead (gfx)
|
|
|
|
|
theFrame->FirstChild(aPresContext, nsnull, &theFrame);
|
|
|
|
|
if (theFrame) {
|
|
|
|
|
theFrame->GetFrameType(getter_AddRefs(fType));
|
|
|
|
|
if (nsLayoutAtoms::scrollFrame == fType.get()) {
|
|
|
|
|
*aScrollFrame = theFrame;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
1998-08-28 02:54:06 +00:00
|
|
|
|
NS_IMETHODIMP
|
1998-09-10 19:32:14 +00:00
|
|
|
|
PresShell::InitialReflow(nscoord aWidth, nscoord aHeight)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
1999-02-03 19:38:16 +00:00
|
|
|
|
nsIContent* root = nsnull;
|
1998-09-10 19:32:14 +00:00
|
|
|
|
|
1999-12-23 02:02:33 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
|
if (mDocument) {
|
|
|
|
|
uri = dont_AddRef(mDocument->GetDocumentURL());
|
|
|
|
|
if (uri) {
|
|
|
|
|
char* url = nsnull;
|
|
|
|
|
uri->GetSpec(&url);
|
2001-04-18 06:06:31 +00:00
|
|
|
|
printf("*** PresShell::InitialReflow (this=%p, url='%s')\n", (void*)this, url);
|
1999-12-23 02:02:33 +00:00
|
|
|
|
Recycle(url);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-05-15 03:37:21 +00:00
|
|
|
|
// notice that we ignore the result
|
|
|
|
|
NotifyReflowObservers(NS_PRESSHELL_INITIAL_REFLOW);
|
2000-06-09 05:07:42 +00:00
|
|
|
|
mCaret->EraseCaret();
|
|
|
|
|
//StCaretHider caretHider(mCaret); // stack-based class hides caret until dtor.
|
1999-09-14 23:43:35 +00:00
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1998-06-03 15:46:54 +00:00
|
|
|
|
|
1999-05-04 23:27:42 +00:00
|
|
|
|
if (mPresContext) {
|
1998-04-13 20:24:54 +00:00
|
|
|
|
nsRect r(0, 0, aWidth, aHeight);
|
|
|
|
|
mPresContext->SetVisibleArea(r);
|
|
|
|
|
}
|
|
|
|
|
|
1999-05-04 23:27:42 +00:00
|
|
|
|
if (mDocument) {
|
1999-02-03 19:38:16 +00:00
|
|
|
|
root = mDocument->GetRootContent();
|
|
|
|
|
}
|
|
|
|
|
|
1999-10-18 22:20:37 +00:00
|
|
|
|
// Get the root frame from the frame manager
|
|
|
|
|
nsIFrame* rootFrame;
|
|
|
|
|
mFrameManager->GetRootFrame(&rootFrame);
|
|
|
|
|
|
1999-02-03 19:38:16 +00:00
|
|
|
|
if (nsnull != root) {
|
1999-11-10 03:41:09 +00:00
|
|
|
|
MOZ_TIMER_DEBUGLOG(("Reset and start: Frame Creation: PresShell::InitialReflow(), this=%p\n", this));
|
|
|
|
|
MOZ_TIMER_RESET(mFrameCreationWatch);
|
|
|
|
|
MOZ_TIMER_START(mFrameCreationWatch);
|
2000-02-11 01:21:05 +00:00
|
|
|
|
CtlStyleWatch(kStyleWatchEnable,mStyleSet);
|
1999-10-18 22:20:37 +00:00
|
|
|
|
|
|
|
|
|
if (!rootFrame) {
|
1999-02-03 19:38:16 +00:00
|
|
|
|
// Have style sheet processor construct a frame for the
|
|
|
|
|
// precursors to the root content object's frame
|
1999-10-18 22:20:37 +00:00
|
|
|
|
mStyleSet->ConstructRootFrame(mPresContext, root, rootFrame);
|
|
|
|
|
mFrameManager->SetRootFrame(rootFrame);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
1999-02-03 19:38:16 +00:00
|
|
|
|
|
2000-02-13 06:07:38 +00:00
|
|
|
|
CheckForFocus(mDocument);
|
|
|
|
|
|
1999-02-03 19:38:16 +00:00
|
|
|
|
// Have the style sheet processor construct frame for the root
|
|
|
|
|
// content object down
|
|
|
|
|
mStyleSet->ContentInserted(mPresContext, nsnull, root, 0);
|
|
|
|
|
NS_RELEASE(root);
|
1999-09-21 07:53:49 +00:00
|
|
|
|
VERIFY_STYLE_TREE;
|
1999-11-10 03:41:09 +00:00
|
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Frame Creation: PresShell::InitialReflow(), this=%p\n", this));
|
|
|
|
|
MOZ_TIMER_STOP(mFrameCreationWatch);
|
2000-02-11 01:21:05 +00:00
|
|
|
|
CtlStyleWatch(kStyleWatchDisable,mStyleSet);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-10-18 22:20:37 +00:00
|
|
|
|
if (rootFrame) {
|
1999-11-10 03:41:09 +00:00
|
|
|
|
MOZ_TIMER_DEBUGLOG(("Reset and start: Reflow: PresShell::InitialReflow(), this=%p\n", this));
|
|
|
|
|
MOZ_TIMER_RESET(mReflowWatch);
|
|
|
|
|
MOZ_TIMER_START(mReflowWatch);
|
1998-09-10 19:32:14 +00:00
|
|
|
|
// Kick off a top-down reflow
|
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
|
|
|
|
("enter nsPresShell::InitialReflow: %d,%d", aWidth, aHeight));
|
|
|
|
|
#ifdef NS_DEBUG
|
1999-11-01 22:12:45 +00:00
|
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-01 22:12:45 +00:00
|
|
|
|
frameDebug->VerifyTree();
|
|
|
|
|
}
|
1998-09-10 19:32:14 +00:00
|
|
|
|
}
|
1999-08-27 21:50:37 +00:00
|
|
|
|
#endif
|
|
|
|
|
#ifdef DEBUG_kipp
|
|
|
|
|
nsPresShell_ReflowStackPointerTop = (char*) &aWidth;
|
1998-09-10 19:32:14 +00:00
|
|
|
|
#endif
|
1998-10-02 01:12:39 +00:00
|
|
|
|
nsRect bounds;
|
1998-09-10 19:32:14 +00:00
|
|
|
|
mPresContext->GetVisibleArea(bounds);
|
1998-10-02 01:12:39 +00:00
|
|
|
|
nsSize maxSize(bounds.width, bounds.height);
|
|
|
|
|
nsHTMLReflowMetrics desiredSize(nsnull);
|
|
|
|
|
nsReflowStatus status;
|
|
|
|
|
nsIRenderingContext* rcx = nsnull;
|
|
|
|
|
|
2000-01-11 22:15:20 +00:00
|
|
|
|
nsresult rv=CreateRenderingContext(rootFrame, &rcx);
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-10-02 01:12:39 +00:00
|
|
|
|
|
2000-08-21 20:10:07 +00:00
|
|
|
|
mIsReflowing = PR_TRUE;
|
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
|
nsHTMLReflowState reflowState(mPresContext, rootFrame,
|
1999-03-05 04:29:11 +00:00
|
|
|
|
eReflowReason_Initial, rcx, maxSize);
|
1999-11-19 15:33:29 +00:00
|
|
|
|
nsIView* view;
|
1998-10-01 04:46:11 +00:00
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
|
rootFrame->WillReflow(mPresContext);
|
1999-11-19 15:33:29 +00:00
|
|
|
|
rootFrame->GetView(mPresContext, &view);
|
|
|
|
|
if (view) {
|
|
|
|
|
nsContainerFrame::PositionFrameView(mPresContext, rootFrame, view);
|
|
|
|
|
}
|
1999-11-24 06:03:41 +00:00
|
|
|
|
rootFrame->Reflow(mPresContext, desiredSize, reflowState, status);
|
1999-10-30 02:52:11 +00:00
|
|
|
|
rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height);
|
|
|
|
|
mPresContext->SetVisibleArea(nsRect(0,0,desiredSize.width,desiredSize.height));
|
1999-11-19 15:33:29 +00:00
|
|
|
|
if (view) {
|
|
|
|
|
nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, rootFrame, view,
|
|
|
|
|
nsnull);
|
|
|
|
|
}
|
1999-11-24 06:03:41 +00:00
|
|
|
|
rootFrame->DidReflow(mPresContext, NS_FRAME_REFLOW_FINISHED);
|
1999-07-07 22:34:31 +00:00
|
|
|
|
|
1998-09-10 19:32:14 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
1999-11-01 22:12:45 +00:00
|
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-01 22:12:45 +00:00
|
|
|
|
frameDebug->VerifyTree();
|
|
|
|
|
}
|
1998-10-01 04:46:11 +00:00
|
|
|
|
}
|
1999-10-30 02:52:11 +00:00
|
|
|
|
#endif
|
|
|
|
|
VERIFY_STYLE_TREE;
|
1998-10-02 01:12:39 +00:00
|
|
|
|
NS_IF_RELEASE(rcx);
|
1998-09-10 19:32:14 +00:00
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::InitialReflow"));
|
1999-11-10 03:41:09 +00:00
|
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Reflow: PresShell::InitialReflow(), this=%p\n", this));
|
|
|
|
|
MOZ_TIMER_STOP(mReflowWatch);
|
2000-08-21 20:10:07 +00:00
|
|
|
|
|
|
|
|
|
mIsReflowing = PR_FALSE;
|
1998-09-10 19:32:14 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
1998-09-10 19:32:14 +00:00
|
|
|
|
|
1999-10-15 04:29:30 +00:00
|
|
|
|
if (mViewManager && mCaret && !mViewEventListener) {
|
|
|
|
|
nsIScrollableView* scrollingView = nsnull;
|
|
|
|
|
mViewManager->GetRootScrollableView(&scrollingView);
|
|
|
|
|
|
|
|
|
|
if (scrollingView) {
|
|
|
|
|
mViewEventListener = new PresShellViewEventListener;
|
|
|
|
|
|
|
|
|
|
if (!mViewEventListener)
|
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
|
|
NS_ADDREF(mViewEventListener);
|
|
|
|
|
mViewEventListener->SetPresShell(this);
|
|
|
|
|
scrollingView->AddScrollPositionListener((nsIScrollPositionListener *)mViewEventListener);
|
|
|
|
|
mViewManager->AddCompositeListener((nsICompositeListener *)mViewEventListener);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-25 19:52:49 +00:00
|
|
|
|
mPaintingSuppressed = PR_TRUE;
|
|
|
|
|
// Kick off a one-shot timer based off our pref value. When this timer
|
|
|
|
|
// fires, if painting is still locked down, then we will go ahead and
|
|
|
|
|
// trigger a full invalidate and allow painting to proceed normally.
|
|
|
|
|
mPaintSuppressionTimer = do_CreateInstance("@mozilla.org/timer;1");
|
|
|
|
|
if (!mPaintSuppressionTimer)
|
|
|
|
|
// Uh-oh. We must be out of memory. No point in keeping painting locked down.
|
|
|
|
|
mPaintingSuppressed = PR_FALSE;
|
|
|
|
|
else {
|
|
|
|
|
// Initialize the timer.
|
|
|
|
|
PRInt32 delay = PAINTLOCK_EVENT_DELAY; // Use this value if we fail to get the pref value.
|
|
|
|
|
nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID));
|
|
|
|
|
if (prefs)
|
|
|
|
|
prefs->GetIntPref("nglayout.initialpaint.delay", &delay);
|
|
|
|
|
mPaintSuppressionTimer->Init(sPaintSuppressionCallback, this, delay, NS_PRIORITY_HIGH);
|
|
|
|
|
}
|
|
|
|
|
|
1998-09-10 19:32:14 +00:00
|
|
|
|
return NS_OK; //XXX this needs to be real. MMP
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-25 19:52:49 +00:00
|
|
|
|
void
|
|
|
|
|
PresShell::sPaintSuppressionCallback(nsITimer *aTimer, void* aPresShell)
|
|
|
|
|
{
|
|
|
|
|
PresShell* self = NS_STATIC_CAST(PresShell*, aPresShell);
|
|
|
|
|
if (self)
|
|
|
|
|
self->UnsuppressPainting(PR_TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
1998-09-10 19:32:14 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
|
|
|
|
|
{
|
2000-05-15 03:37:21 +00:00
|
|
|
|
// notice that we ignore the result
|
|
|
|
|
NotifyReflowObservers(NS_PRESSHELL_RESIZE_REFLOW);
|
2000-04-03 03:55:38 +00:00
|
|
|
|
mViewManager->CacheWidgetChanges(PR_TRUE);
|
|
|
|
|
|
2000-06-09 05:07:42 +00:00
|
|
|
|
mCaret->EraseCaret();
|
|
|
|
|
//StCaretHider caretHider(mCaret); // stack-based class hides caret until dtor.
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1998-09-10 19:32:14 +00:00
|
|
|
|
|
1999-05-04 23:27:42 +00:00
|
|
|
|
if (mPresContext) {
|
1998-09-10 19:32:14 +00:00
|
|
|
|
nsRect r(0, 0, aWidth, aHeight);
|
|
|
|
|
mPresContext->SetVisibleArea(r);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If we don't have a root frame yet, that means we haven't had our initial
|
|
|
|
|
// reflow...
|
1999-10-18 22:20:37 +00:00
|
|
|
|
nsIFrame* rootFrame;
|
|
|
|
|
mFrameManager->GetRootFrame(&rootFrame);
|
|
|
|
|
if (rootFrame) {
|
1998-04-13 20:24:54 +00:00
|
|
|
|
// Kick off a top-down reflow
|
1998-05-20 16:24:54 +00:00
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
|
|
|
|
("enter nsPresShell::ResizeReflow: %d,%d", aWidth, aHeight));
|
1998-04-13 20:24:54 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
1999-11-01 22:12:45 +00:00
|
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-01 22:12:45 +00:00
|
|
|
|
frameDebug->VerifyTree();
|
|
|
|
|
}
|
1998-05-20 16:24:54 +00:00
|
|
|
|
}
|
1999-08-27 21:50:37 +00:00
|
|
|
|
#endif
|
|
|
|
|
#ifdef DEBUG_kipp
|
|
|
|
|
nsPresShell_ReflowStackPointerTop = (char*) &aWidth;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
#endif
|
1998-10-02 01:12:39 +00:00
|
|
|
|
nsRect bounds;
|
1998-05-22 18:36:40 +00:00
|
|
|
|
mPresContext->GetVisibleArea(bounds);
|
1998-10-02 01:12:39 +00:00
|
|
|
|
nsSize maxSize(bounds.width, bounds.height);
|
|
|
|
|
nsHTMLReflowMetrics desiredSize(nsnull);
|
|
|
|
|
nsReflowStatus status;
|
|
|
|
|
nsIRenderingContext* rcx = nsnull;
|
|
|
|
|
|
2000-01-11 22:15:20 +00:00
|
|
|
|
nsresult rv=CreateRenderingContext(rootFrame, &rcx);
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-10-02 01:12:39 +00:00
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
|
nsHTMLReflowState reflowState(mPresContext, rootFrame,
|
1999-03-05 04:29:11 +00:00
|
|
|
|
eReflowReason_Resize, rcx, maxSize);
|
1999-11-19 15:33:29 +00:00
|
|
|
|
nsIView* view;
|
1998-10-01 04:46:11 +00:00
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
|
rootFrame->WillReflow(mPresContext);
|
1999-11-19 15:33:29 +00:00
|
|
|
|
rootFrame->GetView(mPresContext, &view);
|
|
|
|
|
if (view) {
|
|
|
|
|
nsContainerFrame::PositionFrameView(mPresContext, rootFrame, view);
|
|
|
|
|
}
|
1999-11-24 06:03:41 +00:00
|
|
|
|
rootFrame->Reflow(mPresContext, desiredSize, reflowState, status);
|
1999-10-30 02:52:11 +00:00
|
|
|
|
rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height);
|
1999-11-19 15:33:29 +00:00
|
|
|
|
if (view) {
|
|
|
|
|
nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, rootFrame, view,
|
|
|
|
|
nsnull);
|
|
|
|
|
}
|
1999-11-24 06:03:41 +00:00
|
|
|
|
rootFrame->DidReflow(mPresContext, NS_FRAME_REFLOW_FINISHED);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
1999-11-01 22:12:45 +00:00
|
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-01 22:12:45 +00:00
|
|
|
|
frameDebug->VerifyTree();
|
|
|
|
|
}
|
1998-10-01 04:46:11 +00:00
|
|
|
|
}
|
1999-10-30 02:52:11 +00:00
|
|
|
|
#endif
|
|
|
|
|
VERIFY_STYLE_TREE;
|
1998-10-02 01:12:39 +00:00
|
|
|
|
NS_IF_RELEASE(rcx);
|
1998-05-20 16:24:54 +00:00
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::ResizeReflow"));
|
|
|
|
|
|
1998-04-13 20:24:54 +00:00
|
|
|
|
// XXX if debugging then we should assert that the cache is empty
|
|
|
|
|
} else {
|
|
|
|
|
#ifdef NOISY
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("PresShell::ResizeReflow: null root frame\n");
|
1998-04-13 20:24:54 +00:00
|
|
|
|
#endif
|
|
|
|
|
}
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
2000-03-22 23:19:10 +00:00
|
|
|
|
// if the proper flag is set, VerifyReflow now
|
2000-03-23 00:10:26 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
2000-03-22 23:19:10 +00:00
|
|
|
|
if (GetVerifyReflowEnable() && (VERIFY_REFLOW_DURING_RESIZE_REFLOW & gVerifyReflowFlags))
|
|
|
|
|
{
|
|
|
|
|
mInVerifyReflow = PR_TRUE;
|
2000-08-28 22:28:56 +00:00
|
|
|
|
/*PRBool ok = */VerifyIncrementalReflow();
|
2000-03-22 23:19:10 +00:00
|
|
|
|
mInVerifyReflow = PR_FALSE;
|
|
|
|
|
}
|
2000-03-23 00:10:26 +00:00
|
|
|
|
#endif
|
1999-02-13 04:45:44 +00:00
|
|
|
|
|
2000-04-03 03:55:38 +00:00
|
|
|
|
mViewManager->CacheWidgetChanges(PR_FALSE);
|
2000-06-23 05:15:04 +00:00
|
|
|
|
HandlePostedDOMEvents();
|
|
|
|
|
HandlePostedAttributeChanges();
|
2000-07-13 23:00:59 +00:00
|
|
|
|
HandlePostedReflowCallbacks();
|
2000-04-03 03:55:38 +00:00
|
|
|
|
|
2001-04-17 23:25:21 +00:00
|
|
|
|
//Set resize event timer
|
|
|
|
|
CreateResizeEventTimer();
|
|
|
|
|
|
|
|
|
|
return NS_OK; //XXX this needs to be real. MMP
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define RESIZE_EVENT_DELAY 200
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
PresShell::CreateResizeEventTimer ()
|
|
|
|
|
{
|
|
|
|
|
KillResizeEventTimer();
|
|
|
|
|
|
|
|
|
|
mResizeEventTimer = do_CreateInstance("@mozilla.org/timer;1");
|
|
|
|
|
if (mResizeEventTimer) {
|
|
|
|
|
mResizeEventTimer->Init(sResizeEventCallback, this, RESIZE_EVENT_DELAY, NS_PRIORITY_HIGH);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
PresShell::KillResizeEventTimer()
|
|
|
|
|
{
|
|
|
|
|
if(mResizeEventTimer) {
|
|
|
|
|
mResizeEventTimer->Cancel();
|
|
|
|
|
mResizeEventTimer = nsnull;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
PresShell::sResizeEventCallback(nsITimer *aTimer, void* aPresShell)
|
|
|
|
|
{
|
|
|
|
|
PresShell* self = NS_STATIC_CAST(PresShell*, aPresShell);
|
|
|
|
|
if (self) {
|
|
|
|
|
self->FireResizeEvent();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
PresShell::FireResizeEvent()
|
|
|
|
|
{
|
2000-05-17 05:27:22 +00:00
|
|
|
|
//Send resize event from here.
|
|
|
|
|
nsEvent event;
|
2000-11-08 00:31:06 +00:00
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
2000-05-17 05:27:22 +00:00
|
|
|
|
event.eventStructType = NS_EVENT;
|
|
|
|
|
event.message = NS_RESIZE_EVENT;
|
|
|
|
|
event.time = 0;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObj;
|
|
|
|
|
mDocument->GetScriptGlobalObject(getter_AddRefs(globalObj));
|
|
|
|
|
globalObj->HandleDOMEvent(mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-07-16 23:27:46 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::ScrollFrameIntoView(nsIFrame *aFrame){
|
1999-02-21 03:49:32 +00:00
|
|
|
|
if (!aFrame)
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
2000-11-04 08:21:20 +00:00
|
|
|
|
|
2000-05-11 22:40:51 +00:00
|
|
|
|
// Before we scroll the frame into view, ask the command dispatcher
|
|
|
|
|
// if we're resetting focus because a window just got an activate
|
|
|
|
|
// event. If we are, we do not want to scroll the frame into view.
|
|
|
|
|
// Example: The user clicks on an anchor, and then deactivates the
|
|
|
|
|
// window. When they reactivate the window, the expected behavior
|
|
|
|
|
// is not for the anchor link to scroll back into view. That is what
|
|
|
|
|
// this check is preventing.
|
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
|
aFrame->GetContent(getter_AddRefs(content));
|
|
|
|
|
if(content) {
|
|
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
|
content->GetDocument(*getter_AddRefs(document));
|
|
|
|
|
if(document){
|
2000-11-04 08:21:20 +00:00
|
|
|
|
nsCOMPtr<nsIFocusController> focusController;
|
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
|
|
|
|
|
document->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
|
2000-05-11 22:40:51 +00:00
|
|
|
|
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
|
|
|
|
|
if(ourWindow) {
|
2000-11-04 08:21:20 +00:00
|
|
|
|
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
|
|
|
|
|
if (focusController) {
|
|
|
|
|
PRBool dontScroll;
|
|
|
|
|
focusController->GetSuppressFocusScroll(&dontScroll);
|
|
|
|
|
if(dontScroll)
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-05-11 22:40:51 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2000-11-04 08:21:20 +00:00
|
|
|
|
|
1999-02-21 19:43:40 +00:00
|
|
|
|
if (IsScrollingEnabled())
|
1999-07-19 18:38:33 +00:00
|
|
|
|
return ScrollFrameIntoView(aFrame, NS_PRESSHELL_SCROLL_ANYWHERE,
|
|
|
|
|
NS_PRESSHELL_SCROLL_ANYWHERE);
|
1999-02-21 19:43:40 +00:00
|
|
|
|
return NS_OK;
|
1999-02-21 03:49:32 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-07-16 23:27:46 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::NotifyDestroyingFrame(nsIFrame* aFrame)
|
|
|
|
|
{
|
|
|
|
|
// Cancel any pending reflow commands targeted at this frame
|
2001-03-13 06:38:59 +00:00
|
|
|
|
CancelReflowCommandInternal(aFrame, nsnull, mReflowCommands);
|
|
|
|
|
CancelReflowCommandInternal(aFrame, nsnull, mTimeoutReflowCommands);
|
|
|
|
|
|
1999-07-16 23:27:46 +00:00
|
|
|
|
|
1999-08-05 20:17:44 +00:00
|
|
|
|
// Notify the frame manager
|
|
|
|
|
if (mFrameManager) {
|
|
|
|
|
mFrameManager->NotifyDestroyingFrame(aFrame);
|
|
|
|
|
}
|
|
|
|
|
|
1999-07-16 23:27:46 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
1999-02-13 04:45:44 +00:00
|
|
|
|
|
1999-08-04 04:02:40 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetFrameManager(nsIFrameManager** aFrameManager) const
|
|
|
|
|
{
|
|
|
|
|
*aFrameManager = mFrameManager;
|
|
|
|
|
NS_IF_ADDREF(mFrameManager);
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
1999-02-13 04:45:44 +00:00
|
|
|
|
NS_IMETHODIMP PresShell::GetCaret(nsICaret **outCaret)
|
|
|
|
|
{
|
|
|
|
|
if (!outCaret || !mCaret)
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
2000-01-04 20:24:09 +00:00
|
|
|
|
return mCaret->QueryInterface(NS_GET_IID(nsICaret), (void **)outCaret);
|
1999-02-13 04:45:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-08-04 20:46:16 +00:00
|
|
|
|
NS_IMETHODIMP PresShell::SetCaretEnabled(PRBool aInEnable)
|
1999-04-01 23:58:11 +00:00
|
|
|
|
{
|
2000-06-16 14:05:03 +00:00
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
PRBool oldEnabled = mCaretEnabled;
|
1999-04-01 23:58:11 +00:00
|
|
|
|
|
2000-06-16 14:05:03 +00:00
|
|
|
|
mCaretEnabled = aInEnable;
|
1999-04-01 23:58:11 +00:00
|
|
|
|
|
2000-06-16 14:05:03 +00:00
|
|
|
|
if (mCaret && (mCaretEnabled != oldEnabled))
|
|
|
|
|
{
|
2000-09-07 05:26:25 +00:00
|
|
|
|
/* Don't change the caret's selection here! This was an evil side-effect of SetCaretEnabled()
|
2000-06-01 02:39:52 +00:00
|
|
|
|
nsCOMPtr<nsIDOMSelection> domSel;
|
|
|
|
|
if (NS_SUCCEEDED(GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(domSel))) && domSel)
|
|
|
|
|
mCaret->SetCaretDOMSelection(domSel);
|
2000-09-07 05:26:25 +00:00
|
|
|
|
*/
|
2000-06-01 02:39:52 +00:00
|
|
|
|
result = mCaret->SetCaretVisible(mCaretEnabled);
|
2000-06-16 14:05:03 +00:00
|
|
|
|
}
|
1999-04-01 23:58:11 +00:00
|
|
|
|
|
2000-06-16 14:05:03 +00:00
|
|
|
|
return result;
|
1999-04-01 23:58:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-07-28 22:12:45 +00:00
|
|
|
|
NS_IMETHODIMP PresShell::SetCaretWidth(PRInt16 pixels)
|
|
|
|
|
{
|
|
|
|
|
return mCaret->SetCaretWidth(pixels);
|
|
|
|
|
}
|
2000-05-11 04:25:43 +00:00
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP PresShell::SetCaretReadOnly(PRBool aReadOnly)
|
|
|
|
|
{
|
2000-06-01 02:39:52 +00:00
|
|
|
|
return mCaret->SetCaretReadOnly(aReadOnly);
|
2000-05-11 04:25:43 +00:00
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
1999-08-04 20:46:16 +00:00
|
|
|
|
NS_IMETHODIMP PresShell::GetCaretEnabled(PRBool *aOutEnabled)
|
|
|
|
|
{
|
|
|
|
|
if (!aOutEnabled) { return NS_ERROR_INVALID_ARG; }
|
|
|
|
|
*aOutEnabled = mCaretEnabled;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP PresShell::SetDisplayNonTextSelection(PRBool aInEnable)
|
1999-05-17 00:21:18 +00:00
|
|
|
|
{
|
|
|
|
|
mDisplayNonTextSelection = PR_TRUE;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
1999-08-04 20:46:16 +00:00
|
|
|
|
NS_IMETHODIMP PresShell::GetDisplayNonTextSelection(PRBool *aOutEnable)
|
1999-05-17 00:21:18 +00:00
|
|
|
|
{
|
1999-08-04 20:46:16 +00:00
|
|
|
|
if (!aOutEnable)
|
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
|
*aOutEnable = mDisplayNonTextSelection;
|
1999-05-17 00:21:18 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-02 21:45:21 +00:00
|
|
|
|
//implementation of nsISelectionController
|
1999-04-01 23:58:11 +00:00
|
|
|
|
|
1999-10-22 00:19:18 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::CharacterMove(PRBool aForward, PRBool aExtend)
|
1999-02-19 23:47:36 +00:00
|
|
|
|
{
|
1999-12-11 00:02:08 +00:00
|
|
|
|
return mSelection->CharacterMove(aForward, aExtend);
|
1999-10-22 00:19:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::WordMove(PRBool aForward, PRBool aExtend)
|
|
|
|
|
{
|
1999-12-11 00:02:08 +00:00
|
|
|
|
return mSelection->WordMove(aForward, aExtend);
|
1999-10-22 00:19:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::LineMove(PRBool aForward, PRBool aExtend)
|
|
|
|
|
{
|
1999-12-11 00:02:08 +00:00
|
|
|
|
return mSelection->LineMove(aForward, aExtend);
|
1999-10-22 00:19:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::IntraLineMove(PRBool aForward, PRBool aExtend)
|
|
|
|
|
{
|
1999-12-11 00:02:08 +00:00
|
|
|
|
return mSelection->IntraLineMove(aForward, aExtend);
|
1999-10-22 00:19:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::PageMove(PRBool aForward, PRBool aExtend)
|
|
|
|
|
{
|
2001-04-26 18:37:04 +00:00
|
|
|
|
#if 1
|
1999-12-16 22:48:02 +00:00
|
|
|
|
return ScrollPage(aForward);
|
2001-04-26 18:37:04 +00:00
|
|
|
|
#else
|
1999-12-16 22:48:02 +00:00
|
|
|
|
|
1999-12-11 00:02:08 +00:00
|
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
|
nsresult result = GetViewManager(getter_AddRefs(viewManager));
|
|
|
|
|
if (NS_SUCCEEDED(result) && viewManager)
|
|
|
|
|
{
|
1999-12-15 03:54:52 +00:00
|
|
|
|
nsIScrollableView *scrollView;
|
|
|
|
|
result = viewManager->GetRootScrollableView(&scrollView);
|
1999-12-11 00:02:08 +00:00
|
|
|
|
if (NS_SUCCEEDED(result) && scrollView)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
1999-12-16 22:48:02 +00:00
|
|
|
|
#endif //0
|
1999-10-22 00:19:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::ScrollPage(PRBool aForward)
|
1999-12-11 00:02:08 +00:00
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
|
nsresult result = GetViewManager(getter_AddRefs(viewManager));
|
|
|
|
|
if (NS_SUCCEEDED(result) && viewManager)
|
|
|
|
|
{
|
1999-12-15 03:54:52 +00:00
|
|
|
|
nsIScrollableView *scrollView;
|
|
|
|
|
result = viewManager->GetRootScrollableView(&scrollView);
|
1999-12-11 00:02:08 +00:00
|
|
|
|
if (NS_SUCCEEDED(result) && scrollView)
|
|
|
|
|
{
|
|
|
|
|
scrollView->ScrollByPages(aForward ? 1 : -1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-15 03:54:52 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::ScrollLine(PRBool aForward)
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
|
nsresult result = GetViewManager(getter_AddRefs(viewManager));
|
|
|
|
|
if (NS_SUCCEEDED(result) && viewManager)
|
|
|
|
|
{
|
|
|
|
|
nsIScrollableView *scrollView;
|
|
|
|
|
result = viewManager->GetRootScrollableView(&scrollView);
|
|
|
|
|
if (NS_SUCCEEDED(result) && scrollView)
|
|
|
|
|
{
|
2000-05-16 11:35:12 +00:00
|
|
|
|
scrollView->ScrollByLines(0, aForward ? 1 : -1);
|
1999-12-15 03:54:52 +00:00
|
|
|
|
//NEW FOR LINES
|
|
|
|
|
// force the update to happen now, otherwise multiple scrolls can
|
|
|
|
|
// occur before the update is processed. (bug #7354)
|
|
|
|
|
|
|
|
|
|
// I'd use Composite here, but it doesn't always work.
|
|
|
|
|
// vm->Composite();
|
2000-01-26 23:04:40 +00:00
|
|
|
|
viewManager->ForceUpdate();
|
1999-12-15 03:54:52 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::ScrollHorizontal(PRBool aLeft)
|
|
|
|
|
{
|
2000-05-16 11:35:12 +00:00
|
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
|
nsresult result = GetViewManager(getter_AddRefs(viewManager));
|
|
|
|
|
if (NS_SUCCEEDED(result) && viewManager)
|
|
|
|
|
{
|
|
|
|
|
nsIScrollableView *scrollView;
|
|
|
|
|
result = viewManager->GetRootScrollableView(&scrollView);
|
|
|
|
|
if (NS_SUCCEEDED(result) && scrollView)
|
|
|
|
|
{
|
|
|
|
|
scrollView->ScrollByLines(aLeft ? -1 : 1, 0);
|
|
|
|
|
//NEW FOR LINES
|
|
|
|
|
// force the update to happen now, otherwise multiple scrolls can
|
|
|
|
|
// occur before the update is processed. (bug #7354)
|
|
|
|
|
|
|
|
|
|
// I'd use Composite here, but it doesn't always work.
|
|
|
|
|
// vm->Composite();
|
|
|
|
|
viewManager->ForceUpdate();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
1999-12-15 03:54:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-12-11 00:02:08 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::CompleteScroll(PRBool aForward)
|
|
|
|
|
{
|
1999-12-16 22:48:02 +00:00
|
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
|
nsresult result = GetViewManager(getter_AddRefs(viewManager));
|
|
|
|
|
if (NS_SUCCEEDED(result) && viewManager)
|
|
|
|
|
{
|
|
|
|
|
nsIScrollableView *scrollView;
|
|
|
|
|
result = viewManager->GetRootScrollableView(&scrollView);
|
|
|
|
|
if (NS_SUCCEEDED(result) && scrollView)
|
|
|
|
|
{
|
|
|
|
|
scrollView->ScrollByWhole(!aForward);//TRUE = top, aForward TRUE=bottom
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
1999-12-11 00:02:08 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::CompleteMove(PRBool aForward, PRBool aExtend)
|
1999-10-22 00:19:18 +00:00
|
|
|
|
{
|
2000-09-14 11:45:01 +00:00
|
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
|
if (NS_FAILED(GetDocument(getter_AddRefs(document))) || !document)
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMNodeList>nodeList;
|
|
|
|
|
nsAutoString bodyTag; bodyTag.AssignWithConversion("body");
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(document);
|
|
|
|
|
if (!doc)
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
nsresult result = doc->GetElementsByTagName(bodyTag, getter_AddRefs(nodeList));
|
|
|
|
|
|
|
|
|
|
if (NS_FAILED(result) || !nodeList)
|
|
|
|
|
return result?result:NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
|
|
PRUint32 count;
|
|
|
|
|
nodeList->GetLength(&count);
|
|
|
|
|
|
|
|
|
|
if (count < 1)
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
|
|
// Use the first body node in the list:
|
|
|
|
|
nsCOMPtr<nsIDOMNode> node;
|
|
|
|
|
result = nodeList->Item(0, getter_AddRefs(node));
|
|
|
|
|
if (NS_SUCCEEDED(result) && node)
|
|
|
|
|
{
|
|
|
|
|
//return node->QueryInterface(NS_GET_IID(nsIDOMElement), (void **)aBodyElement);
|
|
|
|
|
// Is above equivalent to this:
|
|
|
|
|
nsCOMPtr<nsIDOMElement> bodyElement = do_QueryInterface(node);
|
|
|
|
|
if (bodyElement)
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsIContent> bodyContent = do_QueryInterface(bodyElement);
|
|
|
|
|
if (bodyContent)
|
|
|
|
|
{
|
|
|
|
|
PRInt32 offset = 0;
|
|
|
|
|
if (aForward)
|
|
|
|
|
{
|
|
|
|
|
bodyContent->ChildCount(offset);
|
|
|
|
|
}
|
|
|
|
|
result = mSelection->HandleClick(bodyContent,offset,offset,aExtend, PR_FALSE,aExtend);
|
2001-04-26 18:37:04 +00:00
|
|
|
|
// if we got this far, attempt to scroll no matter what the above result is
|
|
|
|
|
CompleteScroll(aForward);
|
2000-09-14 11:45:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
1999-10-22 00:19:18 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::SelectAll()
|
|
|
|
|
{
|
1999-12-11 00:02:08 +00:00
|
|
|
|
return mSelection->SelectAll();
|
1999-02-19 23:47:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-07-26 11:31:12 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::CheckVisibility(nsIDOMNode *node, PRInt16 startOffset, PRInt16 EndOffset, PRBool *_retval)
|
|
|
|
|
{
|
|
|
|
|
if (!node || startOffset>EndOffset || !_retval || startOffset<0 || EndOffset<0)
|
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
|
*_retval = PR_FALSE; //initialize return parameter
|
|
|
|
|
nsCOMPtr<nsIContent> content(do_QueryInterface(node));
|
|
|
|
|
if (!content)
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
nsIFrame *frame;
|
|
|
|
|
nsresult result = GetPrimaryFrameFor(content,&frame);
|
2000-08-17 23:55:32 +00:00
|
|
|
|
if (NS_FAILED(result)) //failure is taken as a no.
|
|
|
|
|
return result;
|
|
|
|
|
if (!frame) //no frame to look at so it must not be visible
|
|
|
|
|
return NS_OK;
|
2000-07-26 11:31:12 +00:00
|
|
|
|
//start process now to go through all frames to find startOffset. then check chars after that to see
|
|
|
|
|
//if anything until EndOffset is visible.
|
|
|
|
|
PRBool finished = PR_FALSE;
|
|
|
|
|
frame->CheckVisibility(mPresContext,startOffset,EndOffset,PR_TRUE,&finished, _retval);
|
|
|
|
|
return NS_OK;//dont worry about other return val
|
|
|
|
|
}
|
|
|
|
|
|
1999-12-02 21:45:21 +00:00
|
|
|
|
//end implementations nsISelectionController
|
1999-10-22 00:19:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1998-11-06 16:16:01 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::StyleChangeReflow()
|
|
|
|
|
{
|
2000-05-15 03:37:21 +00:00
|
|
|
|
|
|
|
|
|
// notify any presshell observers about the reflow.
|
|
|
|
|
// notice that we ignore the result
|
|
|
|
|
NotifyReflowObservers(NS_PRESSHELL_STYLE_CHANGE_REFLOW);
|
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1998-11-06 16:16:01 +00:00
|
|
|
|
|
1999-10-18 22:20:37 +00:00
|
|
|
|
nsIFrame* rootFrame;
|
|
|
|
|
mFrameManager->GetRootFrame(&rootFrame);
|
|
|
|
|
if (rootFrame) {
|
1998-11-06 16:16:01 +00:00
|
|
|
|
// Kick off a top-down reflow
|
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS,
|
|
|
|
|
("enter nsPresShell::StyleChangeReflow"));
|
|
|
|
|
#ifdef NS_DEBUG
|
1999-11-01 22:12:45 +00:00
|
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-01 22:12:45 +00:00
|
|
|
|
frameDebug->VerifyTree();
|
|
|
|
|
}
|
1998-11-06 16:16:01 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
nsRect bounds;
|
|
|
|
|
mPresContext->GetVisibleArea(bounds);
|
|
|
|
|
nsSize maxSize(bounds.width, bounds.height);
|
|
|
|
|
nsHTMLReflowMetrics desiredSize(nsnull);
|
|
|
|
|
nsReflowStatus status;
|
|
|
|
|
nsIRenderingContext* rcx = nsnull;
|
|
|
|
|
|
2000-01-11 22:15:20 +00:00
|
|
|
|
nsresult rv=CreateRenderingContext(rootFrame, &rcx);
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
1998-11-06 16:16:01 +00:00
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
|
nsHTMLReflowState reflowState(mPresContext, rootFrame,
|
2000-03-15 15:16:03 +00:00
|
|
|
|
eReflowReason_StyleChange, rcx, maxSize);
|
1999-11-19 15:33:29 +00:00
|
|
|
|
nsIView* view;
|
1998-11-06 16:16:01 +00:00
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
|
rootFrame->WillReflow(mPresContext);
|
1999-11-19 15:33:29 +00:00
|
|
|
|
rootFrame->GetView(mPresContext, &view);
|
|
|
|
|
if (view) {
|
|
|
|
|
nsContainerFrame::PositionFrameView(mPresContext, rootFrame, view);
|
|
|
|
|
}
|
1999-11-24 06:03:41 +00:00
|
|
|
|
rootFrame->Reflow(mPresContext, desiredSize, reflowState, status);
|
1999-10-30 02:52:11 +00:00
|
|
|
|
rootFrame->SizeTo(mPresContext, desiredSize.width, desiredSize.height);
|
1999-11-19 15:33:29 +00:00
|
|
|
|
mPresContext->SetVisibleArea(nsRect(0,0,desiredSize.width,desiredSize.height));
|
|
|
|
|
if (view) {
|
|
|
|
|
nsContainerFrame::SyncFrameViewAfterReflow(mPresContext, rootFrame, view,
|
|
|
|
|
nsnull);
|
|
|
|
|
}
|
1999-11-24 06:03:41 +00:00
|
|
|
|
rootFrame->DidReflow(mPresContext, NS_FRAME_REFLOW_FINISHED);
|
1998-11-06 16:16:01 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
1999-11-01 22:12:45 +00:00
|
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-01 22:12:45 +00:00
|
|
|
|
frameDebug->VerifyTree();
|
|
|
|
|
}
|
1998-11-06 16:16:01 +00:00
|
|
|
|
}
|
1999-10-30 02:52:11 +00:00
|
|
|
|
#endif
|
|
|
|
|
VERIFY_STYLE_TREE;
|
1998-11-06 16:16:01 +00:00
|
|
|
|
NS_IF_RELEASE(rcx);
|
|
|
|
|
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::StyleChangeReflow"));
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
1998-11-06 16:16:01 +00:00
|
|
|
|
|
|
|
|
|
return NS_OK; //XXX this needs to be real. MMP
|
|
|
|
|
}
|
|
|
|
|
|
1998-12-29 04:45:18 +00:00
|
|
|
|
NS_IMETHODIMP
|
1999-02-12 17:45:58 +00:00
|
|
|
|
PresShell::GetRootFrame(nsIFrame** aResult) const
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
1999-10-18 22:20:37 +00:00
|
|
|
|
return mFrameManager->GetRootFrame(aResult);
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-12-07 03:43:02 +00:00
|
|
|
|
NS_IMETHODIMP
|
1999-02-12 17:45:58 +00:00
|
|
|
|
PresShell::GetPageSequenceFrame(nsIPageSequenceFrame** aResult) const
|
1998-12-07 03:43:02 +00:00
|
|
|
|
{
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
1999-10-18 22:20:37 +00:00
|
|
|
|
nsIFrame* rootFrame;
|
1998-12-07 03:43:02 +00:00
|
|
|
|
nsIFrame* child;
|
1999-12-07 05:28:32 +00:00
|
|
|
|
nsIPageSequenceFrame* pageSequence = nsnull;
|
1998-12-07 03:43:02 +00:00
|
|
|
|
|
1999-12-07 05:28:32 +00:00
|
|
|
|
// The page sequence frame is the child of the rootFrame
|
1999-10-18 22:20:37 +00:00
|
|
|
|
mFrameManager->GetRootFrame(&rootFrame);
|
2000-01-22 01:16:50 +00:00
|
|
|
|
rootFrame->FirstChild(mPresContext, nsnull, &child);
|
1999-12-07 05:28:32 +00:00
|
|
|
|
|
1998-12-07 03:43:02 +00:00
|
|
|
|
if (nsnull != child) {
|
1999-12-07 05:28:32 +00:00
|
|
|
|
|
|
|
|
|
// but the child could be wrapped in a scrollframe so lets check
|
|
|
|
|
nsIScrollableFrame* scrollable = nsnull;
|
2000-01-04 20:24:09 +00:00
|
|
|
|
nsresult rv = child->QueryInterface(NS_GET_IID(nsIScrollableFrame),
|
|
|
|
|
(void **)&scrollable);
|
1999-12-07 05:28:32 +00:00
|
|
|
|
if (NS_SUCCEEDED(rv) && (nsnull != scrollable)) {
|
|
|
|
|
// if it is then get the scrolled frame
|
|
|
|
|
scrollable->GetScrolledFrame(nsnull, child);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// make sure the child is a pageSequence
|
2000-01-04 20:24:09 +00:00
|
|
|
|
rv = child->QueryInterface(NS_GET_IID(nsIPageSequenceFrame),
|
|
|
|
|
(void**)&pageSequence);
|
1999-12-07 05:28:32 +00:00
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv),"Error: Could not find pageSequence!");
|
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
|
*aResult = pageSequence;
|
1998-12-07 03:43:02 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
1999-12-07 05:28:32 +00:00
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
|
*aResult = nsnull;
|
1998-12-07 03:43:02 +00:00
|
|
|
|
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
1998-06-03 15:46:54 +00:00
|
|
|
|
NS_IMETHODIMP
|
1998-07-22 23:32:19 +00:00
|
|
|
|
PresShell::BeginUpdate(nsIDocument *aDocument)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
|
|
|
|
mUpdateCount++;
|
1998-06-03 15:46:54 +00:00
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-06-03 15:46:54 +00:00
|
|
|
|
NS_IMETHODIMP
|
1998-07-22 23:32:19 +00:00
|
|
|
|
PresShell::EndUpdate(nsIDocument *aDocument)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
|
|
|
|
NS_PRECONDITION(0 != mUpdateCount, "too many EndUpdate's");
|
|
|
|
|
if (--mUpdateCount == 0) {
|
|
|
|
|
// XXX do something here
|
|
|
|
|
}
|
1998-06-03 15:46:54 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-07-22 23:32:19 +00:00
|
|
|
|
PresShell::BeginLoad(nsIDocument *aDocument)
|
1999-09-20 06:55:24 +00:00
|
|
|
|
{
|
1999-10-19 22:27:20 +00:00
|
|
|
|
#ifdef MOZ_PERF_METRICS
|
1999-09-20 06:55:24 +00:00
|
|
|
|
// Reset style resolution stopwatch maintained by style set
|
2000-02-11 01:21:05 +00:00
|
|
|
|
MOZ_TIMER_DEBUGLOG(("Reset: Style Resolution: PresShell::BeginLoad(), this=%p\n", this));
|
|
|
|
|
CtlStyleWatch(kStyleWatchReset,mStyleSet);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
#endif
|
2000-05-16 01:11:29 +00:00
|
|
|
|
mDocumentLoading = PR_TRUE;
|
1998-06-03 15:46:54 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-07-22 23:32:19 +00:00
|
|
|
|
PresShell::EndLoad(nsIDocument *aDocument)
|
1998-06-03 15:46:54 +00:00
|
|
|
|
{
|
2000-06-15 00:35:46 +00:00
|
|
|
|
|
|
|
|
|
// Restore frame state for the root scroll frame
|
|
|
|
|
nsIFrame* rootFrame = nsnull;
|
|
|
|
|
GetRootFrame(&rootFrame);
|
|
|
|
|
if (rootFrame && mHistoryState) {
|
|
|
|
|
nsIFrame* scrollFrame = nsnull;
|
|
|
|
|
GetRootScrollFrame(mPresContext, rootFrame, &scrollFrame);
|
|
|
|
|
if (scrollFrame) {
|
|
|
|
|
mFrameManager->RestoreFrameStateFor(mPresContext, scrollFrame, mHistoryState, nsIStatefulFrame::eDocumentScrollState);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-10-19 22:27:20 +00:00
|
|
|
|
#ifdef MOZ_PERF_METRICS
|
1999-09-20 06:55:24 +00:00
|
|
|
|
// Dump reflow, style resolution and frame construction times here.
|
1999-11-10 03:41:09 +00:00
|
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Reflow: PresShell::EndLoad(), this=%p\n", this));
|
|
|
|
|
MOZ_TIMER_STOP(mReflowWatch);
|
|
|
|
|
MOZ_TIMER_LOG(("Reflow time (this=%p): ", this));
|
|
|
|
|
MOZ_TIMER_PRINT(mReflowWatch);
|
|
|
|
|
|
|
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Frame Creation: PresShell::EndLoad(), this=%p\n", this));
|
|
|
|
|
MOZ_TIMER_STOP(mFrameCreationWatch);
|
|
|
|
|
MOZ_TIMER_LOG(("Frame construction plus style resolution time (this=%p): ", this));
|
|
|
|
|
MOZ_TIMER_PRINT(mFrameCreationWatch);
|
1999-09-20 06:55:24 +00:00
|
|
|
|
|
|
|
|
|
// Print style resolution stopwatch maintained by style set
|
2000-02-11 01:21:05 +00:00
|
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Style Resolution: PresShell::EndLoad(), this=%p\n", this));
|
|
|
|
|
CtlStyleWatch(kStyleWatchStop|kStyleWatchDisable, mStyleSet);
|
|
|
|
|
MOZ_TIMER_LOG(("Style resolution time (this=%p): ", this));
|
|
|
|
|
CtlStyleWatch(kStyleWatchPrint, mStyleSet);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
#endif
|
2000-05-16 01:11:29 +00:00
|
|
|
|
mDocumentLoading = PR_FALSE;
|
1998-06-03 15:46:54 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-07-22 23:32:19 +00:00
|
|
|
|
PresShell::BeginReflow(nsIDocument *aDocument, nsIPresShell* aShell)
|
1998-06-03 15:46:54 +00:00
|
|
|
|
{
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
1998-07-22 23:32:19 +00:00
|
|
|
|
PresShell::EndReflow(nsIDocument *aDocument, nsIPresShell* aShell)
|
1998-06-03 15:46:54 +00:00
|
|
|
|
{
|
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-11-09 03:23:26 +00:00
|
|
|
|
|
|
|
|
|
// aReflowCommand is considered to be already in the queue if the
|
|
|
|
|
// frame it targets is targeted by a pre-existing reflow command in
|
|
|
|
|
// the queue.
|
|
|
|
|
PRBool
|
2001-03-13 06:38:59 +00:00
|
|
|
|
PresShell::AlreadyInQueue(nsIReflowCommand* aReflowCommand,
|
|
|
|
|
nsVoidArray& aQueue)
|
1999-11-09 03:23:26 +00:00
|
|
|
|
{
|
2001-03-13 06:38:59 +00:00
|
|
|
|
PRInt32 i, n = aQueue.Count();
|
1999-11-09 03:23:26 +00:00
|
|
|
|
nsIFrame* targetFrame;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
PRBool inQueue = PR_FALSE;
|
1999-11-12 04:41:34 +00:00
|
|
|
|
|
1999-11-09 03:23:26 +00:00
|
|
|
|
if (NS_SUCCEEDED(aReflowCommand->GetTarget(targetFrame))) {
|
|
|
|
|
// Iterate over the reflow commands and compare the targeted frames.
|
|
|
|
|
for (i = 0; i < n; i++) {
|
2001-03-13 06:38:59 +00:00
|
|
|
|
nsIReflowCommand* rc = (nsIReflowCommand*) aQueue.ElementAt(i);
|
1999-11-09 03:23:26 +00:00
|
|
|
|
if (rc) {
|
|
|
|
|
nsIFrame* targetOfQueuedRC;
|
|
|
|
|
if (NS_SUCCEEDED(rc->GetTarget(targetOfQueuedRC))) {
|
|
|
|
|
nsIReflowCommand::ReflowType RCType;
|
|
|
|
|
nsIReflowCommand::ReflowType queuedRCType;
|
|
|
|
|
aReflowCommand->GetType(RCType);
|
|
|
|
|
rc->GetType(queuedRCType);
|
|
|
|
|
if (targetFrame == targetOfQueuedRC &&
|
1999-12-23 02:02:33 +00:00
|
|
|
|
RCType == queuedRCType) {
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
2001-04-18 06:06:31 +00:00
|
|
|
|
printf("*** PresShell::AlreadyInQueue(): Discarding reflow command: this=%p\n", (void*)this);
|
1999-12-23 02:02:33 +00:00
|
|
|
|
aReflowCommand->List(stdout);
|
|
|
|
|
}
|
1999-11-09 03:23:26 +00:00
|
|
|
|
#endif
|
|
|
|
|
inQueue = PR_TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return inQueue;
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-13 06:38:59 +00:00
|
|
|
|
void
|
|
|
|
|
NotifyAncestorFramesOfReflowCommand(nsIPresShell* aPresShell,
|
|
|
|
|
nsIReflowCommand* aRC,
|
|
|
|
|
PRBool aCommandAdded)
|
|
|
|
|
{
|
|
|
|
|
if (aRC) {
|
|
|
|
|
nsIFrame* target;
|
|
|
|
|
aRC->GetTarget(target);
|
|
|
|
|
if (target) {
|
|
|
|
|
nsIFrame* ancestor;
|
|
|
|
|
target->GetParent(&ancestor);
|
|
|
|
|
while(ancestor) {
|
|
|
|
|
ancestor->ReflowCommandNotify(aPresShell, aRC, aCommandAdded);
|
|
|
|
|
ancestor->GetParent(&ancestor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-12-29 04:56:31 +00:00
|
|
|
|
NS_IMETHODIMP
|
2001-03-13 06:38:59 +00:00
|
|
|
|
PresShell::AppendReflowCommandInternal(nsIReflowCommand* aReflowCommand,
|
|
|
|
|
nsVoidArray& aQueue)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
1999-09-15 00:27:05 +00:00
|
|
|
|
#ifdef DEBUG
|
2000-10-28 22:17:53 +00:00
|
|
|
|
//printf("gShellCounter: %d\n", gShellCounter++);
|
1998-11-26 18:11:02 +00:00
|
|
|
|
if (mInVerifyReflow) {
|
1998-12-29 04:56:31 +00:00
|
|
|
|
return NS_OK;
|
1999-12-23 02:02:33 +00:00
|
|
|
|
}
|
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
2001-04-18 06:06:31 +00:00
|
|
|
|
printf("\nPresShell@%p: adding reflow command\n", (void*)this);
|
1999-12-23 02:02:33 +00:00
|
|
|
|
aReflowCommand->List(stdout);
|
|
|
|
|
if (VERIFY_REFLOW_REALLY_NOISY_RC & gVerifyReflowFlags) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("Current content model:\n");
|
1999-12-23 02:02:33 +00:00
|
|
|
|
nsCOMPtr<nsIContent> rootContent;
|
|
|
|
|
rootContent = getter_AddRefs(mDocument->GetRootContent());
|
|
|
|
|
if (rootContent) {
|
|
|
|
|
rootContent->List(stdout, 0);
|
1999-09-15 00:27:05 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1999-12-23 02:02:33 +00:00
|
|
|
|
}
|
1998-11-26 18:11:02 +00:00
|
|
|
|
#endif
|
2000-09-12 00:35:11 +00:00
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
// Add the reflow command to the queue
|
1999-11-09 03:23:26 +00:00
|
|
|
|
nsresult rv = NS_OK;
|
2001-03-13 06:38:59 +00:00
|
|
|
|
// don't check for duplicates on the timeout queue - it is responsiblity of frames
|
|
|
|
|
// who call SendInterruptNotificationTo to make sure there are no duplicates
|
|
|
|
|
if ((&aQueue == &mTimeoutReflowCommands) ||
|
|
|
|
|
((&aQueue == &mReflowCommands) && !AlreadyInQueue(aReflowCommand, aQueue))) {
|
1999-11-09 03:23:26 +00:00
|
|
|
|
NS_ADDREF(aReflowCommand);
|
2001-03-13 06:38:59 +00:00
|
|
|
|
rv = (aQueue.AppendElement(aReflowCommand) ? NS_OK : NS_ERROR_OUT_OF_MEMORY);
|
2000-09-12 00:35:11 +00:00
|
|
|
|
ReflowCommandAdded(aReflowCommand);
|
2001-03-13 06:38:59 +00:00
|
|
|
|
NotifyAncestorFramesOfReflowCommand(this, aReflowCommand, PR_TRUE);
|
1999-11-09 03:23:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-09-12 08:59:01 +00:00
|
|
|
|
// For async reflow during doc load, post a reflow event if we are not batching reflow commands.
|
|
|
|
|
// For sync reflow during doc load, post a reflow event if we are not batching reflow commands
|
2000-05-16 01:11:29 +00:00
|
|
|
|
// and the document is not loading.
|
2000-09-12 08:59:01 +00:00
|
|
|
|
if ((gAsyncReflowDuringDocLoad && !mBatchReflows) ||
|
|
|
|
|
(!gAsyncReflowDuringDocLoad && !mBatchReflows && !mDocumentLoading)) {
|
|
|
|
|
// If we're in the middle of a drag, process it right away (needed for mac,
|
|
|
|
|
// might as well do it on all platforms just to keep the code paths the same).
|
2000-10-30 09:26:53 +00:00
|
|
|
|
if ( !IsDragInProgress() )
|
2000-06-14 23:18:54 +00:00
|
|
|
|
PostReflowEvent();
|
2000-04-17 07:13:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-11-09 03:23:26 +00:00
|
|
|
|
return rv;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-13 06:38:59 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::AppendReflowCommand(nsIReflowCommand* aReflowCommand)
|
|
|
|
|
{
|
|
|
|
|
return AppendReflowCommandInternal(aReflowCommand, mReflowCommands);
|
|
|
|
|
}
|
|
|
|
|
|
2000-06-14 23:18:54 +00:00
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// IsDragInProgress
|
|
|
|
|
//
|
|
|
|
|
// Ask the drag service if we're in the middle of a drag
|
|
|
|
|
//
|
|
|
|
|
PRBool
|
|
|
|
|
PresShell :: IsDragInProgress ( ) const
|
|
|
|
|
{
|
|
|
|
|
PRBool dragInProgress = PR_FALSE;
|
|
|
|
|
if ( mDragService ) {
|
|
|
|
|
nsCOMPtr<nsIDragSession> session;
|
|
|
|
|
mDragService->GetCurrentSession ( getter_AddRefs(session) );
|
|
|
|
|
if ( session )
|
|
|
|
|
dragInProgress = PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dragInProgress;
|
|
|
|
|
|
|
|
|
|
} // IsDragInProgress
|
|
|
|
|
|
|
|
|
|
|
1999-04-23 20:01:20 +00:00
|
|
|
|
NS_IMETHODIMP
|
2001-03-14 07:47:00 +00:00
|
|
|
|
PresShell::CancelReflowCommandInternal(nsIFrame* aTargetFrame,
|
2001-03-13 06:38:59 +00:00
|
|
|
|
nsIReflowCommand::ReflowType* aCmdType,
|
2001-03-14 07:47:00 +00:00
|
|
|
|
nsVoidArray& aQueue)
|
1999-04-23 20:01:20 +00:00
|
|
|
|
{
|
2001-03-13 06:38:59 +00:00
|
|
|
|
PRInt32 i, n = aQueue.Count();
|
1999-04-23 20:01:20 +00:00
|
|
|
|
for (i = 0; i < n; i++) {
|
2001-03-13 06:38:59 +00:00
|
|
|
|
nsIReflowCommand* rc = (nsIReflowCommand*) aQueue.ElementAt(i);
|
1999-04-23 20:01:20 +00:00
|
|
|
|
if (rc) {
|
2000-01-12 08:28:24 +00:00
|
|
|
|
nsIFrame* target;
|
1999-04-23 20:01:20 +00:00
|
|
|
|
if (NS_SUCCEEDED(rc->GetTarget(target))) {
|
|
|
|
|
if (target == aTargetFrame) {
|
2000-01-12 08:28:24 +00:00
|
|
|
|
if (aCmdType != NULL) {
|
2001-03-14 07:47:00 +00:00
|
|
|
|
// If aCmdType is specified, only remove reflow commands
|
|
|
|
|
// of that type
|
2000-01-12 08:28:24 +00:00
|
|
|
|
nsIReflowCommand::ReflowType type;
|
|
|
|
|
if (NS_SUCCEEDED(rc->GetType(type))) {
|
|
|
|
|
if (type != *aCmdType)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-12-23 02:02:33 +00:00
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
2001-04-18 06:06:31 +00:00
|
|
|
|
printf("PresShell: removing rc=%p for frame ", (void*)rc);
|
1999-12-23 02:02:33 +00:00
|
|
|
|
nsFrame::ListTag(stdout, aTargetFrame);
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("\n");
|
1999-12-23 02:02:33 +00:00
|
|
|
|
}
|
1999-10-29 01:53:56 +00:00
|
|
|
|
#endif
|
2001-03-13 06:38:59 +00:00
|
|
|
|
aQueue.RemoveElementAt(i);
|
2000-09-12 00:35:11 +00:00
|
|
|
|
ReflowCommandRemoved(rc);
|
2001-03-13 06:38:59 +00:00
|
|
|
|
NotifyAncestorFramesOfReflowCommand(this, rc, PR_FALSE);
|
1999-10-29 01:53:56 +00:00
|
|
|
|
NS_RELEASE(rc);
|
1999-04-23 20:01:20 +00:00
|
|
|
|
n--;
|
|
|
|
|
i--;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-03-14 07:47:00 +00:00
|
|
|
|
|
|
|
|
|
DoneRemovingReflowCommands();
|
|
|
|
|
|
1999-04-23 20:01:20 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-13 06:38:59 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::CancelReflowCommand(nsIFrame* aTargetFrame,
|
|
|
|
|
nsIReflowCommand::ReflowType* aCmdType)
|
|
|
|
|
{
|
|
|
|
|
return CancelReflowCommandInternal(aTargetFrame, aCmdType, mReflowCommands);
|
|
|
|
|
}
|
|
|
|
|
|
1999-11-09 03:23:26 +00:00
|
|
|
|
|
2000-09-20 07:20:23 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::CancelAllReflowCommands()
|
|
|
|
|
{
|
|
|
|
|
PRInt32 n = mReflowCommands.Count();
|
|
|
|
|
nsIReflowCommand* rc;
|
2001-03-13 06:38:59 +00:00
|
|
|
|
PRInt32 i;
|
|
|
|
|
for (i = 0; i < n; i++) {
|
2000-09-20 07:20:23 +00:00
|
|
|
|
rc = NS_STATIC_CAST(nsIReflowCommand*, mReflowCommands.ElementAt(0));
|
|
|
|
|
mReflowCommands.RemoveElementAt(0);
|
|
|
|
|
ReflowCommandRemoved(rc);
|
|
|
|
|
NS_RELEASE(rc);
|
|
|
|
|
}
|
2001-03-14 07:47:00 +00:00
|
|
|
|
|
2001-03-13 06:38:59 +00:00
|
|
|
|
n = mTimeoutReflowCommands.Count();
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
|
rc = NS_STATIC_CAST(nsIReflowCommand*, mTimeoutReflowCommands.ElementAt(0));
|
|
|
|
|
mTimeoutReflowCommands.RemoveElementAt(0);
|
|
|
|
|
ReflowCommandRemoved(rc);
|
|
|
|
|
NS_RELEASE(rc);
|
|
|
|
|
}
|
2001-03-14 07:47:00 +00:00
|
|
|
|
|
|
|
|
|
DoneRemovingReflowCommands();
|
|
|
|
|
|
2000-09-20 07:20:23 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_IMETHODIMP
|
1998-11-19 00:43:36 +00:00
|
|
|
|
PresShell::ClearFrameRefs(nsIFrame* aFrame)
|
|
|
|
|
{
|
|
|
|
|
nsIEventStateManager *manager;
|
|
|
|
|
if (NS_OK == mPresContext->GetEventStateManager(&manager)) {
|
|
|
|
|
manager->ClearFrameRefs(aFrame);
|
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
|
}
|
1999-04-01 23:58:11 +00:00
|
|
|
|
|
|
|
|
|
if (mCaret) {
|
|
|
|
|
mCaret->ClearFrameRefs(aFrame);
|
|
|
|
|
}
|
|
|
|
|
|
1998-11-21 00:19:36 +00:00
|
|
|
|
if (aFrame == mCurrentEventFrame) {
|
2000-04-24 04:41:27 +00:00
|
|
|
|
aFrame->GetContent(&mCurrentEventContent);
|
1998-11-21 00:19:36 +00:00
|
|
|
|
mCurrentEventFrame = nsnull;
|
|
|
|
|
}
|
1999-09-02 18:14:01 +00:00
|
|
|
|
|
|
|
|
|
for (int i=0; i<mCurrentEventFrameStack.Count(); i++) {
|
|
|
|
|
if (aFrame == (nsIFrame*)mCurrentEventFrameStack.ElementAt(i)) {
|
2000-04-24 04:41:27 +00:00
|
|
|
|
//One of our stack frames was deleted. Get its content so that when we
|
|
|
|
|
//pop it we can still get its new frame from its content
|
|
|
|
|
nsIContent *currentEventContent;
|
|
|
|
|
aFrame->GetContent(¤tEventContent);
|
|
|
|
|
mCurrentEventContentStack.ReplaceElementAt((void*)currentEventContent, i);
|
1999-09-02 18:14:01 +00:00
|
|
|
|
mCurrentEventFrameStack.ReplaceElementAt(nsnull, i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
|
return NS_OK;
|
1998-11-19 00:43:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-02-05 18:25:29 +00:00
|
|
|
|
NS_IMETHODIMP
|
1999-02-12 17:45:58 +00:00
|
|
|
|
PresShell::CreateRenderingContext(nsIFrame *aFrame,
|
|
|
|
|
nsIRenderingContext** aResult)
|
1998-10-02 01:12:39 +00:00
|
|
|
|
{
|
1999-02-12 17:45:58 +00:00
|
|
|
|
NS_PRECONDITION(nsnull != aResult, "null ptr");
|
|
|
|
|
if (nsnull == aResult) {
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
|
1998-10-02 01:12:39 +00:00
|
|
|
|
nsIView *view = nsnull;
|
|
|
|
|
nsPoint pt;
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
1999-10-26 04:44:41 +00:00
|
|
|
|
aFrame->GetView(mPresContext, &view);
|
1998-10-02 01:12:39 +00:00
|
|
|
|
|
|
|
|
|
if (nsnull == view)
|
1999-10-26 04:44:41 +00:00
|
|
|
|
aFrame->GetOffsetFromView(mPresContext, pt, &view);
|
1998-10-02 01:12:39 +00:00
|
|
|
|
|
2000-01-26 23:04:40 +00:00
|
|
|
|
nsCOMPtr<nsIWidget> widget;
|
|
|
|
|
if (nsnull != view) {
|
|
|
|
|
nsCOMPtr<nsIViewManager> vm;
|
|
|
|
|
view->GetViewManager(*getter_AddRefs(vm));
|
|
|
|
|
vm->GetWidgetForView(view, getter_AddRefs(widget));
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
1998-10-02 01:12:39 +00:00
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
|
nsCOMPtr<nsIDeviceContext> dx;
|
1998-11-14 01:52:27 +00:00
|
|
|
|
|
1999-02-12 17:45:58 +00:00
|
|
|
|
nsIRenderingContext* result = nsnull;
|
|
|
|
|
rv = mPresContext->GetDeviceContext(getter_AddRefs(dx));
|
1999-02-12 18:41:26 +00:00
|
|
|
|
if (NS_SUCCEEDED(rv) && dx) {
|
2000-01-26 23:04:40 +00:00
|
|
|
|
if (nsnull != widget) {
|
|
|
|
|
rv = dx->CreateRenderingContext(widget, result);
|
1999-02-12 17:45:58 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
rv = dx->CreateRenderingContext(result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*aResult = result;
|
1998-10-02 01:12:39 +00:00
|
|
|
|
|
|
|
|
|
return rv;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-02-05 18:25:29 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::CantRenderReplacedElement(nsIPresContext* aPresContext,
|
|
|
|
|
nsIFrame* aFrame)
|
|
|
|
|
{
|
1999-08-05 20:17:44 +00:00
|
|
|
|
if (mFrameManager) {
|
1999-10-30 01:31:49 +00:00
|
|
|
|
return mFrameManager->CantRenderReplacedElement(aPresContext, aFrame);
|
1999-02-05 18:25:29 +00:00
|
|
|
|
}
|
1999-08-05 20:17:44 +00:00
|
|
|
|
|
|
|
|
|
return NS_OK;
|
1999-02-05 18:25:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-02-12 05:39:33 +00:00
|
|
|
|
NS_IMETHODIMP
|
2001-03-27 23:59:56 +00:00
|
|
|
|
PresShell::GoToAnchor(const nsString& aAnchorName)
|
1999-02-12 05:39:33 +00:00
|
|
|
|
{
|
2000-10-11 13:50:45 +00:00
|
|
|
|
nsCOMPtr<nsIDOMDocument> doc = do_QueryInterface(mDocument);
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLDocument> htmlDoc = do_QueryInterface(mDocument);
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
nsCOMPtr<nsIContent> content;
|
1999-02-12 05:39:33 +00:00
|
|
|
|
|
2000-10-11 13:50:45 +00:00
|
|
|
|
// Search for an element with a matching "id" attribute
|
|
|
|
|
if (doc) {
|
1999-02-12 05:39:33 +00:00
|
|
|
|
nsCOMPtr<nsIDOMElement> element;
|
2000-07-28 21:48:08 +00:00
|
|
|
|
rv = doc->GetElementById(aAnchorName, getter_AddRefs(element));
|
1999-04-09 04:28:15 +00:00
|
|
|
|
if (NS_SUCCEEDED(rv) && element) {
|
1999-02-12 05:39:33 +00:00
|
|
|
|
// Get the nsIContent interface, because that's what we need to
|
|
|
|
|
// get the primary frame
|
2000-10-11 13:50:45 +00:00
|
|
|
|
content = do_QueryInterface(element);
|
1999-03-20 01:51:00 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1999-02-12 05:39:33 +00:00
|
|
|
|
|
2000-10-11 13:50:45 +00:00
|
|
|
|
// Search for an anchor element with a matching "name" attribute
|
|
|
|
|
if (!content && htmlDoc) {
|
|
|
|
|
nsCOMPtr<nsIDOMNodeList> list;
|
|
|
|
|
// Find a matching list of named nodes
|
|
|
|
|
rv = htmlDoc->GetElementsByName(aAnchorName, getter_AddRefs(list));
|
|
|
|
|
if (NS_SUCCEEDED(rv) && list) {
|
|
|
|
|
PRUint32 count;
|
|
|
|
|
PRUint32 i;
|
|
|
|
|
list->GetLength(&count);
|
|
|
|
|
// Loop through the named nodes looking for the first anchor
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
|
nsCOMPtr<nsIDOMNode> node;
|
|
|
|
|
rv = list->Item(i, getter_AddRefs(node));
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// Ensure it's an anchor element
|
|
|
|
|
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(node);
|
|
|
|
|
nsAutoString tagName;
|
|
|
|
|
if (element && NS_SUCCEEDED(element->GetTagName(tagName))) {
|
|
|
|
|
tagName.ToLowerCase();
|
|
|
|
|
if (tagName.EqualsWithConversion("a")) {
|
|
|
|
|
content = do_QueryInterface(element);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Search for anchor in the HTML namespace with a matching name
|
|
|
|
|
if (!content && !htmlDoc)
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsIDOMNodeList> list;
|
|
|
|
|
NS_NAMED_LITERAL_STRING(nameSpace, "http://www.w3.org/1999/xhtml");
|
|
|
|
|
// Get the list of anchor elements
|
|
|
|
|
rv = doc->GetElementsByTagNameNS(nameSpace, NS_LITERAL_STRING("a"), getter_AddRefs(list));
|
|
|
|
|
if (NS_SUCCEEDED(rv) && list) {
|
|
|
|
|
PRUint32 count;
|
|
|
|
|
PRUint32 i;
|
|
|
|
|
list->GetLength(&count);
|
|
|
|
|
// Loop through the named nodes looking for the first anchor
|
|
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
|
nsCOMPtr<nsIDOMNode> node;
|
|
|
|
|
rv = list->Item(i, getter_AddRefs(node));
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// Compare the name attribute
|
|
|
|
|
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(node);
|
|
|
|
|
nsAutoString value;
|
|
|
|
|
if (element && NS_SUCCEEDED(element->GetAttribute(NS_LITERAL_STRING("name"), value))) {
|
|
|
|
|
if (value.EqualsWithConversion(aAnchorName)) {
|
|
|
|
|
content = do_QueryInterface(element);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (content) {
|
1999-03-20 01:51:00 +00:00
|
|
|
|
nsIFrame* frame;
|
2000-10-11 13:50:45 +00:00
|
|
|
|
|
1999-03-20 01:51:00 +00:00
|
|
|
|
// Get the primary frame
|
|
|
|
|
if (NS_SUCCEEDED(GetPrimaryFrameFor(content, &frame))) {
|
1999-07-19 18:38:33 +00:00
|
|
|
|
rv = ScrollFrameIntoView(frame, NS_PRESSHELL_SCROLL_TOP,
|
|
|
|
|
NS_PRESSHELL_SCROLL_ANYWHERE);
|
2001-03-27 23:59:56 +00:00
|
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
|
// Should we select the target?
|
|
|
|
|
// This action is controlled by a preference: the default is to not select.
|
|
|
|
|
nsCOMPtr<nsIPref> prefs(do_GetService(kPrefServiceCID,&rv));
|
|
|
|
|
if (NS_SUCCEEDED(rv) && prefs) {
|
|
|
|
|
PRBool selectAnchor;
|
|
|
|
|
rv = prefs->GetBoolPref("layout.selectanchor",&selectAnchor);
|
|
|
|
|
if (NS_SUCCEEDED(rv) && selectAnchor) {
|
|
|
|
|
rv = SelectContent(content);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-02-12 05:39:33 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
rv = NS_ERROR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-27 23:59:56 +00:00
|
|
|
|
nsresult
|
|
|
|
|
PresShell::SelectContent(nsIContent *aContent)
|
|
|
|
|
{
|
|
|
|
|
nsresult rv;
|
|
|
|
|
nsCOMPtr<nsISelection> sel;
|
|
|
|
|
rv = GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(sel));
|
|
|
|
|
if (NS_SUCCEEDED(rv) && sel) {
|
|
|
|
|
nsCOMPtr<nsIDOMRange> range(do_CreateInstance(kRangeCID,&rv));
|
|
|
|
|
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aContent));
|
|
|
|
|
if (NS_SUCCEEDED(rv) && node) {
|
|
|
|
|
rv = range->SelectNode(node);
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
|
sel->RemoveAllRanges();
|
|
|
|
|
rv = sel->AddRange(range);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
1999-02-18 22:52:21 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::ScrollFrameIntoView(nsIFrame *aFrame,
|
1999-07-19 18:38:33 +00:00
|
|
|
|
PRIntn aVPercent,
|
|
|
|
|
PRIntn aHPercent) const
|
1999-02-18 22:52:21 +00:00
|
|
|
|
{
|
1999-07-19 18:38:33 +00:00
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
if (!aFrame) {
|
1999-02-18 22:52:21 +00:00
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
1999-07-19 18:38:33 +00:00
|
|
|
|
}
|
2000-11-04 08:21:20 +00:00
|
|
|
|
|
2000-05-11 22:40:51 +00:00
|
|
|
|
// Before we scroll the frame into view, ask the command dispatcher
|
|
|
|
|
// if we're resetting focus because a window just got an activate
|
|
|
|
|
// event. If we are, we do not want to scroll the frame into view.
|
|
|
|
|
// Example: The user clicks on an anchor, and then deactivates the
|
|
|
|
|
// window. When they reactivate the window, the expected behavior
|
|
|
|
|
// is not for the anchor link to scroll back into view. That is what
|
|
|
|
|
// this check is preventing.
|
|
|
|
|
// XXX: The dependency on the command dispatcher needs to be fixed.
|
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
|
aFrame->GetContent(getter_AddRefs(content));
|
|
|
|
|
if(content) {
|
|
|
|
|
nsCOMPtr<nsIDocument> document;
|
|
|
|
|
content->GetDocument(*getter_AddRefs(document));
|
|
|
|
|
if(document){
|
2000-11-04 08:21:20 +00:00
|
|
|
|
nsCOMPtr<nsIFocusController> focusController;
|
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> ourGlobal;
|
|
|
|
|
document->GetScriptGlobalObject(getter_AddRefs(ourGlobal));
|
2000-05-11 22:40:51 +00:00
|
|
|
|
nsCOMPtr<nsPIDOMWindow> ourWindow = do_QueryInterface(ourGlobal);
|
|
|
|
|
if(ourWindow) {
|
2000-11-04 08:21:20 +00:00
|
|
|
|
ourWindow->GetRootFocusController(getter_AddRefs(focusController));
|
|
|
|
|
if (focusController) {
|
|
|
|
|
PRBool dontScroll;
|
|
|
|
|
focusController->GetSuppressFocusScroll(&dontScroll);
|
|
|
|
|
if(dontScroll)
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-05-11 22:40:51 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2000-11-04 08:21:20 +00:00
|
|
|
|
|
1999-07-19 18:38:33 +00:00
|
|
|
|
if (mViewManager) {
|
|
|
|
|
// Get the viewport scroller
|
2000-08-29 01:56:46 +00:00
|
|
|
|
nsIScrollableView* scrollingView;
|
|
|
|
|
mViewManager->GetRootScrollableView(&scrollingView);
|
1999-02-18 22:52:21 +00:00
|
|
|
|
|
|
|
|
|
if (scrollingView) {
|
|
|
|
|
nsIView* scrolledView;
|
|
|
|
|
nsPoint offset;
|
1999-07-19 18:38:33 +00:00
|
|
|
|
nsIView* closestView;
|
1999-02-18 22:52:21 +00:00
|
|
|
|
|
1999-07-19 18:38:33 +00:00
|
|
|
|
// Determine the offset from aFrame to the scrolled view. We do that by
|
|
|
|
|
// getting the offset from its closest view and then walking up
|
1999-02-18 22:52:21 +00:00
|
|
|
|
scrollingView->GetScrolledView(scrolledView);
|
1999-10-26 04:44:41 +00:00
|
|
|
|
aFrame->GetOffsetFromView(mPresContext, offset, &closestView);
|
1999-07-19 18:38:33 +00:00
|
|
|
|
|
2001-01-10 02:43:00 +00:00
|
|
|
|
// If this is an inline frame, we need to change the top of the
|
|
|
|
|
// offset to include the whole line.
|
|
|
|
|
nsCOMPtr<nsIAtom> frameType;
|
|
|
|
|
nsIFrame *prevFrame = aFrame;
|
|
|
|
|
nsIFrame *frame = aFrame;
|
|
|
|
|
while (frame && (frame->GetFrameType(getter_AddRefs(frameType)),
|
|
|
|
|
frameType.get() == nsLayoutAtoms::inlineFrame)) {
|
|
|
|
|
prevFrame = frame;
|
|
|
|
|
prevFrame->GetParent(&frame);
|
|
|
|
|
}
|
|
|
|
|
if (frame != aFrame &&
|
|
|
|
|
frame &&
|
|
|
|
|
frameType.get() == nsLayoutAtoms::blockFrame) {
|
|
|
|
|
// find the line containing aFrame and increase the top of |offset|.
|
|
|
|
|
nsCOMPtr<nsILineIterator> lines( do_QueryInterface(frame) );
|
|
|
|
|
if (lines) {
|
|
|
|
|
PRInt32 index = -1;
|
|
|
|
|
lines->FindLineContaining(prevFrame, &index);
|
|
|
|
|
if (index >= 0) {
|
|
|
|
|
nsIFrame *trash1;
|
|
|
|
|
PRInt32 trash2;
|
|
|
|
|
nsRect lineBounds;
|
|
|
|
|
PRUint32 trash3;
|
|
|
|
|
if (NS_SUCCEEDED(lines->GetLine(index, &trash1, &trash2,
|
|
|
|
|
lineBounds, &trash3))) {
|
|
|
|
|
nsPoint blockOffset;
|
|
|
|
|
nsIView* blockView;
|
|
|
|
|
frame->GetOffsetFromView(mPresContext, blockOffset, &blockView);
|
|
|
|
|
if (blockView == closestView) {
|
|
|
|
|
// XXX If views not equal, this is hard. Do we want to bother?
|
|
|
|
|
nscoord newoffset = lineBounds.y + blockOffset.y;
|
|
|
|
|
if (newoffset < offset.y) offset.y = newoffset;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1999-07-19 18:38:33 +00:00
|
|
|
|
// XXX Deal with the case where there is a scrolled element, e.g., a
|
|
|
|
|
// DIV in the middle...
|
1999-08-07 20:43:47 +00:00
|
|
|
|
while ((closestView != nsnull) && (closestView != scrolledView)) {
|
1999-07-19 18:38:33 +00:00
|
|
|
|
nscoord x, y;
|
|
|
|
|
|
|
|
|
|
// Update the offset
|
|
|
|
|
closestView->GetPosition(&x, &y);
|
|
|
|
|
offset.MoveBy(x, y);
|
|
|
|
|
|
|
|
|
|
// Get its parent view
|
|
|
|
|
closestView->GetParent(closestView);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Determine the visible rect in the scrolled view's coordinate space.
|
|
|
|
|
// The size of the visible area is the clip view size
|
|
|
|
|
const nsIView* clipView;
|
|
|
|
|
nsRect visibleRect;
|
|
|
|
|
|
|
|
|
|
scrollingView->GetScrollPosition(visibleRect.x, visibleRect.y);
|
|
|
|
|
scrollingView->GetClipView(&clipView);
|
|
|
|
|
clipView->GetDimensions(&visibleRect.width, &visibleRect.height);
|
|
|
|
|
|
|
|
|
|
// The actual scroll offsets
|
|
|
|
|
nscoord scrollOffsetX = visibleRect.x;
|
|
|
|
|
nscoord scrollOffsetY = visibleRect.y;
|
|
|
|
|
|
|
|
|
|
// The frame's bounds in the coordinate space of the scrolled frame
|
|
|
|
|
nsRect frameBounds;
|
|
|
|
|
aFrame->GetRect(frameBounds);
|
|
|
|
|
frameBounds.x = offset.x;
|
|
|
|
|
frameBounds.y = offset.y;
|
|
|
|
|
|
|
|
|
|
// See how the frame should be positioned vertically
|
|
|
|
|
if (NS_PRESSHELL_SCROLL_ANYWHERE == aVPercent) {
|
|
|
|
|
// The caller doesn't care where the frame is positioned vertically,
|
|
|
|
|
// so long as it's fully visible
|
|
|
|
|
if (frameBounds.y < visibleRect.y) {
|
|
|
|
|
// Scroll up so the frame's top edge is visible
|
|
|
|
|
scrollOffsetY = frameBounds.y;
|
|
|
|
|
} else if (frameBounds.YMost() > visibleRect.YMost()) {
|
|
|
|
|
// Scroll down so the frame's bottom edge is visible. Make sure the
|
|
|
|
|
// frame's top edge is still visible
|
|
|
|
|
scrollOffsetY += frameBounds.YMost() - visibleRect.YMost();
|
|
|
|
|
if (scrollOffsetY > frameBounds.y) {
|
|
|
|
|
scrollOffsetY = frameBounds.y;
|
1999-02-19 23:43:41 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2000-01-25 20:36:24 +00:00
|
|
|
|
} else if (NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE == aVPercent) {
|
|
|
|
|
// Scroll only if no part of the frame is visible in this view
|
|
|
|
|
if (frameBounds.YMost() < visibleRect.y) {
|
|
|
|
|
// Scroll up so the frame's top edge is visible
|
|
|
|
|
scrollOffsetY = frameBounds.y;
|
|
|
|
|
} else if (frameBounds.y > visibleRect.YMost()) {
|
|
|
|
|
// Scroll down so the frame's bottom edge is visible. Make sure the
|
|
|
|
|
// frame's top edge is still visible
|
|
|
|
|
scrollOffsetY += frameBounds.YMost() - visibleRect.YMost();
|
|
|
|
|
if (scrollOffsetY > frameBounds.y) {
|
|
|
|
|
scrollOffsetY = frameBounds.y;
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-07-19 18:38:33 +00:00
|
|
|
|
} else {
|
|
|
|
|
// Align the frame edge according to the specified percentage
|
|
|
|
|
nscoord frameAlignY = frameBounds.y + (frameBounds.height * aVPercent) / 100;
|
|
|
|
|
scrollOffsetY = frameAlignY - (visibleRect.height * aVPercent) / 100;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// See how the frame should be positioned horizontally
|
|
|
|
|
if (NS_PRESSHELL_SCROLL_ANYWHERE == aHPercent) {
|
|
|
|
|
// The caller doesn't care where the frame is positioned horizontally,
|
|
|
|
|
// so long as it's fully visible
|
|
|
|
|
if (frameBounds.x < visibleRect.x) {
|
|
|
|
|
// Scroll left so the frame's left edge is visible
|
|
|
|
|
scrollOffsetX = frameBounds.x;
|
|
|
|
|
} else if (frameBounds.XMost() > visibleRect.XMost()) {
|
|
|
|
|
// Scroll right so the frame's right edge is visible. Make sure the
|
|
|
|
|
// frame's left edge is still visible
|
|
|
|
|
scrollOffsetX += frameBounds.XMost() - visibleRect.XMost();
|
|
|
|
|
if (scrollOffsetX > frameBounds.x) {
|
|
|
|
|
scrollOffsetX = frameBounds.x;
|
1999-02-20 21:27:28 +00:00
|
|
|
|
}
|
1999-02-19 23:43:41 +00:00
|
|
|
|
}
|
2000-01-25 20:36:24 +00:00
|
|
|
|
} else if (NS_PRESSHELL_SCROLL_IF_NOT_VISIBLE == aHPercent) {
|
|
|
|
|
// Scroll only if no part of the frame is visible in this view
|
|
|
|
|
if (frameBounds.XMost() < visibleRect.x) {
|
|
|
|
|
// Scroll left so the frame's left edge is visible
|
|
|
|
|
scrollOffsetX = frameBounds.x;
|
|
|
|
|
} else if (frameBounds.x > visibleRect.XMost()) {
|
|
|
|
|
// Scroll right so the frame's right edge is visible. Make sure the
|
|
|
|
|
// frame's left edge is still visible
|
|
|
|
|
scrollOffsetX += frameBounds.XMost() - visibleRect.XMost();
|
|
|
|
|
if (scrollOffsetX > frameBounds.x) {
|
|
|
|
|
scrollOffsetX = frameBounds.x;
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-07-19 18:38:33 +00:00
|
|
|
|
} else {
|
|
|
|
|
// Align the frame edge according to the specified percentage
|
|
|
|
|
nscoord frameAlignX = frameBounds.x + (frameBounds.width * aHPercent) / 100;
|
|
|
|
|
scrollOffsetX = frameAlignX - (visibleRect.width * aHPercent) / 100;
|
1999-02-19 23:43:41 +00:00
|
|
|
|
}
|
2001-04-24 23:17:22 +00:00
|
|
|
|
scrollingView->ScrollTo(scrollOffsetX, scrollOffsetY, NS_VMREFRESH_IMMEDIATE);
|
1999-02-18 22:52:21 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-18 06:06:31 +00:00
|
|
|
|
// CopyStringToClipboard: copy simple string to clipboard
|
|
|
|
|
nsresult PresShell::CopyStringToClipboard(nsString& aString,
|
|
|
|
|
PRInt32 aClipboardID)
|
|
|
|
|
{
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
|
|
// get the clipboard
|
|
|
|
|
nsCOMPtr<nsIClipboard>
|
|
|
|
|
clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
NS_ENSURE_TRUE(clipboard, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
|
|
// create a transferable for putting data on the clipboard
|
|
|
|
|
nsCOMPtr<nsITransferable>
|
|
|
|
|
trans(do_CreateInstance("@mozilla.org/widget/transferable;1", &rv));
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
NS_ENSURE_TRUE(trans, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
|
|
// Add the text data flavor to the transferable
|
|
|
|
|
rv = trans->AddDataFlavor(kUnicodeMime);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
// get wStrings to hold clip data
|
|
|
|
|
nsCOMPtr<nsISupportsWString>
|
|
|
|
|
data(do_CreateInstance("@mozilla.org/supports-wstring;1", &rv));
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
NS_ENSURE_TRUE(data, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
|
|
// populate the string
|
|
|
|
|
rv = data->SetData(NS_CONST_CAST(PRUnichar*, aString.GetUnicode()));
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
// qi the data object an |nsISupports| so that when the transferable holds
|
|
|
|
|
// onto it, it will addref the correct interface.
|
|
|
|
|
nsCOMPtr<nsISupports> genericData(do_QueryInterface(data, &rv));
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
NS_ENSURE_TRUE(genericData, NS_ERROR_FAILURE);
|
|
|
|
|
|
|
|
|
|
// set the transfer data
|
|
|
|
|
rv = trans->SetTransferData(kUnicodeMime, genericData,
|
|
|
|
|
aString.Length() * 2);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
// put the transferable on the clipboard
|
|
|
|
|
rv = clipboard->SetData(trans, nsnull, aClipboardID);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// CopyStringToClipboard: copy string to clipboard(s) for platform
|
|
|
|
|
nsresult PresShell::CopyStringToClipboard(nsString& aString)
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_dr
|
|
|
|
|
printf("dr :: CopyStringToClipboard: %s\n",
|
|
|
|
|
NS_ConvertUCS2toUTF8(aString).get());
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
|
|
// copy to the global clipboard
|
|
|
|
|
rv = CopyStringToClipboard(aString, nsIClipboard::kGlobalClipboard);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
|
|
|
|
|
#ifdef XP_UNIX
|
|
|
|
|
// unix also needs us to copy to the selection clipboard
|
|
|
|
|
rv = CopyStringToClipboard(aString, nsIClipboard::kSelectionClipboard);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DoCopyLinkLocation: copy link location to clipboard
|
|
|
|
|
NS_IMETHODIMP PresShell::DoCopyLinkLocation(nsIDOMNode* aNode)
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_dr
|
|
|
|
|
printf("dr :: PresShell::DoCopyLinkLocation\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aNode);
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
|
|
// are we an anchor?
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor(do_QueryInterface(aNode, &rv));
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
if (anchor) {
|
|
|
|
|
// if so, copy the link:
|
|
|
|
|
nsAutoString anchorText;
|
|
|
|
|
rv = anchor->GetHref(anchorText);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
return CopyStringToClipboard(anchorText);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if no link, fail.
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DoCopyImageLocation: copy image location to clipboard
|
|
|
|
|
NS_IMETHODIMP PresShell::DoCopyImageLocation(nsIDOMNode* aNode)
|
|
|
|
|
{
|
|
|
|
|
#ifdef DEBUG_dr
|
|
|
|
|
printf("dr :: PresShell::DoCopyImageLocation\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aNode);
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
|
|
// are we an image?
|
|
|
|
|
nsCOMPtr<nsIDOMHTMLImageElement> img(do_QueryInterface(aNode, &rv));
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
if (img) {
|
|
|
|
|
// if so, copy the location:
|
|
|
|
|
nsAutoString srcText;
|
|
|
|
|
rv = img->GetSrc(srcText);
|
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
|
return CopyStringToClipboard(srcText);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if no image, fail.
|
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DoCopyImageContents: copy image contents to clipboard
|
|
|
|
|
NS_IMETHODIMP PresShell::DoCopyImageContents(nsIDOMNode* aNode)
|
|
|
|
|
{
|
|
|
|
|
// XXX dr: platform-specific widget code works on windows and mac.
|
|
|
|
|
// when linux copy image contents works, this should get written
|
|
|
|
|
// and hooked up to the front end, similarly to cmd_copyImageLocation.
|
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
|
}
|
1999-04-07 03:56:07 +00:00
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::DoCopy()
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
|
GetDocument(getter_AddRefs(doc));
|
2000-07-14 21:58:50 +00:00
|
|
|
|
if (!doc) return NS_ERROR_FAILURE;
|
|
|
|
|
|
|
|
|
|
nsresult rv;
|
2000-09-14 11:45:01 +00:00
|
|
|
|
nsCOMPtr<nsISelection> sel;
|
2000-07-14 21:58:50 +00:00
|
|
|
|
nsCOMPtr<nsIEventStateManager> manager;
|
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
|
rv = mPresContext->GetEventStateManager(getter_AddRefs(manager));
|
|
|
|
|
if (NS_FAILED(rv) || !manager)
|
|
|
|
|
return rv?rv:NS_ERROR_FAILURE;
|
|
|
|
|
rv = manager->GetFocusedContent(getter_AddRefs(content));
|
|
|
|
|
if (NS_SUCCEEDED(rv) && content)
|
|
|
|
|
{
|
|
|
|
|
//check to see if we need to get selection from frame
|
|
|
|
|
//optimization that MAY need to be expanded as more things implement their own "selection"
|
|
|
|
|
nsCOMPtr<nsIDOMNSHTMLInputElement> htmlInputElement(do_QueryInterface(content));
|
|
|
|
|
nsCOMPtr<nsIDOMNSHTMLTextAreaElement> htmlTextAreaElement(do_QueryInterface(content));
|
|
|
|
|
if (htmlInputElement || htmlTextAreaElement)
|
2000-06-14 02:57:26 +00:00
|
|
|
|
{
|
2000-07-14 21:58:50 +00:00
|
|
|
|
nsIFrame *htmlInputFrame;
|
|
|
|
|
rv = GetPrimaryFrameFor(content, &htmlInputFrame);
|
|
|
|
|
if (NS_FAILED(rv) || !htmlInputFrame)
|
|
|
|
|
return rv?rv:NS_ERROR_FAILURE;
|
|
|
|
|
nsCOMPtr<nsISelectionController> selCon;
|
|
|
|
|
rv = htmlInputFrame->GetSelectionController(mPresContext,getter_AddRefs(selCon));
|
|
|
|
|
if (NS_FAILED(rv) || !selCon)
|
|
|
|
|
return rv?rv:NS_ERROR_FAILURE;
|
|
|
|
|
rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(sel));
|
2000-06-14 02:57:26 +00:00
|
|
|
|
}
|
2000-07-14 21:58:50 +00:00
|
|
|
|
}
|
|
|
|
|
if (!sel) //get selection from this PresShell
|
|
|
|
|
rv = GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(sel));
|
|
|
|
|
|
|
|
|
|
if (NS_FAILED(rv) || !sel)
|
|
|
|
|
return rv?rv:NS_ERROR_FAILURE;
|
|
|
|
|
|
2000-08-28 22:28:56 +00:00
|
|
|
|
// Now we have the selection. Make sure it's nonzero:
|
|
|
|
|
PRBool isCollapsed;
|
|
|
|
|
sel->GetIsCollapsed(&isCollapsed);
|
|
|
|
|
if (isCollapsed)
|
|
|
|
|
return NS_OK;
|
|
|
|
|
|
2001-02-15 13:22:26 +00:00
|
|
|
|
// call the copy code
|
|
|
|
|
rv = nsCopySupport::HTMLCopy(sel, doc, nsIClipboard::kGlobalClipboard);
|
|
|
|
|
if (NS_FAILED(rv))
|
2000-07-14 21:58:50 +00:00
|
|
|
|
return rv;
|
2001-02-19 21:50:04 +00:00
|
|
|
|
|
2000-07-14 21:58:50 +00:00
|
|
|
|
// Now that we have copied, update the Paste menu item
|
|
|
|
|
nsCOMPtr<nsIScriptGlobalObject> globalObject;
|
|
|
|
|
doc->GetScriptGlobalObject(getter_AddRefs(globalObject));
|
2000-09-01 01:54:35 +00:00
|
|
|
|
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(globalObject);
|
2000-07-14 21:58:50 +00:00
|
|
|
|
if (domWindow)
|
|
|
|
|
{
|
|
|
|
|
domWindow->UpdateCommands(NS_ConvertASCIItoUCS2("clipboard"));
|
|
|
|
|
}
|
|
|
|
|
|
1999-04-07 03:56:07 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
1999-08-30 22:38:58 +00:00
|
|
|
|
NS_IMETHODIMP
|
2000-06-15 00:35:46 +00:00
|
|
|
|
PresShell::CaptureHistoryState(nsILayoutHistoryState** aState, PRBool aLeavingPage)
|
1999-08-30 22:38:58 +00:00
|
|
|
|
{
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
|
|
NS_PRECONDITION(nsnull != aState, "null state pointer");
|
|
|
|
|
|
2000-01-14 09:28:54 +00:00
|
|
|
|
if (!mHistoryState) {
|
|
|
|
|
// Create the document state object
|
|
|
|
|
rv = NS_NewLayoutHistoryState(aState); // This addrefs
|
1999-08-30 22:38:58 +00:00
|
|
|
|
|
2000-01-14 09:28:54 +00:00
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
*aState = nsnull;
|
|
|
|
|
return rv;
|
2000-02-11 22:54:37 +00:00
|
|
|
|
}
|
1999-08-30 22:38:58 +00:00
|
|
|
|
|
2000-01-14 09:28:54 +00:00
|
|
|
|
mHistoryState = *aState;
|
2000-02-11 22:54:37 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
*aState = mHistoryState;
|
|
|
|
|
NS_IF_ADDREF(mHistoryState);
|
2000-01-14 09:28:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
2000-02-11 22:54:37 +00:00
|
|
|
|
// Capture frame state for the entire frame hierarchy
|
|
|
|
|
nsIFrame* rootFrame = nsnull;
|
|
|
|
|
rv = GetRootFrame(&rootFrame);
|
|
|
|
|
if (NS_FAILED(rv) || nsnull == rootFrame) return rv;
|
2000-06-15 00:35:46 +00:00
|
|
|
|
// Capture frame state for the root scroll frame
|
|
|
|
|
// Don't capture state when first creating doc element heirarchy
|
|
|
|
|
// As the scroll position is 0 and this will cause us to loose
|
|
|
|
|
// our previously saved place!
|
|
|
|
|
if (aLeavingPage) {
|
|
|
|
|
nsIFrame* scrollFrame = nsnull;
|
|
|
|
|
rv = GetRootScrollFrame(mPresContext, rootFrame, &scrollFrame);
|
|
|
|
|
if (scrollFrame) {
|
|
|
|
|
rv = mFrameManager->CaptureFrameStateFor(mPresContext, scrollFrame, mHistoryState, nsIStatefulFrame::eDocumentScrollState);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-11 22:54:37 +00:00
|
|
|
|
|
|
|
|
|
rv = mFrameManager->CaptureFrameState(mPresContext, rootFrame, mHistoryState);
|
2000-01-14 09:28:54 +00:00
|
|
|
|
|
1999-08-30 22:38:58 +00:00
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
2000-03-24 03:36:58 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetHistoryState(nsILayoutHistoryState** aState)
|
|
|
|
|
{
|
|
|
|
|
NS_IF_ADDREF(mHistoryState);
|
|
|
|
|
*aState = mHistoryState;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
1999-08-30 22:38:58 +00:00
|
|
|
|
NS_IMETHODIMP
|
1999-08-31 14:35:50 +00:00
|
|
|
|
PresShell::SetHistoryState(nsILayoutHistoryState* aLayoutHistoryState)
|
1999-08-30 22:38:58 +00:00
|
|
|
|
{
|
1999-08-31 14:35:50 +00:00
|
|
|
|
mHistoryState = aLayoutHistoryState;
|
|
|
|
|
return NS_OK;
|
1999-08-30 22:38:58 +00:00
|
|
|
|
}
|
2000-03-23 00:34:54 +00:00
|
|
|
|
|
|
|
|
|
static PRBool
|
|
|
|
|
IsGeneratedContentFrame(nsIFrame* aFrame)
|
|
|
|
|
{
|
|
|
|
|
nsFrameState frameState;
|
|
|
|
|
|
|
|
|
|
aFrame->GetFrameState(&frameState);
|
|
|
|
|
return (frameState & NS_FRAME_GENERATED_CONTENT) != 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static PRBool
|
|
|
|
|
IsPseudoFrame(nsIFrame* aFrame, nsIContent* aParentContent)
|
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsIContent> content;
|
|
|
|
|
|
|
|
|
|
aFrame->GetContent(getter_AddRefs(content));
|
|
|
|
|
return content.get() == aParentContent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static nsIFrame*
|
|
|
|
|
GetFirstChildFrame(nsIPresContext* aPresContext,
|
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
|
nsIContent* aContent)
|
|
|
|
|
{
|
|
|
|
|
nsIFrame* childFrame;
|
|
|
|
|
|
|
|
|
|
// Get the first child frame
|
|
|
|
|
aFrame->FirstChild(aPresContext, nsnull, &childFrame);
|
|
|
|
|
|
2000-03-31 07:22:38 +00:00
|
|
|
|
// If the child frame is a pseudo-frame, then return its first child.
|
|
|
|
|
// Note that the frame we create for the generated content is also a
|
|
|
|
|
// pseudo-frame and so don't drill down in that case
|
|
|
|
|
if (childFrame && IsPseudoFrame(childFrame, aContent) &&
|
|
|
|
|
!IsGeneratedContentFrame(childFrame)) {
|
2000-03-23 00:34:54 +00:00
|
|
|
|
return GetFirstChildFrame(aPresContext, childFrame, aContent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return childFrame;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static nsIFrame*
|
|
|
|
|
GetLastChildFrame(nsIPresContext* aPresContext,
|
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
|
nsIContent* aContent)
|
|
|
|
|
{
|
|
|
|
|
NS_PRECONDITION(aFrame, "NULL frame pointer");
|
|
|
|
|
|
|
|
|
|
// Get the last in flow frame
|
|
|
|
|
nsIFrame* lastInFlow;
|
|
|
|
|
while (aFrame) {
|
|
|
|
|
lastInFlow = aFrame;
|
|
|
|
|
lastInFlow->GetNextInFlow(&aFrame);
|
|
|
|
|
}
|
|
|
|
|
|
2000-03-31 07:22:38 +00:00
|
|
|
|
// Get the last child frame
|
2000-03-23 00:34:54 +00:00
|
|
|
|
nsIFrame* firstChildFrame;
|
|
|
|
|
lastInFlow->FirstChild(aPresContext, nsnull, &firstChildFrame);
|
|
|
|
|
if (firstChildFrame) {
|
|
|
|
|
nsFrameList frameList(firstChildFrame);
|
|
|
|
|
nsIFrame* lastChildFrame = frameList.LastChild();
|
|
|
|
|
|
|
|
|
|
NS_ASSERTION(lastChildFrame, "unexpected error");
|
|
|
|
|
|
2000-03-31 07:22:38 +00:00
|
|
|
|
// Get the frame's first-in-flow. This matters in case the frame has
|
|
|
|
|
// been continuted across multiple lines
|
|
|
|
|
while (PR_TRUE) {
|
|
|
|
|
nsIFrame* prevInFlow;
|
|
|
|
|
lastChildFrame->GetPrevInFlow(&prevInFlow);
|
|
|
|
|
if (prevInFlow) {
|
|
|
|
|
lastChildFrame = prevInFlow;
|
|
|
|
|
} else {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the last child frame is a pseudo-frame, then return its last child.
|
|
|
|
|
// Note that the frame we create for the generated content is also a
|
|
|
|
|
// pseudo-frame and so don't drill down in that case
|
|
|
|
|
if (lastChildFrame && IsPseudoFrame(lastChildFrame, aContent) &&
|
|
|
|
|
!IsGeneratedContentFrame(lastChildFrame)) {
|
2000-03-23 00:34:54 +00:00
|
|
|
|
return GetLastChildFrame(aPresContext, lastChildFrame, aContent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return lastChildFrame;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nsnull;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetGeneratedContentIterator(nsIContent* aContent,
|
|
|
|
|
GeneratedContentType aType,
|
|
|
|
|
nsIContentIterator** aIterator) const
|
|
|
|
|
{
|
|
|
|
|
nsIFrame* primaryFrame;
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
|
|
// Initialize OUT parameter
|
|
|
|
|
*aIterator = nsnull;
|
|
|
|
|
|
|
|
|
|
// Get the primary frame associated with the content object
|
|
|
|
|
GetPrimaryFrameFor(aContent, &primaryFrame);
|
|
|
|
|
if (primaryFrame) {
|
|
|
|
|
// See whether it's a request for the before or after generated content
|
|
|
|
|
if (Before == aType) {
|
|
|
|
|
// The most efficient thing to do is to get the first child frame,
|
|
|
|
|
// and see if it is associated with generated content
|
|
|
|
|
nsIFrame* firstChildFrame = GetFirstChildFrame(mPresContext, primaryFrame, aContent);
|
|
|
|
|
if (firstChildFrame && IsGeneratedContentFrame(firstChildFrame)) {
|
|
|
|
|
// Create an iterator
|
|
|
|
|
rv = NS_NewGeneratedContentIterator(mPresContext, firstChildFrame, aIterator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
// Avoid finding the last child frame unless we need to. Instead probe
|
|
|
|
|
// for the existence of the pseudo-element
|
|
|
|
|
nsCOMPtr<nsIStyleContext> styleContext;
|
|
|
|
|
nsCOMPtr<nsIStyleContext> pseudoStyleContext;
|
|
|
|
|
|
|
|
|
|
primaryFrame->GetStyleContext(getter_AddRefs(styleContext));
|
|
|
|
|
mPresContext->ProbePseudoStyleContextFor(aContent, nsCSSAtoms::afterPseudo,
|
|
|
|
|
styleContext, PR_FALSE,
|
|
|
|
|
getter_AddRefs(pseudoStyleContext));
|
|
|
|
|
if (pseudoStyleContext) {
|
|
|
|
|
nsIFrame* lastChildFrame = GetLastChildFrame(mPresContext, primaryFrame, aContent);
|
2000-09-14 05:40:48 +00:00
|
|
|
|
if (lastChildFrame)
|
|
|
|
|
{ // it is now legal for GetLastChildFrame to return null. see bug 52307 (a regression from bug 18754)
|
|
|
|
|
// in the case of a null child frame, we treat the frame as having no "after" style
|
|
|
|
|
// the "before" handler above already does this check
|
|
|
|
|
NS_ASSERTION(IsGeneratedContentFrame(lastChildFrame),
|
|
|
|
|
"can't find generated content frame");
|
|
|
|
|
// Create an iterator
|
|
|
|
|
rv = NS_NewGeneratedContentIterator(mPresContext, lastChildFrame, aIterator);
|
|
|
|
|
}
|
2000-03-23 00:34:54 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
1999-11-09 03:23:26 +00:00
|
|
|
|
|
2000-10-09 03:08:41 +00:00
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::SetAnonymousContentFor(nsIContent* aContent, nsISupportsArray* aAnonymousElements)
|
|
|
|
|
{
|
|
|
|
|
NS_PRECONDITION(aContent != nsnull, "null ptr");
|
|
|
|
|
if (! aContent)
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
|
|
NS_PRECONDITION(aAnonymousElements != nsnull, "null ptr");
|
|
|
|
|
if (! aAnonymousElements)
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
|
|
|
|
|
if (! mAnonymousContentTable) {
|
|
|
|
|
mAnonymousContentTable = new nsSupportsHashtable;
|
|
|
|
|
if (! mAnonymousContentTable)
|
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsISupportsKey key(aContent);
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsISupportsArray> oldAnonymousElements =
|
|
|
|
|
getter_AddRefs(NS_STATIC_CAST(nsISupportsArray*, mAnonymousContentTable->Get(&key)));
|
|
|
|
|
|
|
|
|
|
if (oldAnonymousElements) {
|
|
|
|
|
// If we're trying to set anonymous content for an element that
|
|
|
|
|
// already had anonymous content, then we need to be sure to clean
|
|
|
|
|
// up after the old content. (This can happen, for example, when a
|
|
|
|
|
// reframe occurs.)
|
|
|
|
|
PRUint32 count;
|
|
|
|
|
oldAnonymousElements->Count(&count);
|
|
|
|
|
|
|
|
|
|
while (PRInt32(--count) >= 0) {
|
|
|
|
|
nsCOMPtr<nsISupports> isupports( getter_AddRefs(oldAnonymousElements->ElementAt(count)) );
|
|
|
|
|
nsCOMPtr<nsIContent> content( do_QueryInterface(isupports) );
|
|
|
|
|
NS_ASSERTION(content != nsnull, "not an nsIContent");
|
|
|
|
|
if (! content)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
content->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mAnonymousContentTable->Put(&key, aAnonymousElements);
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetAnonymousContentFor(nsIContent* aContent, nsISupportsArray** aAnonymousElements)
|
|
|
|
|
{
|
|
|
|
|
if (! mAnonymousContentTable) {
|
|
|
|
|
*aAnonymousElements = nsnull;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsISupportsKey key(aContent);
|
|
|
|
|
*aAnonymousElements =
|
|
|
|
|
NS_REINTERPRET_CAST(nsISupportsArray*, mAnonymousContentTable->Get(&key)); // addrefs
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static PRBool PR_CALLBACK
|
|
|
|
|
ClearDocumentEnumerator(nsHashKey* aKey, void* aData, void* aClosure)
|
|
|
|
|
{
|
|
|
|
|
nsISupportsArray* anonymousElements =
|
|
|
|
|
NS_STATIC_CAST(nsISupportsArray*, aData);
|
|
|
|
|
|
|
|
|
|
PRUint32 count;
|
|
|
|
|
anonymousElements->Count(&count);
|
|
|
|
|
while (PRInt32(--count) >= 0) {
|
|
|
|
|
nsCOMPtr<nsISupports> isupports( getter_AddRefs(anonymousElements->ElementAt(count)) );
|
|
|
|
|
nsCOMPtr<nsIContent> content( do_QueryInterface(isupports) );
|
|
|
|
|
NS_ASSERTION(content != nsnull, "not an nsIContent");
|
|
|
|
|
if (! content)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
content->SetDocument(nsnull, PR_TRUE, PR_TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::ReleaseAnonymousContent()
|
|
|
|
|
{
|
|
|
|
|
if (mAnonymousContentTable) {
|
|
|
|
|
mAnonymousContentTable->Enumerate(ClearDocumentEnumerator);
|
|
|
|
|
delete mAnonymousContentTable;
|
|
|
|
|
mAnonymousContentTable = nsnull;
|
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-25 19:52:49 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::IsPaintingSuppressed(PRBool* aResult)
|
|
|
|
|
{
|
|
|
|
|
*aResult = mPaintingSuppressed;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
PresShell::UnsuppressAndInvalidate()
|
|
|
|
|
{
|
|
|
|
|
mPaintingSuppressed = PR_FALSE;
|
|
|
|
|
nsIFrame* rootFrame;
|
|
|
|
|
mFrameManager->GetRootFrame(&rootFrame);
|
|
|
|
|
if (rootFrame) {
|
|
|
|
|
nsRect rect;
|
|
|
|
|
rootFrame->GetRect(rect);
|
|
|
|
|
((nsFrame*)rootFrame)->Invalidate(mPresContext, rect, PR_FALSE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::UnsuppressPainting(PRBool aCancelTimer)
|
|
|
|
|
{
|
|
|
|
|
if (mPaintSuppressionTimer && aCancelTimer) {
|
|
|
|
|
mPaintSuppressionTimer->Cancel();
|
|
|
|
|
mPaintSuppressionTimer = nsnull;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mPaintingSuppressed || !aCancelTimer)
|
|
|
|
|
return NS_OK;
|
|
|
|
|
|
|
|
|
|
// If we have reflows pending, just wait until we process
|
|
|
|
|
// the reflows and get all the frames where we want them
|
|
|
|
|
// before actually unlocking the painting. Otherwise
|
|
|
|
|
// go ahead and unlock now.
|
|
|
|
|
if (mReflowCommands.Count() > 0)
|
|
|
|
|
mShouldUnsuppressPainting = PR_TRUE;
|
|
|
|
|
else
|
|
|
|
|
UnsuppressAndInvalidate();
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
2000-10-09 03:08:41 +00:00
|
|
|
|
|
2000-07-13 23:00:59 +00:00
|
|
|
|
// Post a request to handle an arbitrary callback after reflow has finished.
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::PostReflowCallback(nsIReflowCallback* aCallback)
|
|
|
|
|
{
|
|
|
|
|
nsCallbackEventRequest* request = nsnull;
|
|
|
|
|
void* result = nsnull;
|
|
|
|
|
AllocateFrame(sizeof(nsCallbackEventRequest), &result);
|
|
|
|
|
request = (nsCallbackEventRequest*)result;
|
|
|
|
|
|
|
|
|
|
request->callback = aCallback;
|
|
|
|
|
NS_ADDREF(aCallback);
|
|
|
|
|
request->next = nsnull;
|
|
|
|
|
|
|
|
|
|
if (mLastCallbackEventRequest) {
|
|
|
|
|
mLastCallbackEventRequest = mLastCallbackEventRequest->next = request;
|
|
|
|
|
} else {
|
|
|
|
|
mFirstCallbackEventRequest = request;
|
|
|
|
|
mLastCallbackEventRequest = request;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2000-10-07 00:49:08 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::CancelReflowCallback(nsIReflowCallback* aCallback)
|
|
|
|
|
{
|
|
|
|
|
nsCallbackEventRequest* before = nsnull;
|
|
|
|
|
nsCallbackEventRequest* node = mFirstCallbackEventRequest;
|
|
|
|
|
while(node)
|
|
|
|
|
{
|
|
|
|
|
nsIReflowCallback* callback = node->callback;
|
|
|
|
|
|
|
|
|
|
if (callback == aCallback)
|
|
|
|
|
{
|
|
|
|
|
nsCallbackEventRequest* toFree = node;
|
|
|
|
|
if (node == mFirstCallbackEventRequest) {
|
|
|
|
|
mFirstCallbackEventRequest = node->next;
|
|
|
|
|
node = mFirstCallbackEventRequest;
|
|
|
|
|
before = nsnull;
|
|
|
|
|
} else {
|
|
|
|
|
node = node->next;
|
|
|
|
|
before->next = node;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FreeFrame(sizeof(nsCallbackEventRequest), toFree);
|
|
|
|
|
NS_RELEASE(callback);
|
|
|
|
|
} else {
|
|
|
|
|
before = node;
|
|
|
|
|
node = node->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2000-06-23 05:15:04 +00:00
|
|
|
|
/**
|
|
|
|
|
* Post a request to handle a DOM event after Reflow has finished.
|
|
|
|
|
* The event must have been created with the "new" operator.
|
|
|
|
|
*/
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::PostDOMEvent(nsIContent* aContent, nsEvent* aEvent)
|
|
|
|
|
{
|
|
|
|
|
// ok we have a list of events to handle. Queue them up and handle them
|
|
|
|
|
// after we finish reflow.
|
|
|
|
|
nsDOMEventRequest* request = nsnull;
|
|
|
|
|
void* result = nsnull;
|
|
|
|
|
AllocateFrame(sizeof(nsDOMEventRequest), &result);
|
|
|
|
|
request = (nsDOMEventRequest*)result;
|
|
|
|
|
|
|
|
|
|
request->content = aContent;
|
|
|
|
|
NS_ADDREF(aContent);
|
|
|
|
|
|
|
|
|
|
request->event = aEvent;
|
|
|
|
|
request->next = nsnull;
|
|
|
|
|
|
|
|
|
|
if (mLastDOMEventRequest) {
|
|
|
|
|
mLastDOMEventRequest = mLastDOMEventRequest->next = request;
|
|
|
|
|
} else {
|
|
|
|
|
mFirstDOMEventRequest = request;
|
|
|
|
|
mLastDOMEventRequest = request;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Post a request to set and attribute after reflow has finished.
|
|
|
|
|
*/
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::PostAttributeChange(nsIContent* aContent,
|
|
|
|
|
PRInt32 aNameSpaceID,
|
|
|
|
|
nsIAtom* aName,
|
|
|
|
|
const nsString& aValue,
|
|
|
|
|
PRBool aNotify,
|
|
|
|
|
nsAttributeChangeType aType)
|
|
|
|
|
{
|
|
|
|
|
// ok we have a list of events to handle. Queue them up and handle them
|
|
|
|
|
// after we finish reflow.
|
|
|
|
|
nsAttributeChangeRequest* request = nsnull;
|
|
|
|
|
|
|
|
|
|
void* result = nsnull;
|
|
|
|
|
AllocateFrame(sizeof(nsAttributeChangeRequest), &result);
|
|
|
|
|
request = (nsAttributeChangeRequest*)result;
|
|
|
|
|
|
|
|
|
|
request->content = aContent;
|
|
|
|
|
NS_ADDREF(aContent);
|
|
|
|
|
|
|
|
|
|
request->nameSpaceID = aNameSpaceID;
|
|
|
|
|
request->name = aName;
|
|
|
|
|
request->value = aValue;
|
|
|
|
|
request->notify = aNotify;
|
|
|
|
|
request->type = aType;
|
|
|
|
|
request->next = nsnull;
|
|
|
|
|
|
|
|
|
|
if (mLastAttributeRequest) {
|
|
|
|
|
mLastAttributeRequest = mLastAttributeRequest->next = request;
|
|
|
|
|
} else {
|
|
|
|
|
mFirstAttributeRequest = request;
|
|
|
|
|
mLastAttributeRequest = request;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2000-10-07 00:49:08 +00:00
|
|
|
|
|
2000-07-13 23:00:59 +00:00
|
|
|
|
void
|
|
|
|
|
PresShell::HandlePostedReflowCallbacks()
|
|
|
|
|
{
|
|
|
|
|
PRBool shouldFlush = PR_FALSE;
|
|
|
|
|
nsCallbackEventRequest* node = mFirstCallbackEventRequest;
|
|
|
|
|
while(node)
|
|
|
|
|
{
|
|
|
|
|
nsIReflowCallback* callback = node->callback;
|
|
|
|
|
nsCallbackEventRequest* toFree = node;
|
|
|
|
|
node = node->next;
|
|
|
|
|
mFirstCallbackEventRequest = node;
|
|
|
|
|
FreeFrame(sizeof(nsCallbackEventRequest), toFree);
|
2000-09-20 07:20:23 +00:00
|
|
|
|
callback->ReflowFinished(this, &shouldFlush);
|
2000-07-13 23:00:59 +00:00
|
|
|
|
NS_RELEASE(callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mFirstCallbackEventRequest = mLastCallbackEventRequest = nsnull;
|
|
|
|
|
|
|
|
|
|
if (shouldFlush)
|
|
|
|
|
FlushPendingNotifications();
|
|
|
|
|
}
|
|
|
|
|
|
2000-06-23 05:15:04 +00:00
|
|
|
|
void
|
|
|
|
|
PresShell::HandlePostedDOMEvents()
|
|
|
|
|
{
|
2000-07-19 20:09:59 +00:00
|
|
|
|
while(mFirstDOMEventRequest)
|
2000-06-23 05:15:04 +00:00
|
|
|
|
{
|
2000-07-19 20:09:59 +00:00
|
|
|
|
/* pull the node from the event request list. Be prepared for reentrant access to the list
|
|
|
|
|
from within HandleDOMEvent and its callees! */
|
|
|
|
|
nsDOMEventRequest* node = mFirstDOMEventRequest;
|
2000-06-23 05:15:04 +00:00
|
|
|
|
nsEventStatus status = nsEventStatus_eIgnore;
|
2000-07-19 20:09:59 +00:00
|
|
|
|
|
|
|
|
|
mFirstDOMEventRequest = node->next;
|
|
|
|
|
if (nsnull == mFirstDOMEventRequest) {
|
|
|
|
|
mLastDOMEventRequest = nsnull;
|
|
|
|
|
}
|
|
|
|
|
|
2000-09-20 07:20:23 +00:00
|
|
|
|
node->content->HandleDOMEvent(mPresContext, node->event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
2000-06-23 05:15:04 +00:00
|
|
|
|
NS_RELEASE(node->content);
|
|
|
|
|
delete node->event;
|
2000-07-19 20:09:59 +00:00
|
|
|
|
node->nsDOMEventRequest::~nsDOMEventRequest(); // doesn't do anything, but just in case
|
|
|
|
|
FreeFrame(sizeof(nsDOMEventRequest), node);
|
2000-06-23 05:15:04 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
PresShell::HandlePostedAttributeChanges()
|
|
|
|
|
{
|
2000-07-19 20:09:59 +00:00
|
|
|
|
while(mFirstAttributeRequest)
|
2000-06-23 05:15:04 +00:00
|
|
|
|
{
|
2000-07-19 20:09:59 +00:00
|
|
|
|
/* pull the node from the request list. Be prepared for reentrant access to the list
|
|
|
|
|
from within SetAttribute/UnsetAttribute and its callees! */
|
|
|
|
|
nsAttributeChangeRequest* node = mFirstAttributeRequest;
|
|
|
|
|
|
|
|
|
|
mFirstAttributeRequest = node->next;
|
|
|
|
|
if (nsnull == mFirstAttributeRequest) {
|
|
|
|
|
mLastAttributeRequest = nsnull;
|
|
|
|
|
}
|
|
|
|
|
|
2000-06-23 05:15:04 +00:00
|
|
|
|
if (node->type == eChangeType_Set)
|
|
|
|
|
node->content->SetAttribute(node->nameSpaceID, node->name, node->value, node->notify);
|
|
|
|
|
else
|
|
|
|
|
node->content->UnsetAttribute(node->nameSpaceID, node->name, node->notify);
|
|
|
|
|
|
|
|
|
|
NS_RELEASE(node->content);
|
2000-07-19 20:09:59 +00:00
|
|
|
|
node->nsAttributeChangeRequest::~nsAttributeChangeRequest();
|
|
|
|
|
FreeFrame(sizeof(nsAttributeChangeRequest), node);
|
2000-06-23 05:15:04 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-10-17 05:07:39 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::IsSafeToFlush(PRBool& aIsSafeToFlush)
|
|
|
|
|
{
|
|
|
|
|
aIsSafeToFlush = PR_TRUE;
|
|
|
|
|
|
|
|
|
|
if (mIsReflowing) {
|
|
|
|
|
// Not safe if we are reflowing
|
|
|
|
|
aIsSafeToFlush = PR_FALSE;
|
|
|
|
|
} else {
|
|
|
|
|
// Not safe if we are painting
|
|
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
|
nsresult rv = GetViewManager(getter_AddRefs(viewManager));
|
|
|
|
|
if (NS_SUCCEEDED(rv) && (nsnull != viewManager)) {
|
|
|
|
|
PRBool isPainting = PR_FALSE;
|
|
|
|
|
viewManager->IsPainting(isPainting);
|
|
|
|
|
if (isPainting) {
|
|
|
|
|
aIsSafeToFlush = PR_FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-01-28 22:58:17 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::FlushPendingNotifications()
|
|
|
|
|
{
|
2000-10-17 05:07:39 +00:00
|
|
|
|
PRBool isSafeToFlush;
|
|
|
|
|
IsSafeToFlush(isSafeToFlush);
|
|
|
|
|
|
|
|
|
|
if (isSafeToFlush) {
|
2000-01-28 22:58:17 +00:00
|
|
|
|
ProcessReflowCommands(PR_FALSE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2000-02-09 15:48:01 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::IsReflowLocked(PRBool* aIsReflowLocked)
|
|
|
|
|
{
|
2000-04-17 07:13:57 +00:00
|
|
|
|
*aIsReflowLocked = mIsReflowing;
|
2000-02-09 15:48:01 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2000-01-28 00:48:02 +00:00
|
|
|
|
NS_IMETHODIMP
|
2000-04-17 07:13:57 +00:00
|
|
|
|
PresShell::BeginReflowBatching()
|
2000-01-28 00:48:02 +00:00
|
|
|
|
{
|
|
|
|
|
mBatchReflows = PR_TRUE;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
2000-04-17 07:13:57 +00:00
|
|
|
|
PresShell::EndReflowBatching(PRBool aFlushPendingReflows)
|
2000-01-28 00:48:02 +00:00
|
|
|
|
{
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
mBatchReflows = PR_FALSE;
|
|
|
|
|
if (aFlushPendingReflows) {
|
|
|
|
|
rv = FlushPendingNotifications();
|
|
|
|
|
}
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetReflowBatchingStatus(PRBool* aIsBatching)
|
|
|
|
|
{
|
|
|
|
|
*aIsBatching = mBatchReflows;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
1998-06-03 15:46:54 +00:00
|
|
|
|
NS_IMETHODIMP
|
1998-07-22 23:32:19 +00:00
|
|
|
|
PresShell::ContentChanged(nsIDocument *aDocument,
|
|
|
|
|
nsIContent* aContent,
|
1998-05-09 03:22:41 +00:00
|
|
|
|
nsISupports* aSubContent)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1998-09-29 23:46:05 +00:00
|
|
|
|
nsresult rv = mStyleSet->ContentChanged(mPresContext, aContent, aSubContent);
|
1999-09-21 07:53:49 +00:00
|
|
|
|
VERIFY_STYLE_TREE;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
1999-01-29 18:57:56 +00:00
|
|
|
|
|
1998-09-29 23:46:05 +00:00
|
|
|
|
return rv;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-02-27 07:15:09 +00:00
|
|
|
|
NS_IMETHODIMP
|
1999-04-20 00:06:58 +00:00
|
|
|
|
PresShell::ContentStatesChanged(nsIDocument* aDocument,
|
|
|
|
|
nsIContent* aContent1,
|
|
|
|
|
nsIContent* aContent2)
|
1999-02-27 07:15:09 +00:00
|
|
|
|
{
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1999-04-20 00:06:58 +00:00
|
|
|
|
nsresult rv = mStyleSet->ContentStatesChanged(mPresContext, aContent1, aContent2);
|
1999-09-21 07:53:49 +00:00
|
|
|
|
VERIFY_STYLE_TREE;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
1999-02-27 07:15:09 +00:00
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
1998-09-18 19:53:27 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::AttributeChanged(nsIDocument *aDocument,
|
|
|
|
|
nsIContent* aContent,
|
1999-10-15 23:16:45 +00:00
|
|
|
|
PRInt32 aNameSpaceID,
|
1998-09-29 23:46:05 +00:00
|
|
|
|
nsIAtom* aAttribute,
|
|
|
|
|
PRInt32 aHint)
|
1998-09-18 19:53:27 +00:00
|
|
|
|
{
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1999-10-15 23:16:45 +00:00
|
|
|
|
nsresult rv = mStyleSet->AttributeChanged(mPresContext, aContent, aNameSpaceID, aAttribute, aHint);
|
1999-09-21 07:53:49 +00:00
|
|
|
|
VERIFY_STYLE_TREE;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
1998-09-29 23:46:05 +00:00
|
|
|
|
return rv;
|
1998-09-18 19:53:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-06-03 15:46:54 +00:00
|
|
|
|
NS_IMETHODIMP
|
1998-07-22 23:32:19 +00:00
|
|
|
|
PresShell::ContentAppended(nsIDocument *aDocument,
|
1998-09-10 19:32:14 +00:00
|
|
|
|
nsIContent* aContainer,
|
|
|
|
|
PRInt32 aNewIndexInContainer)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1999-11-10 03:41:09 +00:00
|
|
|
|
MOZ_TIMER_DEBUGLOG(("Start: Frame Creation: PresShell::ContentAppended(), this=%p\n", this));
|
|
|
|
|
MOZ_TIMER_START(mFrameCreationWatch);
|
2000-02-11 01:21:05 +00:00
|
|
|
|
CtlStyleWatch(kStyleWatchEnable,mStyleSet);
|
1998-09-29 23:46:05 +00:00
|
|
|
|
nsresult rv = mStyleSet->ContentAppended(mPresContext, aContainer, aNewIndexInContainer);
|
1999-09-21 07:53:49 +00:00
|
|
|
|
VERIFY_STYLE_TREE;
|
1999-08-31 14:35:50 +00:00
|
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rv) && nsnull != mHistoryState) {
|
|
|
|
|
// If history state has been set by session history, ask the frame manager
|
|
|
|
|
// to restore frame state for the frame hierarchy created for the chunk of
|
|
|
|
|
// content that just came in.
|
2001-04-05 03:11:30 +00:00
|
|
|
|
// That is the frames with numbers after aNewIndexInContainer.
|
|
|
|
|
PRInt32 count = 0;
|
|
|
|
|
aContainer->ChildCount(count);
|
|
|
|
|
|
|
|
|
|
PRInt32 i;
|
|
|
|
|
nsCOMPtr<nsIContent> newChild;
|
|
|
|
|
for (i = aNewIndexInContainer; i < count; ++i) {
|
|
|
|
|
aContainer->ChildAt(i, *getter_AddRefs(newChild));
|
|
|
|
|
if (!newChild) {
|
|
|
|
|
// We should never get here.
|
|
|
|
|
NS_ERROR("Got a null child when restoring state!");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
nsIFrame* frame;
|
|
|
|
|
rv = GetPrimaryFrameFor(newChild, &frame);
|
|
|
|
|
if (NS_SUCCEEDED(rv) && nsnull != frame)
|
|
|
|
|
mFrameManager->RestoreFrameState(mPresContext, frame, mHistoryState);
|
|
|
|
|
}
|
1999-08-31 14:35:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-11-10 03:41:09 +00:00
|
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Frame Creation: PresShell::ContentAppended(), this=%p\n", this));
|
|
|
|
|
MOZ_TIMER_STOP(mFrameCreationWatch);
|
2000-02-11 01:21:05 +00:00
|
|
|
|
CtlStyleWatch(kStyleWatchDisable,mStyleSet);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
1998-09-10 19:32:14 +00:00
|
|
|
|
return rv;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-06-03 15:46:54 +00:00
|
|
|
|
NS_IMETHODIMP
|
1998-09-10 19:32:14 +00:00
|
|
|
|
PresShell::ContentInserted(nsIDocument* aDocument,
|
|
|
|
|
nsIContent* aContainer,
|
|
|
|
|
nsIContent* aChild,
|
|
|
|
|
PRInt32 aIndexInContainer)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1998-09-29 23:46:05 +00:00
|
|
|
|
nsresult rv = mStyleSet->ContentInserted(mPresContext, aContainer, aChild, aIndexInContainer);
|
1999-09-21 07:53:49 +00:00
|
|
|
|
VERIFY_STYLE_TREE;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
1998-09-10 19:32:14 +00:00
|
|
|
|
return rv;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-06-03 15:46:54 +00:00
|
|
|
|
NS_IMETHODIMP
|
1998-09-10 19:32:14 +00:00
|
|
|
|
PresShell::ContentReplaced(nsIDocument* aDocument,
|
|
|
|
|
nsIContent* aContainer,
|
|
|
|
|
nsIContent* aOldChild,
|
|
|
|
|
nsIContent* aNewChild,
|
|
|
|
|
PRInt32 aIndexInContainer)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1998-09-29 23:46:05 +00:00
|
|
|
|
nsresult rv = mStyleSet->ContentReplaced(mPresContext, aContainer, aOldChild,
|
|
|
|
|
aNewChild, aIndexInContainer);
|
1999-09-21 07:53:49 +00:00
|
|
|
|
VERIFY_STYLE_TREE;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
1998-09-10 19:32:14 +00:00
|
|
|
|
return rv;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-06-03 15:46:54 +00:00
|
|
|
|
NS_IMETHODIMP
|
1998-09-24 21:39:47 +00:00
|
|
|
|
PresShell::ContentRemoved(nsIDocument *aDocument,
|
|
|
|
|
nsIContent* aContainer,
|
|
|
|
|
nsIContent* aChild,
|
|
|
|
|
PRInt32 aIndexInContainer)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1998-09-29 23:46:05 +00:00
|
|
|
|
nsresult rv = mStyleSet->ContentRemoved(mPresContext, aContainer,
|
|
|
|
|
aChild, aIndexInContainer);
|
1999-09-21 07:53:49 +00:00
|
|
|
|
VERIFY_STYLE_TREE;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
1998-09-10 19:32:14 +00:00
|
|
|
|
return rv;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-11-26 01:34:53 +00:00
|
|
|
|
nsresult
|
|
|
|
|
PresShell::ReconstructFrames(void)
|
1998-11-17 02:14:38 +00:00
|
|
|
|
{
|
|
|
|
|
nsresult rv = NS_OK;
|
1999-01-26 00:05:21 +00:00
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1999-03-01 16:57:35 +00:00
|
|
|
|
rv = mStyleSet->ReconstructDocElementHierarchy(mPresContext);
|
1999-09-21 07:53:49 +00:00
|
|
|
|
VERIFY_STYLE_TREE;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
1999-03-01 16:57:35 +00:00
|
|
|
|
|
1998-11-17 02:14:38 +00:00
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
1998-11-26 01:34:53 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::StyleSheetAdded(nsIDocument *aDocument,
|
|
|
|
|
nsIStyleSheet* aStyleSheet)
|
|
|
|
|
{
|
|
|
|
|
return ReconstructFrames();
|
|
|
|
|
}
|
|
|
|
|
|
1999-02-03 19:38:16 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::StyleSheetRemoved(nsIDocument *aDocument,
|
|
|
|
|
nsIStyleSheet* aStyleSheet)
|
|
|
|
|
{
|
|
|
|
|
return ReconstructFrames();
|
|
|
|
|
}
|
|
|
|
|
|
1998-11-26 01:34:53 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::StyleSheetDisabledStateChanged(nsIDocument *aDocument,
|
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
|
PRBool aDisabled)
|
|
|
|
|
{
|
2000-06-22 23:58:03 +00:00
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
|
|
|
|
// first notify the style set that a sheet's state has changed
|
|
|
|
|
if (mStyleSet) {
|
|
|
|
|
rv = mStyleSet->NotifyStyleSheetStateChanged(aDisabled ? PR_FALSE : PR_TRUE);
|
|
|
|
|
}
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
|
|
// rebuild the frame-world
|
1998-11-26 01:34:53 +00:00
|
|
|
|
return ReconstructFrames();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::StyleRuleChanged(nsIDocument *aDocument,
|
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
|
nsIStyleRule* aStyleRule,
|
|
|
|
|
PRInt32 aHint)
|
|
|
|
|
{
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1998-11-26 01:34:53 +00:00
|
|
|
|
nsresult rv = mStyleSet->StyleRuleChanged(mPresContext, aStyleSheet,
|
|
|
|
|
aStyleRule, aHint);
|
1999-09-21 07:53:49 +00:00
|
|
|
|
VERIFY_STYLE_TREE;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
1998-11-26 01:34:53 +00:00
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::StyleRuleAdded(nsIDocument *aDocument,
|
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
|
nsIStyleRule* aStyleRule)
|
|
|
|
|
{
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1999-04-03 18:58:04 +00:00
|
|
|
|
nsresult rv = mStyleSet->StyleRuleAdded(mPresContext, aStyleSheet,
|
|
|
|
|
aStyleRule);
|
1999-09-21 07:53:49 +00:00
|
|
|
|
VERIFY_STYLE_TREE;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
1999-04-03 18:58:04 +00:00
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
1999-03-10 01:17:49 +00:00
|
|
|
|
// XXX For now reconstruct everything
|
|
|
|
|
return ReconstructFrames();
|
1998-11-26 01:34:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::StyleRuleRemoved(nsIDocument *aDocument,
|
|
|
|
|
nsIStyleSheet* aStyleSheet,
|
|
|
|
|
nsIStyleRule* aStyleRule)
|
|
|
|
|
{
|
2000-04-17 07:13:57 +00:00
|
|
|
|
WillCauseReflow();
|
1999-04-03 18:58:04 +00:00
|
|
|
|
nsresult rv = mStyleSet->StyleRuleRemoved(mPresContext, aStyleSheet,
|
|
|
|
|
aStyleRule);
|
1999-09-21 07:53:49 +00:00
|
|
|
|
VERIFY_STYLE_TREE;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
DidCauseReflow();
|
1999-04-03 18:58:04 +00:00
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
1999-03-10 01:17:49 +00:00
|
|
|
|
// XXX For now reconstruct everything
|
|
|
|
|
return ReconstructFrames();
|
1998-11-26 01:34:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-07-22 23:32:19 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::DocumentWillBeDestroyed(nsIDocument *aDocument)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
1998-06-03 15:46:54 +00:00
|
|
|
|
return NS_OK;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1998-12-29 04:45:18 +00:00
|
|
|
|
NS_IMETHODIMP
|
1999-02-12 17:45:58 +00:00
|
|
|
|
PresShell::GetPrimaryFrameFor(nsIContent* aContent,
|
1999-07-06 03:52:33 +00:00
|
|
|
|
nsIFrame** aResult) const
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
1999-08-05 03:23:39 +00:00
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
|
|
if (mFrameManager) {
|
|
|
|
|
rv = mFrameManager->GetPrimaryFrameFor(aContent, aResult);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
*aResult = nsnull;
|
|
|
|
|
rv = NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rv;
|
1998-04-13 20:24:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
1999-02-25 19:55:06 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetStyleContextFor(nsIFrame* aFrame,
|
|
|
|
|
nsIStyleContext** aStyleContext) const
|
|
|
|
|
{
|
|
|
|
|
if (!aFrame || !aStyleContext) {
|
|
|
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
|
}
|
|
|
|
|
return (aFrame->GetStyleContext(aStyleContext));
|
|
|
|
|
}
|
1999-02-10 23:21:22 +00:00
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetLayoutObjectFor(nsIContent* aContent,
|
|
|
|
|
nsISupports** aResult) const
|
|
|
|
|
{
|
|
|
|
|
nsresult result = NS_ERROR_NULL_POINTER;
|
|
|
|
|
if ((nsnull!=aResult) && (nsnull!=aContent))
|
|
|
|
|
{
|
|
|
|
|
*aResult = nsnull;
|
|
|
|
|
nsIFrame *primaryFrame=nsnull;
|
1999-02-12 17:45:58 +00:00
|
|
|
|
result = GetPrimaryFrameFor(aContent, &primaryFrame);
|
1999-02-10 23:21:22 +00:00
|
|
|
|
if ((NS_SUCCEEDED(result)) && (nsnull!=primaryFrame))
|
|
|
|
|
{
|
2000-01-04 20:24:09 +00:00
|
|
|
|
result = primaryFrame->QueryInterface(NS_GET_IID(nsISupports),
|
|
|
|
|
(void**)aResult);
|
1999-02-10 23:21:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
2000-03-03 23:15:29 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetSubShellFor(nsIContent* aContent,
|
|
|
|
|
nsISupports** aResult) const
|
|
|
|
|
{
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aContent);
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
|
*aResult = nsnull;
|
|
|
|
|
|
|
|
|
|
if (mSubShellMap) {
|
|
|
|
|
mSubShellMap->Search(aContent, 0, (void**)aResult);
|
|
|
|
|
if (*aResult) {
|
|
|
|
|
NS_ADDREF(*aResult);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::SetSubShellFor(nsIContent* aContent,
|
|
|
|
|
nsISupports* aSubShell)
|
|
|
|
|
{
|
|
|
|
|
NS_ENSURE_ARG_POINTER(aContent);
|
|
|
|
|
|
|
|
|
|
// If aSubShell is NULL, then remove the mapping
|
|
|
|
|
if (!aSubShell) {
|
|
|
|
|
if (mSubShellMap) {
|
|
|
|
|
mSubShellMap->Remove(aContent);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// Create a new DST if necessary
|
|
|
|
|
if (!mSubShellMap) {
|
|
|
|
|
if (!mDSTNodeArena) {
|
|
|
|
|
mDSTNodeArena = nsDST::NewMemoryArena();
|
|
|
|
|
if (!mDSTNodeArena) {
|
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
mSubShellMap = new nsDST(mDSTNodeArena);
|
|
|
|
|
if (!mSubShellMap) {
|
|
|
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add a mapping to the hash table
|
|
|
|
|
mSubShellMap->Insert(aContent, (void*)aSubShell, nsnull);
|
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
1999-02-10 23:21:22 +00:00
|
|
|
|
|
|
|
|
|
|
1998-12-29 03:38:16 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetPlaceholderFrameFor(nsIFrame* aFrame,
|
1999-02-12 17:45:58 +00:00
|
|
|
|
nsIFrame** aResult) const
|
1998-12-29 03:38:16 +00:00
|
|
|
|
{
|
1999-08-05 03:23:39 +00:00
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
|
|
if (mFrameManager) {
|
|
|
|
|
rv = mFrameManager->GetPlaceholderFrameFor(aFrame, aResult);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
*aResult = nsnull;
|
|
|
|
|
rv = NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rv;
|
1998-12-29 03:38:16 +00:00
|
|
|
|
}
|
2001-03-09 03:29:00 +00:00
|
|
|
|
#ifdef IBMBIDI
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::SetCursorBidiLevel(PRUint8 aLevel)
|
|
|
|
|
{
|
|
|
|
|
// If the current level is undefined, we have just inserted new text.
|
|
|
|
|
// In this case, we don't want to reset the keyboard language
|
|
|
|
|
PRBool afterInsert = mBidiLevel & BIDI_LEVEL_UNDEFINED;
|
|
|
|
|
mBidiLevel = aLevel;
|
|
|
|
|
|
|
|
|
|
// PRBool parityChange = ((mBidiLevel ^ aLevel) & 1); // is the parity of the new level different from the current level?
|
|
|
|
|
// if (parityChange) // if so, change the keyboard language
|
|
|
|
|
if (mBidiKeyboard && !afterInsert)
|
|
|
|
|
mBidiKeyboard->SetLangFromBidiLevel(aLevel);
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetCursorBidiLevel(PRUint8 *aOutLevel)
|
|
|
|
|
{
|
|
|
|
|
if (!aOutLevel) { return NS_ERROR_INVALID_ARG; }
|
|
|
|
|
*aOutLevel = mBidiLevel;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::UndefineCursorBidiLevel()
|
|
|
|
|
{
|
|
|
|
|
mBidiLevel |= BIDI_LEVEL_UNDEFINED;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::BidiStyleChangeReflow()
|
|
|
|
|
{
|
|
|
|
|
// Have the root frame's style context remap its style
|
|
|
|
|
nsIFrame* rootFrame;
|
|
|
|
|
mFrameManager->GetRootFrame(&rootFrame);
|
|
|
|
|
|
|
|
|
|
if (rootFrame) {
|
|
|
|
|
nsIStyleContext* rootStyleContext;
|
|
|
|
|
rootFrame->GetStyleContext(&rootStyleContext);
|
|
|
|
|
rootStyleContext->RemapStyle(mPresContext.get() );
|
|
|
|
|
NS_RELEASE(rootStyleContext);
|
|
|
|
|
|
|
|
|
|
ReconstructFrames();
|
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
#endif // IBMBIDI
|
1998-12-29 03:38:16 +00:00
|
|
|
|
|
1998-08-28 02:54:06 +00:00
|
|
|
|
//nsIViewObserver
|
|
|
|
|
|
2000-04-25 04:43:11 +00:00
|
|
|
|
// If the element is absolutely positioned and has a specified clip rect
|
|
|
|
|
// then it pushes the current rendering context and sets the clip rect.
|
|
|
|
|
// Returns PR_TRUE if the clip rect is set and PR_FALSE otherwise
|
|
|
|
|
static PRBool
|
|
|
|
|
SetClipRect(nsIRenderingContext& aRenderingContext, nsIFrame* aFrame)
|
|
|
|
|
{
|
|
|
|
|
PRBool clipState;
|
|
|
|
|
const nsStyleDisplay* display;
|
|
|
|
|
aFrame->GetStyleData(eStyleStruct_Display, (const nsStyleStruct*&) display);
|
|
|
|
|
const nsStylePosition* position;
|
|
|
|
|
aFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&) position);
|
|
|
|
|
|
|
|
|
|
// 'clip' only applies to absolutely positioned elements, and is
|
|
|
|
|
// relative to the element's border edge. 'clip' applies to the entire
|
|
|
|
|
// element: border, padding, and content areas, and even scrollbars if
|
|
|
|
|
// there are any.
|
|
|
|
|
if (position->IsAbsolutelyPositioned() && (display->mClipFlags & NS_STYLE_CLIP_RECT)) {
|
|
|
|
|
nsSize size;
|
|
|
|
|
|
|
|
|
|
// Start with the 'auto' values and then factor in user specified values
|
|
|
|
|
aFrame->GetSize(size);
|
|
|
|
|
nsRect clipRect(0, 0, size.width, size.height);
|
|
|
|
|
|
|
|
|
|
if (display->mClipFlags & NS_STYLE_CLIP_RECT) {
|
|
|
|
|
if (0 == (NS_STYLE_CLIP_TOP_AUTO & display->mClipFlags)) {
|
|
|
|
|
clipRect.y = display->mClip.y;
|
|
|
|
|
}
|
|
|
|
|
if (0 == (NS_STYLE_CLIP_LEFT_AUTO & display->mClipFlags)) {
|
|
|
|
|
clipRect.x = display->mClip.x;
|
|
|
|
|
}
|
|
|
|
|
if (0 == (NS_STYLE_CLIP_RIGHT_AUTO & display->mClipFlags)) {
|
2000-06-22 05:28:36 +00:00
|
|
|
|
clipRect.width = display->mClip.width;
|
2000-04-25 04:43:11 +00:00
|
|
|
|
}
|
|
|
|
|
if (0 == (NS_STYLE_CLIP_BOTTOM_AUTO & display->mClipFlags)) {
|
2000-06-22 05:28:36 +00:00
|
|
|
|
clipRect.height = display->mClip.height;
|
2000-04-25 04:43:11 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set updated clip-rect into the rendering context
|
|
|
|
|
aRenderingContext.PushState();
|
|
|
|
|
aRenderingContext.SetClipRect(clipRect, nsClipCombine_kIntersect, clipState);
|
|
|
|
|
return PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PR_FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
1998-12-18 15:54:23 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::Paint(nsIView *aView,
|
|
|
|
|
nsIRenderingContext& aRenderingContext,
|
|
|
|
|
const nsRect& aDirtyRect)
|
1998-08-28 02:54:06 +00:00
|
|
|
|
{
|
1998-08-30 19:16:11 +00:00
|
|
|
|
void* clientData;
|
|
|
|
|
nsIFrame* frame;
|
1998-10-30 22:06:14 +00:00
|
|
|
|
nsresult rv = NS_OK;
|
1998-08-28 02:54:06 +00:00
|
|
|
|
|
|
|
|
|
NS_ASSERTION(!(nsnull == aView), "null view");
|
|
|
|
|
|
1998-08-30 19:16:11 +00:00
|
|
|
|
aView->GetClientData(clientData);
|
|
|
|
|
frame = (nsIFrame *)clientData;
|
2001-04-25 19:52:49 +00:00
|
|
|
|
|
1999-09-14 23:43:35 +00:00
|
|
|
|
if (nsnull != frame)
|
|
|
|
|
{
|
2000-06-09 05:07:42 +00:00
|
|
|
|
mCaret->EraseCaret();
|
|
|
|
|
//StCaretHider caretHider(mCaret); // stack-based class hides caret until dtor.
|
1998-08-28 02:54:06 +00:00
|
|
|
|
|
2000-04-25 04:43:11 +00:00
|
|
|
|
// If the frame is absolutely positioned, then the 'clip' property
|
|
|
|
|
// applies
|
|
|
|
|
PRBool setClipRect = SetClipRect(aRenderingContext, frame);
|
|
|
|
|
|
1999-11-24 06:03:41 +00:00
|
|
|
|
rv = frame->Paint(mPresContext, aRenderingContext, aDirtyRect,
|
1999-03-26 00:39:35 +00:00
|
|
|
|
NS_FRAME_PAINT_LAYER_BACKGROUND);
|
1999-11-24 06:03:41 +00:00
|
|
|
|
rv = frame->Paint(mPresContext, aRenderingContext, aDirtyRect,
|
1999-03-26 00:39:35 +00:00
|
|
|
|
NS_FRAME_PAINT_LAYER_FLOATERS);
|
1999-11-24 06:03:41 +00:00
|
|
|
|
rv = frame->Paint(mPresContext, aRenderingContext, aDirtyRect,
|
1999-03-26 00:39:35 +00:00
|
|
|
|
NS_FRAME_PAINT_LAYER_FOREGROUND);
|
1999-09-14 23:43:35 +00:00
|
|
|
|
|
2000-04-25 04:43:11 +00:00
|
|
|
|
if (setClipRect) {
|
|
|
|
|
PRBool clipState;
|
|
|
|
|
aRenderingContext.PopState(clipState);
|
|
|
|
|
}
|
2000-10-11 13:50:45 +00:00
|
|
|
|
|
1998-10-30 22:06:14 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
|
// Draw a border around the frame
|
1999-11-01 22:12:45 +00:00
|
|
|
|
if (nsIFrameDebug::GetShowFrameBorders()) {
|
1998-10-30 22:06:14 +00:00
|
|
|
|
nsRect r;
|
|
|
|
|
frame->GetRect(r);
|
|
|
|
|
aRenderingContext.SetColor(NS_RGB(0,0,255));
|
|
|
|
|
aRenderingContext.DrawRect(0, 0, r.width, r.height);
|
|
|
|
|
}
|
2000-02-03 02:49:58 +00:00
|
|
|
|
// Draw a border around the current event target
|
|
|
|
|
if ((nsIFrameDebug::GetShowEventTargetFrameBorder()) && (aView == mCurrentTargetView)) {
|
|
|
|
|
aRenderingContext.SetColor(NS_RGB(128,0,128));
|
|
|
|
|
aRenderingContext.DrawRect(mCurrentTargetRect.x, mCurrentTargetRect.y, mCurrentTargetRect.width, mCurrentTargetRect.height);
|
|
|
|
|
}
|
1998-10-30 22:06:14 +00:00
|
|
|
|
#endif
|
|
|
|
|
}
|
1999-09-14 23:43:35 +00:00
|
|
|
|
|
1998-08-28 02:54:06 +00:00
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
1999-06-15 03:14:28 +00:00
|
|
|
|
nsIFrame*
|
|
|
|
|
PresShell::GetCurrentEventFrame()
|
|
|
|
|
{
|
|
|
|
|
if (!mCurrentEventFrame && mCurrentEventContent) {
|
1999-11-03 07:11:45 +00:00
|
|
|
|
// Make sure the content still has a document reference. If not,
|
|
|
|
|
// then we assume it is no longer in the content tree and the
|
|
|
|
|
// frame shouldn't get an event, nor should we even assume its
|
|
|
|
|
// safe to try and find the frame.
|
|
|
|
|
nsCOMPtr<nsIDocument> doc;
|
|
|
|
|
nsresult result = mCurrentEventContent->GetDocument(*getter_AddRefs(doc));
|
|
|
|
|
if (NS_SUCCEEDED(result) && doc) {
|
|
|
|
|
GetPrimaryFrameFor(mCurrentEventContent, &mCurrentEventFrame);
|
|
|
|
|
}
|
1999-06-15 03:14:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mCurrentEventFrame;
|
|
|
|
|
}
|
|
|
|
|
|
2000-06-24 03:58:13 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::GetEventTargetFrame(nsIFrame** aFrame)
|
|
|
|
|
{
|
|
|
|
|
*aFrame = GetCurrentEventFrame();
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
1999-09-02 18:14:01 +00:00
|
|
|
|
void
|
2000-04-24 04:41:27 +00:00
|
|
|
|
PresShell::PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent)
|
1999-09-02 18:14:01 +00:00
|
|
|
|
{
|
2000-04-24 04:41:27 +00:00
|
|
|
|
if (mCurrentEventFrame || mCurrentEventContent) {
|
1999-09-02 18:14:01 +00:00
|
|
|
|
mCurrentEventFrameStack.InsertElementAt((void*)mCurrentEventFrame, 0);
|
2000-04-24 04:41:27 +00:00
|
|
|
|
mCurrentEventContentStack.InsertElementAt((void*)mCurrentEventContent, 0);
|
1999-09-02 18:14:01 +00:00
|
|
|
|
}
|
2000-04-24 04:41:27 +00:00
|
|
|
|
mCurrentEventFrame = aFrame;
|
|
|
|
|
mCurrentEventContent = aContent;
|
|
|
|
|
NS_IF_ADDREF(aContent);
|
1999-09-02 18:14:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2000-04-24 04:41:27 +00:00
|
|
|
|
PresShell::PopCurrentEventInfo()
|
1999-09-02 18:14:01 +00:00
|
|
|
|
{
|
|
|
|
|
mCurrentEventFrame = nsnull;
|
2000-04-24 04:41:27 +00:00
|
|
|
|
NS_IF_RELEASE(mCurrentEventContent);
|
1999-09-02 18:14:01 +00:00
|
|
|
|
|
1999-09-02 19:21:45 +00:00
|
|
|
|
if (0 != mCurrentEventFrameStack.Count()) {
|
1999-09-02 18:14:01 +00:00
|
|
|
|
mCurrentEventFrame = (nsIFrame*)mCurrentEventFrameStack.ElementAt(0);
|
|
|
|
|
mCurrentEventFrameStack.RemoveElementAt(0);
|
2000-04-24 04:41:27 +00:00
|
|
|
|
mCurrentEventContent = (nsIContent*)mCurrentEventContentStack.ElementAt(0);
|
|
|
|
|
mCurrentEventContentStack.RemoveElementAt(0);
|
1999-09-02 18:14:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-12-18 15:54:23 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::HandleEvent(nsIView *aView,
|
|
|
|
|
nsGUIEvent* aEvent,
|
2000-03-22 02:43:08 +00:00
|
|
|
|
nsEventStatus* aEventStatus,
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
|
PRBool aForceHandle,
|
2000-03-22 02:43:08 +00:00
|
|
|
|
PRBool& aHandled)
|
1998-08-28 02:54:06 +00:00
|
|
|
|
{
|
1998-08-30 19:16:11 +00:00
|
|
|
|
void* clientData;
|
|
|
|
|
nsIFrame* frame;
|
1998-11-21 00:19:36 +00:00
|
|
|
|
nsresult rv = NS_OK;
|
1998-08-28 02:54:06 +00:00
|
|
|
|
|
|
|
|
|
NS_ASSERTION(!(nsnull == aView), "null view");
|
|
|
|
|
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
|
aHandled = PR_TRUE;
|
2000-03-22 02:43:08 +00:00
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
if (mIsDestroying || mIsReflowing) {
|
1998-11-18 05:25:26 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-01 01:01:33 +00:00
|
|
|
|
if (aEvent->eventStructType == NS_ACCESSIBLE_EVENT)
|
|
|
|
|
return HandleEventInternal(aEvent, aView, NS_EVENT_FLAG_INIT, aEventStatus);
|
|
|
|
|
|
|
|
|
|
|
1998-08-30 19:16:11 +00:00
|
|
|
|
aView->GetClientData(clientData);
|
|
|
|
|
frame = (nsIFrame *)clientData;
|
1998-08-28 02:54:06 +00:00
|
|
|
|
|
1999-12-11 00:02:08 +00:00
|
|
|
|
/* if (mSelection && aEvent->eventStructType == NS_KEY_EVENT)
|
1999-09-13 22:19:31 +00:00
|
|
|
|
{//KEY HANDLERS WILL GET RID OF THIS
|
1999-10-26 04:44:41 +00:00
|
|
|
|
if (mDisplayNonTextSelection && NS_SUCCEEDED(mSelection->HandleKeyEvent(mPresContext, aEvent)))
|
1999-09-13 22:19:31 +00:00
|
|
|
|
{
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-12-11 00:02:08 +00:00
|
|
|
|
*/
|
1998-11-18 05:25:26 +00:00
|
|
|
|
if (nsnull != frame) {
|
2000-04-24 04:41:27 +00:00
|
|
|
|
PushCurrentEventInfo(nsnull, nsnull);
|
1999-05-20 23:16:53 +00:00
|
|
|
|
|
1999-07-26 15:02:19 +00:00
|
|
|
|
nsIEventStateManager *manager;
|
|
|
|
|
if (NS_OK == mPresContext->GetEventStateManager(&manager)) {
|
2000-06-07 01:20:13 +00:00
|
|
|
|
//change 6-01-00 mjudge,ftang adding ime as an event that needs focused element
|
|
|
|
|
if (NS_IS_KEY_EVENT(aEvent) || NS_IS_IME_EVENT(aEvent)) {
|
1999-07-26 15:02:19 +00:00
|
|
|
|
//Key events go to the focused frame, not point based.
|
2000-04-24 04:41:27 +00:00
|
|
|
|
manager->GetFocusedContent(&mCurrentEventContent);
|
|
|
|
|
if (mCurrentEventContent)
|
|
|
|
|
GetPrimaryFrameFor(mCurrentEventContent, &mCurrentEventFrame);
|
2000-03-22 02:43:08 +00:00
|
|
|
|
else {
|
|
|
|
|
// XXX This is the way key events seem to work? Why?????
|
|
|
|
|
// They spend time doing calls to GetFrameForPoint with the
|
|
|
|
|
// point as (0,0) (or sometimes something else).
|
|
|
|
|
|
|
|
|
|
// XXX If this code is really going to stay, it should
|
|
|
|
|
// probably go into a separate function, because its just
|
|
|
|
|
// a duplicate of the code a few lines below:
|
|
|
|
|
|
|
|
|
|
// This is because we want to give the point in the same
|
|
|
|
|
// coordinates as the frame's own Rect, so mRect.Contains(aPoint)
|
|
|
|
|
// works. However, this point is relative to the frame's rect, so
|
|
|
|
|
// we need to add on the origin of the rect.
|
2000-08-20 01:14:34 +00:00
|
|
|
|
/* nsPoint eventPoint;
|
2000-03-22 02:43:08 +00:00
|
|
|
|
frame->GetOrigin(eventPoint);
|
|
|
|
|
eventPoint += aEvent->point;
|
|
|
|
|
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_FOREGROUND, &mCurrentEventFrame);
|
|
|
|
|
if (rv != NS_OK) {
|
|
|
|
|
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_FLOATERS, &mCurrentEventFrame);
|
|
|
|
|
if (rv != NS_OK) {
|
|
|
|
|
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_BACKGROUND, &mCurrentEventFrame);
|
|
|
|
|
if (rv != NS_OK) {
|
2000-08-20 01:14:34 +00:00
|
|
|
|
#ifdef XP_MAC*/
|
2000-05-24 08:28:41 +00:00
|
|
|
|
// On the Mac it is possible to be running with no windows open, only the native menu bar.
|
|
|
|
|
// In this situation, we need to handle key board events but there are no frames, so
|
|
|
|
|
// we set mCurrentEventContent and that works itself out in HandleEventInternal.
|
|
|
|
|
mCurrentEventContent = mDocument->GetRootContent();
|
|
|
|
|
mCurrentEventFrame = nsnull;
|
2000-08-20 01:14:34 +00:00
|
|
|
|
/*#else
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
|
if (aForceHandle) {
|
|
|
|
|
mCurrentEventFrame = frame;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mCurrentEventFrame = nsnull;
|
|
|
|
|
}
|
2000-03-22 02:43:08 +00:00
|
|
|
|
aHandled = PR_FALSE;
|
2000-05-24 08:28:41 +00:00
|
|
|
|
#endif
|
2000-03-22 02:43:08 +00:00
|
|
|
|
rv = NS_OK;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-08-20 01:14:34 +00:00
|
|
|
|
*/
|
2000-03-22 02:43:08 +00:00
|
|
|
|
}
|
1999-07-26 15:02:19 +00:00
|
|
|
|
}
|
1999-09-02 18:14:01 +00:00
|
|
|
|
else {
|
2000-03-22 02:43:08 +00:00
|
|
|
|
// This is because we want to give the point in the same
|
|
|
|
|
// coordinates as the frame's own Rect, so mRect.Contains(aPoint)
|
|
|
|
|
// works. However, this point is relative to the frame's rect, so
|
|
|
|
|
// we need to add on the origin of the rect.
|
|
|
|
|
nsPoint eventPoint;
|
|
|
|
|
frame->GetOrigin(eventPoint);
|
|
|
|
|
eventPoint += aEvent->point;
|
|
|
|
|
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_FOREGROUND, &mCurrentEventFrame);
|
|
|
|
|
if (rv != NS_OK) {
|
|
|
|
|
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_FLOATERS, &mCurrentEventFrame);
|
|
|
|
|
if (rv != NS_OK) {
|
|
|
|
|
rv = frame->GetFrameForPoint(mPresContext, eventPoint, NS_FRAME_PAINT_LAYER_BACKGROUND, &mCurrentEventFrame);
|
|
|
|
|
if (rv != NS_OK) {
|
massive landing of joki changes.
Relevant nsbeta3+ bugs 43309, 44503, 2634, 2504,5981, 24698, 25758, 33577,
36062, 36217, 41191, 41491, 42356, 42829, 43016
r=saari (joki code). also been tested by heikki and bryner
2000-08-08 21:31:05 +00:00
|
|
|
|
if (aForceHandle) {
|
|
|
|
|
mCurrentEventFrame = frame;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
mCurrentEventFrame = nsnull;
|
|
|
|
|
}
|
2000-03-22 02:43:08 +00:00
|
|
|
|
aHandled = PR_FALSE;
|
|
|
|
|
rv = NS_OK;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
1999-09-02 18:14:01 +00:00
|
|
|
|
}
|
2000-04-24 04:41:27 +00:00
|
|
|
|
if (GetCurrentEventFrame()) {
|
2000-09-19 21:47:04 +00:00
|
|
|
|
rv = HandleEventInternal(aEvent, aView, NS_EVENT_FLAG_INIT, aEventStatus);
|
1998-11-18 05:25:26 +00:00
|
|
|
|
}
|
1999-07-26 15:02:19 +00:00
|
|
|
|
NS_RELEASE(manager);
|
1998-11-18 05:25:26 +00:00
|
|
|
|
}
|
2000-02-03 02:49:58 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
|
if ((nsIFrameDebug::GetShowEventTargetFrameBorder()) && (GetCurrentEventFrame())) {
|
|
|
|
|
nsIView *oldView = mCurrentTargetView;
|
|
|
|
|
nsPoint offset(0,0);
|
|
|
|
|
nsRect oldTargetRect(mCurrentTargetRect);
|
|
|
|
|
mCurrentEventFrame->GetRect(mCurrentTargetRect);
|
|
|
|
|
mCurrentEventFrame->GetView(mPresContext, &mCurrentTargetView);
|
|
|
|
|
if ( ! mCurrentTargetView ) {
|
|
|
|
|
mCurrentEventFrame->GetOffsetFromView(mPresContext, offset, &mCurrentTargetView);
|
|
|
|
|
}
|
|
|
|
|
if (mCurrentTargetView) {
|
|
|
|
|
mCurrentTargetRect.x = offset.x;
|
|
|
|
|
mCurrentTargetRect.y = offset.y;
|
|
|
|
|
// use aView or mCurrentTargetView??
|
|
|
|
|
if ( (mCurrentTargetRect != oldTargetRect) || (mCurrentTargetView != oldView)) {
|
|
|
|
|
nsIViewManager *vm;
|
|
|
|
|
if ((NS_OK == GetViewManager(&vm)) && vm) {
|
|
|
|
|
vm->UpdateView(mCurrentTargetView,mCurrentTargetRect,0);
|
|
|
|
|
if (oldView)
|
|
|
|
|
vm->UpdateView(oldView,oldTargetRect,0);
|
|
|
|
|
NS_IF_RELEASE(vm);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2000-04-24 04:41:27 +00:00
|
|
|
|
PopCurrentEventInfo();
|
1998-11-18 05:25:26 +00:00
|
|
|
|
}
|
1998-11-21 00:19:36 +00:00
|
|
|
|
else {
|
2000-03-22 02:43:08 +00:00
|
|
|
|
aHandled = PR_FALSE;
|
2000-05-24 08:28:41 +00:00
|
|
|
|
rv = NS_OK;
|
1998-11-21 00:19:36 +00:00
|
|
|
|
}
|
1998-08-28 02:54:06 +00:00
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-24 04:41:27 +00:00
|
|
|
|
NS_IMETHODIMP
|
2000-09-19 21:47:04 +00:00
|
|
|
|
PresShell::HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame, nsIContent* aContent, PRUint32 aFlags, nsEventStatus* aStatus)
|
2000-04-24 04:41:27 +00:00
|
|
|
|
{
|
|
|
|
|
nsresult ret;
|
|
|
|
|
|
|
|
|
|
PushCurrentEventInfo(aFrame, aContent);
|
2000-09-19 21:47:04 +00:00
|
|
|
|
ret = HandleEventInternal(aEvent, nsnull, aFlags, aStatus);
|
2000-04-24 04:41:27 +00:00
|
|
|
|
PopCurrentEventInfo();
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
2000-09-19 21:47:04 +00:00
|
|
|
|
PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView, PRUint32 aFlags, nsEventStatus* aStatus)
|
2000-04-24 04:41:27 +00:00
|
|
|
|
{
|
2001-04-01 01:01:33 +00:00
|
|
|
|
if (aEvent->eventStructType == NS_ACCESSIBLE_EVENT)
|
|
|
|
|
{
|
|
|
|
|
void* clientData;
|
|
|
|
|
aView->GetClientData(clientData);
|
|
|
|
|
nsIFrame* frame = (nsIFrame *)clientData;
|
|
|
|
|
return frame->HandleEvent(mPresContext, (nsGUIEvent*)aEvent, aStatus);
|
|
|
|
|
}
|
|
|
|
|
|
2000-08-10 22:07:33 +00:00
|
|
|
|
nsresult rv = NS_OK;
|
2000-04-24 04:41:27 +00:00
|
|
|
|
|
|
|
|
|
nsIEventStateManager *manager;
|
2000-05-26 00:26:54 +00:00
|
|
|
|
if (NS_OK == mPresContext->GetEventStateManager(&manager) && GetCurrentEventFrame()) {
|
2000-04-24 04:41:27 +00:00
|
|
|
|
//1. Give event to event manager for pre event state changes and generation of synthetic events.
|
|
|
|
|
rv = manager->PreHandleEvent(mPresContext, aEvent, mCurrentEventFrame, aStatus, aView);
|
|
|
|
|
|
|
|
|
|
//2. Give event to the DOM for third party and JS use.
|
|
|
|
|
if ((GetCurrentEventFrame()) && NS_OK == rv) {
|
|
|
|
|
if (mCurrentEventContent) {
|
|
|
|
|
rv = mCurrentEventContent->HandleDOMEvent(mPresContext, aEvent, nsnull,
|
2000-09-19 21:47:04 +00:00
|
|
|
|
aFlags, aStatus);
|
2000-04-24 04:41:27 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
nsIContent* targetContent;
|
|
|
|
|
if (NS_OK == mCurrentEventFrame->GetContentForEvent(mPresContext, aEvent, &targetContent) && nsnull != targetContent) {
|
|
|
|
|
rv = targetContent->HandleDOMEvent(mPresContext, aEvent, nsnull,
|
2000-09-19 21:47:04 +00:00
|
|
|
|
aFlags, aStatus);
|
2000-04-24 04:41:27 +00:00
|
|
|
|
NS_RELEASE(targetContent);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//3. Give event to the Frames for browser default processing.
|
|
|
|
|
// XXX The event isn't translated into the local coordinate space
|
|
|
|
|
// of the frame...
|
|
|
|
|
if (GetCurrentEventFrame() && NS_OK == rv && aEvent->eventStructType != NS_EVENT) {
|
|
|
|
|
rv = mCurrentEventFrame->HandleEvent(mPresContext, (nsGUIEvent*)aEvent, aStatus);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//4. Give event to event manager for post event state changes and generation of synthetic events.
|
|
|
|
|
if ((GetCurrentEventFrame()) && NS_OK == rv) {
|
|
|
|
|
rv = manager->PostHandleEvent(mPresContext, aEvent, mCurrentEventFrame, aStatus, aView);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
NS_RELEASE(manager);
|
|
|
|
|
}
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
2000-06-29 02:02:43 +00:00
|
|
|
|
// Dispatch event to content only (NOT full processing)
|
|
|
|
|
// See also HandleEventWithTarget which does full event processing.
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::HandleDOMEventWithTarget(nsIContent* aTargetContent, nsEvent* aEvent, nsEventStatus* aStatus)
|
|
|
|
|
{
|
|
|
|
|
nsresult ret;
|
|
|
|
|
|
|
|
|
|
PushCurrentEventInfo(nsnull, aTargetContent);
|
|
|
|
|
|
|
|
|
|
// Bug 41013: Check if the event should be dispatched to content.
|
|
|
|
|
// It's possible that we are in the middle of destroying the window
|
|
|
|
|
// and the js context is out of date. This check detects the case
|
|
|
|
|
// that caused a crash in bug 41013, but there may be a better way
|
|
|
|
|
// to handle this situation!
|
|
|
|
|
nsCOMPtr<nsISupports> container;
|
|
|
|
|
ret = mPresContext->GetContainer(getter_AddRefs(container));
|
|
|
|
|
if (NS_SUCCEEDED(ret) && container) {
|
|
|
|
|
|
|
|
|
|
// Dispatch event to content
|
|
|
|
|
ret = aTargetContent->HandleDOMEvent(mPresContext, aEvent, nsnull, NS_EVENT_FLAG_INIT, aStatus);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PopCurrentEventInfo();
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
1998-12-18 15:54:23 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::Scrolled(nsIView *aView)
|
1998-08-28 02:54:06 +00:00
|
|
|
|
{
|
1998-08-30 19:16:11 +00:00
|
|
|
|
void* clientData;
|
|
|
|
|
nsIFrame* frame;
|
1998-08-28 02:54:06 +00:00
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
|
|
NS_ASSERTION(!(nsnull == aView), "null view");
|
|
|
|
|
|
1998-08-30 19:16:11 +00:00
|
|
|
|
aView->GetClientData(clientData);
|
|
|
|
|
frame = (nsIFrame *)clientData;
|
1998-08-28 02:54:06 +00:00
|
|
|
|
|
|
|
|
|
if (nsnull != frame)
|
1998-09-05 20:57:57 +00:00
|
|
|
|
rv = frame->Scrolled(aView);
|
1998-08-28 02:54:06 +00:00
|
|
|
|
else
|
|
|
|
|
rv = NS_OK;
|
|
|
|
|
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
1998-12-18 15:54:23 +00:00
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::ResizeReflow(nsIView *aView, nscoord aWidth, nscoord aHeight)
|
1998-08-28 02:54:06 +00:00
|
|
|
|
{
|
|
|
|
|
return ResizeReflow(aWidth, aHeight);
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
//--------------------------------------------------------
|
|
|
|
|
// Start of protected and private methods on the PresShell
|
|
|
|
|
//--------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
//-------------- Begin Reflow Event Definition ------------------------
|
|
|
|
|
|
|
|
|
|
struct ReflowEvent : public PLEvent {
|
|
|
|
|
ReflowEvent(nsIPresShell* aPresShell);
|
|
|
|
|
~ReflowEvent() { }
|
|
|
|
|
|
|
|
|
|
void HandleEvent() {
|
|
|
|
|
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mPresShell);
|
|
|
|
|
if (presShell) {
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
2001-04-18 06:06:31 +00:00
|
|
|
|
printf("\n*** Handling reflow event: PresShell=%p, event=%p\n", (void*)presShell.get(), (void*)this);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
// XXX Statically cast the pres shell pointer so that we can call
|
|
|
|
|
// protected methods on the pres shell. (the ReflowEvent struct
|
|
|
|
|
// is a friend of the PresShell class)
|
|
|
|
|
PresShell* ps = NS_REINTERPRET_CAST(PresShell*, presShell.get());
|
|
|
|
|
PRBool isBatching;
|
|
|
|
|
ps->SetReflowEventStatus(PR_FALSE);
|
|
|
|
|
ps->GetReflowBatchingStatus(&isBatching);
|
2000-10-24 06:34:01 +00:00
|
|
|
|
if (!isBatching) {
|
|
|
|
|
nsCOMPtr<nsIViewManager> viewManager;
|
|
|
|
|
// Set a kung fu death grip on the view manager associated with the pres shell
|
|
|
|
|
// before processing that pres shell's reflow commands. Fixes bug 54868.
|
|
|
|
|
presShell->GetViewManager(getter_AddRefs(viewManager));
|
|
|
|
|
ps->ProcessReflowCommands(PR_TRUE);
|
|
|
|
|
|
|
|
|
|
// Now, explicitly release the pres shell before the view manager
|
|
|
|
|
presShell = nsnull;
|
|
|
|
|
viewManager = nsnull;
|
|
|
|
|
}
|
2000-04-17 07:13:57 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
mPresShell = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsWeakPtr mPresShell;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void PR_CALLBACK HandlePLEvent(ReflowEvent* aEvent)
|
|
|
|
|
{
|
|
|
|
|
aEvent->HandleEvent();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void PR_CALLBACK DestroyPLEvent(ReflowEvent* aEvent)
|
|
|
|
|
{
|
|
|
|
|
delete aEvent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ReflowEvent::ReflowEvent(nsIPresShell* aPresShell)
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(aPresShell, "Null parameters!");
|
|
|
|
|
|
|
|
|
|
mPresShell = getter_AddRefs(NS_GetWeakReference(aPresShell));
|
|
|
|
|
|
|
|
|
|
PL_InitEvent(this, aPresShell,
|
|
|
|
|
(PLHandleEventProc) ::HandlePLEvent,
|
|
|
|
|
(PLDestroyEventProc) ::DestroyPLEvent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------- End Reflow Event Definition ---------------------------
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
PresShell::PostReflowEvent()
|
|
|
|
|
{
|
|
|
|
|
if (!mPendingReflowEvent && !mIsReflowing && mReflowCommands.Count() > 0) {
|
|
|
|
|
ReflowEvent* ev = new ReflowEvent(NS_STATIC_CAST(nsIPresShell*, this));
|
|
|
|
|
mEventQueue->PostEvent(ev);
|
|
|
|
|
mPendingReflowEvent = PR_TRUE;
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
if (VERIFY_REFLOW_NOISY_RC & gVerifyReflowFlags) {
|
2001-04-18 06:06:31 +00:00
|
|
|
|
printf("\n*** PresShell::PostReflowEvent(), this=%p, event=%p\n", (void*)this, (void*)ev);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
PresShell::WillCauseReflow()
|
|
|
|
|
{
|
|
|
|
|
mViewManager->CacheWidgetChanges(PR_TRUE);
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
PresShell::DidCauseReflow()
|
|
|
|
|
{
|
|
|
|
|
mViewManager->CacheWidgetChanges(PR_FALSE);
|
2000-09-12 00:35:11 +00:00
|
|
|
|
|
2000-09-12 08:59:01 +00:00
|
|
|
|
if (!gAsyncReflowDuringDocLoad && mDocumentLoading) {
|
2000-05-16 01:11:29 +00:00
|
|
|
|
FlushPendingNotifications();
|
|
|
|
|
}
|
2000-09-12 00:35:11 +00:00
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-13 06:38:59 +00:00
|
|
|
|
void
|
|
|
|
|
PresShell::ProcessReflowCommand(nsVoidArray& aQueue,
|
|
|
|
|
PRBool aAccumulateTime,
|
|
|
|
|
nsHTMLReflowMetrics& aDesiredSize,
|
|
|
|
|
nsSize& aMaxSize,
|
|
|
|
|
nsIRenderingContext& aRenderingContext)
|
|
|
|
|
{
|
|
|
|
|
// Use RemoveElementAt in case the reflowcommand dispatches a
|
|
|
|
|
// new one during its execution.
|
|
|
|
|
nsIReflowCommand* rc = (nsIReflowCommand*)aQueue.ElementAt(0);
|
|
|
|
|
aQueue.RemoveElementAt(0);
|
|
|
|
|
|
|
|
|
|
// Dispatch the reflow command
|
|
|
|
|
PRTime beforeReflow, afterReflow;
|
|
|
|
|
if (aAccumulateTime)
|
|
|
|
|
beforeReflow = PR_Now();
|
|
|
|
|
rc->Dispatch(mPresContext, aDesiredSize, aMaxSize, aRenderingContext); // dispatch the reflow command
|
|
|
|
|
if (aAccumulateTime)
|
|
|
|
|
afterReflow = PR_Now();
|
|
|
|
|
|
|
|
|
|
ReflowCommandRemoved(rc);
|
|
|
|
|
NS_RELEASE(rc);
|
|
|
|
|
VERIFY_STYLE_TREE;
|
|
|
|
|
|
|
|
|
|
if (aAccumulateTime) {
|
|
|
|
|
PRInt64 totalTime, diff;
|
|
|
|
|
LL_SUB(diff, afterReflow, beforeReflow);
|
|
|
|
|
|
|
|
|
|
LL_I2L(totalTime, mAccumulatedReflowTime);
|
|
|
|
|
LL_ADD(totalTime, totalTime, diff);
|
|
|
|
|
LL_L2I(mAccumulatedReflowTime, totalTime);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
nsresult
|
|
|
|
|
PresShell::ProcessReflowCommands(PRBool aInterruptible)
|
|
|
|
|
{
|
|
|
|
|
MOZ_TIMER_DEBUGLOG(("Start: Reflow: PresShell::ProcessReflowCommands(), this=%p\n", this));
|
|
|
|
|
MOZ_TIMER_START(mReflowWatch);
|
|
|
|
|
|
|
|
|
|
if (0 != mReflowCommands.Count()) {
|
|
|
|
|
nsHTMLReflowMetrics desiredSize(nsnull);
|
|
|
|
|
nsIRenderingContext* rcx;
|
|
|
|
|
nsIFrame* rootFrame;
|
|
|
|
|
mFrameManager->GetRootFrame(&rootFrame);
|
2001-03-13 06:38:59 +00:00
|
|
|
|
nsSize maxSize;
|
|
|
|
|
rootFrame->GetSize(maxSize);
|
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
nsresult rv=CreateRenderingContext(rootFrame, &rcx);
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
if (GetVerifyReflowEnable()) {
|
|
|
|
|
if (VERIFY_REFLOW_ALL & gVerifyReflowFlags) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("ProcessReflowCommands: begin incremental reflow\n");
|
2000-04-17 07:13:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) {
|
|
|
|
|
PRInt32 i, n = mReflowCommands.Count();
|
2001-04-18 06:06:31 +00:00
|
|
|
|
printf("\nPresShell::ProcessReflowCommands: this=%p, count=%d\n", (void*)this, n);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
|
nsIReflowCommand* rc = (nsIReflowCommand*)
|
|
|
|
|
mReflowCommands.ElementAt(i);
|
|
|
|
|
rc->List(stdout);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
mIsReflowing = PR_TRUE;
|
2001-03-13 06:38:59 +00:00
|
|
|
|
PRInt64 maxTime;
|
2000-04-17 07:13:57 +00:00
|
|
|
|
while (0 != mReflowCommands.Count()) {
|
2001-03-13 06:38:59 +00:00
|
|
|
|
ProcessReflowCommand(mReflowCommands, aInterruptible, desiredSize, maxSize, *rcx);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
if (aInterruptible) {
|
|
|
|
|
LL_I2L(maxTime, gMaxRCProcessingTime);
|
2001-03-13 07:44:46 +00:00
|
|
|
|
PRInt64 temp;
|
|
|
|
|
LL_I2L(temp, mAccumulatedReflowTime);
|
|
|
|
|
if (LL_CMP(temp, >, maxTime))
|
2000-04-17 07:13:57 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
mIsReflowing = PR_FALSE;
|
|
|
|
|
|
2001-03-14 07:47:00 +00:00
|
|
|
|
DoneRemovingReflowCommands();
|
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
if (aInterruptible) {
|
2001-03-13 06:38:59 +00:00
|
|
|
|
// process the timeout reflow commands completely
|
|
|
|
|
// printf("timeout reflows=%d \n", mTimeoutReflowCommands.Count());
|
|
|
|
|
while (0 != mTimeoutReflowCommands.Count()) {
|
|
|
|
|
ProcessReflowCommand(mTimeoutReflowCommands, PR_TRUE, desiredSize, maxSize, *rcx);
|
|
|
|
|
}
|
|
|
|
|
if (mReflowCommands.Count() > 0) { // Reflow Commands are still queued up.
|
|
|
|
|
// Schedule a reflow event to handle the remaining reflow commands asynchronously.
|
2000-04-17 07:13:57 +00:00
|
|
|
|
PostReflowEvent();
|
|
|
|
|
}
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("Time spent in PresShell::ProcessReflowCommands(), this=%p, time=%d micro seconds\n",
|
2001-04-18 06:06:31 +00:00
|
|
|
|
(void*)this, mAccumulatedReflowTime);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
mAccumulatedReflowTime = 0;
|
|
|
|
|
}
|
2001-03-13 06:38:59 +00:00
|
|
|
|
NS_IF_RELEASE(rcx);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
if (VERIFY_REFLOW_DUMP_COMMANDS & gVerifyReflowFlags) {
|
2001-04-18 06:06:31 +00:00
|
|
|
|
printf("\nPresShell::ProcessReflowCommands() finished: this=%p\n", (void*)this);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nsIFrameDebug::GetVerifyTreeEnable()) {
|
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
|
|
|
|
|
if (NS_SUCCEEDED(rootFrame->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
|
(void**)&frameDebug))) {
|
|
|
|
|
frameDebug->VerifyTree();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (GetVerifyReflowEnable()) {
|
|
|
|
|
// First synchronously render what we have so far so that we can
|
|
|
|
|
// see it.
|
|
|
|
|
nsIView* rootView;
|
|
|
|
|
mViewManager->GetRootView(rootView);
|
|
|
|
|
mViewManager->UpdateView(rootView, NS_VMREFRESH_IMMEDIATE);
|
|
|
|
|
|
|
|
|
|
mInVerifyReflow = PR_TRUE;
|
|
|
|
|
PRBool ok = VerifyIncrementalReflow();
|
|
|
|
|
mInVerifyReflow = PR_FALSE;
|
|
|
|
|
if (VERIFY_REFLOW_ALL & gVerifyReflowFlags) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("ProcessReflowCommands: finished (%s)\n",
|
2000-04-17 07:13:57 +00:00
|
|
|
|
ok ? "ok" : "failed");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (0 != mReflowCommands.Count()) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("XXX yikes! reflow commands queued during verify-reflow\n");
|
2000-04-17 07:13:57 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MOZ_TIMER_DEBUGLOG(("Stop: Reflow: PresShell::ProcessReflowCommands(), this=%p\n", this));
|
|
|
|
|
MOZ_TIMER_STOP(mReflowWatch);
|
|
|
|
|
|
2000-06-23 05:15:04 +00:00
|
|
|
|
HandlePostedDOMEvents();
|
|
|
|
|
HandlePostedAttributeChanges();
|
2000-07-13 23:00:59 +00:00
|
|
|
|
HandlePostedReflowCallbacks();
|
2001-04-25 19:52:49 +00:00
|
|
|
|
|
|
|
|
|
if (mShouldUnsuppressPainting && mReflowCommands.Count() == 0) {
|
|
|
|
|
// We only unlock if we're out of reflows. It's pointless
|
|
|
|
|
// to unlock if reflows are still pending, since reflows
|
|
|
|
|
// are just going to thrash the frames around some more. By
|
|
|
|
|
// waiting we avoid an overeager "jitter" effect.
|
|
|
|
|
mShouldUnsuppressPainting = PR_FALSE;
|
|
|
|
|
UnsuppressAndInvalidate();
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-03-13 06:38:59 +00:00
|
|
|
|
nsresult
|
|
|
|
|
PresShell::SendInterruptNotificationTo(nsIFrame* aFrame,
|
|
|
|
|
nsIPresShell::InterruptType aInterruptType)
|
|
|
|
|
{
|
|
|
|
|
// create a reflow command targeted at aFrame
|
|
|
|
|
nsIReflowCommand* reflowCmd;
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
|
|
// Target the reflow comamnd at aFrame
|
|
|
|
|
rv = NS_NewHTMLReflowCommand(&reflowCmd, aFrame,
|
|
|
|
|
nsIReflowCommand::Timeout);
|
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
|
// Add the reflow command
|
|
|
|
|
AppendReflowCommandInternal(reflowCmd, mTimeoutReflowCommands);
|
|
|
|
|
NS_RELEASE(reflowCmd);
|
|
|
|
|
}
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
PresShell::CancelInterruptNotificationTo(nsIFrame* aFrame,
|
|
|
|
|
nsIPresShell:: InterruptType aInterruptType)
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
return CancelReflowCommandInternal(aFrame, nsnull, mTimeoutReflowCommands);
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-17 07:13:57 +00:00
|
|
|
|
nsresult
|
|
|
|
|
PresShell::GetReflowEventStatus(PRBool* aPending)
|
|
|
|
|
{
|
|
|
|
|
if (aPending)
|
|
|
|
|
*aPending = mPendingReflowEvent;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
PresShell::SetReflowEventStatus(PRBool aPending)
|
|
|
|
|
{
|
|
|
|
|
mPendingReflowEvent = aPending;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
PresShell::CloneStyleSet(nsIStyleSet* aSet, nsIStyleSet** aResult)
|
|
|
|
|
{
|
2001-02-19 21:50:04 +00:00
|
|
|
|
nsresult rv;
|
|
|
|
|
nsCOMPtr<nsIStyleSet> clone(do_CreateInstance(kStyleSetCID,&rv));
|
2000-04-17 07:13:57 +00:00
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PRInt32 i, n;
|
|
|
|
|
n = aSet->GetNumberOfOverrideStyleSheets();
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
|
nsIStyleSheet* ss;
|
|
|
|
|
ss = aSet->GetOverrideStyleSheetAt(i);
|
|
|
|
|
if (nsnull != ss) {
|
|
|
|
|
clone->AppendOverrideStyleSheet(ss);
|
|
|
|
|
NS_RELEASE(ss);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
n = aSet->GetNumberOfDocStyleSheets();
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
|
nsIStyleSheet* ss;
|
|
|
|
|
ss = aSet->GetDocStyleSheetAt(i);
|
|
|
|
|
if (nsnull != ss) {
|
|
|
|
|
clone->AddDocStyleSheet(ss, mDocument);
|
|
|
|
|
NS_RELEASE(ss);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
n = aSet->GetNumberOfBackstopStyleSheets();
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
|
nsIStyleSheet* ss;
|
|
|
|
|
ss = aSet->GetBackstopStyleSheetAt(i);
|
|
|
|
|
if (nsnull != ss) {
|
|
|
|
|
clone->AppendBackstopStyleSheet(ss);
|
|
|
|
|
NS_RELEASE(ss);
|
|
|
|
|
}
|
|
|
|
|
}
|
2001-02-19 21:50:04 +00:00
|
|
|
|
*aResult = clone.get();
|
|
|
|
|
NS_ADDREF(*aResult);
|
2000-04-17 07:13:57 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-13 06:38:59 +00:00
|
|
|
|
|
2000-09-12 00:35:11 +00:00
|
|
|
|
nsresult
|
|
|
|
|
PresShell::ReflowCommandAdded(nsIReflowCommand* aRC)
|
|
|
|
|
{
|
|
|
|
|
|
2000-09-12 08:59:01 +00:00
|
|
|
|
if (gAsyncReflowDuringDocLoad) {
|
|
|
|
|
NS_PRECONDITION(mRCCreatedDuringLoad >= 0, "PresShell's reflow command queue is in a bad state.");
|
|
|
|
|
if (mDocumentLoading) {
|
|
|
|
|
PRInt32 flags;
|
|
|
|
|
aRC->GetFlags(&flags);
|
|
|
|
|
flags |= NS_RC_CREATED_DURING_DOCUMENT_LOAD;
|
|
|
|
|
aRC->SetFlags(flags);
|
|
|
|
|
mRCCreatedDuringLoad++;
|
2000-09-12 00:35:11 +00:00
|
|
|
|
|
2001-04-13 23:24:25 +00:00
|
|
|
|
#ifdef PR_LOGGING
|
|
|
|
|
if (PR_LOG_TEST(gLog, PR_LOG_DEBUG)) {
|
|
|
|
|
nsIFrame* target;
|
|
|
|
|
aRC->GetTarget(target);
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIAtom> type;
|
|
|
|
|
target->GetFrameType(getter_AddRefs(type));
|
|
|
|
|
|
|
|
|
|
nsAutoString typeStr;
|
|
|
|
|
type->ToString(typeStr);
|
|
|
|
|
|
|
|
|
|
PR_LOG(gLog, PR_LOG_DEBUG,
|
|
|
|
|
("presshell=%p, ReflowCommandAdded(%p) target=%p[%s] mRCCreatedDuringLoad=%d\n",
|
|
|
|
|
this, aRC, target, NS_ConvertUCS2toUTF8(typeStr).get(), mRCCreatedDuringLoad));
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2000-09-12 08:59:01 +00:00
|
|
|
|
if (!mDummyLayoutRequest) {
|
|
|
|
|
AddDummyLayoutRequest();
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-09-12 00:35:11 +00:00
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
PresShell::ReflowCommandRemoved(nsIReflowCommand* aRC)
|
|
|
|
|
{
|
2000-09-12 08:59:01 +00:00
|
|
|
|
if (gAsyncReflowDuringDocLoad) {
|
|
|
|
|
NS_PRECONDITION(mRCCreatedDuringLoad >= 0, "PresShell's reflow command queue is in a bad state.");
|
|
|
|
|
PRInt32 flags;
|
|
|
|
|
aRC->GetFlags(&flags);
|
|
|
|
|
if (flags & NS_RC_CREATED_DURING_DOCUMENT_LOAD) {
|
|
|
|
|
mRCCreatedDuringLoad--;
|
2001-04-13 23:24:25 +00:00
|
|
|
|
|
|
|
|
|
PR_LOG(gLog, PR_LOG_DEBUG,
|
|
|
|
|
("presshell=%p, ReflowCommandRemoved(%p) mRCCreatedDuringLoad=%d\n",
|
|
|
|
|
this, aRC, mRCCreatedDuringLoad));
|
2000-09-12 08:59:01 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2000-09-12 00:35:11 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-14 07:47:00 +00:00
|
|
|
|
void
|
|
|
|
|
PresShell::DoneRemovingReflowCommands()
|
|
|
|
|
{
|
2001-04-11 03:07:50 +00:00
|
|
|
|
if (mRCCreatedDuringLoad == 0 && mDummyLayoutRequest) {
|
2001-03-14 07:47:00 +00:00
|
|
|
|
RemoveDummyLayoutRequest();
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-09-12 00:35:11 +00:00
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
PresShell::AddDummyLayoutRequest(void)
|
|
|
|
|
{
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
2000-09-12 08:59:01 +00:00
|
|
|
|
if (gAsyncReflowDuringDocLoad) {
|
2000-09-20 07:20:23 +00:00
|
|
|
|
rv = DummyLayoutRequest::Create(getter_AddRefs(mDummyLayoutRequest), this);
|
2000-09-12 00:35:11 +00:00
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
|
2000-09-12 08:59:01 +00:00
|
|
|
|
nsCOMPtr<nsILoadGroup> loadGroup;
|
|
|
|
|
if (mDocument) {
|
|
|
|
|
rv = mDocument->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
}
|
2000-09-12 00:35:11 +00:00
|
|
|
|
|
2000-09-12 08:59:01 +00:00
|
|
|
|
if (loadGroup) {
|
2001-02-21 20:38:08 +00:00
|
|
|
|
nsCOMPtr<nsIChannel> channel = do_QueryInterface(mDummyLayoutRequest);
|
|
|
|
|
rv = channel->SetLoadGroup(loadGroup);
|
2000-09-12 08:59:01 +00:00
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2001-02-21 20:38:08 +00:00
|
|
|
|
rv = loadGroup->AddRequest(mDummyLayoutRequest, nsnull);
|
2000-09-12 08:59:01 +00:00
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-09-12 00:35:11 +00:00
|
|
|
|
|
2001-04-11 03:07:50 +00:00
|
|
|
|
PR_LOG(gLog, PR_LOG_ALWAYS,
|
|
|
|
|
("presshell=%p, Added dummy layout request %p", this, mDummyLayoutRequest.get()));
|
|
|
|
|
}
|
2000-09-12 08:59:01 +00:00
|
|
|
|
}
|
2000-09-12 00:35:11 +00:00
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
PresShell::RemoveDummyLayoutRequest(void)
|
|
|
|
|
{
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
|
2000-09-12 08:59:01 +00:00
|
|
|
|
if (gAsyncReflowDuringDocLoad) {
|
|
|
|
|
nsCOMPtr<nsILoadGroup> loadGroup;
|
|
|
|
|
if (mDocument) {
|
|
|
|
|
rv = mDocument->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
|
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
|
}
|
2000-09-12 00:35:11 +00:00
|
|
|
|
|
2000-09-12 08:59:01 +00:00
|
|
|
|
if (loadGroup && mDummyLayoutRequest) {
|
2001-04-10 06:01:08 +00:00
|
|
|
|
rv = loadGroup->RemoveRequest(mDummyLayoutRequest, nsnull, NS_OK);
|
2000-09-12 08:59:01 +00:00
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
2000-09-12 00:35:11 +00:00
|
|
|
|
|
2001-04-11 03:07:50 +00:00
|
|
|
|
PR_LOG(gLog, PR_LOG_ALWAYS,
|
|
|
|
|
("presshell=%p, Removed dummy layout request %p", this, mDummyLayoutRequest.get()));
|
|
|
|
|
|
2000-09-12 08:59:01 +00:00
|
|
|
|
mDummyLayoutRequest = nsnull;
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-09-12 00:35:11 +00:00
|
|
|
|
return rv;
|
|
|
|
|
}
|
2000-04-17 07:13:57 +00:00
|
|
|
|
|
|
|
|
|
//------------------------------------------------------
|
|
|
|
|
// End of protected and private methods on the PresShell
|
|
|
|
|
//------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// Start of DEBUG only code
|
|
|
|
|
|
1998-07-13 19:49:42 +00:00
|
|
|
|
#ifdef NS_DEBUG
|
|
|
|
|
#include "nsViewsCID.h"
|
|
|
|
|
#include "nsWidgetsCID.h"
|
|
|
|
|
#include "nsIScrollableView.h"
|
|
|
|
|
#include "nsIDeviceContext.h"
|
|
|
|
|
#include "nsIURL.h"
|
1999-04-03 21:54:32 +00:00
|
|
|
|
#include "nsILinkHandler.h"
|
1998-07-13 19:49:42 +00:00
|
|
|
|
|
2000-01-04 20:24:09 +00:00
|
|
|
|
static NS_DEFINE_CID(kViewManagerCID, NS_VIEW_MANAGER_CID);
|
|
|
|
|
static NS_DEFINE_CID(kScrollingViewCID, NS_SCROLLING_VIEW_CID);
|
|
|
|
|
static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID);
|
1998-07-13 19:49:42 +00:00
|
|
|
|
|
|
|
|
|
static void
|
1998-11-25 18:41:02 +00:00
|
|
|
|
LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg)
|
|
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("verifyreflow: ");
|
1998-11-25 18:41:02 +00:00
|
|
|
|
nsAutoString name;
|
|
|
|
|
if (nsnull != k1) {
|
1999-11-01 22:12:45 +00:00
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (NS_SUCCEEDED(k1->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-01 22:12:45 +00:00
|
|
|
|
frameDebug->GetFrameName(name);
|
|
|
|
|
}
|
1998-11-25 18:41:02 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2000-04-03 11:39:09 +00:00
|
|
|
|
name.AssignWithConversion("(null)");
|
1998-11-25 18:41:02 +00:00
|
|
|
|
}
|
2000-10-28 22:17:53 +00:00
|
|
|
|
fputs(name, stdout);
|
|
|
|
|
|
|
|
|
|
printf(" != ");
|
1998-11-25 18:41:02 +00:00
|
|
|
|
|
|
|
|
|
if (nsnull != k2) {
|
1999-11-01 22:12:45 +00:00
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (NS_SUCCEEDED(k2->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-01 22:12:45 +00:00
|
|
|
|
frameDebug->GetFrameName(name);
|
|
|
|
|
}
|
1998-11-25 18:41:02 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2000-04-03 11:39:09 +00:00
|
|
|
|
name.AssignWithConversion("(null)");
|
1998-11-25 18:41:02 +00:00
|
|
|
|
}
|
2000-10-28 22:17:53 +00:00
|
|
|
|
fputs(name, stdout);
|
1998-11-25 18:41:02 +00:00
|
|
|
|
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf(" %s", aMsg);
|
1998-11-25 18:41:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg,
|
|
|
|
|
const nsRect& r1, const nsRect& r2)
|
1998-07-13 19:49:42 +00:00
|
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("VerifyReflow Error:\n");
|
1998-11-19 17:22:29 +00:00
|
|
|
|
nsAutoString name;
|
1999-11-01 22:12:45 +00:00
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (NS_SUCCEEDED(k1->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
|
(void**)&frameDebug))) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
fprintf(stdout, " ");
|
1999-11-01 22:12:45 +00:00
|
|
|
|
frameDebug->GetFrameName(name);
|
2000-10-28 22:17:53 +00:00
|
|
|
|
fputs(name, stdout);
|
2001-04-18 06:06:31 +00:00
|
|
|
|
fprintf(stdout, " %p ", (void*)k1);
|
1999-11-01 22:12:45 +00:00
|
|
|
|
}
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("{%d, %d, %d, %d}", r1.x, r1.y, r1.width, r1.height);
|
1998-11-25 18:41:02 +00:00
|
|
|
|
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf(" != \n");
|
1998-11-25 18:41:02 +00:00
|
|
|
|
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (NS_SUCCEEDED(k2->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
|
(void**)&frameDebug))) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
fprintf(stdout, " ");
|
1999-11-01 22:12:45 +00:00
|
|
|
|
frameDebug->GetFrameName(name);
|
2000-10-28 22:17:53 +00:00
|
|
|
|
fputs(name, stdout);
|
2001-04-18 06:06:31 +00:00
|
|
|
|
fprintf(stdout, " %p ", (void*)k2);
|
1999-11-01 22:12:45 +00:00
|
|
|
|
}
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("{%d, %d, %d, %d}\n", r2.x, r2.y, r2.width, r2.height);
|
1998-11-25 18:41:02 +00:00
|
|
|
|
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf(" %s\n", aMsg);
|
1998-07-13 19:49:42 +00:00
|
|
|
|
}
|
1998-04-13 20:24:54 +00:00
|
|
|
|
|
1999-04-03 18:58:04 +00:00
|
|
|
|
static PRBool
|
2000-03-17 01:50:54 +00:00
|
|
|
|
CompareTrees(nsIPresContext* aFirstPresContext, nsIFrame* aFirstFrame,
|
|
|
|
|
nsIPresContext* aSecondPresContext, nsIFrame* aSecondFrame)
|
1998-04-13 20:24:54 +00:00
|
|
|
|
{
|
2000-03-22 23:19:10 +00:00
|
|
|
|
if (!aFirstPresContext || !aFirstFrame || !aSecondPresContext || !aSecondFrame)
|
|
|
|
|
return PR_TRUE;
|
1999-04-03 18:58:04 +00:00
|
|
|
|
PRBool ok = PR_TRUE;
|
1998-11-25 18:41:02 +00:00
|
|
|
|
nsIAtom* listName = nsnull;
|
|
|
|
|
PRInt32 listIndex = 0;
|
|
|
|
|
do {
|
|
|
|
|
nsIFrame* k1, *k2;
|
2000-03-17 01:50:54 +00:00
|
|
|
|
aFirstFrame->FirstChild(aFirstPresContext, listName, &k1);
|
|
|
|
|
aSecondFrame->FirstChild(aSecondPresContext, listName, &k2);
|
1998-11-25 18:41:02 +00:00
|
|
|
|
PRInt32 l1 = nsContainerFrame::LengthOf(k1);
|
|
|
|
|
PRInt32 l2 = nsContainerFrame::LengthOf(k2);
|
|
|
|
|
if (l1 != l2) {
|
1999-04-03 18:58:04 +00:00
|
|
|
|
ok = PR_FALSE;
|
1998-11-25 18:41:02 +00:00
|
|
|
|
LogVerifyMessage(k1, k2, "child counts don't match: ");
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("%d != %d\n", l1, l2);
|
1999-09-10 18:49:23 +00:00
|
|
|
|
if (0 == (VERIFY_REFLOW_ALL & gVerifyReflowFlags)) {
|
1998-11-25 18:41:02 +00:00
|
|
|
|
break;
|
1998-07-13 19:49:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
1998-11-25 18:41:02 +00:00
|
|
|
|
nsRect r1, r2;
|
|
|
|
|
nsIView* v1, *v2;
|
|
|
|
|
nsIWidget* w1, *w2;
|
|
|
|
|
for (;;) {
|
|
|
|
|
if (((nsnull == k1) && (nsnull != k2)) ||
|
|
|
|
|
((nsnull != k1) && (nsnull == k2))) {
|
1999-04-03 18:58:04 +00:00
|
|
|
|
ok = PR_FALSE;
|
1998-11-25 18:41:02 +00:00
|
|
|
|
LogVerifyMessage(k1, k2, "child lists are different\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (nsnull != k1) {
|
|
|
|
|
// Verify that the frames are the same size
|
|
|
|
|
k1->GetRect(r1);
|
|
|
|
|
k2->GetRect(r2);
|
|
|
|
|
if (r1 != r2) {
|
1999-04-03 18:58:04 +00:00
|
|
|
|
ok = PR_FALSE;
|
1998-11-25 18:41:02 +00:00
|
|
|
|
LogVerifyMessage(k1, k2, "(frame rects)", r1, r2);
|
|
|
|
|
}
|
1998-07-13 19:49:42 +00:00
|
|
|
|
|
1998-11-25 18:41:02 +00:00
|
|
|
|
// Make sure either both have views or neither have views; if they
|
|
|
|
|
// do have views, make sure the views are the same size. If the
|
|
|
|
|
// views have widgets, make sure they both do or neither does. If
|
|
|
|
|
// they do, make sure the widgets are the same size.
|
2000-03-17 01:50:54 +00:00
|
|
|
|
k1->GetView(aFirstPresContext, &v1);
|
|
|
|
|
k2->GetView(aSecondPresContext, &v2);
|
1998-11-25 18:41:02 +00:00
|
|
|
|
if (((nsnull == v1) && (nsnull != v2)) ||
|
|
|
|
|
((nsnull != v1) && (nsnull == v2))) {
|
1999-04-03 18:58:04 +00:00
|
|
|
|
ok = PR_FALSE;
|
1998-11-25 18:41:02 +00:00
|
|
|
|
LogVerifyMessage(k1, k2, "child views are not matched\n");
|
|
|
|
|
}
|
|
|
|
|
else if (nsnull != v1) {
|
|
|
|
|
v1->GetBounds(r1);
|
|
|
|
|
v2->GetBounds(r2);
|
|
|
|
|
if (r1 != r2) {
|
|
|
|
|
LogVerifyMessage(k1, k2, "(view rects)", r1, r2);
|
|
|
|
|
}
|
1998-07-13 19:49:42 +00:00
|
|
|
|
|
1998-11-25 18:41:02 +00:00
|
|
|
|
v1->GetWidget(w1);
|
|
|
|
|
v2->GetWidget(w2);
|
|
|
|
|
if (((nsnull == w1) && (nsnull != w2)) ||
|
|
|
|
|
((nsnull != w1) && (nsnull == w2))) {
|
1999-04-03 18:58:04 +00:00
|
|
|
|
ok = PR_FALSE;
|
1998-11-25 18:41:02 +00:00
|
|
|
|
LogVerifyMessage(k1, k2, "child widgets are not matched\n");
|
|
|
|
|
}
|
|
|
|
|
else if (nsnull != w1) {
|
|
|
|
|
w1->GetBounds(r1);
|
|
|
|
|
w2->GetBounds(r2);
|
|
|
|
|
if (r1 != r2) {
|
|
|
|
|
LogVerifyMessage(k1, k2, "(widget rects)", r1, r2);
|
|
|
|
|
}
|
1998-07-13 19:49:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1999-09-10 18:49:23 +00:00
|
|
|
|
if (!ok && (0 == (VERIFY_REFLOW_ALL & gVerifyReflowFlags))) {
|
1998-11-25 18:41:02 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2000-03-22 23:19:10 +00:00
|
|
|
|
// verify that neither frame has a space manager,
|
|
|
|
|
// or they both do and the space managers are equivalent
|
|
|
|
|
nsCOMPtr<nsIFrameManager>fm1;
|
|
|
|
|
nsCOMPtr<nsIPresShell> ps1;
|
|
|
|
|
nsISpaceManager *sm1; // note, no ref counting here
|
|
|
|
|
aFirstPresContext->GetShell(getter_AddRefs(ps1));
|
|
|
|
|
NS_ASSERTION(ps1, "no pres shell for primary tree!");
|
|
|
|
|
ps1->GetFrameManager(getter_AddRefs(fm1));
|
|
|
|
|
NS_ASSERTION(fm1, "no frame manager for primary tree!");
|
|
|
|
|
fm1->GetFrameProperty((nsIFrame*)k1, nsLayoutAtoms::spaceManagerProperty,
|
|
|
|
|
0, (void **)&sm1);
|
|
|
|
|
// look at the test frame
|
|
|
|
|
nsCOMPtr<nsIFrameManager>fm2;
|
|
|
|
|
nsCOMPtr<nsIPresShell> ps2;
|
|
|
|
|
nsISpaceManager *sm2; // note, no ref counting here
|
|
|
|
|
aSecondPresContext->GetShell(getter_AddRefs(ps2));
|
|
|
|
|
NS_ASSERTION(ps2, "no pres shell for test tree!");
|
|
|
|
|
ps2->GetFrameManager(getter_AddRefs(fm2));
|
|
|
|
|
NS_ASSERTION(fm2, "no frame manager for test tree!");
|
|
|
|
|
fm2->GetFrameProperty((nsIFrame*)k2, nsLayoutAtoms::spaceManagerProperty,
|
|
|
|
|
0, (void **)&sm2);
|
|
|
|
|
// now compare the space managers
|
|
|
|
|
if (((nsnull == sm1) && (nsnull != sm2)) ||
|
|
|
|
|
((nsnull != sm1) && (nsnull == sm2))) { // one is null, and the other is not
|
|
|
|
|
ok = PR_FALSE;
|
|
|
|
|
LogVerifyMessage(k1, k2, "space managers are not matched\n");
|
|
|
|
|
}
|
|
|
|
|
else if (sm1 && sm2) { // both are not null, compare them
|
|
|
|
|
// first, compare yMost
|
|
|
|
|
nscoord yMost1, yMost2;
|
|
|
|
|
nsresult smresult = sm1->YMost(yMost1);
|
|
|
|
|
if (NS_ERROR_ABORT != smresult)
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(smresult), "bad result");
|
|
|
|
|
smresult = sm2->YMost(yMost2);
|
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(smresult), "bad result");
|
|
|
|
|
if (yMost1 != yMost2) {
|
|
|
|
|
LogVerifyMessage(k1, k2, "yMost of space managers differs\n");
|
|
|
|
|
}
|
|
|
|
|
// now compare bands by sampling
|
|
|
|
|
PRInt32 yIncrement = yMost1/100;
|
|
|
|
|
if (0==yIncrement) {
|
|
|
|
|
yIncrement = 1; // guarantee we make progress in the loop below
|
|
|
|
|
}
|
|
|
|
|
nscoord yOffset = 0;
|
|
|
|
|
for ( ; ok && yOffset < yMost1; yOffset += yIncrement)
|
|
|
|
|
{
|
|
|
|
|
nscoord small=5, large=100;
|
|
|
|
|
nsBandData band1, band2;
|
|
|
|
|
nsBandTrapezoid trap1[20], trap2[20];
|
|
|
|
|
band1.mSize = band2.mSize = 20;
|
|
|
|
|
band1.mTrapezoids = trap1;
|
|
|
|
|
band2.mTrapezoids = trap2;
|
|
|
|
|
sm1->GetBandData(yOffset, nsSize(small,small), band1);
|
|
|
|
|
sm2->GetBandData(yOffset, nsSize(small,small), band2);
|
|
|
|
|
if (band1.mCount != band2.mCount)
|
|
|
|
|
{ // count mismatch, stop comparing
|
|
|
|
|
LogVerifyMessage(k1, k2, "band.mCount of space managers differs\n");
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("count1= %d, count2=%d, yOffset = %d, size=%d\n",
|
|
|
|
|
band1.mCount, band2.mCount, yOffset, small);
|
2000-03-22 23:19:10 +00:00
|
|
|
|
ok = PR_FALSE;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else // band counts match, compare individual traps
|
|
|
|
|
{
|
|
|
|
|
PRInt32 trapIndex=0;
|
|
|
|
|
for ( ;trapIndex<band1.mCount; trapIndex++)
|
|
|
|
|
{
|
|
|
|
|
PRBool match = (trap1[trapIndex].EqualGeometry(trap2[trapIndex])) &&
|
|
|
|
|
trap1[trapIndex].mState == trap2[trapIndex].mState;
|
|
|
|
|
if (!match)
|
|
|
|
|
{
|
|
|
|
|
LogVerifyMessage(k1, k2, "band.mTrapezoids of space managers differs\n");
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf ("index %d\n", trapIndex);
|
2000-03-22 23:19:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// test the larger maxSize
|
|
|
|
|
sm1->GetBandData(yOffset, nsSize(large,large), band1);
|
|
|
|
|
sm2->GetBandData(yOffset, nsSize(large,large), band2);
|
|
|
|
|
if (band1.mCount != band2.mCount)
|
|
|
|
|
{ // count mismatch, stop comparing
|
|
|
|
|
LogVerifyMessage(k1, k2, "band.mCount of space managers differs\n");
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("count1= %d, count2=%d, yOffset = %d, size=%d\n",
|
2000-03-22 23:19:10 +00:00
|
|
|
|
band1.mCount, band2.mCount, yOffset, small);
|
|
|
|
|
ok = PR_FALSE;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else // band counts match, compare individual traps
|
|
|
|
|
{
|
|
|
|
|
PRInt32 trapIndex=0;
|
|
|
|
|
for ( ; trapIndex<band1.mCount; trapIndex++)
|
|
|
|
|
{
|
|
|
|
|
PRBool match = (trap1[trapIndex].EqualGeometry(trap2[trapIndex])) &&
|
|
|
|
|
trap1[trapIndex].mState == trap2[trapIndex].mState;
|
|
|
|
|
if (!match)
|
|
|
|
|
{
|
|
|
|
|
LogVerifyMessage(k1, k2, "band.mTrapezoids of space managers differs\n");
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf ("index %d\n", trapIndex);
|
2000-03-22 23:19:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1998-11-25 18:41:02 +00:00
|
|
|
|
// Compare the sub-trees too
|
2000-03-17 01:50:54 +00:00
|
|
|
|
if (!CompareTrees(aFirstPresContext, k1, aSecondPresContext, k2)) {
|
1999-09-10 18:49:23 +00:00
|
|
|
|
ok = PR_FALSE;
|
|
|
|
|
if (0 == (VERIFY_REFLOW_ALL & gVerifyReflowFlags)) {
|
1999-04-03 18:58:04 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
1998-11-25 18:41:02 +00:00
|
|
|
|
|
|
|
|
|
// Advance to next sibling
|
1999-02-10 06:13:38 +00:00
|
|
|
|
k1->GetNextSibling(&k1);
|
|
|
|
|
k2->GetNextSibling(&k2);
|
1998-07-13 19:49:42 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
1998-11-25 18:41:02 +00:00
|
|
|
|
break;
|
1998-07-13 19:49:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
1999-09-10 18:49:23 +00:00
|
|
|
|
if (!ok && (0 == (VERIFY_REFLOW_ALL & gVerifyReflowFlags))) {
|
1998-11-25 18:41:02 +00:00
|
|
|
|
break;
|
1998-07-13 19:49:42 +00:00
|
|
|
|
}
|
1998-11-25 18:41:02 +00:00
|
|
|
|
NS_IF_RELEASE(listName);
|
|
|
|
|
|
|
|
|
|
nsIAtom* listName1;
|
|
|
|
|
nsIAtom* listName2;
|
2000-03-17 01:50:54 +00:00
|
|
|
|
aFirstFrame->GetAdditionalChildListName(listIndex, &listName1);
|
|
|
|
|
aSecondFrame->GetAdditionalChildListName(listIndex, &listName2);
|
1998-11-25 18:41:02 +00:00
|
|
|
|
listIndex++;
|
|
|
|
|
if (listName1 != listName2) {
|
1999-09-10 18:49:23 +00:00
|
|
|
|
if (0 == (VERIFY_REFLOW_ALL & gVerifyReflowFlags)) {
|
|
|
|
|
ok = PR_FALSE;
|
|
|
|
|
}
|
1998-11-25 18:41:02 +00:00
|
|
|
|
LogVerifyMessage(k1, k2, "child list names are not matched: ");
|
|
|
|
|
nsAutoString tmp;
|
|
|
|
|
if (nsnull != listName1) {
|
|
|
|
|
listName1->ToString(tmp);
|
2000-10-28 22:17:53 +00:00
|
|
|
|
fputs(tmp, stdout);
|
1998-11-25 18:41:02 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2000-10-28 22:17:53 +00:00
|
|
|
|
fputs("(null)", stdout);
|
|
|
|
|
printf(" != ");
|
1998-11-25 18:41:02 +00:00
|
|
|
|
if (nsnull != listName2) {
|
|
|
|
|
listName2->ToString(tmp);
|
2000-10-28 22:17:53 +00:00
|
|
|
|
fputs(tmp, stdout);
|
1998-11-25 18:41:02 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
2000-10-28 22:17:53 +00:00
|
|
|
|
fputs("(null)", stdout);
|
|
|
|
|
printf("\n");
|
1998-11-25 18:41:02 +00:00
|
|
|
|
NS_IF_RELEASE(listName1);
|
|
|
|
|
NS_IF_RELEASE(listName2);
|
|
|
|
|
break;
|
1998-07-13 19:49:42 +00:00
|
|
|
|
}
|
1998-11-25 18:41:02 +00:00
|
|
|
|
NS_IF_RELEASE(listName2);
|
|
|
|
|
listName = listName1;
|
1999-04-03 18:58:04 +00:00
|
|
|
|
} while (ok && (listName != nsnull));
|
|
|
|
|
|
|
|
|
|
return ok;
|
|
|
|
|
}
|
1999-11-01 22:12:45 +00:00
|
|
|
|
#endif
|
1999-04-03 18:58:04 +00:00
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
|
static nsIFrame*
|
|
|
|
|
FindTopFrame(nsIFrame* aRoot)
|
|
|
|
|
{
|
|
|
|
|
if (nsnull != aRoot) {
|
|
|
|
|
nsIContent* content;
|
|
|
|
|
aRoot->GetContent(&content);
|
|
|
|
|
if (nsnull != content) {
|
|
|
|
|
nsIAtom* tag;
|
|
|
|
|
content->GetTag(tag);
|
|
|
|
|
if (nsnull != tag) {
|
|
|
|
|
NS_RELEASE(tag);
|
|
|
|
|
NS_RELEASE(content);
|
|
|
|
|
return aRoot;
|
|
|
|
|
}
|
|
|
|
|
NS_RELEASE(content);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Try one of the children
|
|
|
|
|
nsIFrame* kid;
|
|
|
|
|
aRoot->FirstChild(nsnull, &kid);
|
|
|
|
|
while (nsnull != kid) {
|
|
|
|
|
nsIFrame* result = FindTopFrame(kid);
|
|
|
|
|
if (nsnull != result) {
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
kid->GetNextSibling(&kid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return nsnull;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
1998-07-13 19:49:42 +00:00
|
|
|
|
|
1999-11-01 22:12:45 +00:00
|
|
|
|
#ifdef DEBUG
|
1998-07-13 19:49:42 +00:00
|
|
|
|
// After an incremental reflow, we verify the correctness by doing a
|
|
|
|
|
// full reflow into a fresh frame tree.
|
1999-09-10 18:49:23 +00:00
|
|
|
|
PRBool
|
1998-07-13 19:49:42 +00:00
|
|
|
|
PresShell::VerifyIncrementalReflow()
|
|
|
|
|
{
|
2000-04-17 14:40:46 +00:00
|
|
|
|
if (VERIFY_REFLOW_NOISY & gVerifyReflowFlags) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("Building Verification Tree...\n");
|
2000-04-17 14:40:46 +00:00
|
|
|
|
}
|
1998-07-13 19:49:42 +00:00
|
|
|
|
// All the stuff we are creating that needs releasing
|
|
|
|
|
nsIPresContext* cx;
|
|
|
|
|
nsIViewManager* vm;
|
|
|
|
|
nsIPresShell* sh;
|
|
|
|
|
|
|
|
|
|
// Create a presentation context to view the new frame tree
|
|
|
|
|
nsresult rv;
|
1999-02-12 17:45:58 +00:00
|
|
|
|
PRBool isPaginated = PR_FALSE;
|
|
|
|
|
mPresContext->IsPaginated(&isPaginated);
|
|
|
|
|
if (isPaginated) {
|
1998-07-13 19:49:42 +00:00
|
|
|
|
rv = NS_NewPrintPreviewContext(&cx);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
rv = NS_NewGalleyContext(&cx);
|
|
|
|
|
}
|
2000-04-17 07:13:57 +00:00
|
|
|
|
|
1999-04-03 18:58:04 +00:00
|
|
|
|
nsISupports* container;
|
|
|
|
|
if (NS_SUCCEEDED(mPresContext->GetContainer(&container)) &&
|
|
|
|
|
(nsnull != container)) {
|
|
|
|
|
cx->SetContainer(container);
|
1999-04-03 21:54:32 +00:00
|
|
|
|
nsILinkHandler* lh;
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (NS_SUCCEEDED(container->QueryInterface(NS_GET_IID(nsILinkHandler),
|
1999-04-03 21:54:32 +00:00
|
|
|
|
(void**)&lh))) {
|
|
|
|
|
cx->SetLinkHandler(lh);
|
|
|
|
|
NS_RELEASE(lh);
|
|
|
|
|
}
|
1999-04-03 18:58:04 +00:00
|
|
|
|
NS_RELEASE(container);
|
|
|
|
|
}
|
2000-04-17 07:13:57 +00:00
|
|
|
|
|
1998-07-13 19:49:42 +00:00
|
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to create presentation context");
|
1999-02-12 17:45:58 +00:00
|
|
|
|
nsCOMPtr<nsIDeviceContext> dc;
|
|
|
|
|
mPresContext->GetDeviceContext(getter_AddRefs(dc));
|
2000-03-02 07:13:02 +00:00
|
|
|
|
cx->Init(dc);
|
1998-07-13 19:49:42 +00:00
|
|
|
|
|
|
|
|
|
// Get our scrolling preference
|
|
|
|
|
nsScrollPreference scrolling;
|
1998-08-28 04:56:56 +00:00
|
|
|
|
nsIView* rootView;
|
|
|
|
|
mViewManager->GetRootView(rootView);
|
1998-07-13 19:49:42 +00:00
|
|
|
|
nsIScrollableView* scrollView;
|
2000-01-04 20:24:09 +00:00
|
|
|
|
rv = rootView->QueryInterface(NS_GET_IID(nsIScrollableView),
|
|
|
|
|
(void**)&scrollView);
|
1998-07-13 19:49:42 +00:00
|
|
|
|
if (NS_OK == rv) {
|
1998-08-30 19:16:11 +00:00
|
|
|
|
scrollView->GetScrollPreference(scrolling);
|
1998-07-13 19:49:42 +00:00
|
|
|
|
}
|
1998-08-30 19:16:11 +00:00
|
|
|
|
nsIWidget* rootWidget;
|
|
|
|
|
rootView->GetWidget(rootWidget);
|
1998-07-13 19:49:42 +00:00
|
|
|
|
void* nativeParentWidget = rootWidget->GetNativeData(NS_NATIVE_WIDGET);
|
|
|
|
|
|
|
|
|
|
// Create a new view manager.
|
1999-04-03 18:58:04 +00:00
|
|
|
|
rv = nsComponentManager::CreateInstance(kViewManagerCID, nsnull,
|
2000-01-04 20:24:09 +00:00
|
|
|
|
NS_GET_IID(nsIViewManager),
|
|
|
|
|
(void**) &vm);
|
1999-04-03 18:58:04 +00:00
|
|
|
|
if (NS_FAILED(rv)) {
|
1998-07-13 19:49:42 +00:00
|
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to create view manager");
|
|
|
|
|
}
|
1999-04-03 18:58:04 +00:00
|
|
|
|
rv = vm->Init(dc);
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to init view manager");
|
|
|
|
|
}
|
1998-08-28 02:54:06 +00:00
|
|
|
|
|
1998-07-13 19:49:42 +00:00
|
|
|
|
// Create a child window of the parent that is our "root view/window"
|
|
|
|
|
// Create a view
|
|
|
|
|
nsRect tbounds;
|
|
|
|
|
mPresContext->GetVisibleArea(tbounds);
|
1999-04-03 18:58:04 +00:00
|
|
|
|
nsIView* view;
|
|
|
|
|
rv = nsComponentManager::CreateInstance(kViewCID, nsnull,
|
2000-01-04 20:24:09 +00:00
|
|
|
|
NS_GET_IID(nsIView),
|
|
|
|
|
(void **) &view);
|
1999-04-03 18:58:04 +00:00
|
|
|
|
if (NS_FAILED(rv)) {
|
1998-07-13 19:49:42 +00:00
|
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to create scroll view");
|
|
|
|
|
}
|
1999-04-03 18:58:04 +00:00
|
|
|
|
rv = view->Init(vm, tbounds, nsnull);
|
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to init scroll view");
|
|
|
|
|
}
|
1998-11-04 04:14:10 +00:00
|
|
|
|
|
|
|
|
|
//now create the widget for the view
|
|
|
|
|
rv = view->CreateWidget(kWidgetCID, nsnull, nativeParentWidget);
|
|
|
|
|
if (NS_OK != rv) {
|
|
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to create scroll view widget");
|
|
|
|
|
}
|
|
|
|
|
|
1998-07-13 19:49:42 +00:00
|
|
|
|
// Setup hierarchical relationship in view manager
|
|
|
|
|
vm->SetRootView(view);
|
|
|
|
|
|
|
|
|
|
// Make the new presentation context the same size as our
|
|
|
|
|
// presentation context.
|
|
|
|
|
nsRect r;
|
|
|
|
|
mPresContext->GetVisibleArea(r);
|
|
|
|
|
cx->SetVisibleArea(r);
|
1999-04-03 18:58:04 +00:00
|
|
|
|
|
1998-11-25 18:41:02 +00:00
|
|
|
|
// Create a new presentation shell to view the document. Use the
|
|
|
|
|
// exact same style information that this document has.
|
1999-04-30 09:04:36 +00:00
|
|
|
|
nsCOMPtr<nsIStyleSet> newSet;
|
|
|
|
|
rv = CloneStyleSet(mStyleSet, getter_AddRefs(newSet));
|
1999-04-03 18:58:04 +00:00
|
|
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to clone style set");
|
|
|
|
|
rv = mDocument->CreateShell(cx, vm, newSet, &sh);
|
2000-03-17 01:50:54 +00:00
|
|
|
|
sh->SetVerifyReflowEnable(PR_FALSE); // turn off verify reflow while we're reflowing the test frame tree
|
1998-07-13 19:49:42 +00:00
|
|
|
|
NS_ASSERTION(NS_OK == rv, "failed to create presentation shell");
|
1999-04-03 18:58:04 +00:00
|
|
|
|
vm->SetViewObserver((nsIViewObserver *)((PresShell*)sh));
|
1998-11-25 18:41:02 +00:00
|
|
|
|
sh->InitialReflow(r.width, r.height);
|
2000-03-17 01:50:54 +00:00
|
|
|
|
sh->SetVerifyReflowEnable(PR_TRUE); // turn on verify reflow again now that we're done reflowing the test frame tree
|
2000-04-17 14:40:46 +00:00
|
|
|
|
if (VERIFY_REFLOW_NOISY & gVerifyReflowFlags) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("Verification Tree built, comparing...\n");
|
2000-04-17 14:40:46 +00:00
|
|
|
|
}
|
1998-07-13 19:49:42 +00:00
|
|
|
|
|
|
|
|
|
// Now that the document has been reflowed, use its frame tree to
|
|
|
|
|
// compare against our frame tree.
|
1998-12-29 04:45:18 +00:00
|
|
|
|
nsIFrame* root1;
|
1999-02-12 17:45:58 +00:00
|
|
|
|
GetRootFrame(&root1);
|
1999-04-03 18:58:04 +00:00
|
|
|
|
nsIFrame* root2;
|
1999-02-12 17:45:58 +00:00
|
|
|
|
sh->GetRootFrame(&root2);
|
2000-03-17 01:50:54 +00:00
|
|
|
|
PRBool ok = CompareTrees(mPresContext, root1, cx, root2);
|
1999-09-10 18:49:23 +00:00
|
|
|
|
if (!ok && (VERIFY_REFLOW_NOISY & gVerifyReflowFlags)) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("Verify reflow failed, primary tree:\n");
|
1999-11-01 22:12:45 +00:00
|
|
|
|
nsIFrameDebug* frameDebug;
|
|
|
|
|
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (NS_SUCCEEDED(root1->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-01 22:12:45 +00:00
|
|
|
|
frameDebug->List(mPresContext, stdout, 0);
|
|
|
|
|
}
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("Verification tree:\n");
|
2000-01-04 20:24:09 +00:00
|
|
|
|
if (NS_SUCCEEDED(root2->QueryInterface(NS_GET_IID(nsIFrameDebug),
|
|
|
|
|
(void**)&frameDebug))) {
|
1999-11-01 22:12:45 +00:00
|
|
|
|
frameDebug->List(mPresContext, stdout, 0);
|
|
|
|
|
}
|
1999-04-03 18:58:04 +00:00
|
|
|
|
}
|
1998-07-13 19:49:42 +00:00
|
|
|
|
|
1999-04-20 00:24:21 +00:00
|
|
|
|
cx->Stop();
|
1999-04-03 18:58:04 +00:00
|
|
|
|
cx->SetContainer(nsnull);
|
1998-07-13 19:49:42 +00:00
|
|
|
|
NS_RELEASE(cx);
|
1999-04-03 18:58:04 +00:00
|
|
|
|
sh->EndObservingDocument();
|
1998-07-13 19:49:42 +00:00
|
|
|
|
NS_RELEASE(sh);
|
1999-04-03 18:58:04 +00:00
|
|
|
|
NS_RELEASE(vm);
|
2000-04-17 14:40:46 +00:00
|
|
|
|
if (VERIFY_REFLOW_NOISY & gVerifyReflowFlags) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("Finished Verifying Reflow...\n");
|
2000-04-17 14:40:46 +00:00
|
|
|
|
}
|
1999-09-10 18:49:23 +00:00
|
|
|
|
|
|
|
|
|
return ok;
|
1998-07-13 19:49:42 +00:00
|
|
|
|
}
|
|
|
|
|
#endif
|
1999-10-15 04:29:30 +00:00
|
|
|
|
|
|
|
|
|
// PresShellViewEventListener
|
|
|
|
|
|
|
|
|
|
NS_IMPL_ISUPPORTS2(PresShellViewEventListener, nsIScrollPositionListener, nsICompositeListener)
|
|
|
|
|
|
|
|
|
|
PresShellViewEventListener::PresShellViewEventListener()
|
|
|
|
|
{
|
|
|
|
|
NS_INIT_ISUPPORTS();
|
|
|
|
|
mPresShell = 0;
|
|
|
|
|
mWasVisible = PR_FALSE;
|
|
|
|
|
mCallCount = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PresShellViewEventListener::~PresShellViewEventListener()
|
|
|
|
|
{
|
|
|
|
|
mPresShell = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
PresShellViewEventListener::SetPresShell(nsIPresShell *aPresShell)
|
|
|
|
|
{
|
|
|
|
|
mPresShell = aPresShell;
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
PresShellViewEventListener::HideCaret()
|
|
|
|
|
{
|
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
|
|
if (mPresShell && 0 == mCallCount)
|
|
|
|
|
{
|
2000-04-27 07:37:12 +00:00
|
|
|
|
nsCOMPtr<nsISelectionController> selCon = do_QueryInterface(mPresShell);
|
|
|
|
|
if (selCon)
|
|
|
|
|
{
|
|
|
|
|
result = selCon->GetCaretEnabled(&mWasVisible);
|
1999-10-15 04:29:30 +00:00
|
|
|
|
|
2000-04-27 07:37:12 +00:00
|
|
|
|
if (NS_SUCCEEDED(result) && mWasVisible)
|
|
|
|
|
result = selCon->SetCaretEnabled(PR_FALSE);
|
|
|
|
|
}
|
1999-10-15 04:29:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
++mCallCount;
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsresult
|
|
|
|
|
PresShellViewEventListener::RestoreCaretVisibility()
|
|
|
|
|
{
|
|
|
|
|
nsresult result = NS_OK;
|
|
|
|
|
|
|
|
|
|
--mCallCount;
|
|
|
|
|
|
|
|
|
|
if (mPresShell && 0 == mCallCount && mWasVisible)
|
2000-04-27 07:37:12 +00:00
|
|
|
|
{
|
|
|
|
|
nsCOMPtr<nsISelectionController> selCon = do_QueryInterface(mPresShell);
|
|
|
|
|
if (selCon)
|
|
|
|
|
result = selCon->SetCaretEnabled(PR_TRUE);
|
|
|
|
|
}
|
1999-10-15 04:29:30 +00:00
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShellViewEventListener::ScrollPositionWillChange(nsIScrollableView *aView, nscoord aX, nscoord aY)
|
|
|
|
|
{
|
|
|
|
|
return HideCaret();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShellViewEventListener::ScrollPositionDidChange(nsIScrollableView *aView, nscoord aX, nscoord aY)
|
|
|
|
|
{
|
|
|
|
|
return RestoreCaretVisibility();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShellViewEventListener::WillRefreshRegion(nsIViewManager *aViewManager,
|
|
|
|
|
nsIView *aView,
|
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
|
nsIRegion *aRegion,
|
|
|
|
|
PRUint32 aUpdateFlags)
|
|
|
|
|
{
|
|
|
|
|
return HideCaret();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShellViewEventListener::DidRefreshRegion(nsIViewManager *aViewManager,
|
|
|
|
|
nsIView *aView,
|
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
|
nsIRegion *aRegion,
|
|
|
|
|
PRUint32 aUpdateFlags)
|
|
|
|
|
{
|
|
|
|
|
return RestoreCaretVisibility();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShellViewEventListener::WillRefreshRect(nsIViewManager *aViewManager,
|
|
|
|
|
nsIView *aView,
|
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
|
const nsRect *aRect,
|
|
|
|
|
PRUint32 aUpdateFlags)
|
|
|
|
|
{
|
|
|
|
|
return HideCaret();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShellViewEventListener::DidRefreshRect(nsIViewManager *aViewManager,
|
|
|
|
|
nsIView *aView,
|
|
|
|
|
nsIRenderingContext *aContext,
|
|
|
|
|
const nsRect *aRect,
|
|
|
|
|
PRUint32 aUpdateFlags)
|
|
|
|
|
{
|
|
|
|
|
return RestoreCaretVisibility();
|
|
|
|
|
}
|
2000-02-11 01:21:05 +00:00
|
|
|
|
|
|
|
|
|
// Enable, Disable and Print, Start, Stop and/or Reset the StyleSet watch
|
|
|
|
|
/*static*/
|
|
|
|
|
nsresult CtlStyleWatch(PRUint32 aCtlValue, nsIStyleSet *aStyleSet)
|
|
|
|
|
{
|
|
|
|
|
NS_ASSERTION(aStyleSet!=nsnull,"aStyleSet cannot be null in CtlStyleWatch");
|
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
|
#ifdef MOZ_PERF_METRICS
|
|
|
|
|
if (aStyleSet != nsnull){
|
|
|
|
|
nsCOMPtr<nsITimeRecorder> watch = do_QueryInterface(aStyleSet, &rv);
|
|
|
|
|
if (NS_SUCCEEDED(rv) && watch) {
|
|
|
|
|
if (aCtlValue & kStyleWatchEnable){
|
|
|
|
|
watch->EnableTimer(NS_TIMER_STYLE_RESOLUTION);
|
|
|
|
|
}
|
|
|
|
|
if (aCtlValue & kStyleWatchDisable){
|
|
|
|
|
watch->DisableTimer(NS_TIMER_STYLE_RESOLUTION);
|
|
|
|
|
}
|
|
|
|
|
if (aCtlValue & kStyleWatchPrint){
|
|
|
|
|
watch->PrintTimer(NS_TIMER_STYLE_RESOLUTION);
|
|
|
|
|
}
|
|
|
|
|
if (aCtlValue & kStyleWatchStart){
|
|
|
|
|
watch->StartTimer(NS_TIMER_STYLE_RESOLUTION);
|
|
|
|
|
}
|
|
|
|
|
if (aCtlValue & kStyleWatchStop){
|
|
|
|
|
watch->StopTimer(NS_TIMER_STYLE_RESOLUTION);
|
|
|
|
|
}
|
|
|
|
|
if (aCtlValue & kStyleWatchReset){
|
|
|
|
|
watch->ResetTimer(NS_TIMER_STYLE_RESOLUTION);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
return rv;
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-21 14:59:47 +00:00
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
//=============================================================
|
|
|
|
|
//=============================================================
|
|
|
|
|
//-- Debug Reflow Counts
|
|
|
|
|
//=============================================================
|
|
|
|
|
//=============================================================
|
2000-04-21 14:59:47 +00:00
|
|
|
|
#ifdef MOZ_REFLOW_PERF
|
2000-04-28 23:32:04 +00:00
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::DumpReflows()
|
|
|
|
|
{
|
|
|
|
|
if (mReflowCountMgr) {
|
|
|
|
|
char * uriStr = nsnull;
|
|
|
|
|
if (mDocument) {
|
|
|
|
|
nsIURI * uri = mDocument->GetDocumentURL();
|
|
|
|
|
if (uri) {
|
|
|
|
|
uri->GetPath(&uriStr);
|
|
|
|
|
NS_RELEASE(uri);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
mReflowCountMgr->DisplayTotals(uriStr);
|
|
|
|
|
mReflowCountMgr->DisplayHTMLTotals(uriStr);
|
|
|
|
|
mReflowCountMgr->DisplayDiffsInTotals("Differences");
|
2001-03-20 13:34:17 +00:00
|
|
|
|
if (uriStr) nsCRT::free(uriStr);
|
2000-04-28 23:32:04 +00:00
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-21 14:59:47 +00:00
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP
|
2001-02-22 13:58:17 +00:00
|
|
|
|
PresShell::CountReflows(const char * aName, PRUint32 aType, nsIFrame * aFrame)
|
2000-04-21 14:59:47 +00:00
|
|
|
|
{
|
|
|
|
|
if (mReflowCountMgr) {
|
2001-02-22 13:58:17 +00:00
|
|
|
|
mReflowCountMgr->Add(aName, (nsReflowReason)aType, aFrame);
|
2000-04-21 14:59:47 +00:00
|
|
|
|
}
|
2001-03-13 06:38:59 +00:00
|
|
|
|
|
2000-04-21 14:59:47 +00:00
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::PaintCount(const char * aName, nsIRenderingContext* aRenderingContext, nsIPresContext* aPresContext, nsIFrame * aFrame, PRUint32 aColor)
|
|
|
|
|
{
|
|
|
|
|
if (mReflowCountMgr) {
|
|
|
|
|
mReflowCountMgr->PaintCount(aName, aRenderingContext, aPresContext, aFrame, aColor);
|
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//-------------------------------------------------------------
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
|
PresShell::SetPaintFrameCount(PRBool aPaintFrameCounts)
|
|
|
|
|
{
|
|
|
|
|
if (mReflowCountMgr) {
|
|
|
|
|
mReflowCountMgr->SetPaintFrameCounts(aPaintFrameCounts);
|
|
|
|
|
}
|
|
|
|
|
return NS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-21 14:59:47 +00:00
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
//-- Reflow Counter Classes Impls
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
ReflowCounter::ReflowCounter(ReflowCountMgr * aMgr) :
|
|
|
|
|
mMgr(aMgr)
|
|
|
|
|
{
|
|
|
|
|
ClearTotals();
|
2000-04-28 23:32:04 +00:00
|
|
|
|
SetTotalsCache();
|
2000-04-21 14:59:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
ReflowCounter::~ReflowCounter()
|
|
|
|
|
{
|
2001-03-13 01:47:22 +00:00
|
|
|
|
|
2000-04-21 14:59:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCounter::ClearTotals()
|
|
|
|
|
{
|
|
|
|
|
for (PRUint32 i=0;i<NUM_REFLOW_TYPES;i++) {
|
|
|
|
|
mTotals[i] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-28 23:32:04 +00:00
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCounter::SetTotalsCache()
|
|
|
|
|
{
|
|
|
|
|
for (PRUint32 i=0;i<NUM_REFLOW_TYPES;i++) {
|
|
|
|
|
mCacheTotals[i] = mTotals[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCounter::CalcDiffInTotals()
|
|
|
|
|
{
|
|
|
|
|
for (PRUint32 i=0;i<NUM_REFLOW_TYPES;i++) {
|
|
|
|
|
mCacheTotals[i] = mTotals[i] - mCacheTotals[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-21 14:59:47 +00:00
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCounter::DisplayTotals(const char * aStr)
|
|
|
|
|
{
|
2000-04-28 23:32:04 +00:00
|
|
|
|
DisplayTotals(mTotals, aStr?aStr:"Totals");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCounter::DisplayDiffTotals(const char * aStr)
|
|
|
|
|
{
|
|
|
|
|
DisplayTotals(mCacheTotals, aStr?aStr:"Diff Totals");
|
2000-04-21 14:59:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCounter::DisplayHTMLTotals(const char * aStr)
|
|
|
|
|
{
|
|
|
|
|
DisplayHTMLTotals(mTotals, aStr?aStr:"Totals");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCounter::DisplayTotals(PRUint32 * aArray, const char * aTitle)
|
|
|
|
|
{
|
2000-04-28 23:32:04 +00:00
|
|
|
|
// figure total
|
|
|
|
|
PRUint32 total = 0;
|
|
|
|
|
PRUint32 i;
|
|
|
|
|
for (i=0;i<NUM_REFLOW_TYPES;i++) {
|
|
|
|
|
total += aArray[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (total == 0) {
|
2000-04-21 14:59:47 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ReflowCounter * gTots = (ReflowCounter *)mMgr->LookUp(kGrandTotalsStr);
|
|
|
|
|
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("%25s\t", aTitle);
|
2000-04-21 14:59:47 +00:00
|
|
|
|
for (i=0;i<NUM_REFLOW_TYPES;i++) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("%d\t", aArray[i]);
|
2000-04-21 14:59:47 +00:00
|
|
|
|
if (gTots != this && aArray[i] > 0) {
|
|
|
|
|
gTots->Add((nsReflowReason)i, aArray[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("%d\n", total);
|
2000-04-21 14:59:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCounter::DisplayHTMLTotals(PRUint32 * aArray, const char * aTitle)
|
|
|
|
|
{
|
2000-04-28 23:32:04 +00:00
|
|
|
|
// figure total
|
|
|
|
|
PRUint32 total = 0;
|
|
|
|
|
PRUint32 i;
|
|
|
|
|
for (i=0;i<NUM_REFLOW_TYPES;i++) {
|
|
|
|
|
total += aArray[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (total == 0) {
|
2000-04-21 14:59:47 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2000-04-28 23:32:04 +00:00
|
|
|
|
|
2000-04-21 14:59:47 +00:00
|
|
|
|
ReflowCounter * gTots = (ReflowCounter *)mMgr->LookUp(kGrandTotalsStr);
|
|
|
|
|
FILE * fd = mMgr->GetOutFile();
|
|
|
|
|
if (!fd) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fprintf(fd, "<tr><td><center>%s</center></td>", aTitle);
|
|
|
|
|
for (i=0;i<NUM_REFLOW_TYPES;i++) {
|
|
|
|
|
fprintf(fd, "<td><center>");
|
|
|
|
|
if (aArray[i]) {
|
|
|
|
|
fprintf(fd, "%d", aArray[i]);
|
|
|
|
|
} else {
|
|
|
|
|
fprintf(fd, " ");
|
|
|
|
|
}
|
|
|
|
|
fprintf(fd, "</center></td>");
|
|
|
|
|
if (gTots != this && aArray[i] > 0) {
|
|
|
|
|
gTots->Add((nsReflowReason)i, aArray[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-04-28 23:32:04 +00:00
|
|
|
|
fprintf(fd, "<td><center>%d</center></td></tr>\n", total);
|
2000-04-21 14:59:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
//-- ReflowCountMgr
|
2000-04-21 14:59:47 +00:00
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
ReflowCountMgr::ReflowCountMgr()
|
|
|
|
|
{
|
|
|
|
|
mCounts = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
|
|
|
|
|
PL_CompareValues, nsnull, nsnull);
|
2001-02-22 13:58:17 +00:00
|
|
|
|
mIndiFrameCounts = PL_NewHashTable(10, PL_HashString, PL_CompareStrings,
|
|
|
|
|
PL_CompareValues, nsnull, nsnull);
|
2001-03-13 01:47:22 +00:00
|
|
|
|
mCycledOnce = PR_FALSE;
|
|
|
|
|
mDumpFrameCounts = PR_FALSE;
|
|
|
|
|
mDumpFrameByFrameCounts = PR_FALSE;
|
|
|
|
|
mPaintFrameByFrameCounts = PR_FALSE;
|
2000-04-21 14:59:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
ReflowCountMgr::~ReflowCountMgr()
|
|
|
|
|
{
|
|
|
|
|
CleanUp();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
ReflowCounter * ReflowCountMgr::LookUp(const char * aName)
|
|
|
|
|
{
|
|
|
|
|
if (nsnull != mCounts) {
|
|
|
|
|
ReflowCounter * counter = (ReflowCounter *)PL_HashTableLookup(mCounts, aName);
|
|
|
|
|
return counter;
|
|
|
|
|
}
|
|
|
|
|
return nsnull;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
2001-02-22 13:58:17 +00:00
|
|
|
|
void ReflowCountMgr::Add(const char * aName, nsReflowReason aType, nsIFrame * aFrame)
|
2000-04-21 14:59:47 +00:00
|
|
|
|
{
|
2001-02-22 13:58:17 +00:00
|
|
|
|
NS_ASSERTION(aName != nsnull, "Name shouldn't be null!");
|
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
if (mDumpFrameCounts && nsnull != mCounts) {
|
2000-04-21 14:59:47 +00:00
|
|
|
|
ReflowCounter * counter = (ReflowCounter *)PL_HashTableLookup(mCounts, aName);
|
|
|
|
|
if (counter == nsnull) {
|
|
|
|
|
counter = new ReflowCounter(this);
|
|
|
|
|
NS_ASSERTION(counter != nsnull, "null ptr");
|
|
|
|
|
char * name = nsCRT::strdup(aName);
|
|
|
|
|
NS_ASSERTION(name != nsnull, "null ptr");
|
|
|
|
|
PL_HashTableAdd(mCounts, name, counter);
|
|
|
|
|
}
|
|
|
|
|
counter->Add(aType);
|
|
|
|
|
}
|
2001-02-22 13:58:17 +00:00
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
if ((mDumpFrameByFrameCounts || mPaintFrameByFrameCounts) &&
|
|
|
|
|
nsnull != mIndiFrameCounts &&
|
|
|
|
|
aFrame != nsnull) {
|
2001-02-22 13:58:17 +00:00
|
|
|
|
char * key = new char[16];
|
|
|
|
|
sprintf(key, "%p", aFrame);
|
|
|
|
|
IndiReflowCounter * counter = (IndiReflowCounter *)PL_HashTableLookup(mIndiFrameCounts, key);
|
|
|
|
|
if (counter == nsnull) {
|
|
|
|
|
counter = new IndiReflowCounter(this);
|
|
|
|
|
NS_ASSERTION(counter != nsnull, "null ptr");
|
|
|
|
|
counter->mFrame = aFrame;
|
|
|
|
|
counter->mName.AssignWithConversion(aName);
|
|
|
|
|
PL_HashTableAdd(mIndiFrameCounts, key, counter);
|
|
|
|
|
}
|
|
|
|
|
// this eliminates extra counts from super classes
|
2001-03-13 01:47:22 +00:00
|
|
|
|
if (counter != nsnull && counter->mName.EqualsWithConversion(aName)) {
|
2001-02-22 13:58:17 +00:00
|
|
|
|
counter->mCount++;
|
|
|
|
|
counter->mCounter.Add(aType, 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
2000-04-21 14:59:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-03-13 01:47:22 +00:00
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCountMgr::PaintCount(const char * aName,
|
|
|
|
|
nsIRenderingContext* aRenderingContext,
|
|
|
|
|
nsIPresContext* aPresContext,
|
|
|
|
|
nsIFrame* aFrame,
|
|
|
|
|
PRUint32 aColor)
|
|
|
|
|
{
|
|
|
|
|
if (mPaintFrameByFrameCounts &&
|
|
|
|
|
nsnull != mIndiFrameCounts &&
|
|
|
|
|
aFrame != nsnull) {
|
|
|
|
|
char * key = new char[16];
|
|
|
|
|
sprintf(key, "%p", aFrame);
|
|
|
|
|
IndiReflowCounter * counter = (IndiReflowCounter *)PL_HashTableLookup(mIndiFrameCounts, key);
|
|
|
|
|
if (counter != nsnull && counter->mName.EqualsWithConversion(aName)) {
|
|
|
|
|
aRenderingContext->PushState();
|
|
|
|
|
nsFont font("Times", NS_FONT_STYLE_NORMAL,NS_FONT_VARIANT_NORMAL,
|
|
|
|
|
NS_FONT_WEIGHT_NORMAL,0,NSIntPointsToTwips(8));
|
|
|
|
|
|
|
|
|
|
nsCOMPtr<nsIFontMetrics> fm;
|
|
|
|
|
aPresContext->GetMetricsFor(font, getter_AddRefs(fm));
|
|
|
|
|
aRenderingContext->SetFont(fm);
|
|
|
|
|
char buf[16];
|
|
|
|
|
sprintf(buf, "%d", counter->mCount);
|
|
|
|
|
nscoord width, height;
|
|
|
|
|
aRenderingContext->GetWidth((char*)buf, width);
|
|
|
|
|
fm->GetHeight(height);
|
|
|
|
|
|
|
|
|
|
nsRect r;
|
|
|
|
|
aFrame->GetRect(r);
|
|
|
|
|
|
|
|
|
|
nscoord x = 0;
|
|
|
|
|
PRUint32 color;
|
|
|
|
|
PRUint32 color2;
|
|
|
|
|
if (aColor != 0) {
|
|
|
|
|
color = aColor;
|
|
|
|
|
color2 = NS_RGB(0,0,0);
|
|
|
|
|
} else {
|
|
|
|
|
PRUint8 rc,gc,bc = 0;
|
|
|
|
|
if (counter->mCount < 5) {
|
|
|
|
|
rc = 255;
|
|
|
|
|
gc = 255;
|
|
|
|
|
} else if ( counter->mCount < 11) {
|
|
|
|
|
gc = 255;
|
|
|
|
|
} else {
|
|
|
|
|
rc = 255;
|
|
|
|
|
}
|
|
|
|
|
color = NS_RGB(rc,gc,bc);
|
|
|
|
|
color2 = NS_RGB(rc/2,gc/2,bc/2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsRect rect(0,0, width+15, height+15);
|
|
|
|
|
aRenderingContext->SetColor(NS_RGB(0,0,0));
|
|
|
|
|
aRenderingContext->FillRect(rect);
|
|
|
|
|
aRenderingContext->SetColor(color2);
|
|
|
|
|
aRenderingContext->DrawString(buf, strlen(buf), x+15,15);
|
|
|
|
|
aRenderingContext->SetColor(color);
|
|
|
|
|
aRenderingContext->DrawString(buf, strlen(buf), x,0);
|
|
|
|
|
|
|
|
|
|
PRBool clipEmpty;
|
|
|
|
|
aRenderingContext->PopState(clipEmpty);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-21 14:59:47 +00:00
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
PRIntn ReflowCountMgr::RemoveItems(PLHashEntry *he, PRIntn i, void *arg)
|
|
|
|
|
{
|
|
|
|
|
char *str = (char *)he->key;
|
|
|
|
|
ReflowCounter * counter = (ReflowCounter *)he->value;
|
|
|
|
|
delete counter;
|
|
|
|
|
delete [] str;
|
|
|
|
|
|
|
|
|
|
return HT_ENUMERATE_REMOVE;
|
|
|
|
|
}
|
|
|
|
|
|
2001-02-22 13:58:17 +00:00
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
PRIntn ReflowCountMgr::RemoveIndiItems(PLHashEntry *he, PRIntn i, void *arg)
|
|
|
|
|
{
|
|
|
|
|
char *str = (char *)he->key;
|
|
|
|
|
IndiReflowCounter * counter = (IndiReflowCounter *)he->value;
|
|
|
|
|
delete counter;
|
|
|
|
|
delete [] str;
|
|
|
|
|
|
|
|
|
|
return HT_ENUMERATE_REMOVE;
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-21 14:59:47 +00:00
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCountMgr::CleanUp()
|
|
|
|
|
{
|
|
|
|
|
if (nsnull != mCounts) {
|
|
|
|
|
PL_HashTableEnumerateEntries(mCounts, RemoveItems, nsnull);
|
|
|
|
|
PL_HashTableDestroy(mCounts);
|
|
|
|
|
mCounts = nsnull;
|
2001-03-13 01:47:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (nsnull != mIndiFrameCounts) {
|
|
|
|
|
PL_HashTableEnumerateEntries(mIndiFrameCounts, RemoveIndiItems, nsnull);
|
|
|
|
|
PL_HashTableDestroy(mIndiFrameCounts);
|
|
|
|
|
mIndiFrameCounts = nsnull;
|
2000-04-21 14:59:47 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
PRIntn ReflowCountMgr::DoSingleTotal(PLHashEntry *he, PRIntn i, void *arg)
|
|
|
|
|
{
|
|
|
|
|
char *str = (char *)he->key;
|
|
|
|
|
ReflowCounter * counter = (ReflowCounter *)he->value;
|
|
|
|
|
|
|
|
|
|
counter->DisplayTotals(str);
|
|
|
|
|
|
|
|
|
|
return HT_ENUMERATE_NEXT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCountMgr::DoGrandTotals()
|
|
|
|
|
{
|
|
|
|
|
if (nsnull != mCounts) {
|
|
|
|
|
ReflowCounter * gTots = (ReflowCounter *)PL_HashTableLookup(mCounts, kGrandTotalsStr);
|
|
|
|
|
if (gTots == nsnull) {
|
|
|
|
|
gTots = new ReflowCounter(this);
|
|
|
|
|
PL_HashTableAdd(mCounts, nsCRT::strdup(kGrandTotalsStr), gTots);
|
|
|
|
|
} else {
|
|
|
|
|
gTots->ClearTotals();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char * title[] = {"Init", "Incrm", "Resze", "Style", "Dirty", "Total"};
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("\t\t\t");
|
2000-04-21 14:59:47 +00:00
|
|
|
|
PRUint32 i;
|
|
|
|
|
for (i=0;i<NUM_REFLOW_TYPES+1;i++) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("\t%s", title[i]);
|
2000-04-21 14:59:47 +00:00
|
|
|
|
}
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("\n");
|
2000-04-21 14:59:47 +00:00
|
|
|
|
for (i=0;i<78;i++) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("-");
|
2000-04-21 14:59:47 +00:00
|
|
|
|
}
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("\n");
|
2000-04-21 14:59:47 +00:00
|
|
|
|
PL_HashTableEnumerateEntries(mCounts, DoSingleTotal, this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-02-22 13:58:17 +00:00
|
|
|
|
static void RecurseIndiTotals(nsIPresContext* aPresContext,
|
|
|
|
|
PLHashTable * aHT,
|
|
|
|
|
nsIFrame * aParentFrame,
|
|
|
|
|
PRInt32 aLevel)
|
|
|
|
|
{
|
|
|
|
|
if (aParentFrame == nsnull) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char key[16];
|
|
|
|
|
sprintf(key, "%p", aParentFrame);
|
|
|
|
|
IndiReflowCounter * counter = (IndiReflowCounter *)PL_HashTableLookup(aHT, key);
|
|
|
|
|
if (counter) {
|
|
|
|
|
counter->mHasBeenOutput = PR_TRUE;
|
|
|
|
|
char * name = counter->mName.ToNewCString();
|
|
|
|
|
for (PRInt32 i=0;i<aLevel;i++) printf(" ");
|
|
|
|
|
printf("%s - %p [%d][", name, aParentFrame, counter->mCount);
|
|
|
|
|
for (PRInt32 inx=0;inx<5;inx++) {
|
|
|
|
|
if (inx != 0) printf(",");
|
|
|
|
|
printf("%d", counter->mCounter.GetTotalByType(nsReflowReason(inx)));
|
|
|
|
|
}
|
|
|
|
|
printf("]\n");
|
|
|
|
|
nsMemory::Free(name);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
nsIFrame * child;
|
|
|
|
|
aParentFrame->FirstChild(aPresContext, nsnull, &child);
|
|
|
|
|
while (child) {
|
|
|
|
|
RecurseIndiTotals(aPresContext, aHT, child, aLevel+1);
|
|
|
|
|
child->GetNextSibling(&child);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
PRIntn ReflowCountMgr::DoSingleIndi(PLHashEntry *he, PRIntn i, void *arg)
|
|
|
|
|
{
|
|
|
|
|
char *str = (char *)he->key;
|
|
|
|
|
IndiReflowCounter * counter = (IndiReflowCounter *)he->value;
|
|
|
|
|
if (counter && !counter->mHasBeenOutput) {
|
|
|
|
|
char * name = counter->mName.ToNewCString();
|
|
|
|
|
printf("%s - %p [%d][", name, counter->mFrame, counter->mCount);
|
|
|
|
|
for (PRInt32 inx=0;inx<5;inx++) {
|
|
|
|
|
if (inx != 0) printf(",");
|
|
|
|
|
printf("%d", counter->mCounter.GetTotalByType(nsReflowReason(inx)));
|
|
|
|
|
}
|
|
|
|
|
printf("]\n");
|
|
|
|
|
nsMemory::Free(name);
|
|
|
|
|
}
|
|
|
|
|
return HT_ENUMERATE_NEXT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCountMgr::DoIndiTotalsTree()
|
|
|
|
|
{
|
|
|
|
|
if (nsnull != mCounts) {
|
|
|
|
|
printf("\n------------------------------------------------\n");
|
|
|
|
|
printf("-- Individual Frame Counts\n");
|
|
|
|
|
printf("------------------------------------------------\n");
|
|
|
|
|
|
|
|
|
|
if (mPresShell) {
|
|
|
|
|
nsIFrame * rootFrame;
|
|
|
|
|
mPresShell->GetRootFrame(&rootFrame);
|
|
|
|
|
RecurseIndiTotals(mPresContext, mIndiFrameCounts, rootFrame, 0);
|
|
|
|
|
printf("------------------------------------------------\n");
|
|
|
|
|
printf("-- Individual Counts of Frames not in Root Tree\n");
|
|
|
|
|
printf("------------------------------------------------\n");
|
|
|
|
|
PL_HashTableEnumerateEntries(mIndiFrameCounts, DoSingleIndi, this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-21 14:59:47 +00:00
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
PRIntn ReflowCountMgr::DoSingleHTMLTotal(PLHashEntry *he, PRIntn i, void *arg)
|
|
|
|
|
{
|
|
|
|
|
char *str = (char *)he->key;
|
|
|
|
|
ReflowCounter * counter = (ReflowCounter *)he->value;
|
|
|
|
|
|
|
|
|
|
counter->DisplayHTMLTotals(str);
|
|
|
|
|
|
|
|
|
|
return HT_ENUMERATE_NEXT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCountMgr::DoGrandHTMLTotals()
|
|
|
|
|
{
|
|
|
|
|
if (nsnull != mCounts) {
|
|
|
|
|
ReflowCounter * gTots = (ReflowCounter *)PL_HashTableLookup(mCounts, kGrandTotalsStr);
|
|
|
|
|
if (gTots == nsnull) {
|
|
|
|
|
gTots = new ReflowCounter(this);
|
|
|
|
|
PL_HashTableAdd(mCounts, nsCRT::strdup(kGrandTotalsStr), gTots);
|
|
|
|
|
} else {
|
|
|
|
|
gTots->ClearTotals();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const char * title[] = {"Class", "Init", "Incrm", "Resze", "Style", "Dirty", "Total"};
|
|
|
|
|
fprintf(mFD, "<tr>");
|
|
|
|
|
PRUint32 i;
|
|
|
|
|
for (i=0;i<NUM_REFLOW_TYPES+2;i++) {
|
|
|
|
|
fprintf(mFD, "<td><center><b>%s<b></center></td>", title[i]);
|
|
|
|
|
}
|
|
|
|
|
fprintf(mFD, "</tr>\n");
|
|
|
|
|
PL_HashTableEnumerateEntries(mCounts, DoSingleHTMLTotal, this);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------
|
|
|
|
|
void ReflowCountMgr::DisplayTotals(const char * aStr)
|
|
|
|
|
{
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("%s\n", aStr?aStr:"No name");
|
2001-03-13 01:47:22 +00:00
|
|
|
|
if (mDumpFrameCounts) {
|
|
|
|
|
DoGrandTotals();
|
|
|
|
|
}
|
|
|
|
|
if (mDumpFrameByFrameCounts) {
|
|
|
|
|
DoIndiTotalsTree();
|
|
|
|
|
}
|
2000-04-21 14:59:47 +00:00
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//------------------------------------
|
|
|
|
|
void ReflowCountMgr::DisplayHTMLTotals(const char * aStr)
|
|
|
|
|
{
|
2000-04-28 23:32:04 +00:00
|
|
|
|
#ifdef WIN32x // XXX NOT XP!
|
2000-04-21 14:59:47 +00:00
|
|
|
|
char name[1024];
|
|
|
|
|
|
|
|
|
|
char * sptr = strrchr(aStr, '/');
|
|
|
|
|
if (sptr) {
|
|
|
|
|
sptr++;
|
|
|
|
|
strcpy(name, sptr);
|
|
|
|
|
char * eptr = strrchr(name, '.');
|
|
|
|
|
if (eptr) {
|
|
|
|
|
*eptr = 0;
|
|
|
|
|
}
|
|
|
|
|
strcat(name, "_stats.html");
|
|
|
|
|
}
|
|
|
|
|
mFD = fopen(name, "w");
|
|
|
|
|
if (mFD) {
|
|
|
|
|
fprintf(mFD, "<html><head><title>Reflow Stats</title></head><body>\n");
|
|
|
|
|
const char * title = aStr?aStr:"No name";
|
|
|
|
|
fprintf(mFD, "<center><b>%s</b><br><table border=1 style=\"background-color:#e0e0e0\">", title);
|
|
|
|
|
DoGrandHTMLTotals();
|
|
|
|
|
fprintf(mFD, "</center></table>\n");
|
|
|
|
|
fprintf(mFD, "</body></html>\n");
|
|
|
|
|
fclose(mFD);
|
|
|
|
|
mFD = nsnull;
|
|
|
|
|
}
|
|
|
|
|
#endif // not XP!
|
|
|
|
|
}
|
2000-04-28 23:32:04 +00:00
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
PRIntn ReflowCountMgr::DoClearTotals(PLHashEntry *he, PRIntn i, void *arg)
|
|
|
|
|
{
|
|
|
|
|
ReflowCounter * counter = (ReflowCounter *)he->value;
|
|
|
|
|
counter->ClearTotals();
|
|
|
|
|
|
|
|
|
|
return HT_ENUMERATE_NEXT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCountMgr::ClearTotals()
|
|
|
|
|
{
|
|
|
|
|
PL_HashTableEnumerateEntries(mCounts, DoClearTotals, this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCountMgr::ClearGrandTotals()
|
|
|
|
|
{
|
|
|
|
|
if (nsnull != mCounts) {
|
|
|
|
|
ReflowCounter * gTots = (ReflowCounter *)PL_HashTableLookup(mCounts, kGrandTotalsStr);
|
|
|
|
|
if (gTots == nsnull) {
|
|
|
|
|
gTots = new ReflowCounter(this);
|
|
|
|
|
PL_HashTableAdd(mCounts, nsCRT::strdup(kGrandTotalsStr), gTots);
|
|
|
|
|
} else {
|
|
|
|
|
gTots->ClearTotals();
|
|
|
|
|
gTots->SetTotalsCache();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
PRIntn ReflowCountMgr::DoDisplayDiffTotals(PLHashEntry *he, PRIntn i, void *arg)
|
|
|
|
|
{
|
|
|
|
|
PRBool cycledOnce = (PRBool)arg;
|
|
|
|
|
|
|
|
|
|
char *str = (char *)he->key;
|
|
|
|
|
ReflowCounter * counter = (ReflowCounter *)he->value;
|
|
|
|
|
|
|
|
|
|
if (cycledOnce) {
|
|
|
|
|
counter->CalcDiffInTotals();
|
|
|
|
|
counter->DisplayDiffTotals(str);
|
|
|
|
|
}
|
|
|
|
|
counter->SetTotalsCache();
|
|
|
|
|
|
|
|
|
|
return HT_ENUMERATE_NEXT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------
|
|
|
|
|
void ReflowCountMgr::DisplayDiffsInTotals(const char * aStr)
|
|
|
|
|
{
|
|
|
|
|
if (mCycledOnce) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("Differences\n");
|
2000-04-28 23:32:04 +00:00
|
|
|
|
for (PRInt32 i=0;i<78;i++) {
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("-");
|
2000-04-28 23:32:04 +00:00
|
|
|
|
}
|
2000-10-28 22:17:53 +00:00
|
|
|
|
printf("\n");
|
2000-04-28 23:32:04 +00:00
|
|
|
|
ClearGrandTotals();
|
|
|
|
|
}
|
|
|
|
|
PL_HashTableEnumerateEntries(mCounts, DoDisplayDiffTotals, (void *)mCycledOnce);
|
|
|
|
|
|
|
|
|
|
mCycledOnce = PR_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
2000-04-21 14:59:47 +00:00
|
|
|
|
#endif // MOZ_REFLOW_PERF
|
2000-10-11 08:33:01 +00:00
|
|
|
|
|
|
|
|
|
// make a color string like #RRGGBB
|
|
|
|
|
void ColorToString(nscolor aColor, nsAutoString &aString)
|
|
|
|
|
{
|
|
|
|
|
nsAutoString tmp;
|
|
|
|
|
aString.SetLength(0);
|
|
|
|
|
|
|
|
|
|
// #
|
|
|
|
|
aString.Append(NS_LITERAL_STRING("#"));
|
|
|
|
|
// RR
|
|
|
|
|
tmp.AppendInt((PRInt32)NS_GET_R(aColor), 16);
|
|
|
|
|
if (tmp.Length() < 2) tmp.AppendInt(0,16);
|
|
|
|
|
aString.Append(tmp);
|
|
|
|
|
tmp.SetLength(0);
|
|
|
|
|
// GG
|
|
|
|
|
tmp.AppendInt((PRInt32)NS_GET_G(aColor), 16);
|
|
|
|
|
if (tmp.Length() < 2) tmp.AppendInt(0,16);
|
|
|
|
|
aString.Append(tmp);
|
|
|
|
|
tmp.SetLength(0);
|
|
|
|
|
// BB
|
|
|
|
|
tmp.AppendInt((PRInt32)NS_GET_B(aColor), 16);
|
|
|
|
|
if (tmp.Length() < 2) tmp.AppendInt(0,16);
|
|
|
|
|
aString.Append(tmp);
|
|
|
|
|
}
|
2001-03-13 01:47:22 +00:00
|
|
|
|
|
|
|
|
|
|