Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Move hyperlink getter code into ia2utils so it can be reused.
  • Loading branch information
jcsteh committed Nov 7, 2017
commit 6f58bc6796743035d9f92ede21b23e74c546b4c6
57 changes: 56 additions & 1 deletion nvdaHelper/common/ia2utils.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This file is a part of the NVDA project.
URL: http://www.nvda-project.org/
Copyright 2006-2010 NVDA contributers.
Copyright 2007-2017 NV Access Limited, Mozilla Corporation
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2.0, as published by
the Free Software Foundation.
Expand All @@ -14,6 +14,7 @@ This license can be found at:

#include <string>
#include <map>
#include "ia2utils.h"

using namespace std;

Expand Down Expand Up @@ -46,3 +47,57 @@ void IA2AttribsToMap(const wstring &attribsString, map<wstring, wstring> &attrib
if (!key.empty())
attribsMap[key] = str;
}

IAccessibleHyperlinkPtr HyperlinkGetter::next() {
if (this->index >= this->count) {
return nullptr;
}
return this->get(this->index++);
}

HtHyperlinkGetter::HtHyperlinkGetter(IAccessibleHypertextPtr hypertext)
: hypertext(hypertext)
{
if (FAILED(hypertext->get_nHyperlinks(&this->count))) {
this->count = 0;
}
}

IAccessibleHyperlinkPtr HtHyperlinkGetter::get(const unsigned long index) {
IAccessibleHyperlinkPtr link;
this->hypertext->get_hyperlink(index, &link);
return link;
}

Ht2HyperlinkGetter::Ht2HyperlinkGetter(IAccessibleHypertext2Ptr hypertext)
: hypertext(hypertext)
{
if (FAILED(hypertext->get_hyperlinks(&this->rawLinks, &this->count))) {
this->count = 0;
}
}

IAccessibleHyperlinkPtr Ht2HyperlinkGetter::get(const unsigned long index) {
// Ensure we don't AddRef this pointer.
return IAccessibleHyperlinkPtr(this->rawLinks[index], false);
}

Ht2HyperlinkGetter::~Ht2HyperlinkGetter() {
CoTaskMemFree(this->rawLinks);
}

// We use a unique_ptr so we can have a polymorphic, optional return.
unique_ptr<HyperlinkGetter> makeHyperlinkGetter(IAccessible2* acc) {
// Try IAccessibleHypertext2 first.
IAccessibleHypertext2Ptr ht2 = acc;
if (ht2) {
return make_unique<Ht2HyperlinkGetter>(move(ht2));
}
// Fall back to IAccessibleHypertext.
IAccessibleHypertextPtr ht = acc;
if (ht) {
return make_unique<HtHyperlinkGetter>(move(ht));
}
// Neither interface is supported.
return nullptr;
}
69 changes: 68 additions & 1 deletion nvdaHelper/common/ia2utils.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
This file is a part of the NVDA project.
URL: http://www.nvda-project.org/
Copyright 2006-2010 NVDA contributers.
Copyright 2007-2017 NV Access Limited, Mozilla Corporation
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2.0, as published by
the Free Software Foundation.
Expand All @@ -15,8 +15,12 @@ This license can be found at:
#ifndef _VBUF_IA2UTILS_H
#define _VBUF_IA2UTILS_H

#include <comdef.h>
#include <comip.h>
#include <string>
#include <map>
#include <memory>
#include <ia2.h>

/**
* Convert an IAccessible2 attributes string to a map of attribute keys and values.
Expand All @@ -29,4 +33,67 @@ This license can be found at:
*/
void IA2AttribsToMap(const std::wstring &attribsString, std::map<std::wstring, std::wstring> &attribsMap);

_COM_SMARTPTR_TYPEDEF(IAccessible2, IID_IAccessible2);
_COM_SMARTPTR_TYPEDEF(IAccessibleHypertext, IID_IAccessibleHypertext);
_COM_SMARTPTR_TYPEDEF(IAccessibleHypertext2, IID_IAccessibleHypertext2);
_COM_SMARTPTR_TYPEDEF(IAccessibleHyperlink, IID_IAccessibleHyperlink);

/**
* Base class to support retrieving hyperlinks (embedded objects) from
* IAccessibleHypertext or IAccessibleHypertext2.
* Callers should use the makeHyperlinkGetter factory function,
* rather than instantiating subclasses directly.
*/
class HyperlinkGetter {
public:
virtual ~HyperlinkGetter() {}

/** Get the next hyperlink.
*/
virtual IAccessibleHyperlinkPtr next();

protected:
long count;
long index = 0;
virtual IAccessibleHyperlinkPtr get(const unsigned long index) = 0;
};

/** Supports retrieval of hyperlinks from IAccessibleHypertext.
*/
class HtHyperlinkGetter: public HyperlinkGetter {
public:
HtHyperlinkGetter(IAccessibleHypertextPtr hypertext);

protected:
virtual IAccessibleHyperlinkPtr get(const unsigned long index) override;

private:
IAccessibleHypertextPtr hypertext;
};

/** Supports retrieval of hyperlinks from IAccessibleHypertext2.
*/
class Ht2HyperlinkGetter: public HyperlinkGetter {
public:
Ht2HyperlinkGetter(IAccessibleHypertext2Ptr hypertext);
virtual ~Ht2HyperlinkGetter();

protected:
virtual IAccessibleHyperlinkPtr get(const unsigned long index) override;

private:
IAccessibleHypertext2Ptr hypertext;
IAccessibleHyperlink** rawLinks = nullptr;
};

/**
* Create an appropriate HyperlinkGetterto retrieve hyperlinks

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HyperlinkGetterto > HyperlinkGetter to

* (embedded objects) if they are supported.
* IAccessibleHypertext2 will be used in preference to IAccessibleHypertext.
* @param acc The accessible to use.
* @return A pointer to the HyperlinkGetter
* or a null pointer if hyperlinks aren't supported.
*/
std::unique_ptr<HyperlinkGetter> makeHyperlinkGetter(IAccessible2* acc);

#endif
87 changes: 0 additions & 87 deletions nvdaHelper/vbufBackends/gecko_ia2/gecko_ia2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,10 @@ This license can be found at:
http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/

#include <comdef.h>
#include <comip.h>
#include <windows.h>
#include <set>
#include <string>
#include <sstream>
#include <memory>
#include <ia2.h>
#include <common/ia2utils.h>
#include <remote/nvdaHelperRemote.h>
Expand Down Expand Up @@ -323,90 +320,6 @@ bool hasAriaHiddenAttribute(const map<wstring,wstring>& IA2AttribsMap){
return (IA2AttribsMapIt != IA2AttribsMap.end() && IA2AttribsMapIt->second == L"true");
}

_COM_SMARTPTR_TYPEDEF(IAccessible2, IID_IAccessible2);
_COM_SMARTPTR_TYPEDEF(IAccessibleHypertext, IID_IAccessibleHypertext);
_COM_SMARTPTR_TYPEDEF(IAccessibleHypertext2, IID_IAccessibleHypertext2);
_COM_SMARTPTR_TYPEDEF(IAccessibleHyperlink, IID_IAccessibleHyperlink);

// Classes to support retrieving hyperlinks (embedded objects) from both
// IAccessibleHypertext and IAccessibleHypertext2.
class HyperlinkGetter {
public:
virtual ~HyperlinkGetter() {
}

// get the next hyperlink.
virtual IAccessibleHyperlinkPtr next() {
if (this->index >= this->count) {
return nullptr;
}
return this->get(this->index++);
}

protected:
long count;
long index = 0;
virtual IAccessibleHyperlinkPtr get(const unsigned long index) = 0;
};

// For IAccessibleHypertext.
class HtHyperlinkGetter: public HyperlinkGetter {
public:
HtHyperlinkGetter(IAccessibleHypertextPtr hypertext): hypertext(hypertext) {
if (FAILED(hypertext->get_nHyperlinks(&this->count))) {
this->count = 0;
}
}

virtual IAccessibleHyperlinkPtr get(const unsigned long index) {
IAccessibleHyperlinkPtr link;
this->hypertext->get_hyperlink(index, &link);
return link;
}

private:
IAccessibleHypertextPtr hypertext;
};

// For IAccessibleHypertext2.
class Ht2HyperlinkGetter: public HyperlinkGetter {
public:
Ht2HyperlinkGetter(IAccessibleHypertext2Ptr hypertext): hypertext(hypertext) {
if (FAILED(hypertext->get_hyperlinks(&this->rawLinks, &this->count))) {
this->count = 0;
}
}

virtual IAccessibleHyperlinkPtr get(const unsigned long index) {
// Ensure we don't AddRef this pointer.
return IAccessibleHyperlinkPtr(this->rawLinks[index], false);
}

virtual ~Ht2HyperlinkGetter() {
CoTaskMemFree(this->rawLinks);
}

private:
IAccessibleHypertext2Ptr hypertext;
IAccessibleHyperlink** rawLinks = nullptr;
};

// We use a unique_ptr so we can have a polymorphic, optional return.
unique_ptr<HyperlinkGetter> makeHyperlinkGetter(IAccessible2* acc) {
// Try IAccessibleHypertext2 first.
IAccessibleHypertext2Ptr ht2 = acc;
if (ht2) {
return make_unique<Ht2HyperlinkGetter>(move(ht2));
}
// Fall back to IAccessibleHypertext.
IAccessibleHypertextPtr ht = acc;
if (ht) {
return make_unique<HtHyperlinkGetter>(move(ht));
}
// Neither interface is supported.
return nullptr;
}

const vector<wstring>ATTRLIST_ROLES(1, L"IAccessible2::attribute_xml-roles");
const wregex REGEX_PRESENTATION_ROLE(L"IAccessible2\\\\:\\\\:attribute_xml-roles:.*\\bpresentation\\b.*;");

Expand Down