Skip to content

Commit e710517

Browse files
committed
refactor: update imports and modularize utility functions for better maintainability
1 parent f479027 commit e710517

13 files changed

Lines changed: 193 additions & 92 deletions

File tree

lib/models/note.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ var moment = require('moment')
1414
var DiffMatchPatch = require('@hackmd/diff-match-patch')
1515
var dmp = new DiffMatchPatch()
1616

17-
const { stripTags } = require('../../utils/string')
17+
const { stripTags } = require('../utils/string')
1818

1919
// core
2020
var config = require('../config')
File renamed without changes.

public/js/cover.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ import {
2525

2626
import { saveAs } from 'file-saver'
2727
import List from 'list.js'
28-
import unescapeHTML from 'lodash/unescape'
28+
import { unescape as unescapeHTML } from 'lodash'
2929

30-
require('./locale')
30+
import './locale'
3131

32-
require('../css/cover.css')
33-
require('../css/site.css')
32+
import '../css/cover.css'
33+
import '../css/site.css'
3434

3535
const options = {
3636
valueNames: ['id', 'text', 'timestamp', 'fromNow', 'time', 'tags', 'pinned'],

public/js/extra.js

Lines changed: 58 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import isURL from 'validator/lib/isURL'
1414
import { transform } from 'markmap-lib/dist/transform'
1515
import { Markmap } from 'markmap-lib/dist/view'
1616

17-
import { stripTags } from '../../utils/string'
17+
import * as stringUtils from './lib/utils/string' // Import namespace
1818

1919
import getUIElements from './lib/editor/ui-elements'
2020
import { emojifyImageDir } from './lib/editor/constants'
@@ -27,28 +27,43 @@ import { renderFretBoard } from './lib/renderer/fretboard/fretboard'
2727
import './lib/renderer/lightbox'
2828
import { renderCSVPreview } from './lib/renderer/csvpreview'
2929

30-
import { escapeAttrValue } from './render'
30+
import * as renderUtils from './render' // Import namespace
3131
import { sanitizeUrl } from './utils'
3232

3333
import markdownit from 'markdown-it'
3434
import markdownitContainer from 'markdown-it-container'
35+
import markdownitAbbr from 'markdown-it-abbr'
36+
import markdownitFootnote from 'markdown-it-footnote'
37+
import markdownitDeflist from 'markdown-it-deflist'
38+
import markdownitMark from 'markdown-it-mark'
39+
import markdownitIns from 'markdown-it-ins'
40+
import markdownitSub from 'markdown-it-sub'
41+
import markdownitSup from 'markdown-it-sup'
42+
import markdownitMathjax from 'markdown-it-mathjax'
43+
import markdownitRuby from 'markdown-it-ruby'
44+
45+
import '@hackmd/emojify.js'
3546

3647
/* Defined regex markdown it plugins */
3748
import Plugin from 'markdown-it-regexp'
3849

39-
require('prismjs/themes/prism.css')
40-
require('prismjs/components/prism-wiki')
41-
require('prismjs/components/prism-haskell')
42-
require('prismjs/components/prism-go')
43-
require('prismjs/components/prism-typescript')
44-
require('prismjs/components/prism-jsx')
45-
require('prismjs/components/prism-makefile')
46-
require('prismjs/components/prism-gherkin')
50+
import plantumlEncoder from 'plantuml-encoder'
4751

48-
require('./lib/common/login')
49-
require('../vendor/md-toc')
50-
let viz = new window.Viz()
51-
const plantumlEncoder = require('plantuml-encoder')
52+
import 'prismjs/themes/prism.css'
53+
import 'prismjs/components/prism-wiki'
54+
import 'prismjs/components/prism-haskell'
55+
import 'prismjs/components/prism-go'
56+
import 'prismjs/components/prism-typescript'
57+
import 'prismjs/components/prism-jsx'
58+
import 'prismjs/components/prism-makefile'
59+
import 'prismjs/components/prism-gherkin'
60+
61+
import './lib/common/login'
62+
import '../vendor/md-toc'
63+
import { instance as vizInstance } from '@viz-js/viz'
64+
65+
let viz = null
66+
vizInstance().then(instance => { viz = instance })
5267

5368
const ui = getUIElements()
5469

@@ -186,7 +201,7 @@ export function renderTags (view) {
186201

187202
function slugifyWithUTF8 (text) {
188203
// remove HTML tags and trim spaces
189-
let newText = stripTags(text.toString().trim())
204+
let newText = stringUtils.stripTags(text.toString().trim()) // Use namespace
190205
// replace space between words with dashes
191206
newText = newText.replace(/\s+/g, '-')
192207
// slugify string to make it valid as an attribute
@@ -345,15 +360,15 @@ export function finishView (view) {
345360
if ($(value).children().length === 0) {
346361
// strip HTML tags to avoid stored XSS
347362
const gistid = value.getAttribute('data-gist-id')
348-
value.setAttribute('data-gist-id', stripTags(gistid))
363+
value.setAttribute('data-gist-id', stringUtils.stripTags(gistid)) // Use namespace
349364
const gistfile = value.getAttribute('data-gist-file')
350-
if (gistfile) value.setAttribute('data-gist-file', stripTags(gistfile))
365+
if (gistfile) value.setAttribute('data-gist-file', stringUtils.stripTags(gistfile)) // Use namespace
351366
const gistline = value.getAttribute('data-gist-line')
352-
if (gistline) value.setAttribute('data-gist-line', stripTags(gistline))
367+
if (gistline) value.setAttribute('data-gist-line', stringUtils.stripTags(gistline)) // Use namespace
353368
const gisthighlightline = value.getAttribute('data-gist-highlight-line')
354-
if (gisthighlightline) value.setAttribute('data-gist-highlight-line', stripTags(gisthighlightline))
369+
if (gisthighlightline) value.setAttribute('data-gist-highlight-line', stringUtils.stripTags(gisthighlightline)) // Use namespace
355370
const gistshowloading = value.getAttribute('data-gist-show-loading')
356-
if (gistshowloading) value.setAttribute('data-gist-show-loading', stripTags(gistshowloading))
371+
if (gistshowloading) value.setAttribute('data-gist-show-loading', stringUtils.stripTags(gistshowloading)) // Use namespace
357372
$(value).gist(window.viewAjaxCallback)
358373
}
359374
})
@@ -406,27 +421,27 @@ export function finishView (view) {
406421
})
407422
// graphviz
408423
var graphvizs = view.find('div.graphviz.raw').removeClass('raw')
409-
graphvizs.each(function (key, value) {
424+
graphvizs.each(async function (key, value) {
410425
try {
411426
var $value = $(value)
412427
const options = deserializeParamAttributeFromElement(value)
413428
var $ele = $(value).parent().parent()
414429
$value.unwrap()
415-
viz.renderString($value.text(), options)
430+
viz.viz.renderSVGElement($value.text(), options)
416431
.then(graphviz => {
417432
if (!graphviz) throw Error('viz.js output empty graph')
418433
$value.html(graphviz)
419434

420435
$ele.addClass('graphviz')
421436
$value.children().unwrap()
422437
})
423-
.catch(err => {
424-
viz = new window.Viz()
438+
.catch(async err => {
439+
viz = await vizInstance()
425440
$value.parent().append(`<div class="alert alert-warning">${escapeHTML(err)}</div>`)
426441
console.warn(err)
427442
})
428443
} catch (err) {
429-
viz = new window.Viz()
444+
viz = await vizInstance()
430445
$value.parent().append(`<div class="alert alert-warning">${escapeHTML(err)}</div>`)
431446
console.warn(err)
432447
}
@@ -830,8 +845,8 @@ export function exportToHTML (view) {
830845
html: src[0].outerHTML,
831846
'ui-toc': toc.html(),
832847
'ui-toc-affix': tocAffix.html(),
833-
lang: (md && md.meta && md.meta.lang) ? `lang="${escapeAttrValue(md.meta.lang)}"` : null,
834-
dir: (md && md.meta && md.meta.dir) ? `dir="${escapeAttrValue(md.meta.dir)}"` : null
848+
lang: (md && md.meta && md.meta.lang) ? `lang="${renderUtils.escapeAttrValue(md.meta.lang)}"` : null, // Use namespace
849+
dir: (md && md.meta && md.meta.dir) ? `dir="${renderUtils.escapeAttrValue(md.meta.dir)}"` : null // Use namespace
835850
}
836851
const html = template(context)
837852
// console.log(html);
@@ -1192,23 +1207,22 @@ export const md = markdownit('default', {
11921207
})
11931208
window.md = md
11941209

1195-
md.use(require('markdown-it-abbr'))
1196-
md.use(require('markdown-it-footnote'))
1197-
md.use(require('markdown-it-deflist'))
1198-
md.use(require('markdown-it-mark'))
1199-
md.use(require('markdown-it-ins'))
1200-
md.use(require('markdown-it-sub'))
1201-
md.use(require('markdown-it-sup'))
1202-
md.use(require('markdown-it-mathjax')({
1210+
md.use(markdownitAbbr)
1211+
md.use(markdownitFootnote)
1212+
md.use(markdownitDeflist)
1213+
md.use(markdownitMark)
1214+
md.use(markdownitIns)
1215+
md.use(markdownitSub)
1216+
md.use(markdownitSup)
1217+
md.use(markdownitMathjax({
12031218
beforeMath: '<span class="mathjax raw">',
12041219
afterMath: '</span>',
12051220
beforeInlineMath: '<span class="mathjax raw">\\(',
12061221
afterInlineMath: '\\)</span>',
12071222
beforeDisplayMath: '<span class="mathjax raw">\\[',
12081223
afterDisplayMath: '\\]</span>'
12091224
}))
1210-
md.use(require('markdown-it-imsize'))
1211-
md.use(require('markdown-it-ruby'))
1225+
md.use(markdownitRuby)
12121226

12131227
window.emojify.setConfig({
12141228
blacklist: {
@@ -1421,11 +1435,17 @@ const pdfPlugin = new Plugin(
14211435
}
14221436
)
14231437

1438+
// Helper function to escape characters with special meaning in RegExp
1439+
function escapeRegExp (string) {
1440+
// $& means the whole matched string
1441+
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
1442+
}
1443+
14241444
const emojijsPlugin = new Plugin(
14251445
// regexp to match emoji shortcodes :something:
14261446
// We generate an universal regex that guaranteed only contains the
14271447
// emojies we have available. This should prevent all false-positives
1428-
new RegExp(':(' + window.emojify.emojiNames.map((item) => { return RegExp.escape(item) }).join('|') + '):', 'i'),
1448+
new RegExp(':(' + window.emojify.emojiNames.map((item) => { return escapeRegExp(item) }).join('|') + '):', 'i'),
14291449

14301450
(match, utils) => {
14311451
const emoji = match[1].toLowerCase()

public/js/index.js

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
/* eslint-env browser, jquery */
2-
/* global CodeMirror, Cookies, moment, serverurl,
2+
/* global Cookies, moment, serverurl,
33
key, Dropbox, ot, hex2rgb, Visibility, inlineAttachment */
44

5+
import CodeMirror from '@hackmd/codemirror'
56
import TurndownService from 'turndown'
7+
import Cookies from 'js-cookie'
8+
import '@vendor/inlineAttachment/inline-attachment'
9+
import '@vendor/inlineAttachment/codemirror.inline-attachment'
10+
import Visibility from 'visibilityjs'
11+
import '@vendor/ot/ot.min.js'
612

713
import { saveAs } from 'file-saver'
814
import randomColor from 'randomcolor'
@@ -20,6 +26,7 @@ import List from 'list.js'
2026
import Idle from '@hackmd/idle-js'
2127

2228
import { Spinner } from 'spin.js'
29+
import io from 'socket.io-client'
2330

2431
import {
2532
checkLoginStateChanged,
@@ -72,7 +79,7 @@ import {
7279
removeHistory
7380
} from './history'
7481

75-
import { preventXSS } from './render'
82+
import * as renderUtils from './render' // Import namespace
7683

7784
import Editor from './lib/editor'
7885

@@ -1235,6 +1242,7 @@ function selectRevision (time) {
12351242
function initRevisionViewer () {
12361243
if (revisionViewer) return
12371244
var revisionViewerTextArea = document.getElementById('revisionViewer')
1245+
// Use the imported CodeMirror instead of the global one
12381246
revisionViewer = CodeMirror.fromTextArea(revisionViewerTextArea, {
12391247
mode: defaultEditorMode,
12401248
viewportMargin: viewportMargin,
@@ -1707,7 +1715,6 @@ function havePermission () {
17071715
window.havePermission = havePermission
17081716

17091717
// socket.io actions
1710-
var io = require('socket.io-client')
17111718
var socket = io.connect({
17121719
path: urlpath ? '/' + urlpath + '/socket.io/' : '',
17131720
query: {
@@ -2789,7 +2796,7 @@ function updateViewInner () {
27892796
ui.area.markdown.html(slides)
27902797
window.RevealMarkdown.initialize()
27912798
// prevent XSS
2792-
ui.area.markdown.html(preventXSS(ui.area.markdown.html()))
2799+
ui.area.markdown.html(renderUtils.preventXSS(ui.area.markdown.html()))
27932800
ui.area.markdown.addClass('slides')
27942801
appState.syncscroll = false
27952802
checkSyncToggle()
@@ -2806,7 +2813,7 @@ function updateViewInner () {
28062813
rendered = md.render(value)
28072814
}
28082815
// prevent XSS
2809-
rendered = preventXSS(rendered)
2816+
rendered = renderUtils.preventXSS(rendered)
28102817
var result = postProcess(rendered).children().toArray()
28112818
partialUpdate(result, lastResult, ui.area.markdown.children().toArray())
28122819
if (result && lastResult && result.length !== lastResult.length) { updateDataAttrs(result, ui.area.markdown.children().toArray()) }

public/js/lib/common/login.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* eslint-env browser, jquery */
2-
/* global Cookies */
2+
import Cookies from 'js-cookie'
33

44
import { serverurl } from '../config'
55

public/js/lib/editor/index.js

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,70 @@
1-
/* global CodeMirror, $, editor, Cookies */
1+
import CodeMirror from '@hackmd/codemirror'
2+
import Cookies from 'js-cookie'
3+
4+
// CodeMirror Modes & Addons Imports
5+
// Modes
6+
import '@hackmd/codemirror/mode/meta.js'
7+
import '@hackmd/codemirror/mode/gfm/gfm.js'
8+
import '@hackmd/codemirror/mode/clike/clike.js'
9+
import '@hackmd/codemirror/mode/javascript/javascript.js'
10+
import '@hackmd/codemirror/mode/css/css.js'
11+
import '@hackmd/codemirror/mode/xml/xml.js'
12+
import '@hackmd/codemirror/mode/htmlmixed/htmlmixed.js'
13+
import '@hackmd/codemirror/mode/htmlembedded/htmlembedded.js'
14+
import '@hackmd/codemirror/mode/python/python.js'
15+
import '@hackmd/codemirror/mode/ruby/ruby.js'
16+
import '@hackmd/codemirror/mode/shell/shell.js'
17+
import '@hackmd/codemirror/mode/php/php.js'
18+
import '@hackmd/codemirror/mode/sql/sql.js'
19+
import '@hackmd/codemirror/mode/haskell/haskell.js'
20+
import '@hackmd/codemirror/mode/coffeescript/coffeescript.js'
21+
import '@hackmd/codemirror/mode/yaml/yaml.js'
22+
import '@hackmd/codemirror/mode/pug/pug.js'
23+
import '@hackmd/codemirror/mode/lua/lua.js'
24+
import '@hackmd/codemirror/mode/cmake/cmake.js'
25+
import '@hackmd/codemirror/mode/nginx/nginx.js'
26+
import '@hackmd/codemirror/mode/perl/perl.js'
27+
import '@hackmd/codemirror/mode/sass/sass.js'
28+
import '@hackmd/codemirror/mode/r/r.js'
29+
import '@hackmd/codemirror/mode/dockerfile/dockerfile.js'
30+
import '@hackmd/codemirror/mode/tiddlywiki/tiddlywiki.js'
31+
// import '@hackmd/codemirror/mode/mediawiki/mediawiki.js'
32+
import '@hackmd/codemirror/mode/go/go.js'
33+
import '@hackmd/codemirror/mode/gherkin/gherkin.js'
34+
import '@hackmd/codemirror/mode/clojure/clojure.js'
35+
// import '@hackmd/codemirror/mode/ocaml/ocaml.js'
36+
import '@hackmd/codemirror/mode/csv/csv.js'
37+
// Keymaps
38+
import '@hackmd/codemirror/keymap/sublime.js'
39+
import '@hackmd/codemirror/keymap/vim.js'
40+
import '@hackmd/codemirror/keymap/emacs.js'
41+
// Addons
42+
import '@hackmd/codemirror/addon/mode/overlay.js'
43+
import '@hackmd/codemirror/addon/selection/active-line.js'
44+
import '@hackmd/codemirror/addon/search/match-highlighter.js'
45+
import '@hackmd/codemirror/addon/edit/matchbrackets.js'
46+
import '@hackmd/codemirror/addon/edit/closebrackets.js'
47+
import '@hackmd/codemirror/addon/edit/matchtags.js'
48+
import '@hackmd/codemirror/addon/edit/closetag.js'
49+
import '@hackmd/codemirror/addon/fold/foldcode.js'
50+
import '@hackmd/codemirror/addon/fold/foldgutter.js'
51+
import '@hackmd/codemirror/addon/fold/brace-fold.js'
52+
import '@hackmd/codemirror/addon/fold/comment-fold.js'
53+
import '@hackmd/codemirror/addon/fold/markdown-fold.js'
54+
import '@hackmd/codemirror/addon/fold/xml-fold.js'
55+
import '@hackmd/codemirror/addon/edit/continuelist.js'
56+
import '@hackmd/codemirror/addon/display/autorefresh.js'
57+
import '@hackmd/codemirror/addon/display/placeholder.js'
58+
import '@hackmd/codemirror/addon/search/search.js'
59+
import '@hackmd/codemirror/addon/search/searchcursor.js'
60+
import '@hackmd/codemirror/addon/search/jump-to-line.js'
61+
import '@hackmd/codemirror/addon/dialog/dialog.js'
62+
import '@hackmd/codemirror/addon/lint/lint.js'
63+
import '@hackmd/codemirror/addon/display/fullscreen.js'
64+
import '@hackmd/codemirror/addon/scroll/simplescrollbars.js'
65+
import '@hackmd/codemirror/addon/search/matchesonscrollbar.js'
66+
67+
/* global $, editor, Cookies */
268
import { options, Alignment, FormatType } from '@susisu/mte-kernel'
369
import debounce from 'lodash/debounce'
470

0 commit comments

Comments
 (0)