qdoc: Sanitize anchors in URLs for functions
When QDoc constructs the full path to a documentation node, it must construct a clean anchor reference. Intra-page links use a different code path, so the links e.g. from Member Functions list to their detailed descriptions always work, but using the link command to link to functions with certain characters (such as 'operator==') failed because the node name was used as-is and not sanitized ('operator-eq-eq'). This change moves HtmlGenerator::cleanRef() static function to its parent class, Generator, and takes it into use in Generator::fullDocumentLocation(). Change-Id: Ic939ffa3ae0f4495ef2a30eff0d4a1de65ea3e8f Task-number: QTBUG-45629 Reviewed-by: Martin Smith <martin.smith@digia.com>
This commit is contained in:
parent
4dd896785b
commit
21c90bcc98
@ -419,6 +419,59 @@ QString Generator::fileName(const Node* node) const
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString Generator::cleanRef(const QString& ref)
|
||||||
|
{
|
||||||
|
QString clean;
|
||||||
|
|
||||||
|
if (ref.isEmpty())
|
||||||
|
return clean;
|
||||||
|
|
||||||
|
clean.reserve(ref.size() + 20);
|
||||||
|
const QChar c = ref[0];
|
||||||
|
const uint u = c.unicode();
|
||||||
|
|
||||||
|
if ((u >= 'a' && u <= 'z') ||
|
||||||
|
(u >= 'A' && u <= 'Z') ||
|
||||||
|
(u >= '0' && u <= '9')) {
|
||||||
|
clean += c;
|
||||||
|
} else if (u == '~') {
|
||||||
|
clean += "dtor.";
|
||||||
|
} else if (u == '_') {
|
||||||
|
clean += "underscore.";
|
||||||
|
} else {
|
||||||
|
clean += QLatin1Char('A');
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < (int) ref.length(); i++) {
|
||||||
|
const QChar c = ref[i];
|
||||||
|
const uint u = c.unicode();
|
||||||
|
if ((u >= 'a' && u <= 'z') ||
|
||||||
|
(u >= 'A' && u <= 'Z') ||
|
||||||
|
(u >= '0' && u <= '9') || u == '-' ||
|
||||||
|
u == '_' || u == ':' || u == '.') {
|
||||||
|
clean += c;
|
||||||
|
} else if (c.isSpace()) {
|
||||||
|
clean += QLatin1Char('-');
|
||||||
|
} else if (u == '!') {
|
||||||
|
clean += "-not";
|
||||||
|
} else if (u == '&') {
|
||||||
|
clean += "-and";
|
||||||
|
} else if (u == '<') {
|
||||||
|
clean += "-lt";
|
||||||
|
} else if (u == '=') {
|
||||||
|
clean += "-eq";
|
||||||
|
} else if (u == '>') {
|
||||||
|
clean += "-gt";
|
||||||
|
} else if (u == '#') {
|
||||||
|
clean += QLatin1Char('#');
|
||||||
|
} else {
|
||||||
|
clean += QLatin1Char('-');
|
||||||
|
clean += QString::number((int)u, 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clean;
|
||||||
|
}
|
||||||
|
|
||||||
QMap<QString, QString>& Generator::formattingLeftMap()
|
QMap<QString, QString>& Generator::formattingLeftMap()
|
||||||
{
|
{
|
||||||
return fmtLeftMaps[format()];
|
return fmtLeftMaps[format()];
|
||||||
@ -521,10 +574,10 @@ QString Generator::fullDocumentLocation(const Node *node, bool useSubdir)
|
|||||||
return fullDocumentLocation(functionNode->associatedProperty());
|
return fullDocumentLocation(functionNode->associatedProperty());
|
||||||
|
|
||||||
else if (functionNode->overloadNumber() > 1)
|
else if (functionNode->overloadNumber() > 1)
|
||||||
anchorRef = QLatin1Char('#') + functionNode->name()
|
anchorRef = QLatin1Char('#') + cleanRef(functionNode->name())
|
||||||
+ QLatin1Char('-') + QString::number(functionNode->overloadNumber());
|
+ QLatin1Char('-') + QString::number(functionNode->overloadNumber());
|
||||||
else
|
else
|
||||||
anchorRef = QLatin1Char('#') + functionNode->name();
|
anchorRef = QLatin1Char('#') + cleanRef(functionNode->name());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -103,6 +103,7 @@ public:
|
|||||||
static bool useOutputSubdirs() { return useOutputSubdirs_; }
|
static bool useOutputSubdirs() { return useOutputSubdirs_; }
|
||||||
static void setQmlTypeContext(QmlTypeNode* t) { qmlTypeContext_ = t; }
|
static void setQmlTypeContext(QmlTypeNode* t) { qmlTypeContext_ = t; }
|
||||||
static QmlTypeNode* qmlTypeContext() { return qmlTypeContext_; }
|
static QmlTypeNode* qmlTypeContext() { return qmlTypeContext_; }
|
||||||
|
static QString cleanRef(const QString& ref);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void beginSubPage(const InnerNode* node, const QString& fileName);
|
virtual void beginSubPage(const InnerNode* node, const QString& fileName);
|
||||||
|
@ -3355,7 +3355,7 @@ void HtmlGenerator::generateSectionInheritedList(const Section& section, const N
|
|||||||
out() << section.pluralMember;
|
out() << section.pluralMember;
|
||||||
}
|
}
|
||||||
out() << " inherited from <a href=\"" << fileName((*p).first)
|
out() << " inherited from <a href=\"" << fileName((*p).first)
|
||||||
<< '#' << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
|
<< '#' << Generator::cleanRef(section.name.toLower()) << "\">"
|
||||||
<< protectEnc((*p).first->plainFullName(relative))
|
<< protectEnc((*p).first->plainFullName(relative))
|
||||||
<< "</a></li>\n";
|
<< "</a></li>\n";
|
||||||
++p;
|
++p;
|
||||||
@ -3610,62 +3610,9 @@ void HtmlGenerator::generateLink(const Atom* atom, CodeMarker* marker)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString HtmlGenerator::cleanRef(const QString& ref)
|
|
||||||
{
|
|
||||||
QString clean;
|
|
||||||
|
|
||||||
if (ref.isEmpty())
|
|
||||||
return clean;
|
|
||||||
|
|
||||||
clean.reserve(ref.size() + 20);
|
|
||||||
const QChar c = ref[0];
|
|
||||||
const uint u = c.unicode();
|
|
||||||
|
|
||||||
if ((u >= 'a' && u <= 'z') ||
|
|
||||||
(u >= 'A' && u <= 'Z') ||
|
|
||||||
(u >= '0' && u <= '9')) {
|
|
||||||
clean += c;
|
|
||||||
} else if (u == '~') {
|
|
||||||
clean += "dtor.";
|
|
||||||
} else if (u == '_') {
|
|
||||||
clean += "underscore.";
|
|
||||||
} else {
|
|
||||||
clean += QLatin1Char('A');
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 1; i < (int) ref.length(); i++) {
|
|
||||||
const QChar c = ref[i];
|
|
||||||
const uint u = c.unicode();
|
|
||||||
if ((u >= 'a' && u <= 'z') ||
|
|
||||||
(u >= 'A' && u <= 'Z') ||
|
|
||||||
(u >= '0' && u <= '9') || u == '-' ||
|
|
||||||
u == '_' || u == ':' || u == '.') {
|
|
||||||
clean += c;
|
|
||||||
} else if (c.isSpace()) {
|
|
||||||
clean += QLatin1Char('-');
|
|
||||||
} else if (u == '!') {
|
|
||||||
clean += "-not";
|
|
||||||
} else if (u == '&') {
|
|
||||||
clean += "-and";
|
|
||||||
} else if (u == '<') {
|
|
||||||
clean += "-lt";
|
|
||||||
} else if (u == '=') {
|
|
||||||
clean += "-eq";
|
|
||||||
} else if (u == '>') {
|
|
||||||
clean += "-gt";
|
|
||||||
} else if (u == '#') {
|
|
||||||
clean += QLatin1Char('#');
|
|
||||||
} else {
|
|
||||||
clean += QLatin1Char('-');
|
|
||||||
clean += QString::number((int)u, 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString HtmlGenerator::registerRef(const QString& ref)
|
QString HtmlGenerator::registerRef(const QString& ref)
|
||||||
{
|
{
|
||||||
QString clean = HtmlGenerator::cleanRef(ref);
|
QString clean = Generator::cleanRef(ref);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
QString& prevRef = refMap[clean.toLower()];
|
QString& prevRef = refMap[clean.toLower()];
|
||||||
|
@ -85,7 +85,6 @@ public:
|
|||||||
|
|
||||||
QString protectEnc(const QString &string);
|
QString protectEnc(const QString &string);
|
||||||
static QString protect(const QString &string, const QString &encoding = "ISO-8859-1");
|
static QString protect(const QString &string, const QString &encoding = "ISO-8859-1");
|
||||||
static QString cleanRef(const QString& ref);
|
|
||||||
static QString sinceTitle(int i) { return sinceTitles[i]; }
|
static QString sinceTitle(int i) { return sinceTitles[i]; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Loading…
Reference in New Issue
Block a user