Skip to content

Commit

Permalink
Support for longDesc in MSHTML and Gecko. Press NVDA+d to open the lo…
Browse files Browse the repository at this point in the history
…ng description. #809
  • Loading branch information
michaelDCurran committed Nov 8, 2012
1 parent 272a020 commit 0ac840a
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 2 deletions.
24 changes: 24 additions & 0 deletions nvdaHelper/vbufBackends/gecko_ia2/gecko_ia2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,30 @@ VBufStorage_fieldNode_t* GeckoVBufBackend_t::fillVBuf(IAccessible2* pacc,
}
}

//Expose all available actions
IAccessibleAction* paccAction=NULL;
pacc->QueryInterface(IID_IAccessibleAction,(void**)&paccAction);
if(paccAction) {
long nActions=0;
paccAction->nActions(&nActions);
for(int i=0;i<nActions;++i) {
BSTR actionName=NULL;
paccAction->get_name(i,&actionName);
if(actionName) {
wstring attribName=L"IAccessibleAction_";
attribName+=actionName;
s.str(L"");
s<<i;
parentNode->addAttribute(attribName,s.str());
if(wcscmp(actionName, L"click")==0||wcscmp(actionName, L"showlongdesc")==0) {
isInteractive=true;
}
SysFreeString(actionName);
}
}
paccAction->Release();
}

// Handle table cell information.
IAccessibleTableCell* paccTableCell = NULL;
// If paccTable is not NULL, it is the table interface for the table above this object.
Expand Down
3 changes: 2 additions & 1 deletion nvdaHelper/vbufBackends/mshtml/mshtml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ inline void getAttributesFromHTMLDOMNode(IHTMLDOMNode* pHTMLDOMNode,wstring& nod
macro_addHTMLAttributeToMap(L"rowspan",false,pHTMLAttributeCollection2,attribsMap,tempVar,tempAttribNode);
macro_addHTMLAttributeToMap(L"scope",false,pHTMLAttributeCollection2,attribsMap,tempVar,tempAttribNode);
}
macro_addHTMLAttributeToMap(L"longdesc",false,pHTMLAttributeCollection2,attribsMap,tempVar,tempAttribNode);
macro_addHTMLAttributeToMap(L"alt",true,pHTMLAttributeCollection2,attribsMap,tempVar,tempAttribNode);
macro_addHTMLAttributeToMap(L"title",false,pHTMLAttributeCollection2,attribsMap,tempVar,tempAttribNode);
macro_addHTMLAttributeToMap(L"src",false,pHTMLAttributeCollection2,attribsMap,tempVar,tempAttribNode);
Expand Down Expand Up @@ -935,7 +936,7 @@ VBufStorage_fieldNode_t* MshtmlVBufBackend_t::fillVBuf(VBufStorage_buffer_t* buf
}

//Is this node interactive?
bool isInteractive=isEditable||(IAStates&STATE_SYSTEM_FOCUSABLE&&nodeName!=L"BODY")||(IAStates&STATE_SYSTEM_LINKED)||(attribsMap.find(L"HTMLAttrib::onclick")!=attribsMap.end())||(attribsMap.find(L"HTMLAttrib::onmouseup")!=attribsMap.end())||(attribsMap.find(L"HTMLAttrib::onmousedown")!=attribsMap.end());
bool isInteractive=isEditable||(IAStates&STATE_SYSTEM_FOCUSABLE&&nodeName!=L"BODY")||(IAStates&STATE_SYSTEM_LINKED)||(attribsMap.find(L"HTMLAttrib::onclick")!=attribsMap.end())||(attribsMap.find(L"HTMLAttrib::onmouseup")!=attribsMap.end())||(attribsMap.find(L"HTMLAttrib::onmousedown")!=attribsMap.end())||(attribsMap.find(L"HTMLAttrib::longdesc")!=attribsMap.end());
//Set up numbering for lists
int LIIndex=0;
if(nodeName.compare(L"OL")==0||nodeName.compare(L"UL")==0) {
Expand Down
2 changes: 2 additions & 0 deletions source/controlTypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@
STATE_SORTED_ASCENDING=0x100000000
STATE_SORTED_DESCENDING=0x200000000
STATES_SORTED=frozenset([STATE_SORTED,STATE_SORTED_ASCENDING,STATE_SORTED_DESCENDING])
STATE_HASLONGDESC=0x400000000

roleLabels={
ROLE_UNKNOWN:_("unknown"),
Expand Down Expand Up @@ -381,6 +382,7 @@
STATE_SORTED:_("sorted"),
STATE_SORTED_ASCENDING:_("sorted ascending"),
STATE_SORTED_DESCENDING:_("sorted descending"),
STATE_HASLONGDESC:"has long description",
}

negativeStateLabels={
Expand Down
7 changes: 7 additions & 0 deletions source/virtualBuffers/MSHTML.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ def _normalizeControlField(self,attrs):
if not role:
role=IAccessibleHandler.IAccessibleRolesToNVDARoles.get(accRole,controlTypes.ROLE_UNKNOWN)
states=set(IAccessibleHandler.IAccessibleStatesToNVDAStates[x] for x in [1<<y for y in xrange(32)] if int(attrs.get('IAccessible::state_%s'%x,0)) and x in IAccessibleHandler.IAccessibleStatesToNVDAStates)
if attrs.get('HTMLAttrib::longdesc'):
states.add(controlTypes.STATE_HASLONGDESC)
#IE exposes destination anchors as links, this is wrong
if nodeName=="A" and role==controlTypes.ROLE_LINK and controlTypes.STATE_LINKED not in states:
role=controlTypes.ROLE_TEXTFRAME
Expand Down Expand Up @@ -266,6 +268,11 @@ def _searchableAttribsForNodeType(self,nodeType):
return None
return attrs

def _activateLongDesc(self,controlField):
longDesc=controlField['HTMLAttrib::longdesc']
self.rootNVDAObject.HTMLNode.document.open(longDesc,'_blank','location=no, menubar=no, toolbar=no')


def _activateNVDAObject(self,obj):
super(MSHTML,self)._activateNVDAObject(obj)
#If we activated a same-page link, then scroll to its anchor
Expand Down
17 changes: 17 additions & 0 deletions source/virtualBuffers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,9 @@ def _activateNVDAObject(self, obj):
"""
obj.doAction()

def _activateLongDesc(self,controlField):
raise NotImplementedError

def _activatePosition(self, info):
obj = info.NVDAObjectAtStart
if not obj:
Expand Down Expand Up @@ -812,6 +815,19 @@ def _shouldSetFocusToObj(self, obj):
"""
return obj.role not in self.APPLICATION_ROLES and controlTypes.STATE_FOCUSABLE in obj.states

def script_activateLongDesc(self,gesture):
info=self.makeTextInfo(textInfos.POSITION_CARET)
info.expand("character")
for field in reversed(info.getTextWithFields()):
if isinstance(field,textInfos.FieldCommand) and field.command=="controlStart":
states=field.field.get('states')
if states and controlTypes.STATE_HASLONGDESC in states:
self._activateLongDesc(field.field)
break
else:
ui.message(_("No long description"))
script_activateLongDesc.__doc__=_("Shows the long description at this position if one is found.")

def script_activatePosition(self,gesture):
info=self.makeTextInfo(textInfos.POSITION_CARET)
self._activatePosition(info)
Expand Down Expand Up @@ -1450,6 +1466,7 @@ def _handleUpdate(self):
braille.handler.handleUpdate(self)

__gestures = {
"kb:NVDA+d": "activateLongDesc",
"kb:enter": "activatePosition",
"kb:space": "activatePosition",
"kb:NVDA+f5": "refreshBuffer",
Expand Down
9 changes: 9 additions & 0 deletions source/virtualBuffers/gecko_ia2.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def _normalizeControlField(self,attrs):
role=controlTypes.ROLE_BLOCKQUOTE
states=set(IAccessibleHandler.IAccessibleStatesToNVDAStates[x] for x in [1<<y for y in xrange(32)] if int(attrs.get('IAccessible::state_%s'%x,0)) and x in IAccessibleHandler.IAccessibleStatesToNVDAStates)
states|=set(IAccessibleHandler.IAccessible2StatesToNVDAStates[x] for x in [1<<y for y in xrange(32)] if int(attrs.get('IAccessible2::state_%s'%x,0)) and x in IAccessibleHandler.IAccessible2StatesToNVDAStates)
if attrs.get("IAccessibleAction_showlongdesc") is not None:
states.add(controlTypes.STATE_HASLONGDESC)
defaultAction=attrs.get('defaultAction','')
if defaultAction=="click":
states.add(controlTypes.STATE_CLICKABLE)
Expand Down Expand Up @@ -142,6 +144,13 @@ def _shouldSetFocusToObj(self, obj):
return True
return super(Gecko_ia2,self)._shouldSetFocusToObj(obj) and obj.role!=controlTypes.ROLE_EMBEDDEDOBJECT

def _activateLongDesc(self,controlField):
index=int(controlField['IAccessibleAction_showlongdesc'])
docHandle=int(controlField['controlIdentifier_docHandle'])
ID=int(controlField['controlIdentifier_ID'])
obj=self.getNVDAObjectFromIdentifier(docHandle,ID)
obj.doAction(index)

def _activateNVDAObject(self, obj):
try:
obj.doAction()
Expand Down
2 changes: 1 addition & 1 deletion user_docs/en/changes.t2t
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

== New Features ==
-Basic support for reading and writing messages in Lotus Notes 8.5. (#543)

- In Browse mode for MSHTML (e.g. Internet Explorer) and Gecko (e.g. Firefox), the existance of long descriptions are now announced. Its also possible to open the long description in a new window by pressing NVDA+d. (#809)

== Bug Fixes ==
- The quick navigation keys for jumping to the next or previous separator in Browse Mode now works in Internet Explorer and other MSHTML controls. (#2781)
Expand Down
1 change: 1 addition & 0 deletions user_docs/en/userGuide.t2t
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ In addition, you can manually force focus mode, after which it will remain in ef
| Find | NVDA+control+f | Pops up a dialog in which you can type some text to find in the current document |
| Find next | NVDA+f3 | Finds the next occurrence of the text in the document that you previously searched for |
| Find previous | NVDA+shift+f3 | Finds the previous occurrence of the text in the document you previously searched for |
| open long description | NVDA+d | Opens a new window containing a long description for the element you are on if it has one. |
%kc:endInclude


Expand Down

0 comments on commit 0ac840a

Please sign in to comment.