Skip to content

Commit ffcac73

Browse files
authored
v3.0.0
v3.0.0
2 parents 4f19fb3 + 32eef2d commit ffcac73

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+2720
-172
lines changed

.env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ REACT_APP_PROXY=http://localhost
55
REACT_APP_API_TIMEOUT=180000
66
REACT_APP_TAG_EDITORIAL=editorial
77
REACT_APP_ENABLE_AUTH_0=false
8+
REACT_APP_GITHUB_RELEASES_API_ENDPOINT=https://api.github.com/repos/c2dh/journal-of-digital-history/releases
9+
REACT_APP_GITHUB_WIKI_FAQ=https://raw.githubusercontent.com/wiki/c2dh/journal-of-digital-history/FAQ.md

package-lock.json

Lines changed: 11 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "jdh",
3-
"version": "2.2.9",
3+
"version": "3.0.0",
44
"private": true,
55
"dependencies": {
66
"@auth0/auth0-react": "^1.1.0",
@@ -32,7 +32,7 @@
3232
"lodash.findindex": "^4.6.0",
3333
"lodash.groupby": "^4.6.0",
3434
"lodash.intersection": "^4.4.0",
35-
"markdown-it": "^12.0.0",
35+
"markdown-it": "^12.3.2",
3636
"markdown-it-mathjax3": "^3.0.0-0",
3737
"markdown-it-replace-link": "^1.1.0",
3838
"mathjax": "^3.2.0",

src/App.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ const Guidelines = lazy(() => import('./pages/Guidelines'))
6767
const NotFound = lazy(() => import('./pages/NotFound'))
6868
const ArticleViewer = lazy(() => import('./pages/ArticleViewer'))
6969
const Fingerprint = lazy(() => import('./pages/Fingerprint'))
70+
const FingerprintViewer = lazy(() => import('./pages/FingerprintViewer'))
71+
const FingerprintExplained = lazy(() => import ('./pages/FingerprintExplained'))
72+
const ReleaseNotes = lazy(() => import ('./pages/ReleaseNotes'))
73+
const Faq = lazy(() => import ('./pages/Faq'))
74+
7075
const { startLangShort, lang } = getStartLang()
7176
console.info('start language:', lang, startLangShort)
7277
i18n
@@ -123,6 +128,10 @@ function LangRoutes() {
123128
<Route path={`${path}/notebook-viewer-form`}>
124129
<NotebookViewerForm />
125130
</Route>
131+
<Route path={`${path}/fingerprint-viewer`} component={FingerprintViewer} />
132+
<Route path={`${path}/fingerprint-explained`} component={FingerprintExplained} />
133+
<Route path={`${path}/release-notes`} component={ReleaseNotes} />
134+
<Route path={`${path}/faq`} component={Faq} />
126135
<Route path={`${path}/notebook-viewer/:encodedUrl`}
127136
component={NotebookViewer}
128137
/>
@@ -206,7 +215,7 @@ export default function App() {
206215
<AppRoutes />
207216
</Suspense>
208217
</main>
209-
<Footer ></Footer>
218+
<Footer hideOnRoutes={['/article/', '/notebook-viewer/']}/>
210219
<ScrollToTop />
211220
</Auth0ProviderWithHistory>
212221
</QueryParamProvider>

src/components/Article/ArticleBibliography.js

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11
import React from 'react'
2-
import {Container, Col, Row} from 'react-bootstrap'
2+
import { Container, Col, Row } from 'react-bootstrap'
33
import { useTranslation } from 'react-i18next'
4+
import { BootstrapColumLayout } from '../../constants'
45

5-
const ArticleBilbiography = ({ articleTree }) => {
6+
7+
const ArticleBilbiography = ({
8+
articleTree,
9+
noAnchor=false,
10+
className='mt-5'
11+
}) => {
612
const { t } = useTranslation()
713

814
return (
9-
<Container className="ArticleBilbiography mt-5">
15+
<Container className={`ArticleBilbiography ${className}`}>
1016
<Row>
11-
<Col md={{ span: 7, offset: 2 }}>
12-
<div id="bibliography" className="anchor" />
17+
<Col {...BootstrapColumLayout}>
18+
{noAnchor
19+
? null
20+
: <div id="bibliography" className="anchor" />
21+
}
1322
<h2 >{t('bibliography')}</h2>
1423
<div dangerouslySetInnerHTML={{
1524
__html: articleTree

src/components/Article/ArticleCell.js

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import React, { lazy } from 'react';
22
import { Container, Row, Col} from 'react-bootstrap'
3-
import ArticleCellOutput from './ArticleCellOutput'
3+
import ArticleCellOutputs from './ArticleCellOutputs'
44
import ArticleCellContent from './ArticleCellContent'
55
import ArticleCellSourceCode from './ArticleCellSourceCode'
66
import ArticleCellFigure from './ArticleCellFigure'
@@ -25,6 +25,8 @@ const ArticleCell = ({
2525
isNarrativeStep,
2626
figure, // ArticleFigure instance
2727
headingLevel=0, // if isHeading, set this to its ArticleHeading.level value
28+
isJavascriptTrusted = false,
29+
onNumClick,
2830
}) => {
2931
let cellBootstrapColumnLayout = metadata.jdh?.text?.bootstrapColumLayout || BootstrapColumLayout;
3032
// we override or set the former layout if it appears in narrative-step
@@ -71,7 +73,14 @@ const ArticleCell = ({
7173
<Container >
7274
<Row>
7375
<Col className="ArticleCellQuote" {...BootstrapQuoteColumLayout}>
74-
<ArticleCellContent layer={layer} content={content} idx={idx} num={num} hideNum={hideNum} />
76+
<ArticleCellContent
77+
onNumClick={onNumClick}
78+
layer={layer}
79+
content={content}
80+
idx={idx}
81+
num={num}
82+
hideNum={hideNum}
83+
/>
7584
</Col>
7685
</Row>
7786
</Container>
@@ -85,17 +94,32 @@ const ArticleCell = ({
8594
metadata={metadata}
8695
figure={figure}
8796
figureColumnLayout={cellObjectBootstrapColumnLayout}
97+
isJavascriptTrusted={isJavascriptTrusted}
8898
isNarrativeStep={isNarrativeStep}
8999
>
90-
<ArticleCellContent hideNum={!!figure} layer={layer} content={content} idx={idx} num={num} />
100+
<ArticleCellContent
101+
onNumClick={onNumClick}
102+
layer={layer}
103+
content={content}
104+
idx={idx}
105+
num={num}
106+
/>
91107
</ArticleCellFigure>
92108
)
93109
}
94110
return (
95111
<Container>
96112
<Row>
97113
<Col {... cellBootstrapColumnLayout}>
98-
<ArticleCellContent headingLevel={headingLevel} hideNum={hideNum} layer={layer} content={content} idx={idx} num={num} />
114+
<ArticleCellContent
115+
headingLevel={headingLevel}
116+
onNumClick={onNumClick}
117+
hideNum={hideNum}
118+
layer={layer}
119+
content={content}
120+
idx={idx}
121+
num={num}
122+
/>
99123
</Col>
100124
</Row>
101125
</Container>
@@ -110,21 +134,24 @@ const ArticleCell = ({
110134
figure={figure}
111135
isNarrativeStep={isNarrativeStep}
112136
figureColumnLayout={cellObjectBootstrapColumnLayout}
137+
isJavascriptTrusted={isJavascriptTrusted}
113138
sourceCode={<ArticleCellSourceCode toggleVisibility content={content} language="python"/>}
114139
></ArticleCellFigure>
115140
)
116141
}
142+
117143
return (
118144
<Container>
119145
<Row>
120146
<Col {... cellBootstrapColumnLayout}>
121147
<div className="ArticleCellContent">
122148
<div className="ArticleCellContent_num"></div>
123149
<ArticleCellSourceCode visible content={content} language="python" />
124-
{outputs.length
125-
? outputs.map((output,i) => <ArticleCellOutput output={output} key={i} />)
126-
: <div className="ArticleCellSourceCode_no_output">no output</div>
127-
}
150+
<ArticleCellOutputs
151+
isJavascriptTrusted={false}
152+
cellIdx={idx}
153+
outputs={outputs}
154+
/>
128155
</div>
129156
</Col>
130157
</Row>

src/components/Article/ArticleCellContent.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,34 @@
11
import React from 'react'
22

33

4-
const ArticleCellContent = ({ idx, className='', content, num, hideNum=false, hideIdx=true, headingLevel=0}) => {
4+
const ArticleCellContent = ({
5+
idx, className='',
6+
content,
7+
num,
8+
layer,
9+
hideNum=false,
10+
hideIdx=true,
11+
headingLevel=0,
12+
onNumClick,
13+
}) => {
14+
const numClassNames = [
15+
headingLevel > 0 ? `level_H${headingLevel}`: '',
16+
typeof onNumClick === 'function'? 'selectable': ''
17+
].join(' ')
18+
const onClickHandler = (e) => {
19+
if (typeof onNumClick === 'function') {
20+
onNumClick(e, { idx, layer })
21+
}
22+
}
523
return (
624
<div className={`ArticleCellContent ${className}`}>
725
{!hideIdx && (<div className="ArticleCellContent_idx">{idx}</div>)}
8-
{!hideNum && (<div className={`ArticleCellContent_num ${headingLevel > 0? `level_H${headingLevel}`:''}`}>{num}</div>)}
26+
{!hideNum && (
27+
<div className={`ArticleCellContent_num ${numClassNames}`} onClick={onClickHandler}
28+
>
29+
{num}
30+
</div>
31+
)}
932
<div dangerouslySetInnerHTML={{__html: content}}></div>
1033
</div>
1134
)

src/components/Article/ArticleCellFigure.js

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
import React from 'react'
2-
import ArticleCellOutput from './ArticleCellOutput'
2+
import ArticleCellOutputs from './ArticleCellOutputs'
33
import ArticleFigure from './ArticleFigure'
44
import { markdownParser } from '../../logic/ipynb'
55
import {BootstrapColumLayout} from '../../constants'
66
import { Container, Row, Col} from 'react-bootstrap'
77

8-
const ArticleCellFigure = ({ figure, metadata={}, outputs=[], sourceCode, figureColumnLayout, children }) => {
8+
const ArticleCellFigure = ({
9+
figure, metadata={}, outputs=[], sourceCode,
10+
isJavascriptTrusted,
11+
figureColumnLayout,
12+
children
13+
}) => {
914
const isFluidContainer = figure.isCover || (metadata.tags && metadata.tags.includes('full-width'))
1015
const captions = outputs.reduce((acc, output) => {
11-
1216
if (output.metadata && Array.isArray(output.metadata?.jdh?.object?.source)) {
1317
acc.push(markdownParser.render(output.metadata.jdh.object.source.join('\n')))
1418
}
@@ -29,20 +33,21 @@ const ArticleCellFigure = ({ figure, metadata={}, outputs=[], sourceCode, figure
2933
if (metadata.jdh?.object?.bootstrapColumLayout) {
3034
figureColumnLayout = { ...figureColumnLayout, ...metadata.jdh?.object?.bootstrapColumLayout }
3135
}
36+
37+
3238
return (
33-
<div className="ArticleCellFigure">
39+
<div className="ArticleCellFigure" >
3440
<Container fluid={isFluidContainer}>
3541
<Row>
3642
<Col {...columnLayout}>
37-
<div >
43+
<div>
3844
<div className="anchor" id={figure.ref} />
39-
{!outputs.length ? (
40-
<div className="ArticleCellFigure_no_output">
41-
</div>
42-
): null}
43-
{outputs.map((output,i) => (
44-
<ArticleCellOutput hideLabel output={output} key={i} />
45-
))}
45+
<ArticleCellOutputs
46+
hideLabel
47+
isJavascriptTrusted={isJavascriptTrusted}
48+
cellIdx={figure.idx}
49+
outputs={outputs}
50+
/>
4651
</div>
4752
{children}
4853
</Col>

src/components/Article/ArticleCellOutput.js

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
import React from 'react'
22
import { useTranslation } from 'react-i18next'
33
import {markdownParser} from '../../logic/ipynb'
4+
import ArticleCellOutputPlugin from './ArticleCellOutputPlugin'
5+
46
const getOutput = (output) => {
57
return Array.isArray(output)
68
? output.join(' ')
79
: output
810
}
911

10-
const ArticleCellOutput = ({ output, height, width, hideLabel=false }) => {
12+
const ArticleCellOutput = ({ output, height, width, hideLabel=false, isJavascriptTrusted=false, cellIdx=-1 }) => {
1113
const outputTypeClassName= `ArticleCellOutput_${output.output_type}`
1214
const { t } = useTranslation()
13-
1415
const style = !isNaN(width) && !isNaN(height) ? {
1516
// constrain output to this size. used for images.
1617
width,
@@ -25,9 +26,22 @@ const ArticleCellOutput = ({ output, height, width, hideLabel=false }) => {
2526
)
2627
}
2728
if (['execute_result', 'display_data'].includes(output.output_type) && output.data['text/html']) {
28-
return (<div className={`ArticleCellOutput withHTML mb-3 ${outputTypeClassName}`} style={style} dangerouslySetInnerHTML={{
29-
__html: getOutput(output.data['text/html'])
30-
}} />)
29+
if (isJavascriptTrusted) { // use DOM directly to handle this
30+
return (
31+
<ArticleCellOutputPlugin
32+
cellIdx={cellIdx}
33+
trustedInnerHTML={getOutput(output.data['text/html'])}
34+
/>
35+
)
36+
}
37+
return (
38+
<div className={`ArticleCellOutput withHTML mb-3 ${outputTypeClassName}`}
39+
style={style}
40+
dangerouslySetInnerHTML={{
41+
__html: getOutput(output.data['text/html'])
42+
}}
43+
/>
44+
)
3145
}
3246

3347
return (
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react'
2+
3+
class ArticleCellOutputPlugin extends React.Component {
4+
constructor(props) {
5+
super(props)
6+
console.info('ArticleCellOutputPlugin created for cell idx:', props.cellIdx)
7+
}
8+
9+
componentDidMount() {
10+
console.info('ArticleCellOutputPlugin @componentDidMount for cell idx:', this.props.cellIdx)
11+
this.el.innerHTML = this.props.trustedInnerHTML
12+
}
13+
14+
componentDidUpdate(prevProps) {
15+
console.info('ArticleCellOutputPlugin @componentDidUpdate for cell idx:', this.props.cellIdx)
16+
if (prevProps.trustedInnerHTML !== this.props.trustedInnerHTML) {
17+
console.info('ArticleCellOutputPlugin changed.', prevProps.trustedInnerHTML)
18+
}
19+
}
20+
21+
render() {
22+
return <div className="ArticleCellOutputPlugin" ref={el => this.el = el} />;
23+
}
24+
}
25+
26+
export default ArticleCellOutputPlugin

0 commit comments

Comments
 (0)