diff options
Diffstat (limited to 'public/js')
-rw-r--r-- | public/js/extra.js | 20 | ||||
-rw-r--r-- | public/js/history.js | 1 | ||||
-rw-r--r-- | public/js/index.js | 9 | ||||
-rw-r--r-- | public/js/lib/editor/index.js | 8 | ||||
-rw-r--r-- | public/js/lib/editor/ui-elements.js | 2 | ||||
-rw-r--r-- | public/js/render.js | 7 | ||||
-rw-r--r-- | public/js/reveal-markdown.js | 4 |
7 files changed, 37 insertions, 14 deletions
diff --git a/public/js/extra.js b/public/js/extra.js index d6bbb0c6..ed1470be 100644 --- a/public/js/extra.js +++ b/public/js/extra.js @@ -570,7 +570,9 @@ export function postProcess (code) { $(value).html(html) }) // link should open in new window or tab - result.find('a:not([href^="#"]):not([target])').attr('target', '_blank') + // also add noopener to prevent clickjacking + // See details: https://mathiasbynens.github.io/rel-noopener/ + result.find('a:not([href^="#"]):not([target])').attr('target', '_blank').attr('rel', 'noopener') // update continue line numbers const linenumberdivs = result.find('.gutter.linenumber').toArray() for (let i = 0; i < linenumberdivs.length; i++) { @@ -832,7 +834,7 @@ const anchorForId = id => { const anchor = document.createElement('a') anchor.className = 'anchor hidden-xs' anchor.href = `#${id}` - anchor.innerHTML = '<span class="octicon octicon-link"></span>' + anchor.innerHTML = '<i class="fa fa-link"></i>' anchor.title = id return anchor } @@ -1143,6 +1145,19 @@ const pdfPlugin = new Plugin( } ) +const emojijsPlugin = new Plugin( + // regexp to match emoji shortcodes :something: + // We generate an universal regex that guaranteed only contains the + // emojies we have available. This should prevent all false-positives + new RegExp(':(' + window.emojify.emojiNames.map((item) => { return RegExp.escape(item) }).join('|') + '):', 'i'), + + (match, utils) => { + const emoji = match[1].toLowerCase() + const div = $(`<img class="emoji" src="${serverurl}/build/emojify.js/dist/images/basic/${emoji}.png"></img>`) + return div[0].outerHTML + } +) + // yaml meta, from https://github.com/eugeneware/remarkable-meta function get (state, line) { const pos = state.bMarks[line] @@ -1187,6 +1202,7 @@ function metaPlugin (md) { } md.use(metaPlugin) +md.use(emojijsPlugin) md.use(youtubePlugin) md.use(vimeoPlugin) md.use(gistPlugin) diff --git a/public/js/history.js b/public/js/history.js index b4c26b42..6007bef4 100644 --- a/public/js/history.js +++ b/public/js/history.js @@ -218,6 +218,7 @@ export function getStorageHistory (callback) { if (typeof data === 'string') { data = JSON.parse(data) } callback(data) } + // eslint-disable-next-line standard/no-callback-literal callback([]) } diff --git a/public/js/index.js b/public/js/index.js index 1330deac..0c575961 100644 --- a/public/js/index.js +++ b/public/js/index.js @@ -17,6 +17,7 @@ import toMarkdown from 'to-markdown' import { saveAs } from 'file-saver' import randomColor from 'randomcolor' import store from 'store' +import hljs from 'highlight.js' import _ from 'lodash' @@ -92,7 +93,7 @@ var cursorMenuThrottle = 50 var cursorActivityDebounce = 50 var cursorAnimatePeriod = 100 var supportContainers = ['success', 'info', 'warning', 'danger'] -var supportCodeModes = ['javascript', 'typescript', 'jsx', 'htmlmixed', 'htmlembedded', 'css', 'xml', 'clike', 'clojure', 'ruby', 'python', 'shell', 'php', 'sql', 'haskell', 'coffeescript', 'yaml', 'pug', 'lua', 'cmake', 'nginx', 'perl', 'sass', 'r', 'dockerfile', 'tiddlywiki', 'mediawiki', 'go', 'gherkin'] +var supportCodeModes = ['javascript', 'typescript', 'jsx', 'htmlmixed', 'htmlembedded', 'css', 'xml', 'clike', 'clojure', 'ruby', 'python', 'shell', 'php', 'sql', 'haskell', 'coffeescript', 'yaml', 'pug', 'lua', 'cmake', 'nginx', 'perl', 'sass', 'r', 'dockerfile', 'tiddlywiki', 'mediawiki', 'go', 'gherkin'].concat(hljs.listLanguages()) var supportCharts = ['sequence', 'flow', 'graphviz', 'mermaid', 'abc'] var supportHeaders = [ { @@ -1479,7 +1480,7 @@ $('#snippetExportModalConfirm').click(function () { file_name: $('#snippetExportModalFileName').val(), code: editor.getValue(), visibility_level: $('#snippetExportModalVisibility').val(), - visibility: $('#snippetExportModalVisibility').val() === 0 ? 'private' : ($('#snippetExportModalVisibility').val() === 10 ? 'internal' : '') + visibility: $('#snippetExportModalVisibility').val() === '0' ? 'private' : ($('#snippetExportModalVisibility').val() === '10' ? 'internal' : 'private') } if (!data.title || !data.file_name || !data.code || !data.visibility_level || !$('#snippetExportModalProjects').val()) return @@ -2510,7 +2511,9 @@ function buildCursor (user) { // editor actions function removeNullByte (cm, change) { var str = change.text.join('\n') + // eslint-disable-next-line no-control-regex if (/\u0000/g.test(str) && change.update) { + // eslint-disable-next-line no-control-regex change.update(change.from, change.to, str.replace(/\u0000/g, '').split('\n')) } } @@ -3045,7 +3048,7 @@ function checkInCode () { function checkAbove (method) { var cursor = editor.getCursor() var text = [] - for (var i = 0; i < cursor.line; i++) { // contain current line + for (var i = 0; i < cursor.line; i++) { // contain current line text.push(editor.getLine(i)) } text = text.join('\n') + '\n' + editor.getLine(cursor.line).slice(0, cursor.ch) diff --git a/public/js/lib/editor/index.js b/public/js/lib/editor/index.js index 0537e927..f05d01b8 100644 --- a/public/js/lib/editor/index.js +++ b/public/js/lib/editor/index.js @@ -492,7 +492,7 @@ export default class Editor { clearInterval(spellcheckTimer) } }, - 100, + 100 ) } } @@ -514,7 +514,7 @@ export default class Editor { } setOverrideBrowserKeymap () { var overrideBrowserKeymap = $( - '.ui-preferences-override-browser-keymap label > input[type="checkbox"]', + '.ui-preferences-override-browser-keymap label > input[type="checkbox"]' ) if (overrideBrowserKeymap.is(':checked')) { Cookies.set('preferences-override-browser-keymap', true, { @@ -529,10 +529,10 @@ export default class Editor { setPreferences () { var overrideBrowserKeymap = $( - '.ui-preferences-override-browser-keymap label > input[type="checkbox"]', + '.ui-preferences-override-browser-keymap label > input[type="checkbox"]' ) var cookieOverrideBrowserKeymap = Cookies.get( - 'preferences-override-browser-keymap', + 'preferences-override-browser-keymap' ) if (cookieOverrideBrowserKeymap && cookieOverrideBrowserKeymap === 'true') { overrideBrowserKeymap.prop('checked', true) diff --git a/public/js/lib/editor/ui-elements.js b/public/js/lib/editor/ui-elements.js index ca06d30c..29a37782 100644 --- a/public/js/lib/editor/ui-elements.js +++ b/public/js/lib/editor/ui-elements.js @@ -67,7 +67,7 @@ export const getUIElements = () => ({ codemirrorScroll: $('.ui-edit-area .CodeMirror .CodeMirror-scroll'), codemirrorSizer: $('.ui-edit-area .CodeMirror .CodeMirror-sizer'), codemirrorSizerInner: $( - '.ui-edit-area .CodeMirror .CodeMirror-sizer > div', + '.ui-edit-area .CodeMirror .CodeMirror-sizer > div' ), markdown: $('.ui-view-area .markdown-body'), resize: { diff --git a/public/js/render.js b/public/js/render.js index 23b8934e..ff5e2bf2 100644 --- a/public/js/render.js +++ b/public/js/render.js @@ -1,6 +1,8 @@ /* eslint-env browser, jquery */ -/* global filterXSS */ // allow some attributes + +var filterXSS = require('xss') + var whiteListAttr = ['id', 'class', 'style'] window.whiteListAttr = whiteListAttr // allow link starts with '.', '/' and custom protocol with '://', exclude link starts with javascript:// @@ -71,5 +73,6 @@ function preventXSS (html) { window.preventXSS = preventXSS module.exports = { - preventXSS: preventXSS + preventXSS: preventXSS, + escapeAttrValue: filterXSS.escapeAttrValue } diff --git a/public/js/reveal-markdown.js b/public/js/reveal-markdown.js index d15b5ebd..ad5bfd04 100644 --- a/public/js/reveal-markdown.js +++ b/public/js/reveal-markdown.js @@ -1,6 +1,6 @@ /* eslint-env browser, jquery */ -import { preventXSS } from './render' +import { preventXSS, escapeAttrValue } from './render' import { md } from './extra' /** @@ -259,7 +259,7 @@ import { md } from './extra' while ((matchesClass = mardownClassRegex.exec(classes))) { var name = matchesClass[1] var value = matchesClass[2] - if (name.substr(0, 5) === 'data-' || window.whiteListAttr.indexOf(name) !== -1) { elementTarget.setAttribute(name, window.filterXSS.escapeAttrValue(value)) } + if (name.substr(0, 5) === 'data-' || window.whiteListAttr.indexOf(name) !== -1) { elementTarget.setAttribute(name, escapeAttrValue(value)) } } return true } |