OSDN Git Service

MSHTML VBufBackend: filter all whitespace from text nodes so that there is no whitesp...
authorMichael Curran <mick@kulgan.net>
Mon, 20 Sep 2010 02:14:34 +0000 (12:14 +1000)
committerJames Teh <jamie@jantrid.net>
Mon, 20 Sep 2010 02:14:34 +0000 (12:14 +1000)
source/NVDAHelper/vbufBackends/mshtml/mshtml.cpp
source/NVDAHelper/vbufBackends/mshtml/mshtml.h

index 4a94d41..3324a8a 100755 (executable)
@@ -207,25 +207,40 @@ inline int getIDFromHTMLDOMNode(IHTMLDOMNode* pHTMLDOMNode) {
        return ID;\r
 }\r
 \r
-inline BSTR getTextFromHTMLDOMNode(IHTMLDOMNode* pHTMLDOMNode) {\r
+inline wstring getTextFromHTMLDOMNode(IHTMLDOMNode* pHTMLDOMNode, bool allowPreformattedText) {\r
        int res=0;\r
        IHTMLDOMTextNode* pHTMLDOMTextNode=NULL;\r
        DEBUG_MSG(L"Trying to get an IHTMLDOMTextNode interface pointer");\r
        if(pHTMLDOMNode->QueryInterface(IID_IHTMLDOMTextNode,(void**)&pHTMLDOMTextNode)!=S_OK) {\r
                DEBUG_MSG(L"Not a text node");\r
-               return NULL;\r
+               return L"";\r
        }\r
-       VBufStorage_textFieldNode_t* textNode=NULL;\r
        DEBUG_MSG(L"Fetch data of DOMTextNode");\r
        BSTR data=NULL;\r
        res=pHTMLDOMTextNode->get_data(&data);\r
        pHTMLDOMTextNode->Release();\r
        if(res!=S_OK||!data) {\r
                DEBUG_MSG(L"Failed to get IHTMLDOMTextNode::data");\r
-               return NULL;\r
+               return L"";\r
        }\r
        DEBUG_MSG(L"Got data from IHTMLDOMTextNode");\r
-       return data;\r
+       wstring s;\r
+       if(allowPreformattedText) {\r
+               s.append(data);\r
+       } else {\r
+               bool lastNotWhitespace=false;\r
+               for(wchar_t* c=data;*c;++c) {\r
+                       if(!iswspace(*c)) {\r
+                               s+=*c;\r
+                               lastNotWhitespace=TRUE;\r
+                       } else if(lastNotWhitespace) {\r
+                               s+=L' ';\r
+                               lastNotWhitespace=FALSE;\r
+                       } \r
+               }\r
+       }\r
+       SysFreeString(data);\r
+       return s;\r
 }\r
 \r
 #define macro_addHTMLCurrentStyleToNodeAttrs(styleName,attrName,node,currentStyleObj,tempBSTR) {\\r
@@ -525,18 +540,17 @@ if(nodeName.compare(L"TABLE")==0) {
        return tableInfoPtr;\r
 }\r
 \r
-VBufStorage_fieldNode_t* MshtmlVBufBackend_t::fillVBuf(VBufStorage_buffer_t* buffer, VBufStorage_controlFieldNode_t* parentNode, VBufStorage_fieldNode_t* previousNode, IHTMLDOMNode* pHTMLDOMNode, int docHandle, fillVBuf_tableInfo* tableInfoPtr, int* LIIndexPtr, bool parentHasContent) {\r
+VBufStorage_fieldNode_t* MshtmlVBufBackend_t::fillVBuf(VBufStorage_buffer_t* buffer, VBufStorage_controlFieldNode_t* parentNode, VBufStorage_fieldNode_t* previousNode, IHTMLDOMNode* pHTMLDOMNode, int docHandle, fillVBuf_tableInfo* tableInfoPtr, int* LIIndexPtr, bool parentHasContent, bool allowPreformattedText) {\r
        BSTR tempBSTR=NULL;\r
        wostringstream tempStringStream;\r
 \r
        //Handle text nodes\r
        { \r
-               tempBSTR=getTextFromHTMLDOMNode(pHTMLDOMNode);\r
-               if(tempBSTR!=NULL) {\r
+               wstring s=getTextFromHTMLDOMNode(pHTMLDOMNode,allowPreformattedText);\r
+               if(!s.empty()) {\r
                        DEBUG_MSG(L"Got text from node");\r
-                       VBufStorage_textFieldNode_t* textNode=buffer->addTextFieldNode(parentNode,previousNode,tempBSTR);\r
+                       VBufStorage_textFieldNode_t* textNode=buffer->addTextFieldNode(parentNode,previousNode,s);\r
                        fillTextFormattingForTextNode(parentNode,textNode);\r
-                       SysFreeString(tempBSTR);\r
                        return textNode;\r
                }\r
        }\r
@@ -573,6 +587,10 @@ VBufStorage_fieldNode_t* MshtmlVBufBackend_t::fillVBuf(VBufStorage_buffer_t* buf
                return NULL;\r
        }\r
 \r
+       //We only allow linebreaks for 'PRE' tags\r
+       if(nodeName.compare(L"PRE")==0) {\r
+               allowPreformattedText=TRUE;\r
+       }\r
        map<wstring,wstring> attribsMap;\r
        map<wstring,wstring>::const_iterator tempIter;\r
        attribsMap[L"IHTMLDOMNode::nodeName"]=nodeName;\r
@@ -788,7 +806,7 @@ VBufStorage_fieldNode_t* MshtmlVBufBackend_t::fillVBuf(VBufStorage_buffer_t* buf
                        if(pacc) {\r
                                IHTMLDOMNode* childPHTMLDOMNode=getRootDOMNodeFromIAccessibleFrame(pacc);\r
                                if(childPHTMLDOMNode) {\r
-                                       previousNode=this->fillVBuf(buffer,parentNode,previousNode,childPHTMLDOMNode,docHandle,tableInfoPtr,LIIndexPtr,hasContent);\r
+                                       previousNode=this->fillVBuf(buffer,parentNode,previousNode,childPHTMLDOMNode,docHandle,tableInfoPtr,LIIndexPtr,hasContent,allowPreformattedText);\r
                                        childPHTMLDOMNode->Release();\r
                                }\r
                        }\r
@@ -812,7 +830,7 @@ VBufStorage_fieldNode_t* MshtmlVBufBackend_t::fillVBuf(VBufStorage_buffer_t* buf
                                                }\r
                                                IHTMLDOMNode* childPHTMLDOMNode=NULL;\r
                                                if(childPDispatch->QueryInterface(IID_IHTMLDOMNode,(void**)&childPHTMLDOMNode)==S_OK) {\r
-                                                       VBufStorage_fieldNode_t* tempNode=this->fillVBuf(buffer,parentNode,previousNode,childPHTMLDOMNode,docHandle,tableInfoPtr,LIIndexPtr,hasContent);\r
+                                                       VBufStorage_fieldNode_t* tempNode=this->fillVBuf(buffer,parentNode,previousNode,childPHTMLDOMNode,docHandle,tableInfoPtr,LIIndexPtr,hasContent,allowPreformattedText);\r
                                                        if(tempNode) {\r
                                                                previousNode=tempNode;\r
                                                        }\r
@@ -930,7 +948,7 @@ IHTMLDOMNode* pHTMLDOMNode=NULL;
                pHTMLElement->Release();\r
        }\r
        assert(pHTMLDOMNode);\r
-       this->fillVBuf(buffer,NULL,NULL,pHTMLDOMNode,docHandle,NULL,NULL,true);\r
+       this->fillVBuf(buffer,NULL,NULL,pHTMLDOMNode,docHandle,NULL,NULL,true,false);\r
        pHTMLDOMNode->Release();\r
 }\r
 \r
index 8f81437..d30c8b8 100755 (executable)
@@ -32,7 +32,7 @@ class MshtmlVBufBackend_t: public VBufBackend_t {
 \r
        virtual void render(VBufStorage_buffer_t* buffer, int docHandle, int ID, VBufStorage_controlFieldNode_t* oldNode=NULL);\r
 \r
-       VBufStorage_fieldNode_t* fillVBuf(VBufStorage_buffer_t* buffer, VBufStorage_controlFieldNode_t* parentNode, VBufStorage_fieldNode_t* previousNode, IHTMLDOMNode* pHTMLDOMNode, int docHandle, fillVBuf_tableInfo* tableInfoPtr, int* LIIndexPtr, bool parentHasContent);\r
+       VBufStorage_fieldNode_t* fillVBuf(VBufStorage_buffer_t* buffer, VBufStorage_controlFieldNode_t* parentNode, VBufStorage_fieldNode_t* previousNode, IHTMLDOMNode* pHTMLDOMNode, int docHandle, fillVBuf_tableInfo* tableInfoPtr, int* LIIndexPtr, bool parentHasContent, bool allowPreformattedText);\r
 \r
        virtual ~MshtmlVBufBackend_t();\r
 \r