下载了一份很久以前泄漏的IE5.0的源代码,虽然已经是很古远的版本了。但是通过调试现有版本浏览器与查看源代码,发现关键部分的差距并不是很大,代码很有参考意义。这里把重要的函数、数据结构摘抄出来以备参考。
1 class NOVTABLE CTreeNode : public CVoid 2 { 3 friend class CTreePos; 4 5 DECLARE_CLASS_TYPES(CTreeNode, CVoid) 6 7 public: 8 DECLARE_MEMCLEAR_NEW_DELETE(); 9 10 CTreeNode(CTreeNode* pParent, CElement* pElement=NULL); 11 12 // Use this to get an interface to the element/node 13 HRESULT GetElementInterface(REFIID riid, void** ppUnk); 14 15 // NOTE: these functions may look like IUnknown functions 16 // but don't make that mistake. They are here to 17 // manage creation of the tearoff to handle all 18 // external references. 19 // These functions should not be called! 20 NV_DECLARE_TEAROFF_METHOD(GetInterface, getinterface, (REFIID riid, LPVOID* ppv)); 21 NV_DECLARE_TEAROFF_METHOD_(ULONG, PutRef, putref, ()); 22 NV_DECLARE_TEAROFF_METHOD_(ULONG, RemoveRef, removeref, ()); 23 24 // These functions are to be used to keep a node/element 25 // combination alive while it may leave the tree. 26 // BEWARE: this may cause the creation of a tearoff. 27 ULONG NodeAddRef(); 28 ULONG NodeRelease(); 29 30 // These functions manage the _fInMarkup bit 31 void PrivateEnterTree(); 32 void PrivateExitTree(); 33 void PrivateMakeDead(); 34 void PrivateMarkupRelease(); 35 36 void SetElement(CElement* pElement); 37 void SetParent(CTreeNode* pNodeParent); 38 39 // Element access and structure methods 40 CElement* Element() { return _pElement; } 41 CElement* SafeElement() { return this?_pElement:NULL; } 42 43 CTreePos* GetBeginPos() { return &_tpBegin; } 44 CTreePos* GetEndPos() { return &_tpEnd; } 45 46 // Context chain access 47 BOOL IsFirstBranch() { return _tpBegin.IsEdgeScope(); } 48 BOOL IsLastBranch() { return _tpEnd.IsEdgeScope(); } 49 CTreeNode* NextBranch(); 50 CTreeNode* PreviousBranch(); 51 52 CDocument* Doc(); 53 54 BOOL IsInMarkup() { return _fInMarkup; } 55 BOOL IsDead() { return ! _fInMarkup; } 56 CRootElement* IsRoot(); 57 CMarkup* GetMarkup(); 58 CRootElement* MarkupRoot(); 59 60 // Does the element that this node points to have currency? 61 BOOL HasCurrency(); 62 63 BOOL IsContainer(); 64 CTreeNode* GetContainerBranch(); 65 CElement* GetContainer() { return GetContainerBranch()->SafeElement(); } 66 67 BOOL SupportsHtml(); 68 69 CTreeNode* Parent() { return _pNodeParent; } 70 71 CTreeNode* Ancestor(ELEMENT_TAG etag); 72 CTreeNode* Ancestor(ELEMENT_TAG* arytag); 73 74 CElement* ZParent() { return ZParentBranch()->SafeElement(); } 75 CTreeNode* ZParentBranch(); 76 77 CElement* RenderParent() { return RenderParentBranch()->SafeElement(); } 78 CTreeNode* RenderParentBranch(); 79 80 CElement* ClipParent() { return ClipParentBranch()->SafeElement(); } 81 CTreeNode* ClipParentBranch(); 82 83 CElement* ScrollingParent() { return ScrollingParentBranch()->SafeElement(); } 84 CTreeNode* ScrollingParentBranch(); 85 86 inline ELEMENT_TAG Tag() { return (ELEMENT_TAG)_etag; } 87 88 ELEMENT_TAG TagType() 89 { 90 switch(_etag) 91 { 92 case ETAG_GENERIC_LITERAL: 93 case ETAG_GENERIC_BUILTIN: 94 return ETAG_GENERIC; 95 default: 96 return (ELEMENT_TAG)_etag; 97 } 98 } 99 100 CTreeNode* GetFirstCommonAncestor(CTreeNode* pNode, CElement* pEltStop); 101 CTreeNode* GetFirstCommonBlockOrLayoutAncestor(CTreeNode* pNodeTwo, CElement* pEltStop); 102 CTreeNode* GetFirstCommonAncestorNode(CTreeNode* pNodeTwo, CElement* pEltStop); 103 104 CTreeNode* SearchBranchForPureBlockElement(CFlowLayout*); 105 CTreeNode* SearchBranchToFlowLayoutForTag(ELEMENT_TAG etag); 106 CTreeNode* SearchBranchToRootForTag(ELEMENT_TAG etag); 107 CTreeNode* SearchBranchToRootForScope(CElement* pElementFindMe); 108 BOOL SearchBranchToRootForNode(CTreeNode* pNodeFindMe); 109 110 CTreeNode* GetCurrentRelativeNode(CElement* pElementFL); 111 112 // The layout attached to the current element may not be accurate, when a 113 // property changes, current element can gain/lose layoutness. When an 114 // element gains/loses layoutness, its layout is created/destroyed lazily. 115 // 116 // So, for the following functions "cur" means return the layout currently 117 // associated with the layout which may not be accurate. "Updated" means 118 // compute the state and return the accurate information. 119 // 120 // Note: Calling "Updated" function may cause the formats to be computed. 121 // 122 // If there is any confusion please talk to (srinib/lylec/brendand) 123 inline CLayout* GetCurLayout(); 124 inline BOOL HasLayout(); 125 126 CLayout* GetCurNearestLayout(); 127 CTreeNode* GetCurNearestLayoutNode(); 128 CElement* GetCurNearestLayoutElement(); 129 130 CLayout* GetCurParentLayout(); 131 CTreeNode* GetCurParentLayoutNode(); 132 CElement* GetCurParentLayoutElement(); 133 134 // the following get functions may create the layout if it is not 135 // created yet. 136 inline CLayout* GetUpdatedLayout(); // checks for NeedsLayout() 137 inline CLayout* GetUpdatedLayoutPtr(); // Call this if NeedsLayout() is already called 138 inline BOOL NeedsLayout(); 139 140 CLayout* GetUpdatedNearestLayout(); 141 CTreeNode* GetUpdatedNearestLayoutNode(); 142 CElement* GetUpdatedNearestLayoutElement(); 143 144 CLayout* GetUpdatedParentLayout(); 145 CTreeNode* GetUpdatedParentLayoutNode(); 146 CElement* GetUpdatedParentLayoutElement(); 147 148 // BUGBUG - these functions should go, we should not need 149 // to know if the element has flowlayout. 150 CFlowLayout* GetFlowLayout(); 151 CTreeNode* GetFlowLayoutNode(); 152 CElement* GetFlowLayoutElement(); 153 CFlowLayout* HasFlowLayout(); 154 155 // Helper methods 156 htmlBlockAlign GetParagraphAlign(BOOL fOuter); 157 htmlControlAlign GetSiteAlign(); 158 159 BOOL IsInlinedElement(); 160 161 BOOL IsPositionStatic(void); 162 BOOL IsPositioned(void); 163 BOOL IsAbsolute(stylePosition st); 164 BOOL IsAbsolute(void); 165 166 BOOL IsAligned(); 167 168 // IsRelative() tells you if the specific element has had a CSS position 169 // property set on it ( by examining _fRelative and _bPositionType on the 170 // FF). It will NOT tell you if something is relative because one of its 171 // ancestors is relative; that information is stored in the CF, and can be 172 // had via IsInheritingRelativeness() 173 BOOL IsRelative(stylePosition st); 174 BOOL IsRelative(void); 175 BOOL IsInheritingRelativeness(void); 176 177 BOOL IsScrollingParent(void); 178 BOOL IsClipParent(void); 179 BOOL IsZParent(void); 180 BOOL IsDisplayNone(void); 181 BOOL IsVisibilityHidden(void); 182 183 // Depth is defined to be 1 plus the count of parents above this element 184 int Depth() const; 185 186 // Format info functions 187 HRESULT CacheNewFormats(CFormatInfo* pCFI); 188 189 void EnsureFormats(); 190 BOOL IsCharFormatValid() { return _iCF>=0; } 191 BOOL IsParaFormatValid() { return _iPF>=0; } 192 BOOL IsFancyFormatValid() { return _iFF>=0; } 193 const CCharFormat* GetCharFormat() { return (_iCF>=0 ? ::GetCharFormatEx(_iCF) : GetCharFormatHelper()); } 194 const CParaFormat* GetParaFormat() { return (_iPF>=0 ? ::GetParaFormatEx(_iPF) : GetParaFormatHelper()); } 195 const CFancyFormat* GetFancyFormat() { return (_iFF>=0 ? ::GetFancyFormatEx(_iFF) : GetFancyFormatHelper()); } 196 const CCharFormat* GetCharFormatHelper(); 197 const CParaFormat* GetParaFormatHelper(); 198 const CFancyFormat* GetFancyFormatHelper(); 199 long GetCharFormatIndex() { return (_iCF>=0 ? _iCF : GetCharFormatIndexHelper()); } 200 long GetParaFormatIndex() { return (_iPF>=0 ? _iPF : GetParaFormatIndexHelper()); } 201 long GetFancyFormatIndex() { return (_iFF>=0 ? _iFF : GetFancyFormatIndexHelper()); } 202 long GetCharFormatIndexHelper(); 203 long GetParaFormatIndexHelper(); 204 long GetFancyFormatIndexHelper(); 205 206 long GetFontHeightInTwips(CUnitValue* pCuv); 207 void GetRelTopLeft(CElement* pElementFL, CParentInfo* ppi, long* pxOffset, long* pyOffset); 208 209 // These GetCascaded methods are taken from style.hdl where they were 210 // originally generated by the PDL parser. 211 CColorValue GetCascadedbackgroundColor(); 212 CColorValue GetCascadedcolor(); 213 CUnitValue GetCascadedletterSpacing(); 214 styleTextTransform GetCascadedtextTransform(); 215 CUnitValue GetCascadedpaddingTop(); 216 CUnitValue GetCascadedpaddingRight(); 217 CUnitValue GetCascadedpaddingBottom(); 218 CUnitValue GetCascadedpaddingLeft(); 219 CColorValue GetCascadedborderTopColor(); 220 CColorValue GetCascadedborderRightColor(); 221 CColorValue GetCascadedborderBottomColor(); 222 CColorValue GetCascadedborderLeftColor(); 223 styleBorderStyle GetCascadedborderTopStyle(); 224 styleBorderStyle GetCascadedborderRightStyle(); 225 styleBorderStyle GetCascadedborderBottomStyle(); 226 styleBorderStyle GetCascadedborderLeftStyle(); 227 CUnitValue GetCascadedborderTopWidth(); 228 CUnitValue GetCascadedborderRightWidth(); 229 CUnitValue GetCascadedborderBottomWidth(); 230 CUnitValue GetCascadedborderLeftWidth(); 231 CUnitValue GetCascadedwidth(); 232 CUnitValue GetCascadedheight(); 233 CUnitValue GetCascadedtop(); 234 CUnitValue GetCascadedbottom(); 235 CUnitValue GetCascadedleft(); 236 CUnitValue GetCascadedright(); 237 styleOverflow GetCascadedoverflowX(); 238 styleOverflow GetCascadedoverflowY(); 239 styleOverflow GetCascadedoverflow(); 240 styleStyleFloat GetCascadedfloat(); 241 stylePosition GetCascadedposition(); 242 long GetCascadedzIndex(); 243 CUnitValue GetCascadedclipTop(); 244 CUnitValue GetCascadedclipLeft(); 245 CUnitValue GetCascadedclipRight(); 246 CUnitValue GetCascadedclipBottom(); 247 BOOL GetCascadedtableLayout(); // fixed - 1, auto - 0 248 BOOL GetCascadedborderCollapse(); // collapse - 1, separate - 0 249 BOOL GetCascadedborderOverride(); 250 WORD GetCascadedfontWeight(); 251 WORD GetCascadedfontHeight(); 252 CUnitValue GetCascadedbackgroundPositionX(); 253 CUnitValue GetCascadedbackgroundPositionY(); 254 BOOL GetCascadedbackgroundRepeatX(); 255 BOOL GetCascadedbackgroundRepeatY(); 256 htmlBlockAlign GetCascadedblockAlign(); 257 styleVisibility GetCascadedvisibility(); 258 styleDisplay GetCascadeddisplay(); 259 BOOL GetCascadedunderline(); 260 styleAccelerator GetCascadedaccelerator(); 261 BOOL GetCascadedoverline(); 262 BOOL GetCascadedstrikeOut(); 263 CUnitValue GetCascadedlineHeight(); 264 CUnitValue GetCascadedtextIndent(); 265 BOOL GetCascadedsubscript(); 266 BOOL GetCascadedsuperscript(); 267 BOOL GetCascadedbackgroundAttachmentFixed(); 268 styleListStyleType GetCascadedlistStyleType(); 269 styleListStylePosition GetCascadedlistStylePosition(); 270 long GetCascadedlistImageCookie(); 271 const TCHAR* GetCascadedfontFaceName(); 272 const TCHAR* GetCascadedfontFamilyName(); 273 BOOL GetCascadedfontItalic(); 274 long GetCascadedbackgroundImageCookie(); 275 BOOL GetCascadedclearLeft(); 276 BOOL GetCascadedclearRight(); 277 styleCursor GetCascadedcursor(); 278 styleTableLayout GetCascadedtableLayoutEnum(); 279 styleBorderCollapse GetCascadedborderCollapseEnum(); 280 styleDir GetCascadedBlockDirection(); 281 styleDir GetCascadeddirection(); 282 styleBidi GetCascadedunicodeBidi(); 283 styleLayoutGridMode GetCascadedlayoutGridMode(); 284 styleLayoutGridType GetCascadedlayoutGridType(); 285 CUnitValue GetCascadedlayoutGridLine(); 286 CUnitValue GetCascadedlayoutGridChar(); 287 LONG GetCascadedtextAutospace(); 288 styleWordBreak GetCascadedwordBreak(); 289 styleLineBreak GetCascadedlineBreak(); 290 styleTextJustify GetCascadedtextJustify(); 291 styleTextJustifyTrim GetCascadedtextJustifyTrim(); 292 CUnitValue GetCascadedmarginTop(); 293 CUnitValue GetCascadedmarginRight(); 294 CUnitValue GetCascadedmarginBottom(); 295 CUnitValue GetCascadedmarginLeft(); 296 CUnitValue GetCascadedtextKashida(); 297 298 // Ref helpers 299 // Right now these just drop right through to the element 300 static void ReplacePtr (CTreeNode** ppNodelhs, CTreeNode* pNoderhs); 301 static void SetPtr (CTreeNode** ppNodelhs, CTreeNode* pNoderhs); 302 static void ClearPtr (CTreeNode** ppNodelhs); 303 static void StealPtrSet (CTreeNode** ppNodelhs, CTreeNode* pNoderhs); 304 static void StealPtrReplace (CTreeNode** ppNodelhs, CTreeNode* pNoderhs); 305 static void ReleasePtr (CTreeNode* pNode); 306 307 // Other helpers 308 void VoidCachedInfo(); 309 void VoidCachedNodeInfo(); 310 void VoidFancyFormat(); 311 312 // Helpers for contained CTreePos's 313 CTreePos* InitBeginPos(BOOL fEdge) 314 { 315 _tpBegin.SetFlags( 316 (_tpBegin.GetFlags()&~(CTreePos::TPF_ETYPE_MASK|CTreePos::TPF_DATA_POS|CTreePos::TPF_EDGE)) 317 | CTreePos::NodeBeg 318 | BOOLFLAG(fEdge, CTreePos::TPF_EDGE)); 319 return &_tpBegin; 320 } 321 322 CTreePos* InitEndPos(BOOL fEdge) 323 { 324 _tpEnd.SetFlags( 325 (_tpEnd.GetFlags()&~(CTreePos::TPF_ETYPE_MASK|CTreePos::TPF_DATA_POS|CTreePos::TPF_EDGE)) 326 | CTreePos::NodeEnd 327 | BOOLFLAG(fEdge, CTreePos::TPF_EDGE)); 328 return &_tpEnd; 329 } 330 331 //+----------------------------------------------------------------------- 332 // 333 // CTreeNode::CLock 334 // 335 //------------------------------------------------------------------------ 336 class CLock 337 { 338 public: 339 DECLARE_MEMALLOC_NEW_DELETE() 340 CLock(CTreeNode* pNode); 341 ~CLock(); 342 343 private: 344 CTreeNode* _pNode; 345 }; 346 347 // Lookaside pointers 348 enum 349 { 350 LOOKASIDE_PRIMARYTEAROFF = 0, 351 LOOKASIDE_CURRENTSTYLE = 1, 352 LOOKASIDE_NODE_NUMBER = 2 353 // *** There are only 2 bits reserved in the node. 354 // *** if you add more lookasides you have to make sure 355 // *** that you make room for those bits. 356 }; 357 358 BOOL HasLookasidePtr(int iPtr) { return (_fHasLookasidePtr&(1<<iPtr)); } 359 void* GetLookasidePtr(int iPtr); 360 HRESULT SetLookasidePtr(int iPtr, void* pv); 361 void* DelLookasidePtr(int iPtr); 362 363 // Primary Tearoff pointer management 364 BOOL HasPrimaryTearoff() { return (HasLookasidePtr(LOOKASIDE_PRIMARYTEAROFF)); } 365 IUnknown* GetPrimaryTearoff() { return ((IUnknown*)GetLookasidePtr(LOOKASIDE_PRIMARYTEAROFF)); } 366 HRESULT SetPrimaryTearoff(IUnknown* pTearoff) { return (SetLookasidePtr(LOOKASIDE_PRIMARYTEAROFF, pTearoff)); } 367 IUnknown* DelPrimaryTearoff() { return ((IUnknown*)DelLookasidePtr(LOOKASIDE_PRIMARYTEAROFF)); } 368 369 // Class Data 370 CElement* _pElement; // The element for this node 371 CTreeNode* _pNodeParent; // The parent in the CTreeNode tree 372 373 // DWORD 1 374 BYTE _etag; // 0-7: element tag 375 BYTE _fFirstCommonAncestorNode : 1; // 8: for finding common ancestor 376 BYTE _fInMarkup : 1; // 9: this node is in a markup and shouldn't die 377 BYTE _fInMarkupDestruction : 1; // 10: Used by CMarkup::DestroySplayTree 378 BYTE _fHasLookasidePtr : 2; // 11-12 Lookaside flags 379 BYTE _fBlockNess : 1; // 13: Cached from format -- valid if _iFF != -1 380 BYTE _fHasLayout : 1; // 14: Cached from format -- valid if _iFF != -1 381 BYTE _fUnused : 1; // 15: Unused 382 383 SHORT _iPF; // 16-31: Paragraph Format 384 385 // DWORD 2 386 SHORT _iCF; // 0-15: Char Format 387 SHORT _iFF; // 16-31: Fancy Format 388 389 protected: 390 // Use GetBeginPos() or GetEndPos() to get at these members 391 CTreePos _tpBegin; // The begin CTreePos for this node 392 CTreePos _tpEnd; // The end CTreePos for this node 393 394 public: 395 // STATIC MEMBERS 396 DECLARE_TEAROFF_TABLE_NAMED(s_apfnNodeVTable) 397 398 private: 399 NO_COPY(CTreeNode); 400 };
1 void CMarkup::FreeTreePos(CTreePos* ptp) 2 { 3 Assert(ptp); 4 5 // set a sentinel to make the traversal terminate 6 ptp->MarkFirst(); 7 ptp->SetNext(NULL); 8 9 // release the subtree, adding its nodes to the free list 10 while(ptp) 11 { 12 if (ptp->FirstChild()) 13 { 14 ptp = ptp->FirstChild(); 15 } 16 else 17 { 18 CTreePos* ptpNext; 19 BOOL fRelease = TRUE; 20 while(fRelease) 21 { 22 fRelease = ptp->IsLastChild(); 23 ptpNext = ptp->Next(); 24 ReleaseTreePos(ptp); 25 ptp = ptpNext; 26 } 27 } 28 } 29 }
1 class CElement : public CBase 2 { 3 DECLARE_CLASS_TYPES(CElement, CBase) 4 5 friend class CDBindMethods; 6 friend class CLayout; 7 friend class CFlowLayout; 8 9 private: 10 DECLARE_MEMCLEAR_NEW_DELETE(); 11 12 public: 13 CElement(ELEMENT_TAG etag, CDocument* pDoc); 14 virtual ~CElement(); 15 16 CDocument* Doc() const { return GetDocPtr(); } 17 18 // creating thunks with AddRef and Release set to peer holder, if present 19 HRESULT CreateTearOffThunk( 20 void* pvObject1, 21 const void* apfn1, 22 IUnknown* pUnkOuter, 23 void** ppvThunk, 24 void* appropdescsInVtblOrder=NULL); 25 26 HRESULT CreateTearOffThunk( 27 void* pvObject1, 28 const void* apfn1, 29 IUnknown* pUnkOuter, 30 void** ppvThunk, 31 void* pvObject2, 32 void* apfn2, 33 DWORD dwMask, 34 const IID* const* apIID, 35 void* appropdescsInVtblOrder=NULL); 36 37 CAttrArray** GetAttrArray() const 38 { 39 return CBase::GetAttrArray(); 40 } 41 void SetAttrArray(CAttrArray* pAA) 42 { 43 CBase::SetAttrArray(pAA); 44 } 45 46 // ********************************************* 47 // 48 // ENUMERATIONS, CLASSES, & STRUCTS 49 // 50 // ********************************************* 51 enum ELEMENTDESC_FLAG 52 { 53 ELEMENTDESC_DONTINHERITSTYLE= (1 << 1), // Do not inherit style from parent 54 ELEMENTDESC_NOANCESTORCLICK = (1 << 2), // We don't want our ancestors to fire clicks 55 ELEMENTDESC_NOTIFYENDPARSE = (1 << 3), // We want to be notified when we're parsed 56 57 ELEMENTDESC_OLESITE = (1 << 4), // class derived from COleSite 58 ELEMENTDESC_OMREADONLY = (1 << 5), // element's value can not be accessed through OM (input/file) 59 ELEMENTDESC_ALLOWSCROLLING = (1 << 6), // allow scrolling 60 ELEMENTDESC_HASDEFDESCENT = (1 << 7), // use 4 pixels descent for default vertical alignment 61 ELEMENTDESC_BODY = (1 << 8), // class is used the BODY element 62 ELEMENTDESC_TEXTSITE = (1 << 9), // class derived from CTxtSite 63 ELEMENTDESC_ANCHOROUT = (1 <<10), // draw anchor border outside site/inside 64 ELEMENTDESC_SHOWTWS = (1 <<11), // show trailing whitespaces 65 ELEMENTDESC_XTAG = (1 <<12), // an xtag - derived from CXElement 66 ELEMENTDESC_NOOFFSETCTX = (1 <<13), // Shift-F10 context menu shows on top-left (not offset) 67 ELEMENTDESC_CARETINS_SL = (1 <<14), // Dont select site after inserting site 68 ELEMENTDESC_CARETINS_DL = (1 <<15), // show caret (SameLine or DifferntLine) 69 ELEMENTDESC_NOSELECT = (1 <<16), // do not select site in edit mode 70 ELEMENTDESC_TABLECELL = (1 <<17), // site is a table cell. Also implies do not 71 // word break before sites. 72 ELEMENTDESC_VPADDING = (1 <<18), // add a pixel vertical padding for this site 73 ELEMENTDESC_EXBORDRINMOV = (1 <<19), // Exclude the border in CSite::Move 74 ELEMENTDESC_DEFAULT = (1 <<20), // acts like a default site to receive return key 75 ELEMENTDESC_CANCEL = (1 <<21), // acts like a cancel site to receive esc key 76 ELEMENTDESC_NOBKGRDRECALC = (1 <<22), // Dis-allow background recalc 77 ELEMENTDESC_NOPCTRESIZE = (1 <<23), // Don't force resize due to percentage height/width 78 ELEMENTDESC_NOLAYOUT = (1 <<24), // element's like script and comment etc. cannot have layout 79 ELEMENTDESC_NEVERSCROLL = (1 <<26), // element can scroll 80 ELEMENTDESC_CANSCROLL = (1 <<27), // element can scroll 81 ELEMENTDESC_LAST = ELEMENTDESC_CANSCROLL, 82 ELEMENTDESC_MAX = LONG_MAX // Force enum to DWORD on Macintosh. 83 }; 84 85 NV_DECLARE_TEAROFF_METHOD(IsEqualObject, isequalobject, (IUnknown* ppunk)); 86 87 // ****************************************** 88 // 89 // Virtual overrides 90 // 91 // ****************************************** 92 virtual void Passivate(); 93 94 DECLARE_PLAIN_IUNKNOWN(CElement); 95 96 STDMETHOD(PrivateQueryInterface)(REFIID, void**); 97 STDMETHOD_(ULONG, PrivateAddRef)(); 98 STDMETHOD_(ULONG, PrivateRelease)(); 99 100 void PrivateEnterTree(); 101 void PrivateExitTree(CMarkup* pMarkupOld); 102 103 virtual HRESULT OnPropertyChange(DISPID dispid, DWORD dwFlags); 104 105 virtual HRESULT GetNaturalExtent(DWORD dwExtentMode, SIZEL* psizel) { return E_FAIL; } 106 107 typedef enum 108 { 109 GETINFO_ISCOMPLETED, // Has loading of an element completed 110 GETINFO_HISTORYCODE // Code used to validate history 111 } GETINFO; 112 113 virtual DWORD GetInfo(GETINFO gi); 114 115 DWORD HistoryCode() { return GetInfo(GETINFO_HISTORYCODE); } 116 117 NV_DECLARE_TEAROFF_METHOD(get_tabIndex, GET_tabIndex, (short*)); 118 119 // The dir property is declared baseimplementation in the pdl. 120 // We need prototype here 121 NV_DECLARE_TEAROFF_METHOD(put_dir, PUT_dir, (BSTR v)); 122 NV_DECLARE_TEAROFF_METHOD(get_dir, GET_dir, (BSTR* p)); 123 124 // these delegaters implement redirection to the window object 125 NV_DECLARE_TEAROFF_METHOD(get_onload, GET_onload, (VARIANT*)); 126 NV_DECLARE_TEAROFF_METHOD(put_onload, PUT_onload, (VARIANT)); 127 NV_DECLARE_TEAROFF_METHOD(get_onunload, GET_onunload, (VARIANT*)); 128 NV_DECLARE_TEAROFF_METHOD(put_onunload, PUT_onunload, (VARIANT)); 129 NV_DECLARE_TEAROFF_METHOD(get_onfocus, GET_onfocus, (VARIANT*)); 130 NV_DECLARE_TEAROFF_METHOD(put_onfocus, PUT_onfocus, (VARIANT)); 131 NV_DECLARE_TEAROFF_METHOD(get_onblur, GET_onblur, (VARIANT*)); 132 NV_DECLARE_TEAROFF_METHOD(put_onblur, PUT_onblur, (VARIANT)); 133 NV_DECLARE_TEAROFF_METHOD(get_onbeforeunload, GET_onbeforeunload, (VARIANT*)); 134 NV_DECLARE_TEAROFF_METHOD(put_onbeforeunload, PUT_onbeforeunload, (VARIANT)); 135 NV_DECLARE_TEAROFF_METHOD(get_onhelp, GET_onhelp, (VARIANT*)); 136 NV_DECLARE_TEAROFF_METHOD(put_onhelp, PUT_onhelp, (VARIANT)); 137 138 NV_DECLARE_TEAROFF_METHOD(get_onscroll, GET_onscroll, (VARIANT*)); 139 NV_DECLARE_TEAROFF_METHOD(put_onscroll, PUT_onscroll, (VARIANT)); 140 NV_DECLARE_TEAROFF_METHOD(get_onresize, GET_onresize, (VARIANT*)); 141 NV_DECLARE_TEAROFF_METHOD(put_onresize, PUT_onresize, (VARIANT)); 142 143 // non-abstract getters for tagName and scopeName. See element.pdl 144 NV_DECLARE_TEAROFF_METHOD(GettagName, gettagname, (BSTR*)); 145 146 // IServiceProvider methods 147 NV_DECLARE_TEAROFF_METHOD(QueryService, queryservice, (REFGUID guidService, REFIID iid, LPVOID* ppv)); 148 149 virtual CAtomTable* GetAtomTable(BOOL* pfExpando=NULL); 150 151 // init / deinit methods 152 class CInit2Context 153 { 154 public: 155 CInit2Context(CHtmTag* pht, CMarkup* pTargetMarkup, DWORD dwFlags) : 156 _pTargetMarkup(pTargetMarkup), _pht(pht), _dwFlags(dwFlags) 157 { 158 } 159 160 CInit2Context(CHtmTag* pht, CMarkup* pTargetMarkup) : 161 _pTargetMarkup(pTargetMarkup), _pht(pht), _dwFlags(0) 162 { 163 } 164 165 CHtmTag* _pht; 166 CMarkup* _pTargetMarkup; 167 DWORD _dwFlags; 168 }; 169 170 virtual HRESULT Init(); 171 virtual HRESULT Init2(CInit2Context* pContext); 172 173 HRESULT InitAttrBag(CHtmTag* pht); 174 HRESULT MergeAttrBag(CHtmTag* pht); 175 176 virtual void Notify (CNotification* pnf); 177 178 HRESULT EnterTree(); 179 void ExitTree(DWORD dwExitFlags); 180 181 // other 182 CBase* GetOmWindow(void); 183 184 // Get the Base Object that owns the attr array for a given property 185 // Allows us to re-direct properties to another objects storage 186 CBase* GetBaseObjectFor(DISPID dispID); 187 188 // Pass the call to the form. 189 //------------------------------------------------------------------------- 190 // +override : special process 191 // +call super : first 192 // -call parent : no 193 // -call children : no 194 //------------------------------------------------------------------------- 195 virtual HRESULT CloseErrorInfo(HRESULT hr); 196 197 // Scrolling methods 198 // Scroll this element into view 199 virtual HRESULT ScrollIntoView( 200 SCROLLPIN spVert=SP_MINIMAL, 201 SCROLLPIN spHorz=SP_MINIMAL, 202 BOOL fScrollBits=TRUE); 203 204 HRESULT DeferScrollIntoView( 205 SCROLLPIN spVert=SP_MINIMAL, 206 SCROLLPIN spHorz=SP_MINIMAL); 207 208 NV_DECLARE_ONCALL_METHOD(DeferredScrollIntoView, deferredscrollintoview, (DWORD_PTR dwParam)); 209 210 // Relative element (non-site) helper methods 211 virtual HTC HitTestPoint(CMessage* pMessage, CTreeNode** ppNodeElement, DWORD dwFlags); 212 213 BOOL CanHandleMessage() 214 { 215 return (HasLayout())?(IsEnabled()&&IsVisible(TRUE)):(TRUE); 216 } 217 218 // STDMETHODCALLTYPE required when passing fn through generic ptr 219 virtual HRESULT STDMETHODCALLTYPE HandleMessage(CMessage* pMessage); 220 221 HRESULT STDMETHODCALLTYPE HandleCaptureMessage(CMessage* pMessage) 222 { 223 return HandleMessage(pMessage); 224 } 225 226 // marka these are to be DELETED !! 227 BOOL DisallowSelection(); 228 229 // set the state of the IME. 230 HRESULT SetImeState(); 231 HRESULT ComputeExtraFormat(DISPID dispID, BOOL fInherits, CTreeNode* pTreeNode, VARIANT* pVarReturn); 232 233 // DoClick() is called by click(). It is also called internally in response 234 // to a mouse click by user. 235 // DoClick() fires the click event and then calls ClickAction() if the event 236 // is not cancelled. 237 // Derived classes can override ClickAction() to provide specific functionality. 238 virtual HRESULT DoClick( 239 CMessage* pMessage=NULL, 240 CTreeNode* pNodeContext=NULL, 241 BOOL fFromLabel=FALSE); 242 virtual HRESULT ClickAction(CMessage* pMessage); 243 244 virtual HRESULT ShowTooltip(CMessage* pmsg, POINT pt); 245 246 HRESULT SetCursorStyle(LPCTSTR pstrIDC, CTreeNode* pNodeContext=NULL); 247 248 void Invalidate(); 249 250 // Element rect and element invalidate support 251 enum GERC_FLAGS 252 { 253 GERC_ONALINE = 1, 254 GERC_CLIPPED = 2 255 }; 256 257 void GetElementRegion(CDataAry<RECT>* paryRects, RECT* prcBound=NULL, DWORD dwFlags=0); 258 HRESULT GetElementRc(RECT* prc, DWORD dwFlags, POINT* ppt=NULL); 259 260 // these helper functions return in container coordinates 261 void GetBoundingSize(SIZE& sz); 262 HRESULT GetBoundingRect(CRect* pRect, DWORD dwFlags=0); 263 HRESULT GetElementTopLeft(POINT& pt); 264 265 // helper to return the actual background color 266 COLORREF GetInheritedBackgroundColor(CTreeNode* pNodeContext=NULL); 267 HRESULT GetInheritedBackgroundColorValue(CColorValue* pVal, CTreeNode* pNodeContext=NULL); 268 virtual HRESULT GetColors(CColorInfo* pCI); 269 COLORREF GetBackgroundColor() 270 { 271 CTreeNode* pNodeContext = GetFirstBranch(); 272 CTreeNode* pNodeParent = pNodeContext->Parent() ? pNodeContext->Parent() : pNodeContext; 273 274 return pNodeParent->Element()->GetInheritedBackgroundColor(pNodeParent); 275 } 276 277 // Events related stuff 278 //-------------------------------------------------------------------------------------- 279 inline BOOL ShouldFireEvents() { return _fEventListenerPresent; } 280 inline void SetEventsShouldFire() { _fEventListenerPresent = TRUE; } 281 BOOL FireCancelableEvent(DISPID dispidMethod, DISPID dispidProp, LPCTSTR pchEventType, BYTE* pbTypes, ...); 282 BOOL BubbleCancelableEvent(CTreeNode* pNodeContext, long lSubDivision, DISPID dispidMethod, DISPID dispidProp, LPCTSTR pchEventType, BYTE* pbTypes, ...); 283 HRESULT FireEventHelper(DISPID dispidMethod, DISPID dispidProp, BYTE* pbTypes, ...); 284 HRESULT FireEvent(DISPID dispidMethod, DISPID dispidProp, LPCTSTR pchEventType, BYTE* pbTypes, ...); 285 HRESULT BubbleEvent(CTreeNode* pNodeContext, long lSubDivision, DISPID dispidMethod, DISPID dispidProp, LPCTSTR pchEventType, BYTE* pbTypes, ...); 286 HRESULT BubbleEventHelper(CTreeNode* pNodeContext, long lSubDivision, DISPID dispidMethod, DISPID dispidProp, BOOL fRaisedByPeer, VARIANT* pvb, BYTE* pbTypes, ...); 287 virtual HRESULT DoSubDivisionEvents(long lSubDivision, DISPID dispidMethod, DISPID dispidProp, VARIANT* pvb, BYTE* pbTypes, ...); 288 HRESULT FireStdEventOnMessage( 289 CTreeNode* pNodeContext, 290 CMessage* pMessage, 291 CTreeNode* pNodeBeginBubbleWith=NULL, 292 CTreeNode* pNodeEvent=NULL); 293 BOOL FireStdEvent_KeyDown(CTreeNode* pNodeContext, CMessage* pMessage, int* piKeyCode, short shift); 294 BOOL FireStdEvent_KeyUp(CTreeNode* pNodeContext, CMessage* pMessage, int* piKeyCode, short shift); 295 BOOL FireStdEvent_KeyPress(CTreeNode* pNodeContext, CMessage* pMessage, int* piKeyCode); 296 BOOL FireStdEvent_MouseHelper( 297 CTreeNode* pNodeContext, 298 CMessage * pMessage, 299 DISPID dispidMethod, 300 DISPID dispidProp, 301 short button, 302 short shift, 303 float x, 304 float y, 305 CTreeNode* pNodeFrom=NULL, 306 CTreeNode* pNodeTo=NULL, 307 CTreeNode* pNodeBeginBubbleWith=NULL, 308 CTreeNode* pNodeEvent=NULL); 309 void Fire_onpropertychange(LPCTSTR strPropName); 310 void Fire_onscroll(); 311 HRESULT Fire_PropertyChangeHelper(DISPID dispid, DWORD dwFlags); 312 313 void STDMETHODCALLTYPE Fire_onfocus(DWORD_PTR dwContext); 314 void STDMETHODCALLTYPE Fire_onblur(DWORD_PTR dwContext); 315 316 BOOL DragElement( 317 CLayout* pFlowLayout, 318 DWORD dwStateKey, 319 IUniformResourceLocator* pUrlToDrag, 320 long lSubDivision); 321 322 BOOL Fire_ondragHelper( 323 long lSubDivision, 324 DISPID dispidEvent, 325 DISPID dispidProp, 326 LPCTSTR pchType, 327 DWORD* pdwDropEffect); 328 void Fire_ondragend(long lSubDivision, DWORD dwDropEffect); 329 330 // Associated image context helpers 331 HRESULT GetImageUrlCookie(LPCTSTR lpszURL, long* plCtxCookie); 332 HRESULT AddImgCtx(DISPID dispID, LONG lCookie); 333 void ReleaseImageCtxts(); 334 void DeleteImageCtx(DISPID dispid); 335 336 // Internal events 337 HRESULT EnsureFormatCacheChange(DWORD dwFlags); 338 BOOL IsFormatCacheValid(); 339 340 // Element Tree methods 341 BOOL IsAligned(); 342 BOOL IsContainer(); 343 BOOL IsNoScope(); 344 BOOL IsBlockElement(); 345 BOOL IsBlockTag(); 346 BOOL IsOwnLineElement(CFlowLayout* pFlowLayoutContext); 347 BOOL IsRunOwner() { return _fOwnsRuns; } 348 BOOL BreaksLine(); 349 BOOL IsTagAndBlock(ELEMENT_TAG eTag) { return Tag()==eTag&&IsBlockElement(); } 350 BOOL IsFlagAndBlock(TAGDESC_FLAGS flag) { return HasFlag(flag)&&IsBlockElement(); } 351 352 HRESULT ClearRunCaches(DWORD dwFlags); 353 354 // Get the first branch for this element 355 CTreeNode* GetFirstBranch() const { return __pNodeFirstBranch; } 356 CTreeNode* GetLastBranch(); 357 BOOL IsOverlapped(); 358 359 // Get the CTreePos extent of this element 360 void GetTreeExtent(CTreePos** pptpStart, CTreePos** pptpEnd); 361 362 //------------------------------------------------------------------------- 363 // 364 // Layout related functions 365 // 366 //------------------------------------------------------------------------- 367 private: 368 BOOL HasLayoutLazy(); // should only be called by HasLayout 369 inline CLayout* GetLayoutLazy(); 370 // Create the layout object to be associated with the current element 371 virtual HRESULT CreateLayout(); 372 373 public: 374 // CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION 375 // CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION 376 // (please read the comments below) 377 // 378 // The layout attached to the current element may not be accurate, when a 379 // property changes, current element can gain/lose layoutness. When an 380 // element gains/loses layoutness, its layout is created/destroyed lazily. 381 // 382 // So, for the following functions "cur" means return the layout currently 383 // associated with the layout which may not be accurate. "Updated" means 384 // compute the state and return the accurate information. 385 // 386 // Note: Calling "Updated" function may cause the formats to be computed. 387 // 388 // If there is any confusion please talk to (srinib/lylec/brendand) 389 CLayout* GetCurLayout() { return GetLayoutPtr(); } 390 BOOL HasLayout() { return !!HasLayoutPtr(); } 391 392 CLayout* GetCurNearestLayout(); 393 CTreeNode* GetCurNearestLayoutNode(); 394 CElement* GetCurNearestLayoutElement(); 395 396 CLayout* GetCurParentLayout(); 397 CTreeNode* GetCurParentLayoutNode(); 398 CElement* GetCurParentLayoutElement(); 399 400 // CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION 401 // CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION CAUTION 402 // (please read the comments above) 403 // 404 // 405 // the following get functions may create the layout if it is not 406 // created yet. 407 inline CLayout* GetUpdatedLayout(); // checks for NeedsLayout() 408 inline CLayout* GetUpdatedLayoutPtr(); // Call this if NeedsLayout() is already called 409 inline BOOL NeedsLayout(); 410 411 CLayout* GetUpdatedNearestLayout(); 412 CTreeNode* GetUpdatedNearestLayoutNode(); 413 CElement* GetUpdatedNearestLayoutElement(); 414 415 CLayout* GetUpdatedParentLayout(); 416 CTreeNode* GetUpdatedParentLayoutNode(); 417 CElement* GetUpdatedParentLayoutElement(); 418 419 420 void DestroyLayout(); 421 422 // this functions return GetFirstBranch()->Parent()->Ancestor(etag)->Element(); safely 423 // returns NULL if the element is not in the tree, or it doesn't have a parent, or no such ansectors in the tree, etc. 424 CElement* GetParentAncestorSafe(ELEMENT_TAG etag) const; 425 CElement* GetParentAncestorSafe(ELEMENT_TAG* arytag) const; 426 427 // BUGBUG - these functions should go, we should not need 428 // to know if the element has flowlayout. 429 CFlowLayout* GetFlowLayout(); 430 CTreeNode* GetFlowLayoutNode(); 431 CElement* GetFlowLayoutElement(); 432 CFlowLayout* HasFlowLayout(); 433 434 // Notification helpers 435 void InvalidateElement(DWORD grfFlags=0); 436 void MinMaxElement(DWORD grfFlags=0); 437 void ResizeElement(DWORD grfFlags=0); 438 void RemeasureElement(DWORD grfFlags=0); 439 void RemeasureInParentContext(DWORD grfFlags=0); 440 void RepositionElement(DWORD grfFlags=0); 441 void ZChangeElement(DWORD grfFlags=0, CPoint* ppt=NULL); 442 443 void SendNotification(enum NOTIFYTYPE ntype, DWORD grfFlags=0, void* pvData=0); 444 void SendNotification(enum NOTIFYTYPE ntype, void* pvData) 445 { 446 SendNotification(ntype, 0, pvData); 447 } 448 void SendNotification(CNotification* pNF); 449 450 long GetSourceIndex(void); 451 452 long CompareZOrder(CElement* pElement); 453 454 // Mark an element's layout (if any) dirty 455 void DirtyLayout(DWORD grfLayout=0); 456 BOOL OpenView(); 457 458 BOOL HasPercentBgImg(); 459 460 // cp and run related helper functions 461 long GetFirstCp(); 462 long GetLastCp(); 463 long GetElementCch(); 464 long GetFirstAndLastCp(long* pcpFirst, long* pcpLast); 465 466 // get the border information related to the element 467 virtual DWORD GetBorderInfo(CDocInfo* pdci, CBorderInfo* pbi, BOOL fAll=FALSE); 468 469 HRESULT GetRange(long* pcp, long* pcch); 470 HRESULT GetPlainTextInScope(CString* pstrText); 471 472 virtual HRESULT Save(CStreamWriteBuff* pStreamWrBuff, BOOL fEnd); 473 HRESULT WriteTag(CStreamWriteBuff* pStreamWrBuff, BOOL fEnd, BOOL fForce=FALSE); 474 virtual HRESULT SaveAttributes(CStreamWriteBuff* pStreamWrBuff, BOOL* pfAny=NULL); 475 HRESULT SaveAttributes(IPropertyBag* pPropBag, BOOL fSaveBlankAttributes=TRUE); 476 HRESULT SaveAttribute( 477 CStreamWriteBuff* pStreamWrBuff, 478 LPTSTR pchName, 479 LPTSTR pchValue, 480 const PROPERTYDESC* pPropDesc=NULL, 481 CBase* pBaseObj=NULL, 482 BOOL fEqualSpaces=TRUE, 483 BOOL fAlwaysQuote=FALSE); 484 485 ELEMENT_TAG Tag() const { return (ELEMENT_TAG)_etag; } 486 inline ELEMENT_TAG TagType() const 487 { 488 switch(_etag) 489 { 490 case ETAG_GENERIC_LITERAL: 491 case ETAG_GENERIC_BUILTIN: 492 return ETAG_GENERIC; 493 default: 494 return (ELEMENT_TAG)_etag; 495 } 496 } 497 498 virtual const TCHAR* TagName(); 499 const TCHAR* NamespaceHtml(); 500 501 // Support for sub-objects created through pdl's 502 // CStyle & Celement implement this differently 503 CElement* GetElementPtr() { return this; } 504 505 BOOL CanShow(); 506 507 BOOL HasFlag(TAGDESC_FLAGS) const; 508 509 static void ReplacePtr(CElement** pplhs, CElement* prhs); 510 static void ReplacePtrSub(CElement** pplhs, CElement* prhs); 511 static void SetPtr(CElement** pplhs, CElement* prhs); 512 static void ClearPtr(CElement** pplhs); 513 static void StealPtrSet(CElement** pplhs, CElement* prhs); 514 static void StealPtrReplace(CElement** pplhs, CElement* prhs); 515 static void ReleasePtr(CElement* pElement); 516 517 // Write unknown attr set 518 HRESULT SaveUnknown(CStreamWriteBuff* pStreamWrBuff, BOOL* pfAny=NULL); 519 HRESULT SaveUnknown(IPropertyBag* pPropBag, BOOL fSaveBlankAttributes=TRUE); 520 521 // Helpers 522 BOOL IsNamed() const { return !!_fIsNamed; } 523 524 // comparison 525 LPCTSTR NameOrIDOfParentForm(); 526 527 // Helper for name or ID 528 LPCTSTR GetIdentifier(void); 529 HRESULT GetUniqueIdentifier(CString* pcstr, BOOL fSetWhenCreated=FALSE, BOOL* pfDidCreate=NULL); 530 LPCTSTR GetAAname() const; 531 LPCTSTR GetAAsubmitname() const; 532 533 // Paste helpers 534 enum Where 535 { 536 Inside, 537 Outside, 538 BeforeBegin, 539 AfterBegin, 540 BeforeEnd, 541 AfterEnd 542 }; 543 544 HRESULT Inject(Where, BOOL fIsHtml, LPTSTR pStr, long cch); 545 546 virtual HRESULT PasteClipboard() { return S_OK; } 547 548 HRESULT InsertAdjacent(Where where, CElement* pElementInsert); 549 550 HRESULT RemoveOuter(); 551 552 // Helper to get the specified text under the element -- invokes saver. 553 HRESULT GetText(BSTR* pbstr, DWORD dwStm); 554 555 // Another helper for databinding 556 HRESULT GetBstrFromElement(BOOL fHTML, BSTR* pbstr); 557 558 // Collection Management helpers 559 NV_DECLARE_PROPERTY_METHOD(GetIDHelper, GETIDHelper, (CString* pf)); 560 NV_DECLARE_PROPERTY_METHOD(SetIDHelper, SETIDHelper, (CString* pf)); 561 NV_DECLARE_PROPERTY_METHOD(GetnameHelper, GETNAMEHelper, (CString* pf)); 562 NV_DECLARE_PROPERTY_METHOD(SetnameHelper, SETNAMEHelper, (CString* pf)); 563 LPCTSTR GetAAid() const; 564 void InvalidateCollection(long lIndex); 565 NV_STDMETHOD(removeAttribute)(BSTR strPropertyName, LONG lFlags, VARIANT_BOOL* pfSuccess); 566 HRESULT SetUniqueNameHelper(LPCTSTR szUniqueName); 567 HRESULT SetIdentifierHelper(LPCTSTR lpszValue, DISPID dspIDThis, DISPID dspOther1, DISPID dspOther2); 568 void OnEnterExitInvalidateCollections(BOOL); 569 void DoElementNameChangeCollections(void); 570 571 // Clone - make a duplicate new element 572 // 573 // !! returns an element with no node! 574 virtual HRESULT Clone(CElement** ppElementClone, CDocument* pDoc); 575 576 void ComputeHorzBorderAndPadding( 577 CCalcInfo* pci, 578 CTreeNode* pNodeContext, 579 CElement* pTxtSite, 580 LONG* pxBorderLeft, 581 LONG* pxPaddingLeft, 582 LONG* pxBorderRight, 583 LONG* pxPaddingRight); 584 585 HRESULT SetDim( 586 DISPID dispID, 587 float fValue, 588 CUnitValue::UNITVALUETYPE uvt, 589 long lDimOf, 590 CAttrArray** ppAA, 591 BOOL fInlineStyle, 592 BOOL* pfChanged); 593 594 virtual HRESULT ComputeFormats(CFormatInfo* pCFI, CTreeNode* pNodeTarget); 595 virtual HRESULT ApplyDefaultFormat(CFormatInfo* pCFI); 596 BOOL ElementNeedsLayout(CFormatInfo* pCFI); 597 BOOL DetermineBlockness(CFormatInfo* pCFI); 598 HRESULT ApplyInnerOuterFormats(CFormatInfo* pCFI); 599 CImgCtx* GetBgImgCtx(); 600 601 // Access Key Handling Helper Functions 602 FOCUS_ITEM GetMnemonicTarget(); 603 HRESULT HandleMnemonic(CMessage* pmsg, BOOL fDoClick, BOOL* pfYieldFailed=NULL); 604 HRESULT GotMnemonic(CMessage* pMessage); 605 HRESULT LostMnemonic(CMessage* pMessage); 606 BOOL MatchAccessKey(CMessage* pmsg); 607 HRESULT OnTabIndexChange(); 608 609 // Styles 610 HRESULT GetStyleObject(CStyle** ppStyle); 611 CAttrArray* GetInLineStyleAttrArray(); 612 CAttrArray** CreateStyleAttrArray(DISPID); 613 614 BOOL HasInLineStyles(void); 615 BOOL HasClassOrID(void); 616 617 CStyle* GetInLineStylePtr(); 618 CStyle* GetRuntimeStylePtr(); 619 620 // Helpers for abstract name properties implemented on derived elements 621 DECLARE_TEAROFF_METHOD(put_name, PUT_name, (BSTR v)); 622 DECLARE_TEAROFF_METHOD(get_name, GET_name, (BSTR* p)); 623 624 htmlBlockAlign GetParagraphAlign(BOOL fOuter); 625 htmlControlAlign GetSiteAlign(); 626 627 BOOL IsInlinedElement(); 628 629 BOOL IsPositionStatic(); 630 BOOL IsPositioned(); 631 BOOL IsAbsolute(); 632 BOOL IsRelative(); 633 BOOL IsInheritingRelativeness(); 634 BOOL IsScrollingParent(); 635 BOOL IsClipParent(); 636 BOOL IsZParent(); 637 BOOL IsLocked(); 638 BOOL IsDisplayNone(); 639 BOOL IsVisibilityHidden(); 640 641 // Reset functionallity 642 // Returns S_OK if successful and E_NOTIMPL if not applicable 643 virtual HRESULT DoReset(void) { return E_NOTIMPL; } 644 645 // Get control's window, does control have window? 646 virtual HWND GetHwnd() { return NULL; } 647 648 // Take the capture. 649 void TakeCapture(BOOL fTake); 650 BOOL HasCapture(); 651 652 // IMsoCommandTarget methods 653 HRESULT STDMETHODCALLTYPE QueryStatus( 654 GUID* pguidCmdGroup, 655 ULONG cCmds, 656 MSOCMD rgCmds[], 657 MSOCMDTEXT* pcmdtext); 658 HRESULT STDMETHODCALLTYPE Exec( 659 GUID* pguidCmdGroup, 660 DWORD nCmdID, 661 DWORD nCmdexecopt, 662 VARIANTARG* pvarargIn, 663 VARIANTARG* pvarargOut); 664 665 BOOL IsEditable(BOOL fCheckContainerOnly=FALSE); 666 667 HRESULT EnsureInMarkup(); 668 669 // Currency / UI-Activity 670 671 // Does this element (or its master) have currency? 672 BOOL HasCurrency(); 673 674 virtual HRESULT RequestYieldCurrency(BOOL fForce); 675 676 // Relinquishes currency 677 virtual HRESULT YieldCurrency(CElement* pElemNew); 678 679 // Relinquishes UI 680 virtual void YieldUI(CElement* pElemNew); 681 682 // Forces UI upon an element 683 virtual HRESULT BecomeUIActive(); 684 685 BOOL NoUIActivate(); // tell us if element can be UIActivate 686 687 BOOL IsFocussable(long lSubDivision); 688 BOOL IsTabbable(long lSubDivision); 689 690 HRESULT PreBecomeCurrent(long lSubDivision, CMessage* pMessage); 691 HRESULT BecomeCurrentFailed(long lSubDivision, CMessage* pMessage); 692 HRESULT PostBecomeCurrent(CMessage* pMessage); 693 694 HRESULT BecomeCurrent( 695 long lSubDivision, 696 BOOL* pfYieldFailed=NULL, 697 CMessage* pMessage=NULL, 698 BOOL fTakeFocus=FALSE); 699 700 HRESULT BubbleBecomeCurrent( 701 long lSubDivision, 702 BOOL* pfYieldFailed=NULL, 703 CMessage* pMessage=NULL, 704 BOOL fTakeFocus=FALSE); 705 706 CElement* GetFocusBlurFireTarget(long lSubDiv); 707 708 HRESULT focusHelper(long lSubDivision); 709 710 virtual HRESULT GetFocusShape(long lSubDivision, CDocInfo* pdci, CShape** ppShape); 711 712 // Forces Currency and uiactivity upon an element 713 HRESULT BecomeCurrentAndActive( 714 CMessage* pmsg=NULL, 715 long lSubDivision=0, 716 BOOL fTakeFocus=FALSE, 717 BOOL* pfYieldFailed=NULL); 718 HRESULT BubbleBecomeCurrentAndActive(CMessage* pmsg=NULL, BOOL fTakeFocus=FALSE); 719 720 virtual HRESULT GetSubDivisionCount(long* pc); 721 virtual HRESULT GetSubDivisionTabs(long* pTabs, long c); 722 virtual HRESULT SubDivisionFromPt(POINT pt, long* plSub); 723 724 // Find an element with the given set of SITE_FLAG's set 725 CElement* FindDefaultElem(BOOL fDefault, BOOL fFull=FALSE); 726 727 // set the default element in a form or in the doc 728 void SetDefaultElem(BOOL fFindNew = FALSE); 729 730 HRESULT GetNextSubdivision(FOCUS_DIRECTION dir, long lSubDivision, long* plSubNew); 731 732 virtual BOOL IsEnabled(); 733 734 virtual BOOL IsValid() { return TRUE; } 735 736 BOOL IsVisible(BOOL fCheckParent); 737 BOOL IsParent(CElement* pElement); // Is pElement a parent of this element? 738 739 virtual HRESULT GetControlInfo(CONTROLINFO* pCI) { return E_FAIL; } 740 virtual BOOL OnMenuEvent(int id, UINT code) { return FALSE; } 741 HRESULT STDMETHODCALLTYPE OnCommand(int id, HWND hwndCtrl, UINT codeNotify) { return S_OK; } 742 HRESULT OnContextMenu(int x, int y, int id); 743 744 HRESULT OnInitMenuPopup(HMENU hmenu, int item, BOOL fSystemMenu); 745 HRESULT OnMenuSelect(UINT uItem, UINT fuFlags, HMENU hmenu); 746 747 // Helper for translating keystrokes into commands 748 HRESULT PerformTA(CMessage* pMessage); 749 750 CImgCtx* GetNearestBgImgCtx(); 751 752 DWORD GetCommandID(LPMSG lpmsg); 753 754 //+--------------------------------------------------------------------------- 755 // 756 // Flag values for CElement::CLock 757 // 758 //---------------------------------------------------------------------------- 759 enum ELEMENTLOCK_FLAG 760 { 761 ELEMENTLOCK_NONE = 0, 762 ELEMENTLOCK_CLICK = 1 << 0, 763 ELEMENTLOCK_PROCESSPOSITION = 1 << 1, 764 ELEMENTLOCK_PROCESSADORNERS = 1 << 2, 765 ELEMENTLOCK_DELETE = 1 << 3, 766 ELEMENTLOCK_FOCUS = 1 << 4, 767 ELEMENTLOCK_CHANGE = 1 << 5, 768 ELEMENTLOCK_UPDATE = 1 << 6, 769 ELEMENTLOCK_SIZING = 1 << 7, 770 ELEMENTLOCK_COMPUTEFORMATS = 1 << 8, 771 ELEMENTLOCK_QUERYSTATUS = 1 << 9, 772 ELEMENTLOCK_BLUR = 1 << 10, 773 ELEMENTLOCK_RECALC = 1 << 11, 774 ELEMENTLOCK_BLOCKCALC = 1 << 12, 775 ELEMENTLOCK_ATTACHPEER = 1 << 13, 776 ELEMENTLOCK_PROCESSREQUESTS = 1 << 14, 777 ELEMENTLOCK_PROCESSMEASURE = 1 << 15, 778 ELEMENTLOCK_LAST = 1 << 15, 779 780 // don't add anymore flags, we only have 16 bits 781 }; 782 783 //+----------------------------------------------------------------------- 784 // 785 // CElement::CLock 786 // 787 //------------------------------------------------------------------------ 788 class CLock 789 { 790 public: 791 DECLARE_MEMALLOC_NEW_DELETE(); 792 CLock(CElement* pElement, ELEMENTLOCK_FLAG enumLockFlags=ELEMENTLOCK_NONE); 793 ~CLock(); 794 795 private: 796 CElement* _pElement; 797 WORD _wLockFlags; 798 }; 799 800 BOOL TestLock(ELEMENTLOCK_FLAG enumLockFlags) { return _wLockFlags&((WORD)enumLockFlags); } 801 802 BOOL TestClassFlag(ELEMENTDESC_FLAG dwFlag) const { return ElementDesc()->_classdescBase._dwFlags&dwFlag; } 803 804 inline BOOL WantEndParseNotification() { return TestClassFlag(CElement::ELEMENTDESC_NOTIFYENDPARSE); } 805 806 // BUGBUG: we should have a general notification mechanism to tell what 807 // elements are listening to which notifications 808 BOOL WantTextChangeNotifications(); 809 810 //+----------------------------------------------------------------------- 811 // 812 // CLASSDESC (class descriptor) 813 // 814 //------------------------------------------------------------------------ 815 class ACCELS 816 { 817 public: 818 ACCELS(ACCELS* pSuper, WORD wAccels); 819 ~ACCELS(); 820 HRESULT EnsureResources(); 821 HRESULT LoadAccelTable(); 822 DWORD GetCommandID(LPMSG pmsg); 823 824 ACCELS* _pSuper; 825 826 BOOL _fResourcesLoaded; 827 828 WORD _wAccels; 829 LPACCEL _pAccels; 830 int _cAccels; 831 }; 832 833 struct CLASSDESC 834 { 835 CBase::CLASSDESC _classdescBase; 836 void* _apfnTearOff; 837 838 BOOL TestFlag(ELEMENTDESC_FLAG dw) const { return (_classdescBase._dwFlags&dw)!=0; } 839 840 // move from CSite::CLASSDESC 841 ACCELS* _pAccelsDesign; 842 ACCELS* _pAccelsRun; 843 }; 844 845 const CLASSDESC* ElementDesc() const 846 { 847 return (const CLASSDESC*)BaseDesc(); 848 } 849 850 public: 851 // Lookaside pointers 852 enum 853 { 854 LOOKASIDE_FILTER = 0, 855 LOOKASIDE_DATABIND = 1, 856 LOOKASIDE_PEER = 2, 857 LOOKASIDE_PEERMGR = 3, 858 LOOKASIDE_ACCESSIBLE = 4, 859 LOOKASIDE_SLAVEMARKUP = 5, 860 LOOKASIDE_REQUEST = 6, 861 LOOKASIDE_ELEMENT_NUMBER = 7 862 863 // *** There are only 7 bits reserved in the element. 864 // *** if you add more lookasides you have to make sure 865 // *** that you make room for those bits. 866 }; 867 868 private: 869 BOOL HasLookasidePtr(int iPtr) { return (_fHasLookasidePtr&(1<<iPtr)); } 870 void* GetLookasidePtr(int iPtr); 871 HRESULT SetLookasidePtr(int iPtr, void* pv); 872 void* DelLookasidePtr(int iPtr); 873 874 public: 875 876 BOOL HasLayoutPtr() const { return _fHasLayoutPtr; } 877 CLayout* GetLayoutPtr() const; 878 void SetLayoutPtr(CLayout* pLayout); 879 CLayout* DelLayoutPtr(); 880 881 BOOL IsInMarkup() const { return _fHasMarkupPtr; } 882 BOOL HasMarkupPtr() const { return _fHasMarkupPtr; } 883 CMarkup* GetMarkupPtr() const; 884 void SetMarkupPtr(CMarkup* pMarkup); 885 void DelMarkupPtr(); 886 887 CRootElement* IsRoot() { return Tag()==ETAG_ROOT?(CRootElement*)this:NULL; } 888 CMarkup* GetMarkup() const { return GetMarkupPtr(); } 889 BOOL IsInPrimaryMarkup() const; 890 BOOL IsInThisMarkup(CMarkup* pMarkup) const; 891 CRootElement* MarkupRoot(); 892 893 CElement* MarkupMaster() const; 894 CMarkup* SlaveMarkup() const { return ((CElement*)this)->GetSlaveMarkupPtr(); } 895 CElement* FireEventWith(); 896 897 CDocument* GetDocPtr() const; 898 899 BOOL HasSlaveMarkupPtr() { return (HasLookasidePtr(LOOKASIDE_SLAVEMARKUP)); } 900 CMarkup* GetSlaveMarkupPtr() { return ((CMarkup*)GetLookasidePtr(LOOKASIDE_SLAVEMARKUP)); } 901 HRESULT SetSlaveMarkupPtr(CMarkup* pSlaveMarkup) { return (SetLookasidePtr(LOOKASIDE_SLAVEMARKUP, pSlaveMarkup)); } 902 CMarkup* DelSlaveMarkupPtr() { return ((CMarkup*)DelLookasidePtr(LOOKASIDE_SLAVEMARKUP)); } 903 904 BOOL HasRequestPtr() { return (HasLookasidePtr(LOOKASIDE_REQUEST)); } 905 CRequest* GetRequestPtr() { return ((CRequest*)GetLookasidePtr(LOOKASIDE_REQUEST)); } 906 HRESULT SetRequestPtr(CRequest* pRequest) { return (SetLookasidePtr(LOOKASIDE_REQUEST, pRequest)); } 907 CRequest* DelRequestPtr() { return ((CRequest*)DelLookasidePtr(LOOKASIDE_REQUEST)); } 908 909 long GetReadyState(); 910 virtual void OnReadyStateChange(); 911 912 // The element is the head of a linked list of important structures. If the element has layout, 913 // then the __pvChain member points to that layout. If not and if the element is in a tree then 914 // then the __pvChain member points to the ped that it is in. Otherwise __pvChain points to the 915 // document. 916 private: 917 void* __pvChain; 918 919 public: 920 CTreeNode* __pNodeFirstBranch; 921 922 // First DWORD of bits 923 ELEMENT_TAG _etag : 8; // 0- 7 element tag 924 unsigned _fHasLookasidePtr : 7; // 8-14 TRUE if lookaside table has pointer 925 unsigned _fIsNamed : 1; // 15 set if element has a name or ID attribute 926 unsigned _wLockFlags :16; // 16-31 Element lock flags for preventing recursion 927 928 // Second DWORD of bits 929 // 930 // Note that the _fMark1 and _fMark2 bits are only safe to use in routines which can *guarantee* 931 // their processing will not be interrupted. If there is a chance that a message loop can cause other, 932 // unrelated code, to execute, these bits could get reset before the original caller is finished. 933 unsigned _fHasMarkupPtr : 1; // 0 TRUE if element has a Markup pointer 934 unsigned _fHasLayoutPtr : 1; // 1 TRUE if element has layout ptr 935 unsigned _fHasPendingFilterTask : 1; // 2 TRUE if there is a pending filter task (see EnsureView) 936 unsigned _fHasPendingRecalcTask : 1; // 3 TRUE if there is a pending recalc task (see EnsureView) 937 unsigned _fLayoutAlwaysValid : 1; // 4 TRUE if element is a site or never has layout 938 unsigned _fOwnsRuns : 1; // 5 TRUE if element owns the runs underneath it 939 unsigned _fInheritFF : 1; // 6 TRUE if element to inherit site and fancy format 940 unsigned _fBreakOnEmpty : 1; // 7 this element breaks a line even is it own no text 941 unsigned _fUnused2 : 4; // 8-11 942 unsigned _fDefinitelyNoBorders : 1; // 12 There are no borders on this element 943 unsigned _fHasTabIndex : 1; // 13 Has a tabindex associated with this element. Look in doc _aryTabIndexInfo 944 unsigned _fHasImage : 1; // 14 has at least one image context 945 unsigned _fResizeOnImageChange : 1; // 15 need to force resize when image changes 946 unsigned _fExplicitEndTag : 1; // 16 element had a close tag (for P) 947 unsigned _fSynthesized : 1; // 17 FALSE (default) if user created, TRUE if synthesized 948 unsigned _fUnused3 : 1; // 18 Unused bit 949 unsigned _fActsLikeButton : 1; // 19 does element act like a push button? 950 unsigned _fEditAtBrowse : 1; // 20 to TestClassFlag(SITEDESC_EDITATBROWSE) in init 951 unsigned _fSite : 1; // 21 element with layout by default 952 unsigned _fDefault : 1; // 22 Is this the default "ok" button/control 953 unsigned _fCancel : 1; // 23 Is this the default "cancel" button/control 954 unsigned _fHasPendingEvent : 1; // 24 A posted event for element is pending 955 unsigned _fEventListenerPresent : 1; // 25 Someone has asked for a connection point/ or set an event handler 956 unsigned _fHasFilterCollectionPtr : 1; // 26 FilterCollectionPtr has been added to _pAA 957 unsigned _fExittreePending : 1; // 27 There is a pending Exittree notification for this element 958 unsigned _fFirstCommonAncestor : 1; // 28 Used in GetFirstCommonAncestor - don't touch! 959 unsigned _fMark1 : 1; // 29 Random mark 960 unsigned _fMark2 : 1; // 30 Another random mark 961 unsigned _fHasStyleExpressions : 1; // 31 There are style expressions on this element 962 963 // STATIC DATA 964 965 // Default property page list for elements that don't have their own. 966 // This gives them the allpage by default. 967 static ACCELS s_AccelsElementDesign; 968 static ACCELS s_AccelsElementRun; 969 970 // Style methods 971 #include "../gen/style.hdl" 972 973 // IHTMLElement methods 974 #define _CElement_ 975 #include "../gen/element.hdl" 976 977 DECLARE_TEAROFF_TABLE(IServiceProvider) 978 979 private: 980 NO_COPY(CElement); 981 };
1 ULONG CBase::SubRelease() 2 { 3 #ifdef _DEBUG 4 ULONG ulAllRefs = _ulAllRefs; 5 #endif 6 if(--_ulAllRefs == 0) 7 { 8 _ulAllRefs = ULREF_IN_DESTRUCTOR; 9 _ulRefs = ULREF_IN_DESTRUCTOR; 10 delete this; 11 } 12 #ifdef _DEBUG 13 return ulAllRefs-1; 14 #else 15 return 0; 16 #endif 17 }
ULONG CBase::PrivateRelease() { ULONG ulRefs = --_ulRefs; if(ulRefs == 0) { _ulRefs = ULREF_IN_DESTRUCTOR; Passivate(); Assert("Unexpected refcnt on return from CBase::Passivate" && _ulRefs==ULREF_IN_DESTRUCTOR); _ulRefs = 0; SubRelease(); } return ulRefs; }
1 class CMarkup : public CBase 2 { 3 friend class CTxtPtr; 4 friend class CTreePos; 5 friend class CMarkupPointer; 6 7 DECLARE_CLASS_TYPES(CMarkup, CBase) 8 9 public: 10 DECLARE_TEAROFF_TABLE(ISelectionRenderingServices) 11 DECLARE_TEAROFF_TABLE(IMarkupContainer) 12 13 DECLARE_MEMCLEAR_NEW_DELETE() 14 15 CMarkup(CDocument* pDoc, CElement* pElementMaster=NULL); 16 ~CMarkup(); 17 18 HRESULT Init(CRootElement* pElementRoot); 19 20 HRESULT CreateInitialMarkup(CRootElement* pElementRoot); 21 22 HRESULT UnloadContents(BOOL fForPassivate=FALSE); 23 24 HRESULT DestroySplayTree(BOOL fReinit); 25 26 void Passivate(); 27 28 HRESULT CreateElement( 29 ELEMENT_TAG etag, 30 CElement** ppElementNew); 31 32 #define _CMarkup_ 33 #include "../gen/markup.hdl" 34 35 // Document props\methods: 36 NV_DECLARE_TEAROFF_METHOD(get_Script, GET_Script, (IDispatch** p)); 37 NV_DECLARE_TEAROFF_METHOD(get_all, GET_all, (IHTMLElementCollection** p)); 38 NV_DECLARE_TEAROFF_METHOD(get_body, GET_body, (IHTMLElement** p)); 39 NV_DECLARE_TEAROFF_METHOD(get_activeElement, GET_activeElement, (IHTMLElement** p)); 40 NV_DECLARE_TEAROFF_METHOD(put_title, PUT_title, (BSTR v)); 41 NV_DECLARE_TEAROFF_METHOD(get_title, GET_title, (BSTR* p)); 42 NV_DECLARE_TEAROFF_METHOD(get_readyState, GET_readyState, (BSTR* p)); 43 NV_DECLARE_TEAROFF_METHOD(put_expando, PUT_expando, (VARIANT_BOOL v)); 44 NV_DECLARE_TEAROFF_METHOD(get_expando, GET_expando, (VARIANT_BOOL* p)); 45 NV_DECLARE_TEAROFF_METHOD(get_parentWindow, GET_parentWindow, (IHTMLWindow2** p)); 46 NV_DECLARE_TEAROFF_METHOD(get_nameProp, GET_nameProp, (BSTR* p)); 47 NV_DECLARE_TEAROFF_METHOD_(HRESULT, queryCommandSupported, querycommandsupported, (BSTR cmdID,VARIANT_BOOL* pfRet)); 48 NV_DECLARE_TEAROFF_METHOD_(HRESULT, queryCommandEnabled, querycommandenabled, (BSTR cmdID,VARIANT_BOOL* pfRet)); 49 NV_DECLARE_TEAROFF_METHOD_(HRESULT, queryCommandState, querycommandstate, (BSTR cmdID,VARIANT_BOOL* pfRet)); 50 NV_DECLARE_TEAROFF_METHOD_(HRESULT, queryCommandIndeterm, querycommandindeterm, (BSTR cmdID,VARIANT_BOOL* pfRet)); 51 NV_DECLARE_TEAROFF_METHOD_(HRESULT, queryCommandText, querycommandtext, (BSTR cmdID,BSTR* pcmdText)); 52 NV_DECLARE_TEAROFF_METHOD_(HRESULT, queryCommandValue, querycommandvalue, (BSTR cmdID,VARIANT* pcmdValue)); 53 NV_DECLARE_TEAROFF_METHOD_(HRESULT, execCommand, execcommand, (BSTR cmdID,VARIANT_BOOL showUI,VARIANT value,VARIANT_BOOL* pfRet)); 54 NV_DECLARE_TEAROFF_METHOD_(HRESULT, execCommandShowHelp, execcommandshowhelp, (BSTR cmdID,VARIANT_BOOL* pfRet)); 55 NV_DECLARE_TEAROFF_METHOD_(HRESULT, createElement, createelement, (BSTR eTag,IHTMLElement** newElem)); 56 NV_DECLARE_TEAROFF_METHOD_(HRESULT, elementFromPoint, elementfrompoint, (long x,long y,IHTMLElement** elementHit)); 57 NV_DECLARE_TEAROFF_METHOD_(HRESULT, toString, tostring, (BSTR* String)); 58 NV_DECLARE_TEAROFF_METHOD_(HRESULT, releaseCapture, releasecapture, ()); 59 NV_DECLARE_TEAROFF_METHOD(get_documentElement, GET_documentelement, (IHTMLElement**pRootElem)); 60 NV_DECLARE_TEAROFF_METHOD(get_uniqueID, GET_uniqueID, (BSTR* p)); 61 NV_DECLARE_TEAROFF_METHOD_(HRESULT, attachEvent, attachevent, (BSTR event,IDispatch* pDisp,VARIANT_BOOL* pfResult)); 62 NV_DECLARE_TEAROFF_METHOD_(HRESULT, detachEvent, detachevent, (BSTR event,IDispatch* pDisp)); 63 NV_DECLARE_TEAROFF_METHOD(get_bgColor, GET_bgColor, (VARIANT* p)); 64 NV_DECLARE_TEAROFF_METHOD(put_bgColor, PUT_bgColor, (VARIANT p)); 65 NV_DECLARE_TEAROFF_METHOD(get_fgColor, GET_fgColor, (VARIANT* p)); 66 NV_DECLARE_TEAROFF_METHOD(put_fgColor, PUT_fgColor, (VARIANT p)); 67 NV_DECLARE_TEAROFF_METHOD(get_linkColor, GET_linkColor, (VARIANT* p)); 68 NV_DECLARE_TEAROFF_METHOD(put_linkColor, PUT_linkColor, (VARIANT p)); 69 NV_DECLARE_TEAROFF_METHOD(get_alinkColor, GET_alinkColor, (VARIANT* p)); 70 NV_DECLARE_TEAROFF_METHOD(put_alinkColor, PUT_alinkColor, (VARIANT p)); 71 NV_DECLARE_TEAROFF_METHOD(get_vlinkColor, GET_vlinkColor, (VARIANT* p)); 72 NV_DECLARE_TEAROFF_METHOD(put_vlinkColor, PUT_vlinkColor, (VARIANT p)); 73 NV_DECLARE_TEAROFF_METHOD(get_parentDocument, GET_parentDocument, (IHTMLDocument2** p)); 74 NV_DECLARE_TEAROFF_METHOD(put_enableDownload, PUT_enableDownload, (VARIANT_BOOL v)); 75 NV_DECLARE_TEAROFF_METHOD(get_enableDownload, GET_enableDownload, (VARIANT_BOOL* p)); 76 NV_DECLARE_TEAROFF_METHOD(put_baseUrl, PUT_baseUrl, (BSTR v)); 77 NV_DECLARE_TEAROFF_METHOD(get_baseUrl, GET_baseUrl, (BSTR* p)); 78 NV_DECLARE_TEAROFF_METHOD(put_inheritStyleSheets, PUT_inheritStyleSheets, (VARIANT_BOOL v)); 79 NV_DECLARE_TEAROFF_METHOD(get_inheritStyleSheets, GET_inheritStyleSheets, (VARIANT_BOOL* p)); 80 NV_DECLARE_TEAROFF_METHOD(getElementsByName, getelementsbyname, (BSTR v, IHTMLElementCollection** p)); 81 NV_DECLARE_TEAROFF_METHOD(getElementsByTagName, getelementsbytagname, (BSTR v, IHTMLElementCollection** p)); 82 NV_DECLARE_TEAROFF_METHOD(getElementById, getelementbyid, (BSTR v, IHTMLElement** p)); 83 84 // IServiceProvider 85 STDMETHOD(QueryService)(REFGUID guidService, REFIID riid, void** ppv); 86 87 // Data Access 88 CDocument* Doc() { return _pDoc; } 89 CRootElement* Root() { return _pElementRoot; } 90 91 BOOL HasCollectionCache() { return HasLookasidePtr(LOOKASIDE_COLLECTIONCACHE); } 92 CCollectionCache* CollectionCache() { return (CCollectionCache*)GetLookasidePtr(LOOKASIDE_COLLECTIONCACHE); } 93 CCollectionCache* DelCollectionCache() { return (CCollectionCache*)DelLookasidePtr(LOOKASIDE_COLLECTIONCACHE); } 94 HRESULT SetCollectionCache(CCollectionCache* pCollectionCache) { return SetLookasidePtr(LOOKASIDE_COLLECTIONCACHE, pCollectionCache); } 95 96 BOOL HasParentMarkup() { return HasLookasidePtr(LOOKASIDE_PARENTMARKUP); } 97 CMarkup* ParentMarkup() { return (CMarkup*)GetLookasidePtr(LOOKASIDE_PARENTMARKUP); } 98 CMarkup* DelParentMarkup() { return (CMarkup*)DelLookasidePtr(LOOKASIDE_PARENTMARKUP); } 99 HRESULT SetParentMarkup(CMarkup* pMarkup) { return SetLookasidePtr(LOOKASIDE_PARENTMARKUP, pMarkup); } 100 101 CElement* Master() { return _pElementMaster; } 102 void ClearMaster() { _pElementMaster = NULL; } 103 104 CProgSink* GetProgSinkC(); 105 IProgSink* GetProgSink(); 106 107 CElement* FirstElement(); 108 109 // Remove 'Assert(Master())', once the root element is gone and these functions 110 // become meaningful for non-slave markups as well. 111 long GetContentFirstCp() { Assert(Master()); return 2; } 112 long GetContentLastCp() { Assert(Master()); return GetTextLength()-2; } 113 long GetContentTextLength() { Assert(Master()); return GetTextLength()-4; } 114 void GetContentTreeExtent(CTreePos** pptpStart, CTreePos** pptpEnd); 115 116 BOOL GetAutoWordSel() const { return TRUE; } 117 118 BOOL GetOverstrike() const { return _fOverstrike; } 119 void SetOverstrike(BOOL fSet) { _fOverstrike = (fSet) ? 1 : 0;} 120 121 BOOL GetLoaded() const { return _fLoaded; } 122 void SetLoaded(BOOL fLoaded) { _fLoaded = fLoaded; } 123 124 void SetStreaming(BOOL flag) { _fStreaming = (flag) ? 1 : 0; } 125 BOOL IsStreaming() const { return _fStreaming; } 126 127 // BUGBUG: need to figure this function out... 128 BOOL IsEditable(BOOL fCheckContainerOnly=FALSE) const; 129 130 // Top element cache 131 void EnsureTopElems(); 132 CElement* GetElementTop(); 133 CElement* GetElementClient() { EnsureTopElems(); return HasTopElemCache()?GetTopElemCache()->__pElementClientCached:NULL; } 134 135 // Other helpers 136 BOOL IsPrimaryMarkup() { return this==Doc()->_pPrimaryMarkup; } 137 long GetTextLength() { return _TxtArray._cchText; } 138 139 // GetRunOwner is an abomination that should be eliminated -- or at least moved off of the markup 140 CLayout* GetRunOwner(CTreeNode* pNode, CLayout* pLayoutParent=NULL); 141 CTreeNode* GetRunOwnerBranch(CTreeNode*, CLayout* pLayoutParent=NULL); 142 143 // Markup manipulation functions 144 void CompactStory() { _TxtArray.ShrinkBlocks(); } 145 146 HRESULT RemoveElementInternal( 147 CElement* pElementRemove, 148 DWORD dwFlags=NULL); 149 150 HRESULT InsertElementInternal( 151 CElement* pElementInsertThis, 152 CTreePosGap* ptpgBegin, 153 CTreePosGap* ptpgEnd, 154 DWORD dwFlags=NULL); 155 156 HRESULT SpliceTreeInternal( 157 CTreePosGap* ptpgStartSource, 158 CTreePosGap* ptpgEndSource, 159 CMarkup* pMarkupTarget =NULL, 160 CTreePosGap* ptpgTarget=NULL, 161 BOOL fRemove=TRUE, 162 DWORD dwFlags=NULL); 163 164 HRESULT InsertTextInternal( 165 CTreePos* ptpAfterInsert, 166 const TCHAR* pch, 167 long cch, 168 DWORD dwFlags=NULL); 169 170 HRESULT FastElemTextSet( 171 CElement* pElem, 172 const TCHAR* psz, 173 int cch, 174 BOOL fAsciiOnly); 175 176 // Undo only operations 177 HRESULT UndoRemoveSplice( 178 CMarkupPointer* pmpBegin, 179 CSpliceRecordList* paryRegion, 180 long cchRemove, 181 TCHAR* pchRemove, 182 long cchNodeReinsert, 183 DWORD dwFlags); 184 185 // Markup operation helpers 186 HRESULT ReparentDirectChildren( 187 CTreeNode* pNodeParentNew, 188 CTreePosGap* ptpgStart=NULL, 189 CTreePosGap* ptpgEnd=NULL); 190 191 HRESULT CreateInclusion( 192 CTreeNode* pNodeStop, 193 CTreePosGap* ptpgLocation, 194 CTreePosGap* ptpgInclusion, 195 long* pcchNeeded=NULL, 196 CTreeNode* pNodeAboveLocation=NULL, 197 BOOL fFullReparent=TRUE, 198 CTreeNode** ppNodeLastAdded=NULL); 199 200 HRESULT CloseInclusion(CTreePosGap* ptpgMiddle, long* pcchRemove=NULL); 201 202 HRESULT RangeAffected(CTreePos* ptpStart, CTreePos* ptpFinish); 203 HRESULT ClearCaches(CTreePos* ptpStart, CTreePos* ptpFinish); 204 HRESULT ClearRunCaches(DWORD dwFlags, CElement* pElement); 205 206 // Markup pointers 207 HRESULT EmbedPointers() { return _pmpFirst?DoEmbedPointers():S_OK; } 208 209 HRESULT DoEmbedPointers(); 210 211 BOOL HasUnembeddedPointers() { return !!_pmpFirst; } 212 213 // TextID manipulation 214 215 // Give a unique text id to every text chunk in 216 // the range given 217 HRESULT SetTextID(CTreePosGap* ptpgStart, CTreePosGap* ptpgEnd, long* plNewTextID); 218 219 // Get text ID for text to right 220 // -1 --> no text to right 221 // 0 --> no assigned TextID 222 long GetTextID(CTreePosGap* ptpg); 223 224 // Starting with ptpgStart, look for 225 // the extent of lTextID 226 HRESULT FindTextID(long lTextID, CTreePosGap* ptpgStart, CTreePosGap* ptpgEnd); 227 228 // If text to the left of ptpLeft has 229 // the same ID as text to the right of 230 // ptpRight, give the right fragment a 231 // new ID 232 void SplitTextID(CTreePos* ptpLeft, CTreePos* ptpRight); 233 234 // Splay Tree Primitives 235 CTreePos* NewTextPos(long cch, SCRIPT_ID sid=sidAsciiLatin, long lTextID=0); 236 CTreePos* NewPointerPos(CMarkupPointer* pPointer, BOOL fRight, BOOL fStick); 237 238 typedef CTreePos SUBLIST; 239 HRESULT Append(CTreePos* ptp); 240 HRESULT Insert(CTreePos* ptpNew, CTreePosGap* ptpgInsert); 241 HRESULT Insert(CTreePos* ptpNew, CTreePos* ptpInsert, BOOL fBefore); 242 HRESULT Move(CTreePos* ptpMove, CTreePosGap* ptpgDest); 243 HRESULT Move(CTreePos* ptpMove, CTreePos* ptpDest, BOOL fBefore); 244 HRESULT Remove(CTreePos* ptpStart, CTreePos* ptpFinish); 245 HRESULT Remove(CTreePos* ptp) { return Remove(ptp, ptp); } 246 HRESULT Split(CTreePos* ptpSplit, long cchLeft, SCRIPT_ID sidNew=sidNil); 247 HRESULT Join(CTreePos* ptpJoin); 248 HRESULT ReplaceTreePos(CTreePos* ptpOld, CTreePos* ptpNew); 249 HRESULT MergeText(CTreePos* ptpMerge); 250 HRESULT SetTextPosID(CTreePos** pptpText, long lTextID); 251 HRESULT RemovePointerPos(CTreePos* ptp, CTreePos** pptpUpdate, long* pichUpdate); 252 253 HRESULT SpliceOut(CTreePos* ptpStart, CTreePos* ptpFinish, SUBLIST* pSublistSplice); 254 HRESULT SpliceIn(SUBLIST* pSublistSplice, CTreePos* ptpSplice); 255 HRESULT InsertPosChain(CTreePos* ptpChainHead, CTreePos* ptpChainTail, CTreePos* ptpInsertBefore); 256 257 // splay tree search routines 258 CTreePos* FirstTreePos() const; 259 CTreePos* LastTreePos() const; 260 CTreePos* TreePosAtCp(long cp, long* pcchOffset) const; 261 CTreePos* TreePosAtSourceIndex(long iSourceIndex); 262 263 // General splay information 264 long NumElems() const { return _tpRoot.GetElemLeft(); } 265 long Cch() const { return _tpRoot._cchLeft; } 266 long CchInRange(CTreePos* ptpFirst, CTreePos* ptpLast); 267 268 // Force a splay 269 void FocusAt(CTreePos* ptp) { ptp->Splay(); } 270 271 // splay tree primitive helpers 272 protected: 273 CTreePos* AllocData1Pos(); 274 CTreePos* AllocData2Pos(); 275 void FreeTreePos(CTreePos* ptp); 276 void ReleaseTreePos(CTreePos* ptp, BOOL fLastRelease=FALSE); 277 BOOL ShouldSplay(long cDepth) const; 278 HRESULT MergeTextHelper(CTreePos* ptpMerge); 279 280 public: 281 // Text Story 282 LONG GetTextLength() const { return _TxtArray._cchText; } 283 284 // Notifications 285 void Notify(CNotification* pnf); 286 void Notify(CNotification& rnf) { Notify(&rnf); } 287 288 // notification helpers 289 protected: 290 void SendNotification(CNotification* pnf, CDataAry<CNotification>* paryNotification); 291 BOOL ElementWantsNotification(CElement* pElement, CNotification* pnf); 292 293 void NotifyElement(CElement* pElement, CNotification* pnf); 294 void NotifyAncestors(CNotification* pnf); 295 void NotifyDescendents(CNotification* pnf); 296 void NotifyTreeLevel(CNotification* pnf); 297 298 public: 299 // Branch searching functions - I'm sure some of these aren't needed 300 // 301 // Note: All of these (except InStory versions) implicitly stop searching at a FlowLayout 302 CTreeNode* FindMyListContainer(CTreeNode* pNodeStartHere); 303 CTreeNode* SearchBranchForChildOfScope(CTreeNode* pNodeStartHere, CElement* pElementFindChildOfMyScope); 304 CTreeNode* SearchBranchForChildOfScopeInStory(CTreeNode* pNodeStartHere, CElement* pElementFindChildOfMyScope); 305 CTreeNode* SearchBranchForScopeInStory(CTreeNode* pNodeStartHere, CElement* pElementFindMyScope); 306 CTreeNode* SearchBranchForScope(CTreeNode* pNodeStartHere, CElement* pElementFindMyScope); 307 CTreeNode* SearchBranchForNode(CTreeNode* pNodeStartHere, CTreeNode* brFindMe); 308 CTreeNode* SearchBranchForNodeInStory(CTreeNode* pNodeStartHere, CTreeNode* brFindMe); 309 CTreeNode* SearchBranchForTag(CTreeNode* pNodeStartHere, ELEMENT_TAG); 310 CTreeNode* SearchBranchForTagInStory(CTreeNode* pNodeStartHere, ELEMENT_TAG); 311 CTreeNode* SearchBranchForBlockElement(CTreeNode* pNodeStartHere, CFlowLayout* pFLContext=NULL); 312 CTreeNode* SearchBranchForNonBlockElement(CTreeNode* pNodeStartHere, CFlowLayout* pFLContext=NULL); 313 CTreeNode* SearchBranchForAnchor(CTreeNode* pNodeStartHere); 314 CTreeNode* SearchBranchForCriteria(CTreeNode* pNodeStartHere, BOOL (*pfnSearchCriteria)(CTreeNode*)); 315 CTreeNode* SearchBranchForCriteriaInStory(CTreeNode* pNodeStartHere, BOOL (*pfnSearchCriteria)(CTreeNode*)); 316 317 void EnsureFormats(); 318 319 // Markup TextFrag services 320 // Markup TextFrags are used to store arbitrary string data in the markup. Mostly 321 // this is used to persist and edit conditional comment tags 322 CMarkupTextFragContext* EnsureTextFragContext(); 323 324 BOOL HasTextFragContext() { return HasLookasidePtr(LOOKASIDE_TEXTFRAGCONTEXT); } 325 CMarkupTextFragContext* GetTextFragContext() { return (CMarkupTextFragContext*)GetLookasidePtr(LOOKASIDE_TEXTFRAGCONTEXT); } 326 HRESULT SetTextFragContext(CMarkupTextFragContext* ptfc) { return SetLookasidePtr(LOOKASIDE_TEXTFRAGCONTEXT, ptfc); } 327 CMarkupTextFragContext* DelTextFragContext() { return (CMarkupTextFragContext*)DelLookasidePtr(LOOKASIDE_TEXTFRAGCONTEXT); } 328 329 // Stores the cached values for the client element 330 CMarkupTopElemCache* EnsureTopElemCache(); 331 332 BOOL HasTopElemCache() { return HasLookasidePtr(LOOKASIDE_TOPELEMCACHE); } 333 CMarkupTopElemCache* GetTopElemCache() { return (CMarkupTopElemCache*)GetLookasidePtr(LOOKASIDE_TOPELEMCACHE); } 334 HRESULT SetTopElemCache(CMarkupTopElemCache* ptec) { return SetLookasidePtr(LOOKASIDE_TOPELEMCACHE, ptec); } 335 CMarkupTopElemCache* DelTopElemCache() { return (CMarkupTopElemCache*)DelLookasidePtr(LOOKASIDE_TOPELEMCACHE); } 336 337 // Selection Methods 338 VOID GetSelectionChunksForLayout(CFlowLayout* pFlowLayout, CPtrAry<HighlightSegment*>* paryHighlight, int* piCpMin, int* piCpMax); 339 HRESULT EnsureSelRenSvc(); 340 VOID HideSelection(); 341 VOID ShowSelection(); 342 VOID InvalidateSelection(BOOL fFireOM); 343 344 345 // Collections support 346 enum 347 { 348 ELEMENT_COLLECTION = 0, 349 FORMS_COLLECTION, 350 ANCHORS_COLLECTION, 351 LINKS_COLLECTION, 352 IMAGES_COLLECTION, 353 APPLETS_COLLECTION, 354 SCRIPTS_COLLECTION, 355 WINDOW_COLLECTION, 356 EMBEDS_COLLECTION, 357 REGION_COLLECTION, 358 LABEL_COLLECTION, 359 NAVDOCUMENT_COLLECTION, 360 FRAMES_COLLECTION, 361 NUM_DOCUMENT_COLLECTIONS 362 }; 363 // DISPID range for FRAMES_COLLECTION 364 enum 365 { 366 FRAME_COLLECTION_MIN_DISPID = ((DISPID_COLLECTION_MIN+DISPID_COLLECTION_MAX)*2)/3+1, 367 FRAME_COLLECTION_MAX_DISPID = DISPID_COLLECTION_MAX 368 }; 369 370 HRESULT EnsureCollectionCache(long lCollectionIndex); 371 HRESULT AddToCollections(CElement* pElement, CCollectionBuildContext* pWalk); 372 373 HRESULT InitCollections(void); 374 375 NV_DECLARE_ENSURE_METHOD(EnsureCollections, ensurecollections, (long lIndex, long* plCollectionVersion)); 376 HRESULT GetCollection(int iIndex, IHTMLElementCollection** ppdisp); 377 HRESULT GetElementByNameOrID(LPTSTR szName, CElement** ppElement); 378 HRESULT GetDispByNameOrID(LPTSTR szName, IDispatch** ppDisp, BOOL fAlwaysCollection=FALSE); 379 380 CTreeNode* InFormCollection(CTreeNode* pNode); 381 382 // Lookaside pointers 383 enum 384 { 385 LOOKASIDE_COLLECTIONCACHE = 0, 386 LOOKASIDE_PARENTMARKUP = 1, 387 LOOKASIDE_BEHAVIORCONTEXT = 2, 388 LOOKASIDE_TEXTFRAGCONTEXT = 3, 389 LOOKASIDE_TOPELEMCACHE = 4, 390 LOOKASIDE_STYLESHEETS = 5, 391 LOOKASIDE_TEXTRANGE = 6, 392 LOOKASIDE_MARKUP_NUMBER = 7 393 }; 394 395 BOOL HasLookasidePtr(int iPtr) { return (_fHasLookasidePtr&(1<<iPtr)); } 396 void* GetLookasidePtr(int iPtr); 397 HRESULT SetLookasidePtr(int iPtr, void* pv); 398 void* DelLookasidePtr(int iPtr); 399 400 void ClearLookasidePtrs(); 401 402 // IUnknown 403 DECLARE_PLAIN_IUNKNOWN(CMarkup); 404 STDMETHOD(PrivateQueryInterface)(REFIID, void**); 405 406 // ISegmentList 407 NV_DECLARE_TEAROFF_METHOD(MovePointersToSegment, movepointerstosegment, ( 408 int iSegmentIndex, IMarkupPointer* pStart, IMarkupPointer* pEnd)); 409 NV_DECLARE_TEAROFF_METHOD(GetSegmentCount, getsegmentcount, ( 410 int* piSegmentCount, SELECTION_TYPE* peType)); 411 412 // ISelectionRenderingServices 413 NV_DECLARE_TEAROFF_METHOD(AddSegment, addsegment, ( 414 IMarkupPointer* pStart, IMarkupPointer* pEnd, HIGHLIGHT_TYPE HighlightType, int* iSegmentIndex)); 415 NV_DECLARE_TEAROFF_METHOD(AddElementSegment, addelementsegment, ( 416 IHTMLElement* pElement, int* iSegmentIndex)); 417 NV_DECLARE_TEAROFF_METHOD(MoveSegmentToPointers, movesegmenttopointers, ( 418 int iSegmentIndex, IMarkupPointer* pStart, IMarkupPointer* pEnd, HIGHLIGHT_TYPE HighlightType)); 419 NV_DECLARE_TEAROFF_METHOD(GetElementSegment, getelementsegment, ( 420 int iSegmentIndex, IHTMLElement** ppElement)); 421 NV_DECLARE_TEAROFF_METHOD(SetElementSegment, setelementsegment, ( 422 int iSegmentIndex, IHTMLElement* pElement)); 423 NV_DECLARE_TEAROFF_METHOD(ClearSegment, clearsegment, ( 424 int iSegmentIndex, BOOL fInvalidate)); 425 NV_DECLARE_TEAROFF_METHOD(ClearSegments, clearsegments, (BOOL fInvalidate)); 426 NV_DECLARE_TEAROFF_METHOD(ClearElementSegments, clearelementsegments, ()); 427 428 // IMarkupContainer methods 429 NV_DECLARE_TEAROFF_METHOD(OwningDoc, owningdoc, ( 430 IHTMLDocument2** ppDoc)); 431 432 // Ref counting helpers 433 static void ReplacePtr(CMarkup** pplhs, CMarkup* prhs); 434 static void SetPtr(CMarkup** pplhs, CMarkup* prhs); 435 static void ClearPtr(CMarkup** pplhs); 436 static void StealPtrSet(CMarkup** pplhs, CMarkup* prhs); 437 static void StealPtrReplace(CMarkup** pplhs, CMarkup* prhs); 438 static void ReleasePtr(CMarkup* pMarkup); 439 440 // CMarkup::CLock 441 class CLock 442 { 443 public: 444 CLock(CMarkup* pMarkup); 445 ~CLock(); 446 447 private: 448 CMarkup* _pMarkup; 449 }; 450 451 protected: 452 static const CLASSDESC s_classdesc; 453 virtual const CBase::CLASSDESC* GetClassDesc() const { return &s_classdesc; } 454 455 // Data 456 public: 457 CProgSink* _pProgSink; 458 459 CDocument* _pDoc; 460 461 // The following are similar to the CDoc's equivalent, but pertain to this 462 // markup alone. 463 long GetMarkupTreeVersion() { return __lMarkupTreeVersion; } 464 long GetMarkupContentsVersion() { return __lMarkupContentsVersion; } 465 466 // Do NOT modify these version numbers unless the document structure 467 // or content is being modified. 468 // 469 // In particular, incrementing these to get a cache to rebuild is 470 // BAD because it causes all sorts of other stuff to rebuilt. 471 long __lMarkupTreeVersion; // Element structure 472 long __lMarkupContentsVersion; // Any content 473 474 void UpdateMarkupTreeVersion() 475 { 476 CDocument* pDoc = Doc(); 477 478 __lMarkupTreeVersion++; 479 __lMarkupContentsVersion++; 480 481 pDoc->__lDocTreeVersion++; 482 pDoc->__lDocContentsVersion++; 483 } 484 485 void UpdateMarkupContentsVersion() 486 { 487 __lMarkupContentsVersion++; 488 Doc()->UpdateDocContentsVersion(); 489 } 490 491 private: 492 CRootElement* _pElementRoot; 493 CElement* _pElementMaster; 494 495 // Story data 496 CTxtArray _TxtArray; 497 498 long _lTopElemsVersion; 499 500 // Selection state 501 CSelectionRenderingServiceProvider* _pSelRenSvcProvider; // Object to Delegate to. 502 503 // Notification data 504 DECLARE_CDataAry(CAryANotify, CNotification) 505 CAryANotify _aryANotification; 506 507 private: 508 // This is the list of pointers positioned in this markup 509 // which do not have an embedding. 510 CMarkupPointer* _pmpFirst; 511 512 // Splay Tree Data 513 CTreePos _tpRoot; // dummy root node 514 CTreePos* _ptpFirst; // cached first (leftmost) node 515 void* _pvPool; // list of pool blocks (so they can be freed) 516 CTreeDataPos* _ptdpFree; // head of free list 517 BYTE _abPoolInitial[sizeof(void*)+TREEDATA1SIZE*INITIAL_TREEPOS_POOL_SIZE]; // The initial pool of TreePos objects 518 519 public: 520 struct 521 { 522 DWORD _fOverstrike : 1; // 1 Overstrike mode vs insert mode 523 DWORD _fLoaded : 1; // 3 Is the markup completely parsed 524 DWORD _fNoUndoInfo : 1; // 4 Don't store any undo info for this markup 525 DWORD _fIncrementalAlloc : 1; // 5 The text array should slow start 526 DWORD _fStreaming : 1; // 6 True during parsing 527 DWORD _fUnstable : 1; // 7 the tree is unstable because of the tree services/DOM operations 528 // were performed on the tree and nobody call to validate the tree 529 DWORD _fInSendAncestor : 1; // 8 Notification - We're sending something to ancestors 530 DWORD _fUnused1 : 1; // 9 531 DWORD _fEnableDownload : 1; // 10 Allows content to be downloaded in this markup 532 DWORD _fPad : 5; // 11-15 Padding to align lookaside flags on byte 533 DWORD _fHasLookasidePtr : 8; // 16-23 Lookaside flags 534 DWORD _fUnused2 : 8; // 24-31 535 }; 536 537 // Style sheets moved from CDocument 538 HRESULT EnsureStyleSheets(); 539 HRESULT ApplyStyleSheets( 540 CStyleInfo* pStyleInfo, 541 ApplyPassType passType=APPLY_All, 542 BOOL* pfContainsImportant=NULL); 543 544 BOOL HasStyleSheets() 545 { 546 return FALSE; 547 } 548 549 private: 550 NO_COPY(CMarkup); 551 };
1 class CTreePos 2 { 3 friend class CMarkup; 4 friend class CTreePosGap; 5 friend class CTreeNode; 6 friend class CSpliceTreeEngine; 7 friend class CMarkupUndoUnit; 8 9 public: 10 DECLARE_MEMALLOC_NEW_DELETE(); 11 12 // TreePos come in various flavors: 13 // Uninit this node is uninitialized 14 // Node marks begin or end of a CTreeNode's scope 15 // Text holds a bunch of text (formerly known as CElementRun) 16 // Pointer implements an IMarkupPointer 17 // Be sure the bit field _eType (below) is big enough for all the flavors 18 enum EType { Uninit=0x0, NodeBeg=0x1, NodeEnd=0x2, Text=0x4, Pointer=0x8 }; 19 20 // cast to CTreeDataPos 21 CTreeDataPos* DataThis(); 22 const CTreeDataPos* DataThis() const; 23 24 // accessors 25 EType Type() const { return (EType)(GetFlags()&TPF_ETYPE_MASK); } 26 void SetType(EType etype) { Assert(etype <= Pointer); SetFlags((GetFlags()&~TPF_ETYPE_MASK)|(etype)); } 27 BOOL IsUninit() const { return !TestFlag(NodeBeg|NodeEnd|Text|Pointer); } 28 BOOL IsNode() const { return TestFlag(NodeBeg|NodeEnd); } 29 BOOL IsText() const { return TestFlag(Text); } 30 BOOL IsPointer() const { return TestFlag(Pointer); } 31 BOOL IsDataPos() const { return TestFlag(TPF_DATA_POS); } 32 BOOL IsData2Pos() const { Assert(!IsNode()); return TestFlag(TPF_DATA2_POS); } 33 BOOL IsBeginNode() const { return TestFlag(NodeBeg); } 34 BOOL IsEndNode() const { return TestFlag(NodeEnd); } 35 BOOL IsEdgeScope() const { Assert(IsNode()); return TestFlag(TPF_EDGE); } 36 BOOL IsBeginElementScope() const { return IsBeginNode()&&IsEdgeScope(); } 37 BOOL IsEndElementScope() const { return IsEndNode()&&IsEdgeScope(); } 38 BOOL IsBeginElementScope(CElement* pElem); 39 BOOL IsEndElementScope(CElement* pElem); 40 41 CMarkup* GetMarkup(); 42 BOOL IsInMarkup(CMarkup* pMarkup) { return GetMarkup()==pMarkup; } 43 44 // The following are logical comparison operations (two pos are equal 45 // when separated by only pointers or empty text positions). 46 int InternalCompare(CTreePos* ptpThat); 47 48 CTreeNode* Branch() const; // Only valid to call on NodePoses 49 CTreeNode* GetBranch() const; // Can be called on any pos, may be expensive 50 51 CMarkupPointer* MarkupPointer() const; 52 void SetMarkupPointer(CMarkupPointer*); 53 54 // GetInterNode finds the node with direct influence 55 // over the position directly after this CTreePos. 56 CTreeNode* GetInterNode() const; 57 58 long Cch() const; 59 long Sid() const; 60 61 BOOL HasTextID() const { return IsText()&&TestFlag(TPF_DATA2_POS); } 62 long TextID() const; 63 64 long GetCElements() const { return IsBeginElementScope()?1:0; } 65 long SourceIndex(); 66 67 long GetCch() const { return IsNode()?1:IsText()?Cch():0; } 68 69 long GetCp(); 70 71 int Gravity() const; 72 void SetGravity(BOOL fRight); 73 int Cling() const; 74 void SetCling(BOOL fStick); 75 76 // modifiers 77 void SetScopeFlags(BOOL fEdge); 78 void ChangeCch(long cchDelta); 79 80 // navigation 81 CTreePos* NextTreePos(); 82 CTreePos* PreviousTreePos(); 83 84 CTreePos* NextNonPtrTreePos(); 85 CTreePos* PreviousNonPtrTreePos(); 86 87 static BOOL IsLegalPosition(CTreePos* ptpLeft, CTreePos* ptpRight); 88 BOOL IsLegalPosition(BOOL fBefore) 89 { 90 return fBefore?IsLegalPosition(PreviousTreePos(), this):IsLegalPosition(this, NextTreePos()); 91 } 92 93 protected: 94 void InitSublist(); 95 CTreePos* Parent() const; 96 CTreePos* LeftChild() const; 97 CTreePos* RightChild() const; 98 CTreePos* LeftmostDescendant() const; 99 CTreePos* RightmostDescendant() const; 100 void GetChildren(CTreePos** ppLeft, CTreePos** ppRight) const; 101 HRESULT Remove(); 102 void Splay(); 103 void RotateUp(CTreePos* p, CTreePos* g); 104 void ReplaceChild(CTreePos* pOld, CTreePos* pNew); 105 void RemoveChild(CTreePos* pOld); 106 void ReplaceOrRemoveChild(CTreePos* pOld, CTreePos* pNew); 107 108 // constructors (for use only by CMarkup and CTreeNode) 109 CTreePos() {} 110 111 private: 112 // distributed order-statistic fields 113 DWORD _cElemLeftAndFlags; // number of elements that begin in my left subtree 114 DWORD _cchLeft; // number of characters in my left subtree 115 // structure fields (to maintain the splay tree) 116 CTreePos* _pFirstChild; // pointer to my leftmost child 第一个孩子(有可能是左,也有可能是右) 117 CTreePos* _pNext; // pointer to right sibling or parent 右兄弟或者父亲 118 119 enum 120 { 121 TPF_ETYPE_MASK = 0x0F, 122 TPF_LEFT_CHILD = 0x10, 123 TPF_LAST_CHILD = 0x20, 124 TPF_EDGE = 0x40, 125 TPF_DATA2_POS = 0x40, 126 TPF_DATA_POS = 0x80, 127 TPF_FLAGS_MASK = 0xFF, 128 TPF_FLAGS_SHIFT = 8 129 }; 130 131 DWORD GetFlags() const { return (_cElemLeftAndFlags); } 132 void SetFlags(DWORD dwFlags) { _cElemLeftAndFlags = dwFlags; } 133 BOOL TestFlag(DWORD dwFlag) const { return (!!(GetFlags()&dwFlag)); } 134 void SetFlag(DWORD dwFlag) { SetFlags(GetFlags()|dwFlag); } 135 void ClearFlag(DWORD dwFlag) { SetFlags(GetFlags()&~(dwFlag)); } 136 137 long GetElemLeft() const { return ((long)(_cElemLeftAndFlags>>TPF_FLAGS_SHIFT)); } 138 void SetElemLeft(DWORD cElem) { _cElemLeftAndFlags = (_cElemLeftAndFlags&TPF_FLAGS_MASK)|(DWORD)(cElem<<TPF_FLAGS_SHIFT); } 139 void AdjElemLeft(long cDelta) { _cElemLeftAndFlags += cDelta << TPF_FLAGS_SHIFT; } 140 BOOL IsLeftChild() const { return (TestFlag(TPF_LEFT_CHILD)); } // 确保当前位置左右信息 141 BOOL IsLastChild() const { return (TestFlag(TPF_LAST_CHILD)); } // 确保是否有下一个兄弟 左/右 Next表示什么 在左边的时候如何判断Next表示什么呢?这时候就需要IsLastChild判断有兄弟没 142 void MarkLeft() { SetFlag(TPF_LEFT_CHILD); } 143 void MarkRight() { ClearFlag(TPF_LEFT_CHILD); } 144 void MarkLeft(BOOL fLeft) { SetFlags((GetFlags()&~TPF_LEFT_CHILD)|BOOLFLAG(fLeft, TPF_LEFT_CHILD)); } 145 void MarkFirst() { ClearFlag(TPF_LAST_CHILD); } 146 void MarkLast() { SetFlag(TPF_LAST_CHILD); } 147 void MarkLast(BOOL fLast) { SetFlags((GetFlags()&~TPF_LAST_CHILD)|BOOLFLAG(fLast, TPF_LAST_CHILD)); } 148 149 void SetFirstChild(CTreePos* ptp) { _pFirstChild = ptp; } 150 void SetNext(CTreePos* ptp) { _pNext = ptp; } 151 CTreePos* FirstChild() const { return (_pFirstChild); } 152 CTreePos* Next() const { return (_pNext); } 153 154 // support for CTreePosGap 155 CTreeNode* SearchBranchForElement(CElement* pElement, BOOL fLeft); 156 157 // count encapsulation 158 enum ECountFlags { TP_LEFT=0x1, TP_DIRECT=0x2, TP_BOTH=0x3 }; 159 160 struct SCounts 161 { 162 DWORD _cch; 163 DWORD _cElem; 164 void Clear(); 165 void Increase(const CTreePos* ptp); // TP_DIRECT is implied 166 BOOL IsNonzero(); 167 }; 168 169 void ClearCounts(); 170 void IncreaseCounts(const CTreePos* ptp, unsigned fFlags); 171 void IncreaseCounts(const SCounts* pCounts ); 172 void DecreaseCounts(const CTreePos* ptp, unsigned fFlags); 173 BOOL HasNonzeroCounts(unsigned fFlags); 174 175 BOOL LogicallyEqual(CTreePos* ptpRight); 176 177 public: 178 NO_COPY(CTreePos); 179 };
1 class CTreeDataPos : public CTreePos 2 { 3 friend class CTreePos; 4 friend class CMarkup; 5 friend class CMarkupUndoUnit; 6 7 public: 8 DECLARE_MEMALLOC_NEW_DELETE() 9 10 protected: 11 union 12 { 13 DATAPOSTEXT t; 14 DATAPOSPOINTER p; 15 }; 16 17 private: 18 CTreeDataPos() {} 19 NO_COPY(CTreeDataPos); 20 };
1 class CMarkupPointer : public CBase, public IMarkupPointer 2 { 3 DECLARE_CLASS_TYPES(CMarkupPointer, CBase); 4 5 friend class CDocument; // for implementation of "OrSlave" versions of Left, Right, MoveToContainer on IHTMLViewServices 6 friend class CMarkup; 7 8 public: 9 DECLARE_MEMALLOC_NEW_DELETE() 10 11 CMarkupPointer(CDocument* pDoc) 12 : _pDoc(pDoc), _pMarkup(NULL), _pmpNext(NULL), _pmpPrev(NULL), 13 _fRightGravity(FALSE), _fCling(FALSE), _fEmbedded(FALSE), _fKeepMarkupAlive(FALSE), 14 _fAlwaysEmbed(FALSE), _ptpRef(NULL), _ichRef(0), _cpCache(-1), _verCp(0) 15 {} 16 17 virtual ~CMarkupPointer() 18 { 19 Unposition(); 20 Assert(!Markup()); 21 } 22 23 // 24 // CBase methods 25 DECLARE_PLAIN_IUNKNOWN(CMarkupPointer); 26 DECLARE_PRIVATE_QI_FUNCS(CBase); 27 28 virtual const CBase::CLASSDESC* GetClassDesc() const; 29 30 /// 31 // IMarkupPointer methods 32 STDMETHODIMP OwningDoc(IHTMLDocument2** ppDoc); 33 STDMETHODIMP Gravity(POINTER_GRAVITY* peGravity); 34 STDMETHODIMP SetGravity(POINTER_GRAVITY eGravity); 35 STDMETHODIMP Cling(BOOL* pfCling); 36 STDMETHODIMP SetCling(BOOL fCling); 37 STDMETHODIMP MoveAdjacentToElement(IHTMLElement* pElement, ELEMENT_ADJACENCY eAdj); 38 STDMETHODIMP MoveToPointer(IMarkupPointer* pPointer); 39 STDMETHODIMP MoveToContainer(IMarkupContainer* pContainer, BOOL fAtStart); 40 STDMETHODIMP Unposition(); 41 STDMETHODIMP IsPositioned(BOOL*); 42 STDMETHODIMP GetContainer(IMarkupContainer**); 43 44 STDMETHODIMP Left( 45 BOOL fMove, 46 MARKUP_CONTEXT_TYPE* pContext, 47 IHTMLElement** ppElement, 48 long* pcch, 49 OLECHAR* pchText); 50 51 STDMETHODIMP Right( 52 BOOL fMove, 53 MARKUP_CONTEXT_TYPE* pContext, 54 IHTMLElement** ppElement, 55 long* pcch, 56 OLECHAR* pchText); 57 58 STDMETHODIMP MoveUnit(MOVEUNIT_ACTION muAction); 59 60 STDMETHODIMP CurrentScope(IHTMLElement** ppElemCurrent); 61 62 STDMETHODIMP FindText( 63 OLECHAR* pchFindText, 64 DWORD dwFlags, 65 IMarkupPointer* pIEndMatch=NULL, 66 IMarkupPointer* pIEndSearch=NULL); 67 68 STDMETHODIMP IsLeftOf (IMarkupPointer* pPointer, BOOL* pfResult); 69 STDMETHODIMP IsLeftOfOrEqualTo (IMarkupPointer* pPointer, BOOL* pfResult); 70 STDMETHODIMP IsRightOf (IMarkupPointer* pPointer, BOOL* pfResult); 71 STDMETHODIMP IsRightOfOrEqualTo (IMarkupPointer* pPointer, BOOL* pfResult); 72 STDMETHODIMP IsEqualTo (IMarkupPointer* pPointerThat, BOOL* pfAreEqual); 73 74 HRESULT FindTextIdentity(long textID, CMarkupPointer* pPointerOtherEnd); 75 HRESULT SetTextIdentity(CMarkupPointer* pPointerOtherEnd, long* plNewTextID); 76 77 HRESULT IsInsideURL(IMarkupPointer* pRight, BOOL* pfResult); 78 79 /// 80 // CMarkupPointer methodse 81 HRESULT Left( 82 BOOL fMove, 83 MARKUP_CONTEXT_TYPE* pContext, 84 CTreeNode** ppNode, 85 long* pcch, 86 OLECHAR* pchText, 87 long* plTextID) 88 { 89 return There(TRUE, fMove, pContext, ppNode, pcch, pchText, plTextID, 0); 90 } 91 92 HRESULT Right( 93 BOOL fMove, 94 MARKUP_CONTEXT_TYPE* pContext, 95 CTreeNode** ppNode, 96 long* pcch, 97 OLECHAR* pchText, 98 long* plTextID) 99 { 100 return There(FALSE, fMove, pContext, ppNode, pcch, pchText, plTextID, 0); 101 } 102 103 int Gravity() const { return _fRightGravity; } 104 BOOL Cling() const { return _fCling; } 105 BOOL KeepMarkupAlive() const { return _fKeepMarkupAlive; } 106 void SetKeepMarkupAlive(BOOL fKeepAlive); 107 BOOL AlwaysEmbed() const { return _fAlwaysEmbed; } 108 void SetAlwaysEmbed(BOOL fAlwaysEmbed); 109 110 HRESULT MoveAdjacentToElement(CElement* pElement, ELEMENT_ADJACENCY adj); 111 HRESULT MoveToPointer(CMarkupPointer* pPointer); 112 HRESULT MoveToContainer(CMarkup* pContainer, BOOL fAtStart, DWORD dwFlags=0); 113 114 HRESULT MoveToGap(CTreePosGap* ptpg, CMarkup* pMarkup, BOOL fForceEmbedding=FALSE); 115 116 HRESULT MoveToReference(CTreePos* ptp, long ich, CMarkup* pMarkup, long cpNew); 117 118 HRESULT MoveToOrphan(CTreePos*); 119 120 CTreeNode* CurrentScope(DWORD dwFlags=0); 121 122 BOOL FindText( 123 TCHAR* pstr, 124 DWORD dwFlags, 125 CMarkupPointer* pEndMatch, 126 CMarkupPointer* pEndSearch); 127 128 BOOL IsEqualTo (CMarkupPointer* pPointerThat); 129 BOOL IsLeftOf (CMarkupPointer* pPointerThat); 130 BOOL IsLeftOfOrEqualTo (CMarkupPointer* pPointerThat); 131 BOOL IsRightOf (CMarkupPointer* pPointerThat); 132 BOOL IsRightOfOrEqualTo (CMarkupPointer* pPointerThat); 133 134 HRESULT MoveToCp(long cp, CMarkup* pMarkup); 135 136 HRESULT QueryBreaks(DWORD* pdwBreaks); 137 138 // public helpers 139 140 // called from CTreePos when it goes away 141 void OnPositionReleased(); 142 143 CDocument* Doc() const { return _pDoc; } 144 145 CTreeNode* Branch() { return _pMarkup?_ptp->GetInterNode():NULL; } 146 147 BOOL IsPositioned() const { return _pMarkup!=NULL; } 148 149 CMarkup* Markup() const { return _pMarkup; } 150 151 void SetMarkup(CMarkup* pMarkup); 152 153 // Get the embedded treepos. Be careful, pointers are not always 154 // embedded. 155 CTreePos* GetEmbeddedTreePos() 156 { 157 Assert(_fEmbedded); 158 return _fEmbedded?_ptpEmbeddedPointer:NULL; 159 } 160 161 // GetNormalizedReference returns a ptp/ich pair which is 162 // immediately after REAL content. Not real content is 163 // pointers and empty text runs. 164 CTreePos* GetNormalizedReference(long& ich) const; 165 166 // Returns the cp for this pointer. -1 if unpositioned; 167 long GetCp(); 168 169 // "There" does the work of both Left and Right 170 HRESULT There( 171 BOOL fLeft, 172 BOOL fMove, 173 MARKUP_CONTEXT_TYPE* pContext, 174 CTreeNode** ppNode, // Not AddRefed 175 long* pcch, 176 OLECHAR* pchText, 177 long* plTextID, 178 DWORD* dwFlags); 179 180 HRESULT There( 181 BOOL fLeft, 182 BOOL fMove, 183 MARKUP_CONTEXT_TYPE* pContext, 184 IHTMLElement** ppElement, 185 long* pcch, 186 OLECHAR* pchText, 187 DWORD* dwFlags); 188 189 private: 190 HRESULT UnEmbed(CTreePos** pptp, long* pich); 191 192 HRESULT Embed(CMarkup* pMarkup, CTreePos* ptp, long ich, long cpNew); 193 194 // representation 195 static const CBase::CLASSDESC s_classdesc; // classDesc (for CBase) 196 197 CDocument* _pDoc; // The doc that owns me 198 199 // The _pMarkup member points the markup I'm positioned in, 200 // when I'm positioned. If it is NULL, then I'm not positioned 201 // in any markup, and thus the members which indicate where 202 // are unused. 203 CMarkup* _pMarkup; 204 205 // Each markup has a list of markup pointers which are in the markup, but 206 // do not have a pointer pos. 207 CMarkupPointer* _pmpNext; 208 CMarkupPointer* _pmpPrev; 209 210 void AddMeToList(); 211 void RemoveMeFromList(); 212 213 // The members _fRightGravity and _fCling always indicate the state of 214 // gravity and cling, even when we are embedded, when the pointer pos 215 // has redundant indicators of this. They are redundant because we want 216 // gravity and cling with out CMarkupPointer. 217 // 218 // The _fEmbedded member is used when _pMarkup is non-NULL to indicate 219 // if our position is indicated by an embedded pointer pos or a reference 220 // to a non-pointer pos / offset pair. 221 unsigned _fRightGravity : 1; // When unpositioned, gravity is stored here 222 unsigned _fCling : 1; // When unpositioned, cling is stored here 223 unsigned _fEmbedded : 1; // Do I have have a pointer pos in the splay tree? 224 unsigned _fKeepMarkupAlive : 1; // Keep addref on markup 225 unsigned _fAlwaysEmbed : 1; // Always embed this pointer 226 227 // The _cpCache member records the cp this pointer is currently at. If 228 // the contents version of the markup matches that stored here, then 229 // _cpCache is up to date. 230 long _cpCache; 231 long _verCp; 232 233 long GetCpSlow() const; 234 BOOL CpIsCached() const; 235 236 void Validate() const {} 237 238 union 239 { 240 CTreePos* _ptp; // Quick access to ptp if embedded or not 241 242 CTreePos* _ptpEmbeddedPointer; // When embeded, this points to Pointer pos 243 244 struct // When not embedded, this says where I am 245 { 246 CTreePos* _ptpRef; // I live just after this (non-pointer) pos 247 long _ichRef; // If text pos, this many chars into it 248 }; 249 }; 250 251 NO_COPY(CMarkupPointer); 252 };