diff options
author | Martin Smith <martin.smith@digia.com> | 2015-02-13 13:00:22 +0100 |
---|---|---|
committer | Martin Smith <martin.smith@digia.com> | 2015-02-20 11:37:18 +0000 |
commit | 62a2f46d290c67343366cb4f707830fe7d8b3d63 (patch) | |
tree | 4bde42e59c1d54e93fa42d2050f955782bc17ca9 /src/tools/qdoc/htmlgenerator.cpp | |
parent | fe7c2662b5a6a458459bf11b8d06a2b34318918d (diff) |
qdoc: Support documentation of JavaScript
This update provides the actual support for documenting
JavaScript. It has been tested with JavaScript commands
in qdoc comments in .qdoc files but not in .js files.
Currently, we have the use case of needing to document
JavaScript using qdoc comments in .qdoc files.
For each qdoc command for QML, i.e. \qmltype, \qmlproperty,
etc, there is now a corresponding JavaScript command, i.e.
\jstype, \jsproperty, etc. Some of these might not be needed,
but they are all provided.
Briefly, document JavaScript in a .qdoc file the same way you
would document QML in a .qdoc file, but instead of using the
\qmlxxx commands, use \jsxxx commands.
Change-Id: Ib68a5f66c16472af87d9f776db162332ca13fbb7
Task-number: QTBUG-43715
Reviewed-by: Topi Reiniƶ <topi.reinio@digia.com>
Diffstat (limited to 'src/tools/qdoc/htmlgenerator.cpp')
-rw-r--r-- | src/tools/qdoc/htmlgenerator.cpp | 196 |
1 files changed, 80 insertions, 116 deletions
diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp index f4ada7132f..8eb96bff17 100644 --- a/src/tools/qdoc/htmlgenerator.cpp +++ b/src/tools/qdoc/htmlgenerator.cpp @@ -513,7 +513,10 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark case Atom::BriefLeft: // Do not output the brief for QML nodes, doc nodes or collections // (groups, modules, qml module nodes) - if (relative->isQmlType() || relative->isDocNode() || relative->isCollectionNode()) { + if (relative->isQmlType() || + relative->isDocumentNode() || + relative->isCollectionNode() || + relative->isJsType()) { skipAhead = skipAtoms(atom, Atom::BriefRight); break; } @@ -549,7 +552,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark } break; case Atom::BriefRight: - if (!relative->isDocNode()) + if (!relative->isDocumentNode()) out() << "</p>\n"; break; case Atom::C: @@ -660,9 +663,9 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark break; case Atom::AnnotatedList: { - GroupNode* gn = qdb_->getGroup(atom->string()); - if (gn) - generateList(gn, marker, atom->string()); + CollectionNode* cn = qdb_->getCollection(atom->string(), Node::DOC); + if (cn) + generateList(cn, marker, atom->string()); } break; case Atom::GeneratedList: @@ -685,10 +688,10 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark else if (atom->string().contains("classesbymodule")) { QString physicalModuleName = atom->string().mid(atom->string().indexOf("classesbymodule") + 15).trimmed(); QDocDatabase* qdb = QDocDatabase::qdocDB(); - ModuleNode* mn = qdb->findModule(physicalModuleName); - if (mn) { + CollectionNode* cn = qdb->findModule(physicalModuleName); + if (cn) { NodeMap m; - mn->getMemberClasses(m); + cn->getMemberClasses(m); if (!m.isEmpty()) { generateAnnotatedList(relative, marker, m); } @@ -751,7 +754,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, const Node *relative, CodeMark Remove permanently if it is not missed. */ else if (atom->string() == "relatedinline") { - const DocNode *dn = static_cast<const DocNode *>(relative); + const DocumentNode *dn = static_cast<const DocumentNode *>(relative); if (dn && !dn->members().isEmpty()) { // Reverse the list into the original scan order. // Should be sorted. But on what? It may not be a @@ -1537,7 +1540,11 @@ void HtmlGenerator::generateQmlTypePage(QmlTypeNode* qcn, CodeMarker* marker) Generator::setQmlTypeContext(qcn); SubTitleSize subTitleSize = LargeSubTitle; QList<Section>::const_iterator s; - QString htmlTitle = qcn->fullTitle() + " QML Type"; + QString htmlTitle = qcn->fullTitle(); + if (qcn->isJsType()) + htmlTitle += " JavaScript Type"; + else + htmlTitle += " QML Type"; generateHeader(htmlTitle, qcn, marker); QList<Section> sections = marker->qmlSections(qcn, CodeMarker::Summary); @@ -1609,7 +1616,11 @@ void HtmlGenerator::generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker* { SubTitleSize subTitleSize = LargeSubTitle; QList<Section>::const_iterator s; - QString htmlTitle = qbtn->fullTitle() + " QML Basic Type"; + QString htmlTitle = qbtn->fullTitle(); + if (qbtn->isJsType()) + htmlTitle += " JavaScript Basic Type"; + else + htmlTitle += " QML Basic Type"; marker = CodeMarker::markerForLanguage(QLatin1String("QML")); @@ -1636,7 +1647,7 @@ void HtmlGenerator::generateQmlBasicTypePage(QmlBasicTypeNode* qbtn, CodeMarker* Generate the HTML page for an entity that doesn't map to any underlying parsable C++ class or QML component. */ -void HtmlGenerator::generateDocNode(DocNode* dn, CodeMarker* marker) +void HtmlGenerator::generateDocumentNode(DocumentNode* dn, CodeMarker* marker) { /* If the document node is a page node, and if the page type @@ -1805,7 +1816,7 @@ void HtmlGenerator::generateCollectionNode(CollectionNode* cn, CodeMarker* marke if (cn->isGroup()) generateAnnotatedList(cn, marker, cn->members()); - else if (cn->isQmlModule()) + else if (cn->isQmlModule() || cn->isJsModule()) generateAnnotatedList(cn, marker, cn->members()); sections = marker->sections(cn, CodeMarker::Detailed, CodeMarker::Okay); @@ -1872,7 +1883,8 @@ void HtmlGenerator::generateNavigationBar(const QString &title, << Atom(Atom::String, cn->name()) << Atom(Atom::ListItemRight); } - else if (node->isQmlType() || node->isQmlBasicType()) { + else if (node->isQmlType() || node->isQmlBasicType() || + node->isJsType() || node->isJsBasicType()) { if (!qmltypespage.isEmpty()) navigationbar << Atom(Atom::ListItemLeft) << Atom(Atom::NavLink, qmltypespage) @@ -2133,10 +2145,10 @@ void HtmlGenerator::generateRequisites(InnerNode *inner, CodeMarker *marker) if (inner->type() == Node::Class || inner->type() == Node::Namespace) { //add the QT variable to the map if (!inner->physicalModuleName().isEmpty()) { - ModuleNode* moduleNode = qdb_->findModule(inner->physicalModuleName()); - if (moduleNode && !moduleNode->qtVariable().isEmpty()) { + CollectionNode* cn = qdb_->findModule(inner->physicalModuleName()); + if (cn && !cn->qtVariable().isEmpty()) { text.clear(); - text << "QT += " + moduleNode->qtVariable(); + text << "QT += " + cn->qtVariable(); requisites.insert(qtVariableText, text); } } @@ -2243,9 +2255,13 @@ void HtmlGenerator::generateQmlRequisites(QmlTypeNode *qcn, CodeMarker *marker) //add the module name and version to the map QString logicalModuleVersion; - QmlModuleNode* qmn = qdb_->findQmlModule(qcn->logicalModuleName()); - if (qmn) - logicalModuleVersion = qmn->logicalModuleVersion(); + CollectionNode* collection = 0; + if (qcn->isJsNode()) + qdb_->findJsModule(qcn->logicalModuleName()); + else + qdb_->findQmlModule(qcn->logicalModuleName()); + if (collection) + logicalModuleVersion = collection->logicalModuleVersion(); else logicalModuleVersion = qcn->logicalModuleVersion(); text.clear(); @@ -2419,7 +2435,10 @@ void HtmlGenerator::generateTableOfContents(const Node *node, } } } - else if (sections && (node->isClass() || node->isNamespace() || node->isQmlType())) { + else if (sections && (node->isClass() || + node->isNamespace() || + node->isQmlType() || + node->isJsType())) { QList<Section>::ConstIterator s = sections->constBegin(); while (s != sections->constEnd()) { if (!s->members.isEmpty()) { @@ -2848,7 +2867,7 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative, generateFullName(node, relative); out() << "</p></td>"; - if (!node->isDocNode()) { + if (!node->isDocumentNode()) { Text brief = node->doc().trimmedBriefText(node->name()); if (!brief.isEmpty()) { out() << "<td class=\"tblDescr\"><p>"; @@ -3025,7 +3044,7 @@ void HtmlGenerator::generateCompactList(ListType listType, } QStringList pieces; - if (it.value()->isQmlType()) + if (it.value()->isQmlType() || it.value()->isJsType()) pieces << it.value()->name(); else pieces = it.value()->fullName(relative).split("::"); @@ -3136,30 +3155,20 @@ void HtmlGenerator::generateQmlItem(const Node *node, void HtmlGenerator::generateList(const Node* relative, CodeMarker* marker, const QString& selector) { - NodeList nl; - CollectionList cl; - QRegExp singleDigit("\\b([0-9])\\b"); - - if (selector == "overviews") { - CNMap groups; - qdb_->mergeCollections(Node::Group, groups, relative); - cl = groups.values(); - foreach (CollectionNode* cn, cl) - nl.append(cn); - generateAnnotatedList(relative, marker, nl); - } - else if (selector == "cpp-modules") { - CNMap modules; - qdb_->mergeCollections(Node::Module, modules, relative); - cl = modules.values(); - foreach (CollectionNode* cn, cl) - nl.append(cn); - generateAnnotatedList(relative, marker, nl); - } - else if (selector == "qml-modules") { - CNMap qmlModules; - qdb_->mergeCollections(Node::QmlModule, qmlModules, relative); - cl = qmlModules.values(); + CNMap cnm; + Node::Genus genus = Node::DontCare; + if (selector == "overviews") + genus = Node::DOC; + else if (selector == "cpp-modules") + genus = Node::CPP; + else if (selector == "qml-modules") + genus = Node::QML; + else if (selector == "js-modules") + genus = Node::JS; + if (genus != Node::DontCare) { + NodeList nl; + qdb_->mergeCollections(genus, cnm, relative); + CollectionList cl = cnm.values(); foreach (CollectionNode* cn, cl) nl.append(cn); generateAnnotatedList(relative, marker, nl); @@ -3167,69 +3176,19 @@ void HtmlGenerator::generateList(const Node* relative, CodeMarker* marker, const else { /* \generatelist {selector} is only allowed in a - comment where the topic is \group, \module, or - \qmlmodule. + comment where the topic is \group, \module, + \qmlmodule, or \jsmodule */ if (!relative || !relative->isCollectionNode()) { - relative->doc().location().warning(tr("\\generatelist {%1} is only allowed in \\group, \\module, and \\qmlmodule comments.").arg(selector)); + relative->doc().location().warning(tr("\\generatelist {%1} is only allowed in \\group, " + "\\module, \\qmlmodule, and \\jsmodule comments.").arg(selector)); return; } - if (selector == "related") { - Node* n = const_cast<Node*>(relative); - CollectionNode* cn = static_cast<CollectionNode*>(n); - qdb_->mergeCollections(cn); - generateAnnotatedList(cn, marker, cn->members()); - } - else { - Node* n = const_cast<Node*>(relative); - CollectionNode* cn = static_cast<CollectionNode*>(n); - qdb_->mergeCollections(cn); - generateAnnotatedList(cn, marker, cn->members()); - } - } - -#if 0 - QStringList keys = groups.uniqueKeys(); - foreach (const QString &key, keys) { - GroupNode* gn = static_cast<GroupNode*>(groups.value(key)); - if (gn) { - out() << QString("<h3><a href=\"%1\">%2</a></h3>\n").arg( - linkForNode(gn, relative)).arg( - protectEnc(gn->fullTitle())); -#if 0 - if (gn->members().isEmpty()) - continue; - - NodeMap nm; - foreach (Node* member, gn->members()) { - if (member->isInternal() || member->isExample() || member->isExternalPage() || - member->isObsolete()) - continue; - // not interested either in individual (Qt Designer etc.) manual chapters - if (member->links().contains(Node::ContentsLink)) - continue; - QString sortKey = member->fullTitle().toLower(); - if (sortKey.startsWith("the ")) - sortKey.remove(0, 4); - sortKey.replace(singleDigit, "0\\1"); - nm.insert(sortKey, member); - } - - out() << "<ul>\n"; - QStringList titles = nm.keys(); - foreach (const QString &t, titles) { - Node* member = nm.value(t); - QString title = member->fullTitle(); - if (title.startsWith("The ")) - title.remove(0, 4); - out() << "<li><a href=\"" << linkForNode(member, relative) << "\">" - << protectEnc(title) << "</a></li>\n"; - } - out() << "</ul>\n"; -#endif - } + Node* n = const_cast<Node*>(relative); + CollectionNode* cn = static_cast<CollectionNode*>(n); + qdb_->mergeCollections(cn); + generateAnnotatedList(cn, marker, cn->members()); } -#endif } void HtmlGenerator::generateSection(const NodeList& nl, @@ -3507,8 +3466,8 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, par1 = QStringRef(); const Node* n = qdb_->findTypeNode(arg.toString(), relative); html += QLatin1String("<span class=\"type\">"); - if (n && n->isQmlBasicType()) { - if (relative && relative->isQmlType()) + if (n && (n->isQmlBasicType() || n->isJsBasicType())) { + if (relative && (relative->isQmlType() || relative->isJsType())) addLink(linkForNode(n,relative), arg, &html); else html += arg; @@ -3778,9 +3737,9 @@ QString HtmlGenerator::fileBase(const Node *node) const QString HtmlGenerator::fileName(const Node *node) { if (node->type() == Node::Document) { - if (static_cast<const DocNode *>(node)->subType() == Node::ExternalPage) + if (static_cast<const DocumentNode *>(node)->subType() == Node::ExternalPage) return node->name(); - if (static_cast<const DocNode *>(node)->subType() == Node::Image) + if (static_cast<const DocumentNode *>(node)->subType() == Node::Image) return node->name(); } return Generator::fileName(node); @@ -3938,13 +3897,15 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative) return QString(); QString fn = fileName(node); - if (node && node->parent() && node->parent()->isQmlType() && node->parent()->isAbstract()) { + if (node && node->parent() && + (node->parent()->isQmlType() || node->parent()->isJsType()) + && node->parent()->isAbstract()) { if (Generator::qmlTypeContext()) fn = fileName(Generator::qmlTypeContext()); } QString link = fn; - if (!node->isInnerNode() || node->type() == Node::QmlPropertyGroup) { + if (!node->isInnerNode() || node->isQmlPropertyGroup() || node->isJsPropertyGroup()) { QString ref = refForNode(node); if (relative && fn == fileName(relative) && ref == refForNode(relative)) return QString(); @@ -4107,7 +4068,7 @@ const QPair<QString,QString> HtmlGenerator::anchorForNode(const Node *node) anchorPair.first = Generator::fileName(node); if (node->type() == Node::Document) { - const DocNode *docNode = static_cast<const DocNode*>(node); + const DocumentNode *docNode = static_cast<const DocumentNode*>(node); anchorPair.second = docNode->title(); } @@ -4418,7 +4379,10 @@ void HtmlGenerator::generateInstantiatedBy(ClassNode* cn, CodeMarker* marker) text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); text << Atom(Atom::String, cn->name()); text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); - text << " is instantiated by QML Type "; + if (qcn->isQmlType()) + text << " is instantiated by QML Type "; + else + text << " is instantiated by Javascript Type "; text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); text << Atom(Atom::String, qcn->name()); @@ -4917,9 +4881,9 @@ void HtmlGenerator::writeDitaRefs(const DitaRefList& ditarefs) xmlWriter().writeStartElement("topicref"); xmlWriter().writeAttribute("navtitle",t->navtitle()); if (t->href().isEmpty()) { - const DocNode* fn = qdb_->findDocNodeByTitle(t->navtitle()); - if (fn) - xmlWriter().writeAttribute("href",fileName(fn)); + const DocumentNode* dn = qdb_->findDocumentNodeByTitle(t->navtitle()); + if (dn) + xmlWriter().writeAttribute("href",fileName(dn)); } else xmlWriter().writeAttribute("href",t->href()); |