zoukankan      html  css  js  c++  java
  • IE源代码摘抄,基于泄漏的IE5.0(持续更新)

    下载了一份很久以前泄漏的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 };
    class CTreeNode
     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 }
    CTreePos的释放函数 CMarkup::FreeTreePos
      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 };
    元素的基类 CElement
     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 }
    CElement的最终释放函数 CBase::SubRelease
    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;
    }
    CBase::SubRelease的上层函数 CBase::PrivateRelease
      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 propsmethods:
     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 };
    代表DOM树的结构 CMarkup类
      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 };
    CTreePos类
     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 };
    class CTreeDataPos
      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 };
    class CMarkupPointer
  • 相关阅读:
    软件工程结课作业
    十三次作业
    十二次作业
    十一次作业
    十次作业
    找回感觉的练习
    CSS背景样式和列表样式
    盒子模型案例应用
    display属性
    margin外边距属性
  • 原文地址:https://www.cnblogs.com/Ox9A82/p/5808552.html
Copyright © 2011-2022 走看看