Skip to content

Commit 5f385e4

Browse files
authored
Merge pull request #2465 from daiyam/gallery
add image gallery
2 parents b018502 + 64f7233 commit 5f385e4

File tree

6 files changed

+150
-2
lines changed

6 files changed

+150
-2
lines changed

browser/components/MarkdownPreview.js

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import yaml from 'js-yaml'
2121
import context from 'browser/lib/context'
2222
import i18n from 'browser/lib/i18n'
2323
import fs from 'fs'
24+
import { render } from 'react-dom'
25+
import Carousel from 'react-image-carousel'
2426
import ConfigManager from '../main/lib/ConfigManager'
2527

2628
const { remote, shell } = require('electron')
@@ -40,7 +42,8 @@ const appPath = fileUrl(
4042
)
4143
const CSS_FILES = [
4244
`${appPath}/node_modules/katex/dist/katex.min.css`,
43-
`${appPath}/node_modules/codemirror/lib/codemirror.css`
45+
`${appPath}/node_modules/codemirror/lib/codemirror.css`,
46+
`${appPath}/node_modules/react-image-carousel/lib/css/main.min.css`
4447
]
4548

4649
function buildStyle (
@@ -767,6 +770,34 @@ export default class MarkdownPreview extends React.Component {
767770
mermaidRender(el, htmlTextHelper.decodeEntities(el.innerHTML), theme)
768771
}
769772
)
773+
774+
_.forEach(
775+
this.refs.root.contentWindow.document.querySelectorAll('.gallery'),
776+
el => {
777+
const images = el.innerHTML.split(/\n/g).filter(i => i.length > 0)
778+
el.innerHTML = ''
779+
780+
const height = el.attributes.getNamedItem('data-height')
781+
if (height && height.value !== 'undefined') {
782+
el.style.height = height.value + 'vh'
783+
}
784+
785+
let autoplay = el.attributes.getNamedItem('data-autoplay')
786+
if (autoplay && autoplay.value !== 'undefined') {
787+
autoplay = parseInt(autoplay.value, 10) || 0
788+
} else {
789+
autoplay = 0
790+
}
791+
792+
render(
793+
<Carousel
794+
images={images}
795+
autoplay={autoplay}
796+
/>,
797+
el
798+
)
799+
}
800+
)
770801
}
771802

772803
focus () {

browser/components/markdown.styl

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,26 @@ pre.fence
421421
canvas, svg
422422
max-width 100% !important
423423

424+
.gallery
425+
width 100%
426+
height 50vh
427+
428+
.carousel
429+
.carousel-main img
430+
min-width auto
431+
max-width 100%
432+
min-height auto
433+
max-height 100%
434+
435+
.carousel-footer::-webkit-scrollbar-corner
436+
background-color transparent
437+
438+
.carousel-main, .carousel-footer
439+
background-color $ui-noteDetail-backgroundColor
440+
.prev, .next
441+
color $ui-text-color
442+
background-color $ui-tag-backgroundColor
443+
424444
themeDarkBackground = darken(#21252B, 10%)
425445
themeDarkText = #f9f9f9
426446
themeDarkBorder = lighten(themeDarkBackground, 20%)
@@ -480,6 +500,14 @@ body[data-theme="dark"]
480500
border-color themeDarkBorder
481501
background-color themeDarkPreview
482502

503+
pre.fence
504+
.gallery
505+
.carousel-main, .carousel-footer
506+
background-color $ui-dark-noteDetail-backgroundColor
507+
.prev, .next
508+
color $ui-dark-text-color
509+
background-color $ui-dark-tag-backgroundColor
510+
483511
themeSolarizedDarkTableOdd = $ui-solarized-dark-noteDetail-backgroundColor
484512
themeSolarizedDarkTableEven = darken($ui-solarized-dark-noteDetail-backgroundColor, 10%)
485513
themeSolarizedDarkTableHead = themeSolarizedDarkTableEven
@@ -515,6 +543,14 @@ body[data-theme="solarized-dark"]
515543
border-color themeDarkBorder
516544
background-color $ui-solarized-dark-noteDetail-backgroundColor
517545

546+
pre.fence
547+
.gallery
548+
.carousel-main, .carousel-footer
549+
background-color $ui-solarized-dark-noteDetail-backgroundColor
550+
.prev, .next
551+
color $ui-solarized-dark-button--active-color
552+
background-color $ui-solarized-dark-button-backgroundColor
553+
518554
themeMonokaiTableOdd = $ui-monokai-noteDetail-backgroundColor
519555
themeMonokaiTableEven = darken($ui-monokai-noteDetail-backgroundColor, 10%)
520556
themeMonokaiTableHead = themeMonokaiTableEven
@@ -543,6 +579,7 @@ body[data-theme="monokai"]
543579
border-right solid 1px themeMonokaiTableBorder
544580
kbd
545581
background-color themeDarkBackground
582+
546583
dl
547584
border-color themeDarkBorder
548585
background-color themeMonokaiTableHead
@@ -552,6 +589,14 @@ body[data-theme="monokai"]
552589
border-color themeDarkBorder
553590
background-color $ui-monokai-noteDetail-backgroundColor
554591

592+
pre.fence
593+
.gallery
594+
.carousel-main, .carousel-footer
595+
background-color $ui-monokai-noteDetail-backgroundColor
596+
.prev, .next
597+
color $ui-monokai-button--active-color
598+
background-color $ui-monokai-button-backgroundColor
599+
555600
themeDraculaTableOdd = $ui-dracula-noteDetail-backgroundColor
556601
themeDraculaTableEven = darken($ui-dracula-noteDetail-backgroundColor, 10%)
557602
themeDraculaTableHead = themeDraculaTableEven
@@ -580,6 +625,7 @@ body[data-theme="dracula"]
580625
border-right solid 1px themeDraculaTableBorder
581626
kbd
582627
background-color themeDarkBackground
628+
583629
dl
584630
border-color themeDarkBorder
585631
background-color themeDraculaTableHead
@@ -588,3 +634,11 @@ body[data-theme="dracula"]
588634
dd
589635
border-color themeDarkBorder
590636
background-color $ui-dracula-noteDetail-backgroundColor
637+
638+
pre.fence
639+
.gallery
640+
.carousel-main, .carousel-footer
641+
background-color $ui-dracula-noteDetail-backgroundColor
642+
.prev, .next
643+
color $ui-dracula-button--active-color
644+
background-color $ui-dracula-button-backgroundColor

browser/lib/markdown.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,21 @@ class Markdown {
145145
<div class="flowchart" data-height="${token.parameters.height}">${token.content}</div>
146146
</pre>`
147147
},
148+
gallery: token => {
149+
const content = token.content.split('\n').slice(0, -1).map(line => {
150+
const match = /!\[[^\]]*]\(([^\)]*)\)/.exec(line)
151+
if (match) {
152+
return match[1]
153+
} else {
154+
return line
155+
}
156+
}).join('\n')
157+
158+
return `<pre class="fence" data-line="${token.map[0]}">
159+
<span class="filename">${token.fileName}</span>
160+
<div class="gallery" data-autoplay="${token.parameters.autoplay}" data-height="${token.parameters.height}">${content}</div>
161+
</pre>`
162+
},
148163
mermaid: token => {
149164
return `<pre class="fence" data-line="${token.map[0]}">
150165
<span class="filename">${token.fileName}</span>

browser/main/lib/dataApi/attachmentManagement.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,15 @@ function migrateAttachments (markdownContent, storagePath, noteKey) {
227227
* @returns {String} postprocessed HTML in which all :storage references are mapped to the actual paths.
228228
*/
229229
function fixLocalURLS (renderedHTML, storagePath) {
230-
return renderedHTML.replace(new RegExp('/?' + STORAGE_FOLDER_PLACEHOLDER + '.*?"', 'g'), function (match) {
230+
/*
231+
A :storage reference is like `:storage/3b6f8bd6-4edd-4b15-96e0-eadc4475b564/f939b2c3.jpg`.
232+
233+
- `STORAGE_FOLDER_PLACEHOLDER` will match `:storage`
234+
- `(?:(?:\\\/|%5C)[\\w.]+)+` will match `/3b6f8bd6-4edd-4b15-96e0-eadc4475b564/f939b2c3.jpg`
235+
- `(?:\\\/|%5C)[\\w.]+` will either match `/3b6f8bd6-4edd-4b15-96e0-eadc4475b564` or `/f939b2c3.jpg`
236+
- `(?:\\\/|%5C)` match the path seperator. `\\\/` for posix systems and `%5C` for windows.
237+
*/
238+
return renderedHTML.replace(new RegExp('/?' + STORAGE_FOLDER_PLACEHOLDER + '(?:(?:\\\/|%5C)[\\w.]+)+', 'g'), function (match) {
231239
var encodedPathSeparators = new RegExp(mdurl.encode(path.win32.sep) + '|' + mdurl.encode(path.posix.sep), 'g')
232240
return match.replace(encodedPathSeparators, path.sep).replace(new RegExp('/?' + STORAGE_FOLDER_PLACEHOLDER, 'g'), 'file:///' + path.join(storagePath, DESTINATION_FOLDER))
233241
})

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,10 @@
9999
"react-codemirror": "^0.3.0",
100100
"react-debounce-render": "^4.0.1",
101101
"react-dom": "^15.0.2",
102+
"react-image-carousel": "^2.0.18",
102103
"react-redux": "^4.4.5",
103104
"react-sortable-hoc": "^0.6.7",
105+
"react-transition-group": "^2.5.0",
104106
"redux": "^3.5.2",
105107
"sander": "^0.5.1",
106108
"sanitize-html": "^1.18.2",

yarn.lock

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2760,6 +2760,10 @@ doctrine@^2.0.0, doctrine@^2.0.2:
27602760
dependencies:
27612761
esutils "^2.0.2"
27622762

2763+
dom-helpers@^3.3.1:
2764+
version "3.3.1"
2765+
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.3.1.tgz#fc1a4e15ffdf60ddde03a480a9c0fece821dd4a6"
2766+
27632767
dom-serializer@0:
27642768
version "0.1.0"
27652769
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
@@ -5382,6 +5386,10 @@ js-tokens@^3.0.0, js-tokens@^3.0.2:
53825386
version "3.0.2"
53835387
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
53845388

5389+
"js-tokens@^3.0.0 || ^4.0.0":
5390+
version "4.0.0"
5391+
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
5392+
53855393
js-yaml@^3.10.0, js-yaml@^3.5.1, js-yaml@^3.7.0:
53865394
version "3.11.0"
53875395
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef"
@@ -5870,6 +5878,12 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3
58705878
dependencies:
58715879
js-tokens "^3.0.0"
58725880

5881+
loose-envify@^1.4.0:
5882+
version "1.4.0"
5883+
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
5884+
dependencies:
5885+
js-tokens "^3.0.0 || ^4.0.0"
5886+
58735887
loud-rejection@^1.0.0, loud-rejection@^1.2.0:
58745888
version "1.6.0"
58755889
resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f"
@@ -7334,6 +7348,13 @@ prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.5.8,
73347348
loose-envify "^1.3.1"
73357349
object-assign "^4.1.1"
73367350

7351+
prop-types@^15.6.2:
7352+
version "15.6.2"
7353+
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.2.tgz#05d5ca77b4453e985d60fc7ff8c859094a497102"
7354+
dependencies:
7355+
loose-envify "^1.3.1"
7356+
object-assign "^4.1.1"
7357+
73377358
proxy-addr@~2.0.3:
73387359
version "2.0.3"
73397360
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.3.tgz#355f262505a621646b3130a728eb647e22055341"
@@ -7513,13 +7534,21 @@ react-dom@^15.0.2:
75137534
object-assign "^4.1.0"
75147535
prop-types "^15.5.10"
75157536

7537+
react-image-carousel@^2.0.18:
7538+
version "2.0.18"
7539+
resolved "https://registry.yarnpkg.com/react-image-carousel/-/react-image-carousel-2.0.18.tgz#5868ea09bd9cca09c4467d3d02695cd4e7792f28"
7540+
75167541
react-input-autosize@^1.1.0:
75177542
version "1.2.0"
75187543
resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-1.2.0.tgz#87241071159f742123897691da6796ec33b57d05"
75197544
dependencies:
75207545
create-react-class "^15.5.2"
75217546
prop-types "^15.5.8"
75227547

7548+
react-lifecycles-compat@^3.0.4:
7549+
version "3.0.4"
7550+
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
7551+
75237552
react-proxy@^1.1.7:
75247553
version "1.1.8"
75257554
resolved "https://registry.yarnpkg.com/react-proxy/-/react-proxy-1.1.8.tgz#9dbfd9d927528c3aa9f444e4558c37830ab8c26a"
@@ -7585,6 +7614,15 @@ react-transform-hmr@^1.0.3:
75857614
global "^4.3.0"
75867615
react-proxy "^1.1.7"
75877616

7617+
react-transition-group@^2.5.0:
7618+
version "2.5.0"
7619+
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.5.0.tgz#70bca0e3546102c4dc5cf3f5f57f73447cce6874"
7620+
dependencies:
7621+
dom-helpers "^3.3.1"
7622+
loose-envify "^1.4.0"
7623+
prop-types "^15.6.2"
7624+
react-lifecycles-compat "^3.0.4"
7625+
75887626
react@^15.5.4:
75897627
version "15.6.2"
75907628
resolved "https://registry.yarnpkg.com/react/-/react-15.6.2.tgz#dba0434ab439cfe82f108f0f511663908179aa72"

0 commit comments

Comments
 (0)