Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
fc3e28d8
Unverified
Commit
fc3e28d8
authored
Oct 17, 2019
by
Robert Knight
Committed by
GitHub
Oct 17, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1438 from hypothesis/convert-markdown-view
Convert markdown editor 2/3 - Convert markdown viewer
parents
637a72f0
8aa53d03
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
148 additions
and
7 deletions
+148
-7
markdown-view.js
src/sidebar/components/markdown-view.js
+45
-0
annotation-test.js
src/sidebar/components/test/annotation-test.js
+8
-2
markdown-view-test.js
src/sidebar/components/test/markdown-view-test.js
+61
-0
index.js
src/sidebar/index.js
+4
-0
annotation.html
src/sidebar/templates/annotation.html
+5
-5
markdown-view.scss
src/styles/sidebar/components/markdown-view.scss
+24
-0
sidebar.scss
src/styles/sidebar/sidebar.scss
+1
-0
No files found.
src/sidebar/components/markdown-view.js
0 → 100644
View file @
fc3e28d8
'use strict'
;
const
classnames
=
require
(
'classnames'
);
const
{
createElement
}
=
require
(
'preact'
);
const
{
useEffect
,
useMemo
,
useRef
}
=
require
(
'preact/hooks'
);
const
propTypes
=
require
(
'prop-types'
);
const
{
replaceLinksWithEmbeds
}
=
require
(
'../media-embedder'
);
const
renderMarkdown
=
require
(
'../render-markdown'
);
/**
* A component which renders markdown as HTML and replaces recognized links
* with embedded video/audio.
*/
function
MarkdownView
({
markdown
=
''
,
textClass
=
{}
})
{
const
html
=
useMemo
(()
=>
(
markdown
?
renderMarkdown
(
markdown
)
:
''
),
[
markdown
,
]);
const
content
=
useRef
(
null
);
useEffect
(()
=>
{
replaceLinksWithEmbeds
(
content
.
current
);
},
[
markdown
]);
return
(
<
div
className
=
{
classnames
(
'markdown-view'
,
textClass
)}
ref
=
{
content
}
dangerouslySetInnerHTML
=
{{
__html
:
html
}}
/
>
);
}
MarkdownView
.
propTypes
=
{
/** The string of markdown to display. */
markdown
:
propTypes
.
string
,
/**
* A CSS classname-to-boolean map of classes to apply to the container of
* the rendered markdown.
*/
textClass
:
propTypes
.
object
,
};
module
.
exports
=
MarkdownView
;
src/sidebar/components/test/annotation-test.js
View file @
fc3e28d8
...
...
@@ -160,6 +160,12 @@ describe('annotation', function() {
})
.
component
(
'markdown'
,
{
bindings
:
require
(
'../markdown'
).
bindings
,
})
.
component
(
'markdownView'
,
{
bindings
:
{
markdown
:
'<'
,
textClass
:
'<'
,
},
});
});
...
...
@@ -1268,9 +1274,9 @@ describe('annotation', function() {
function
(
testCase
)
{
const
el
=
createDirective
(
testCase
.
ann
).
element
;
assert
.
match
(
el
.
find
(
'markdown
'
).
controller
(
'markdown
'
),
el
.
find
(
'markdown
-view'
).
controller
(
'markdownView
'
),
sinon
.
match
({
customT
extClass
:
testCase
.
textClass
,
t
extClass
:
testCase
.
textClass
,
})
);
},
...
...
src/sidebar/components/test/markdown-view-test.js
0 → 100644
View file @
fc3e28d8
'use strict'
;
const
{
createElement
}
=
require
(
'preact'
);
const
{
mount
}
=
require
(
'enzyme'
);
const
MarkdownView
=
require
(
'../markdown-view'
);
describe
(
'MarkdownView'
,
()
=>
{
let
fakeMediaEmbedder
;
let
fakeRenderMarkdown
;
beforeEach
(()
=>
{
fakeRenderMarkdown
=
markdown
=>
`rendered:
${
markdown
}
`
;
fakeMediaEmbedder
=
{
replaceLinksWithEmbeds
:
el
=>
{
// Tag the element as having been processed
el
.
dataset
.
replacedLinksWithEmbeds
=
'yes'
;
},
};
MarkdownView
.
$imports
.
$mock
({
'../render-markdown'
:
fakeRenderMarkdown
,
'../media-embedder'
:
fakeMediaEmbedder
,
});
});
afterEach
(()
=>
{
MarkdownView
.
$imports
.
$restore
();
});
it
(
'renders nothing if no markdown is provied'
,
()
=>
{
const
wrapper
=
mount
(
<
MarkdownView
/>
);
assert
.
equal
(
wrapper
.
text
(),
''
);
});
it
(
'renders markdown as HTML'
,
()
=>
{
const
wrapper
=
mount
(
<
MarkdownView
markdown
=
"**test**"
/>
);
const
rendered
=
wrapper
.
find
(
'.markdown-view'
).
getDOMNode
();
assert
.
equal
(
rendered
.
innerHTML
,
'rendered:**test**'
);
});
it
(
're-renders markdown after an update'
,
()
=>
{
const
wrapper
=
mount
(
<
MarkdownView
markdown
=
"**test**"
/>
);
wrapper
.
setProps
({
markdown
:
'_updated_'
});
const
rendered
=
wrapper
.
find
(
'.markdown-view'
).
getDOMNode
();
assert
.
equal
(
rendered
.
innerHTML
,
'rendered:_updated_'
);
});
it
(
'replaces links with embeds in rendered output'
,
()
=>
{
const
wrapper
=
mount
(
<
MarkdownView
markdown
=
"**test**"
/>
);
const
rendered
=
wrapper
.
find
(
'.markdown-view'
).
getDOMNode
();
assert
.
equal
(
rendered
.
dataset
.
replacedLinksWithEmbeds
,
'yes'
);
});
it
(
'applies `textClass` class to container'
,
()
=>
{
const
wrapper
=
mount
(
<
MarkdownView
markdown
=
"foo"
textClass
=
{{
'fancy-effect'
:
true
}}
/
>
);
assert
.
isTrue
(
wrapper
.
find
(
'.markdown-view.fancy-effect'
).
exists
());
});
});
src/sidebar/index.js
View file @
fc3e28d8
...
...
@@ -162,6 +162,10 @@ function startAngularApp(config) {
wrapReactComponent
(
require
(
'./components/logged-out-message'
))
)
.
component
(
'markdown'
,
require
(
'./components/markdown'
))
.
component
(
'markdownView'
,
wrapReactComponent
(
require
(
'./components/markdown-view'
))
)
.
component
(
'moderationBanner'
,
wrapReactComponent
(
require
(
'./components/moderation-banner'
))
...
...
src/sidebar/templates/annotation.html
View file @
fc3e28d8
...
...
@@ -39,11 +39,11 @@
overflow-hysteresis=
"20"
content-data=
"vm.state().text"
ng-if=
"!vm.editing()"
>
<markdown
text=
"vm.state().text"
custom-text-class=
"{'annotation-body is-hidden':vm.isHiddenByModerator(),
<markdown-view
markdown=
"vm.state().text"
text-class=
"{'annotation-body is-hidden':vm.isHiddenByModerator(),
'has-content':vm.hasContent()}"
read-only=
"true"
>
</markdown>
</
markdown-view
>
</excerpt>
<markdown
text=
"vm.state().text"
on-edit-text=
"vm.setText(text)"
...
...
src/styles/sidebar/components/markdown-view.scss
0 → 100644
View file @
fc3e28d8
.markdown-view
{
@include
styled-text
;
cursor
:
text
;
// Prevent long URLs etc. in body causing overflow
overflow-wrap
:
break-word
;
// Margin between bottom of ascent of username and top of
// x-height of annotation-body should be ~15px.
// Remove additional margin-top added by the first p within
// the annotation-body
p
:first-child
{
margin-top
:
0
;
}
// Margin between bottom of ascent of annotation-body and top of
// ascent of annotation-footer should be ~15px in threaded-replies
// and 20px in the top level annotation.
// Remove additional margin-bottom added by the last p within
// the annotation-body
p
:last-child
{
margin-bottom
:
1px
;
}
}
src/styles/sidebar/sidebar.scss
View file @
fc3e28d8
...
...
@@ -33,6 +33,7 @@ $base-line-height: 20px;
@import
'./components/help-panel'
;
@import
'./components/logged-out-message'
;
@import
'./components/markdown'
;
@import
'./components/markdown-view'
;
@import
'./components/menu'
;
@import
'./components/menu-item'
;
@import
'./components/menu-section'
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment