Skip to content

Commit

Permalink
Revert "Revert "Add anchors to Markdown headers (#2513)""
Browse files Browse the repository at this point in the history
This reverts commit ab26f05.
  • Loading branch information
karriebear committed Jan 21, 2021
1 parent e5a2c42 commit 1ad0509
Show file tree
Hide file tree
Showing 15 changed files with 330 additions and 23 deletions.
1 change: 1 addition & 0 deletions e2e/scripts/st_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@
import streamlit as st

st.header("This header is awesome!")
st.header("This header is awesome too!", anchor="awesome-header")
4 changes: 4 additions & 0 deletions e2e/scripts/st_markdown.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,7 @@
$$
"""
)

st.markdown("# Some header 1")
st.markdown("## Some header 2")
st.markdown("### Some header 3")
1 change: 1 addition & 0 deletions e2e/scripts/st_subheader.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@
import streamlit as st

st.subheader("This subheader is awesome!")
st.subheader("This subheader is awesome too!", anchor="awesome-subheader")
1 change: 1 addition & 0 deletions e2e/scripts/st_title.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@
import streamlit as st

st.title("This title is awesome!")
st.title("This title is awesome too!", anchor="awesome-title")
19 changes: 15 additions & 4 deletions e2e/specs/st_header.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,21 @@ describe("st.header", () => {
cy.visit("http://localhost:3000/");
});

it("displays correct number of elements", () => {
cy.get(".element-container .stMarkdown h2").should("have.length", 2);
});

it("displays a header", () => {
cy.get(".element-container .stMarkdown h2").should(
"contain",
"This header is awesome!"
);
cy.get(".element-container .stMarkdown h2").then(els => {
expect(els[0].textContent).to.eq("This header is awesome!");
expect(els[1].textContent).to.eq("This header is awesome too!");
});
});

it("displays headers with anchors", () => {
cy.get(".element-container .stMarkdown h2").then(els => {
cy.wrap(els[0]).should("have.attr", "id", "this-header-is-awesome");
cy.wrap(els[1]).should("have.attr", "id", "awesome-header");
});
});
});
23 changes: 21 additions & 2 deletions e2e/specs/st_markdown.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ describe("st.markdown", () => {
cy.visit("http://localhost:3000/");
});

it("displays correct number of elements", () => {
cy.get(".element-container .stMarkdown").should("have.length", 11);
});

it("displays markdown", () => {
cy.get(".element-container .stMarkdown").should("have.length", 8);
cy.get(".element-container .stMarkdown").then(els => {
expect(els[0].textContent).to.eq("This markdown is awesome! 😎");
expect(els[1].textContent).to.eq("This <b>HTML tag</b> is escaped!");
Expand All @@ -33,14 +36,30 @@ describe("st.markdown", () => {
expect(els[7].textContent).to.eq(
"ax2+bx+c=0ax^2 + bx + c = 0ax2+bx+c=0"
);
expect(els[8].textContent).to.eq("Some header 1");
expect(els[9].textContent).to.eq("Some header 2");
expect(els[10].textContent).to.eq("Some header 3");

cy.wrap(els[3])
.find("a")
.should("not.exist");

cy.wrap(els[4])
.find("a")
.should("have.attr", "href");
});
});

it("displays headers with anchors", () => {
cy.get(".element-container .stMarkdown").then(els => {
cy.wrap(els[8])
.find("h1")
.should("have.attr", "id", "some-header-1");
cy.wrap(els[9])
.find("h2")
.should("have.attr", "id", "some-header-2");
cy.wrap(els[10])
.find("h3")
.should("have.attr", "id", "some-header-3");
});
});
});
19 changes: 15 additions & 4 deletions e2e/specs/st_subheader.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,21 @@ describe("st.subheader", () => {
cy.visit("http://localhost:3000/");
});

it("displays correct number of elements", () => {
cy.get(".element-container .stMarkdown h3").should("have.length", 2);
});

it("displays a subheader", () => {
cy.get(".element-container .stMarkdown h3").should(
"contain",
"This subheader is awesome!"
);
cy.get(".element-container .stMarkdown h3").then(els => {
expect(els[0].textContent).to.eq("This subheader is awesome!");
expect(els[1].textContent).to.eq("This subheader is awesome too!");
});
});

it("displays subheaders with anchors", () => {
cy.get(".element-container .stMarkdown h3").then(els => {
cy.wrap(els[0]).should("have.attr", "id", "this-subheader-is-awesome");
cy.wrap(els[1]).should("have.attr", "id", "awesome-subheader");
});
});
});
19 changes: 15 additions & 4 deletions e2e/specs/st_title.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,21 @@ describe("st.title", () => {
cy.visit("http://localhost:3000/");
});

it("displays correct number of elements", () => {
cy.get(".element-container .stMarkdown h1").should("have.length", 2);
});

it("displays a title", () => {
cy.get(".element-container .stMarkdown h1").should(
"contain",
"This title is awesome!"
);
cy.get(".element-container .stMarkdown h1").then(els => {
expect(els[0].textContent).to.eq("This title is awesome!");
expect(els[1].textContent).to.eq("This title is awesome too!");
});
});

it("displays title with anchors", () => {
cy.get(".element-container .stMarkdown h1").then(els => {
cy.wrap(els[0]).should("have.attr", "id", "this-title-is-awesome");
cy.wrap(els[1]).should("have.attr", "id", "awesome-title");
});
});
});
23 changes: 23 additions & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ import {
SessionState,
Config,
} from "autogen/proto"
import { without, concat } from "lodash"

import { RERUN_PROMPT_MODAL_DIALOG } from "lib/baseconsts"
import { SessionInfo } from "lib/SessionInfo"
Expand Down Expand Up @@ -101,6 +102,7 @@ interface State {
layout: PageConfig.Layout
initialSidebarState: PageConfig.SidebarState
allowRunOnSave: boolean
reportFinishedHandlers: (() => void)[]
deployParams?: IDeployParams | null
}

Expand Down Expand Up @@ -158,6 +160,7 @@ export class App extends PureComponent<Props, State> {
layout: PageConfig.Layout.CENTERED,
initialSidebarState: PageConfig.SidebarState.AUTO,
allowRunOnSave: true,
reportFinishedHandlers: [],
deployParams: null,
}

Expand Down Expand Up @@ -554,6 +557,12 @@ export class App extends PureComponent<Props, State> {
*/
handleReportFinished(status: ForwardMsg.ReportFinishedStatus): void {
if (status === ForwardMsg.ReportFinishedStatus.FINISHED_SUCCESSFULLY) {
// Notify any subscribers of this event (and do it on the next cycle of
// the event loop)
window.setTimeout(() => {
this.state.reportFinishedHandlers.map(handler => handler())
}, 0)

// Clear any stale elements left over from the previous run.
// (We don't do this if our script had a compilation error and didn't
// finish successfully.)
Expand Down Expand Up @@ -895,6 +904,18 @@ export class App extends PureComponent<Props, State> {
this.setState({ isFullScreen })
}

addReportFinishedHandler = (func: () => void): void => {
this.setState({
reportFinishedHandlers: concat(this.state.reportFinishedHandlers, func),
})
}

removeReportFinishedHandler = (func: () => void): void => {
this.setState({
reportFinishedHandlers: without(this.state.reportFinishedHandlers, func),
})
}

render(): JSX.Element {
const {
allowRunOnSave,
Expand Down Expand Up @@ -935,6 +956,8 @@ export class App extends PureComponent<Props, State> {
embedded: isEmbeddedInIFrame(),
isFullScreen,
setFullScreen: this.handleFullScreen,
addReportFinishedHandler: this.addReportFinishedHandler,
removeReportFinishedHandler: this.removeReportFinishedHandler,
}}
>
<HotKeys
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/components/core/PageLayoutContext/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ export default React.createContext({
embedded: false,
isFullScreen: false,
setFullScreen: (value: boolean) => {},
addReportFinishedHandler: (func: () => void) => {},
removeReportFinishedHandler: (func: () => void) => {},
})
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { mount } from "enzyme"
import {
linkWithTargetBlank,
linkReferenceHasParens,
createAnchorFromText,
} from "./StreamlitMarkdown"

// Fixture Generator
Expand All @@ -33,6 +34,20 @@ const getMarkdownElement = (body: string): ReactElement => {
return <ReactMarkdown source={body} renderers={renderers} />
}

describe("createAnchorFromText", () => {
it("generates slugs correctly", () => {
const cases = [
["some header", "some-header"],
["some -24$35-9824 header", "some-24-35-9824-header"],
["blah___blah___blah", "blah-blah-blah"],
]

cases.forEach(([s, want]) => {
expect(createAnchorFromText(s)).toEqual(want)
})
})
})

describe("linkReference", () => {
it("renders a link with _blank target", () => {
const body = "Some random URL like [Streamlit](https://streamlit.io/)"
Expand Down

0 comments on commit 1ad0509

Please sign in to comment.