Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render JS sidebar #370

Merged
merged 8 commits into from
Mar 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
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
63 changes: 30 additions & 33 deletions client/src/document.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from "react";
import { Link, Location } from "@reach/router";
import { Link } from "@reach/router";

import { NoMatch } from "./routing";

Expand Down Expand Up @@ -100,22 +100,16 @@ function RenderSideBar({ doc }) {
return null;
}
return doc.related_content.map(node => (
<SidebarLeaf
key={node.title}
depth={0}
title={node.title}
content={node.content || []}
/>
<SidebarLeaf key={node.title} parent={node} />
));
}

function SidebarLeaf({ title, content }) {
const titleNode = <h3>{title}</h3>;
function SidebarLeaf({ parent }) {
return (
<div>
{titleNode}
<h3>{parent.title}</h3>
<ul>
{content.map(node => {
{parent.content.map(node => {
if (node.content) {
return (
<li key={node.title}>
Expand All @@ -137,29 +131,31 @@ function SidebarLeaf({ title, content }) {

function SidebarLeaflets({ node }) {
return (
<Location>
{({ location }) => {
let hasActiveChild = false;
const listItems = node.content.map(childNode => {
const isActive = childNode.uri === location.pathname;
if (isActive && !hasActiveChild) {
hasActiveChild = true;
<details open={node.open}>
<summary>
{node.uri ? <Link to={node.uri}>{node.title}</Link> : node.title}
</summary>
<ol>
{node.content.map(childNode => {
if (childNode.content) {
return (
<li key={childNode.title}>
<SidebarLeaflets node={childNode} />
</li>
);
} else {
return (
<li
key={childNode.uri}
className={childNode.isActive && "active"}
>
<Link to={childNode.uri}>{childNode.title}</Link>
</li>
);
}
return (
<li key={childNode.uri} className={isActive ? "active" : undefined}>
<Link to={childNode.uri}>{childNode.title}</Link>
</li>
);
});

return (
<details open={!!hasActiveChild}>
<summary>{node.title}</summary>
<ol>{listItems}</ol>
</details>
);
}}
</Location>
})}
</ol>
</details>
);
}

Expand Down Expand Up @@ -220,6 +216,7 @@ function RenderDocumentBody({ doc }) {
console.warn("Don't know how to deal with info_box!");
return null;
} else if (
section.type === "class_constructor" ||
section.type === "static_methods" ||
section.type === "instance_methods"
) {
Expand Down
7 changes: 5 additions & 2 deletions client/src/mdn.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,13 @@ h1.page-title {

div.sidebar {
float: left;
max-height: 100vh;
max-width: 300px;
position: sticky;
top: 0;
margin-bottom: 20px;
position: relative;
overflow: hidden;
overflow-x: hidden;
overflow-y: scroll;
font-size: 16px;
font-size: 0.88889rem;

Expand Down
68 changes: 43 additions & 25 deletions ssr/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,55 @@ const TOUCHFILE = path.join(PROJECT_ROOT, "client", "src", "touchthis.js");
const BUILD_JSON_SERVER =
process.env.BUILD_JSON_SERVER || "http://localhost:5555";

/** In the document, there's related_content and it contains keys
* called 'mdn_url'. We need to transform them to relative links
* that works with our router.
/**
* Transform the `related_content` object for this document. For each node:
* - rename `mdn_url` to `uri`
* - use `short_title` instead of `title`, if it is available
* - delete `short_description`
* - set `isActive` for the node whose `uri` matches this document's `mdn_url`
* - set `open` for nodes which are active or which have an active child
*
* This /mutates/ the document data.
*/
function fixRelatedContent(document) {
function fixBlock(block) {
if (block.content) {
block.content.forEach(item => {
if (item.mdn_url) {
// always expect this to be a relative URL
if (!item.mdn_url.startsWith("/")) {
throw new Error(
`Document's .mdn_url doesn't start with / (${item.mdn_url})`
);
}
// Complicated way to rename an object key.
item.uri = item.mdn_url;
delete item.mdn_url;
function fixBlock(node) {
if (node.mdn_url) {
// always expect this to be a relative URL
if (!node.mdn_url.startsWith("/")) {
throw new Error(
`Document's .mdn_url doesn't start with / (${item.mdn_url})`
);
}
// Complicated way to rename an object key.
node.uri = node.mdn_url;
delete node.mdn_url;
}

// The sidebar only needs a 'title' and doesn't really care if
// it came from the full title or the 'short_title'.
node.title = node.short_title || node.title;
delete node.short_title;
// At the moment, we never actually use the 'short_description'
// so no use including it.
delete node.short_description;

// isActive means that this node is a link to the current document
// open means that this node or one of its children is a link to the current document
if (node.uri === document.mdn_url) {
node.open = true;
node.isActive = true;
}

if (node.content) {
for (const child of node.content) {
fixBlock(child);
if (child.open) {
node.open = true;
}
// The sidebar only needs a 'title' and doesn't really care if
// it came from the full title or the 'short_title'.
item.title = item.short_title || item.title;
delete item.short_title;
// At the moment, we never actually use the 'short_description'
// so no use including it.
delete item.short_description;
fixBlock(item);
});
}
}
}

if (document.related_content) {
document.related_content.forEach(block => {
fixBlock(block);
Expand Down
2 changes: 1 addition & 1 deletion stumptown
Submodule stumptown updated 546 files