Beispiel #1
0
HRESULT TestMarkupServices(BSTR bstrHtml, MarkupCallback *pCallback, BSTR &message)
{
	IHTMLDocument3 *pHtmlDocRoot = NULL;

	// Create the root document -- a "workspace" for parsing.
	HRESULT hr = CoCreateInstance(CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pHtmlDocRoot));
	if (SUCCEEDED(hr) && pHtmlDocRoot) {
		IPersistStreamInit *pPersistStreamInit = NULL;

		hr = pHtmlDocRoot->QueryInterface(IID_PPV_ARGS(&pPersistStreamInit));
		if (SUCCEEDED(hr)) {
			// Initialize the root document to a default state -- ready for parsing.
			pPersistStreamInit->InitNew();

			IMarkupServices *pMarkupServices = NULL;
			hr = pHtmlDocRoot->QueryInterface(IID_PPV_ARGS(&pMarkupServices));
			if (SUCCEEDED(hr)) {
				IMarkupPointer *pMarkupBegin = NULL;
				IMarkupPointer *pMarkupEnd = NULL;

				// These markup pointers indicate the insertion point.
				hr = pMarkupServices->CreateMarkupPointer(&pMarkupBegin);
				if (SUCCEEDED(hr))
					hr = pMarkupServices->CreateMarkupPointer(&pMarkupEnd);

				if (SUCCEEDED(hr) && pMarkupBegin && pMarkupEnd) {
					IMarkupContainer *pMarkupContainer = NULL;

					// Parse the string -- the markup container contains the parsed HTML.
					// Markup pointers are updated to point to begining and end of new container.
					hr = pMarkupServices->ParseString(bstrHtml, 0, &pMarkupContainer, pMarkupBegin, pMarkupEnd);
					if (SUCCEEDED(hr) && pMarkupContainer) {
						IHTMLDocument3 *pHtmlDoc = NULL;

						// Retrieve the document interface to the markup container.
						hr = pMarkupContainer->QueryInterface(IID_PPV_ARGS(&pHtmlDoc));
						if (SUCCEEDED(hr) && pHtmlDoc) {
							// Invoke the user-defined action for this new fragment.
							hr = pCallback(pHtmlDoc, message);

							// Clean up.
							pHtmlDoc->Release();
						}
						pMarkupContainer->Release();
					}
					pMarkupEnd->Release();
				}
				if (pMarkupBegin)
					pMarkupBegin->Release();
				pMarkupServices->Release();
			}
			pPersistStreamInit->Release();
		}
		pHtmlDocRoot->Release();
	}
	return hr;
}
void CHtmlCaretTestView::OnMovetoend()
{
	IHTMLDocument2 *pHTMLDocument2;
	if(!GetDHtmlDocument(&pHTMLDocument2))return;

	IDisplayServices *pDisplayServices;
	HRESULT hRes = pHTMLDocument2->QueryInterface(IID_IDisplayServices, reinterpret_cast<void**>(&pDisplayServices));
	if (FAILED(hRes))
		return;
	IDisplayPointer *pDisplayPointer;
	hRes = pDisplayServices->CreateDisplayPointer(&pDisplayPointer);
	if (FAILED(hRes))
		return;

	IMarkupServices *pMarkupServices;
	hRes = pDisplayServices->QueryInterface(IID_IMarkupServices, reinterpret_cast<void**>(&pMarkupServices));
	if (FAILED(hRes))
		return;

	IMarkupPointer *pMarkupPointer;
	hRes = pMarkupServices->CreateMarkupPointer(&pMarkupPointer);
	if (FAILED(hRes))
		return;

	IHTMLElement *pElement;
	pHTMLDocument2->get_body(&pElement);
	hRes = pMarkupPointer->MoveAdjacentToElement(pElement, ELEM_ADJ_BeforeEnd);
	if (FAILED(hRes))
		return;

	hRes = pDisplayPointer->MoveToMarkupPointer(pMarkupPointer, NULL);
	if (FAILED(hRes))
		return;

	IHTMLCaret *pHTMLCaret;
	hRes = pDisplayServices->GetCaret(&pHTMLCaret);
	if (FAILED(hRes))
		return;

	hRes = pHTMLCaret->MoveCaretToPointerEx(pDisplayPointer, TRUE, TRUE, CARET_DIRECTION_FORWARD);
	if (FAILED(hRes))
		return;
}
Beispiel #3
0
HRESULT CPasteCommand::Paste(IMarkupPointer* pStart, IMarkupPointer* pEnd, CSpringLoader* psl, BSTR bstrText/*=NULL*/)
{
    HRESULT             hr;
    IMarkupServices*    pMarkupServices = GetMarkupServices();
    BOOL                fResult;
    // Delete the range first
    IFC(pMarkupServices->Remove(pStart, pEnd));

    // If there is nothing to paste we're done
    if(bstrText==NULL || *bstrText==0)
    {
        return S_OK;
    }

    // InsertSanitized text checks whether we accept html or not
    // and handles CR LF characters appropriately
    IFC(GetEditor()->InsertSanitizedText(bstrText, pStart, pMarkupServices, psl, FALSE));

    // Call the url autodetector
    IFC(pStart->IsRightOf(pEnd, &fResult));
    if(fResult)
    {
    }
    else
    {
    }

    // Collapse the range
    IFC(pStart->IsRightOf(pEnd, &fResult));
    if(fResult)
    {
        IFC(pEnd->MoveToPointer(pStart));
    }
    else
    {
        IFC(pStart->MoveToPointer(pEnd));
    }

Cleanup:
    RRETURN(hr);
}
Beispiel #4
0
HRESULT CCopyCommand::PrivateExec(DWORD nCmdexecopt, VARIANTARG* pvarargIn, VARIANTARG* pvarargOut)
{
    HRESULT             hr = S_OK;
    INT                 iSegmentCount;
    ISegmentList*       pSegmentList = NULL;
    SELECTION_TYPE      eSelectionType;
    IMarkupPointer*     pStart = NULL;
    IMarkupPointer*     pEnd = NULL;
    CXindowsEditor*     pEditor = GetEditor();
    IHTMLElement*       pElement = NULL;
    BOOL                fRet;
    IMarkupServices*    pMarkupServices = GetMarkupServices();

    // Do the prep work
    ((IHTMLEditor*)pEditor)->AddRef();

    IFC(GetSegmentList(&pSegmentList));

    IFC(pSegmentList->GetSegmentCount(&iSegmentCount, &eSelectionType));

    // If there is no segments we're done, it's a nogo
    if(iSegmentCount == 0)
    {
        goto Cleanup;
    }

    // Fire the canceable event
    IFC(pMarkupServices->CreateMarkupPointer(&pStart));

    IFC(pMarkupServices->CreateMarkupPointer(&pEnd));

    IFC(MovePointersToSegmentHelper(GetViewServices(), pSegmentList, 0, &pStart, &pEnd));

    IFC(FindCommonElement(pMarkupServices, GetViewServices(), pStart, pEnd, &pElement));

    hr = GetViewServices()->FireCancelableEvent(
        pElement,
        DISPID_EVMETH_ONCOPY,
        DISPID_EVPROP_ONCOPY,
        _T("copy"),
        &fRet);

    if(hr)
    {
        goto Cleanup;
    }

    if(!fRet)
    {
        goto Cleanup;
    }

    // Do the actual copy
    IFC(GetViewServices()->SaveSegmentsToClipboard(pSegmentList));

Cleanup:
    ReleaseInterface(pElement);
    ReleaseInterface((IHTMLEditor*)pEditor);
    ReleaseInterface(pSegmentList);
    ReleaseInterface(pStart);
    ReleaseInterface(pEnd);

    RRETURN(hr);
}
Beispiel #5
0
HRESULT CPasteCommand::PasteFromClipboard (
       IMarkupPointer*  pPasteStart, 
       IMarkupPointer*  pPasteEnd, 
       IDataObject*     pDataObject,
       CSpringLoader*   psl)
{
    CXindowsEditor* pEditor = GetEditor();
    IDataObject*    pdoFromClipboard = NULL;
    CLIPFORMAT      cf = 0;
    HGLOBAL         hglobal = NULL;
    HRESULT         hr = DV_E_FORMATETC;
    HRESULT         hr2 = S_OK;
    HGLOBAL         hUnicode = NULL;
    int             i;
    int             nFETC;
    STGMEDIUM       medium = { 0, NULL };
    FORMATETC*      pfetc;
    LPTSTR          ptext = NULL;
    IHTMLViewServices*  pViewServices = pEditor->GetViewServices();
    IHTMLElement*       pElement = NULL;
    IHTMLElement*       pFlowElement = NULL;
    BOOL                fAcceptsHTML, fContainer;
    IMarkupServices*    pMarkupServices = pEditor->GetMarkupServices();
    IMarkupPointer*     pRangeStart   = NULL;
    IMarkupPointer*     pRangeEnd     = NULL;
    IDataObject*        pdoFiltered = NULL;
    IDocHostUIHandler*  pHostUIHandler = NULL;

    // Set up a pair of pointers for URL Autodetection after the insert
    IFC(pMarkupServices->CreateMarkupPointer(&pRangeStart));
    IFC(pRangeStart->MoveToPointer(pPasteStart));
    IFC(pRangeStart->SetGravity(POINTER_GRAVITY_Left));        

    IFC(pMarkupServices->CreateMarkupPointer(&pRangeEnd));
    IFC(pRangeEnd->MoveToPointer(pPasteStart));
    IFC(pRangeEnd->SetGravity(POINTER_GRAVITY_Right));

    pfetc = GetFETCs(&nFETC);

    Assert(pfetc);

    if(!pDataObject)
    {
        hr2 = OleGetClipboard(&pdoFromClipboard);

        if(hr2 != NOERROR)
        {
            return hr2;
        }

        Assert(pdoFromClipboard);

        // See if the host handler wants to give us a massaged data object.
        IFC(pViewServices->GetDocHostUIHandler(&pHostUIHandler));

        pDataObject = pdoFromClipboard;

        if(pHostUIHandler)
        {
            // The host may want to massage the data object to block/add
            // certain formats.
            hr = pHostUIHandler->FilterDataObject(pDataObject, &pdoFiltered);

            if(!hr && pdoFiltered)
            {
                pDataObject = pdoFiltered;
            }
            else
            {
                hr = S_OK;
            }
        }
    }

    if(pPasteEnd)
    {
        IFC(pMarkupServices->Remove(pPasteStart, pPasteEnd));
    }

    // Check if we accept HTML
    IFC(pViewServices->GetFlowElement(pPasteStart, &pFlowElement));

    if(!pFlowElement)
    {
        // Elements that do not accept HTML, e.g. TextArea, always have a flow layout.
        // If the element does not have a flow layout then it might have been created
        // using the DOM (see bug 42685). Set fAcceptsHTML to true.
        fAcceptsHTML = TRUE;
    }
    else
    {
        IFC(pViewServices->IsContainerElement(pFlowElement, &fContainer, &fAcceptsHTML));
    }

    for(i=0; i<nFETC; i++,pfetc++)
    {
        // make sure the format is either 1.) a plain text format
        // if we are in plain text mode or 2.) a rich text format
        // or 3.) matches the requested format.
        if(cf && cf!=pfetc->cfFormat)
        {
            continue;
        }

        // If we don't accept HTML and i does not correspond to text format
        // skip it
        if(fAcceptsHTML || i==iAnsiFETC || i==iUnicodeFETC)
        {
            // make sure the format is available
            if(pDataObject->QueryGetData(pfetc) != NOERROR)
            {
                continue;
            }

            // If we have one of the formats that uses an hglobal get it
            // and lock it.
            if(i==iAnsiFETC || i==iUnicodeFETC || i==iHTML)
            {
                if(pDataObject->GetData(pfetc, &medium) == NOERROR)
                {
                    Assert(medium.tymed == TYMED_HGLOBAL);

                    hglobal = medium.hGlobal;
                    ptext = (LPTSTR)GlobalLock(hglobal);
                    if(!ptext)
                    {
                        ReleaseStgMedium(&medium);
                        return E_OUTOFMEMORY;
                    }
                }
                else
                {
                    continue;
                }
            }

            switch(i)
            {
            case iHTML:
                {
                    // Fire the springloader.
                    BOOL fSamePosition = FALSE;
                    if(pPasteStart && psl
                        && (!pPasteEnd || (S_OK==pPasteStart->IsEqualTo(pPasteEnd, &fSamePosition) && fSamePosition))
                        && S_OK==psl->Fire(pPasteStart)
                        && pPasteEnd)
                    {
                        pPasteEnd->MoveToPointer(pPasteStart);
                    }

                    hr = pViewServices->DoTheDarnPasteHTML(pPasteStart, pPasteEnd, hglobal);

                    goto Cleanup;
                }
            case iRtfFETC:
                {
                    BOOL fEnabled = FALSE;

                    continue;
                }

            case iRtfAsTextFETC:
            case iAnsiFETC: // ANSI plain text. If data can be stored

                hUnicode = TextHGlobalAtoW(hglobal);
                if(hUnicode)
                {
                    ptext = (LPTSTR)GlobalLock(hUnicode);
                    if(!ptext)
                    {
                        hr = E_OUTOFMEMORY;
                        goto Cleanup;
                    }

                    hr = GetEditor()->InsertSanitizedText(ptext, pPasteStart, pMarkupServices, psl, FALSE);

                    GlobalUnlock(hUnicode);
                }

                goto Cleanup;

            case iUnicodeFETC: // Unicode plain text

                ptext = (LPTSTR)GlobalLock(hglobal);
                if(!ptext)
                {
                    hr = E_OUTOFMEMORY;
                    goto Cleanup;
                }

                hr = GetEditor()->InsertSanitizedText(ptext, pPasteStart, pMarkupServices, psl, FALSE);

                goto Cleanup;
            }

            //Break out of the for loop
            break;
        }
    }

Cleanup:
    ReleaseInterface(pRangeStart);
    ReleaseInterface(pRangeEnd);

    ReleaseInterface(pElement);
    ReleaseInterface(pFlowElement);

    ReleaseInterface(pdoFiltered);
    ReleaseInterface(pHostUIHandler);

    ReleaseInterface(pdoFromClipboard);

    if(hUnicode)
    {
        GlobalFree(hUnicode);
    }

    //If we used the hglobal unlock it and free it.
    if(hglobal)
    {
        GlobalUnlock(hglobal);
        ReleaseStgMedium(&medium);
    }

    return hr;
}
Beispiel #6
0
//+---------------------------------------------------------------------------
//
//  CPasteCommand::Exec
//
//----------------------------------------------------------------------------
HRESULT CPasteCommand::PrivateExec(DWORD nCmdexecopt, VARIANTARG* pvarargIn, VARIANTARG* pvarargOut)
{
    HRESULT             hr = S_OK;
    int                 iSegmentCount, i;
    IMarkupPointer*     pStart = NULL;
    IMarkupPointer*     pEnd = NULL;
    SELECTION_TYPE      eSelectionType;
    IHTMLViewServices*  pViewServices = GetViewServices();
    IMarkupServices*    pMarkupServices = GetMarkupServices();
    ISegmentList*       pSegmentList = NULL;
    BOOL                fRet;
    DWORD               code = 0;
    CXindowsEditor*     pEditor = GetEditor();
    CUndoUnit           undoUnit(pEditor);

    ((IHTMLEditor*)pEditor)->AddRef();

    if(IsSelectionActive())
    {
        return S_OK; // don't paste into an active selection
    }

    // Get the segment etc., let's get busy
    IFC(GetSegmentList(&pSegmentList));
    IFC(pSegmentList->GetSegmentCount(&iSegmentCount, &eSelectionType));
    IFC(pMarkupServices->CreateMarkupPointer(&pStart));
    IFC(pMarkupServices->CreateMarkupPointer(&pEnd));

    if(iSegmentCount != 0)
    {       
        SP_IHTMLElement spElement;
        /*IFC(undoUnit.Begin(IDS_EDUNDOPASTE)); wlw note*/

        for(i=0; i<iSegmentCount; i++)
        {
            IFC(MovePointersToSegmentHelper(GetViewServices(), pSegmentList, i, &pStart, &pEnd));

            IFC(IsPastePossible(pStart, pEnd, &fRet));
            if(!fRet)
            {
                continue;
            }

            IFC(FindCommonElement(pMarkupServices, GetViewServices(), pStart, pEnd, &spElement));

            if(!spElement)
            {
                continue;
            }

            IFC(pViewServices->FireCancelableEvent(spElement, DISPID_EVMETH_ONPASTE, DISPID_EVPROP_ONPASTE,
                _T("paste"), &fRet));

            if(!fRet)
            {
                continue;
            }

            if(pvarargIn && V_VT(pvarargIn)==VT_BSTR)
            {
                // Paste the passed in bstrText 
                IFC(Paste(pStart, pEnd, GetSpringLoader(), V_BSTR(pvarargIn)));
            }
            else
            {
                // Paste from the clipboard
                IFC(PasteFromClipboard(pStart, pEnd, NULL, GetSpringLoader()));
            }
        }

        if((eSelectionType!=SELECTION_TYPE_Auto) && 
            (eSelectionType!=SELECTION_TYPE_Control)) // Control is handled in ExitTree
        {
            pEditor->GetSelectionManager()->EmptySelection();
        }

        if(eSelectionType != SELECTION_TYPE_Auto)
        {
            // Update selection - go to pStart since it has gravity Right
            pEnd->MoveToPointer(pStart);            
            pEditor->Select(pStart, pEnd, SELECTION_TYPE_Caret, &code);
            Assert(code == 0);
        }
    }

Cleanup:   
    ReleaseInterface((IHTMLEditor*)pEditor);
    ReleaseInterface(pSegmentList);
    ReleaseInterface(pStart);
    ReleaseInterface(pEnd);
    RRETURN (hr);
}
Beispiel #7
0
//+---------------------------------------------------------------------------
//
//  CCutCommand::Exec
//
//----------------------------------------------------------------------------
HRESULT CCutCommand::PrivateExec(DWORD nCmdexecopt, VARIANTARG* pvarargIn, VARIANTARG* pvarargOut)
{
    HRESULT             hr = S_OK;
    IHTMLElement*       pElement = NULL;
    int                 iSegmentCount;
    IMarkupPointer*     pStart = NULL;
    IMarkupPointer*     pEnd = NULL;
    SELECTION_TYPE      eSelectionType;
    IMarkupServices*    pMarkupServices = GetMarkupServices();
    ISegmentList*       pSegmentList = NULL;
    BOOL                fRet;
    BOOL                fNotRange = TRUE;
    CUndoUnit           undoUnit(GetEditor());
    CXindowsEditor*     pEditor = GetEditor();

    ((IHTMLEditor*)pEditor)->AddRef();

    // Do the prep work
    IFC(GetSegmentList(&pSegmentList));    
    IFC(pSegmentList->GetSegmentCount(&iSegmentCount, &eSelectionType));           

    // Cut is allowed iff we have a non-empty segment
    if(eSelectionType==SELECTION_TYPE_Caret || iSegmentCount==0)
    {
        goto Cleanup;
    }
    IFC(pMarkupServices->CreateMarkupPointer(&pStart));
    IFC(pMarkupServices->CreateMarkupPointer(&pEnd));   
    IFC(MovePointersToSegmentHelper(GetViewServices(), pSegmentList, 0, &pStart, &pEnd));
    IFC(pStart->IsEqualTo(pEnd, &fRet));
    if(fRet)
    {
        goto Cleanup;
    }

    // Cannot delete or cut unless the range is in the same flow layout
    if(!PointersInSameFlowLayout(pStart, pEnd, NULL, GetViewServices()))
    {
        goto Cleanup;
    }

    // Now Handle the cut 
    /*IFC(undoUnit.Begin(IDS_EDUNDOCUT)); wlw note*/

    IFC(FindCommonElement(pMarkupServices, GetViewServices(), pStart, pEnd, &pElement));

    if(!pElement)
    {
        goto Cleanup;
    }

    IFC(GetViewServices()->FireCancelableEvent( 
        pElement,
        DISPID_EVMETH_ONCUT,
        DISPID_EVPROP_ONCUT,
        _T("cut"),
        &fRet));

    if(!fRet)
    {
        goto Cleanup;
    }

    IFC(GetViewServices()->SaveSegmentsToClipboard(pSegmentList));

    fNotRange = (eSelectionType!=SELECTION_TYPE_Auto && eSelectionType!=SELECTION_TYPE_Control);
    IFC(pEditor->Delete(pStart, pEnd, fNotRange));

    if(eSelectionType == SELECTION_TYPE_Selection)
    {
        pEditor->GetSelectionManager()->EmptySelection();
    }

Cleanup:   
    ReleaseInterface((IHTMLEditor*)pEditor);
    ReleaseInterface(pSegmentList);
    ReleaseInterface(pStart);
    ReleaseInterface(pEnd);
    ReleaseInterface(pElement);
    RRETURN(hr);
}