Merge pull request #1247 from hackmdio/feat/upgrade-depen

Feat/upgrade depen
This commit is contained in:
Max Wu 2019-08-05 00:38:31 +08:00 committed by GitHub
commit 18abc20f39
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
49 changed files with 1428 additions and 1275 deletions

6
app.js
View File

@ -28,8 +28,8 @@ var csp = require('./lib/csp')
function createHttpServer () { function createHttpServer () {
if (config.useSSL) { if (config.useSSL) {
const ca = (function () { const ca = (function () {
let i, len, results let i, len
results = [] const results = []
for (i = 0, len = config.sslCAPath.length; i < len; i++) { for (i = 0, len = config.sslCAPath.length; i < len; i++) {
results.push(fs.readFileSync(config.sslCAPath[i], 'utf8')) results.push(fs.readFileSync(config.sslCAPath[i], 'utf8'))
} }
@ -55,7 +55,7 @@ var server = createHttpServer()
// logger // logger
app.use(morgan('combined', { app.use(morgan('combined', {
'stream': logger.stream stream: logger.stream
})) }))
// socket io // socket io

View File

@ -53,14 +53,14 @@ if (['debug', 'verbose', 'info', 'warn', 'error'].includes(config.loglevel)) {
// load LDAP CA // load LDAP CA
if (config.ldap.tlsca) { if (config.ldap.tlsca) {
let ca = config.ldap.tlsca.split(',') const certificateAuthorities = config.ldap.tlsca.split(',')
let caContent = [] const caContent = []
for (let i of ca) { for (const ca of certificateAuthorities) {
if (fs.existsSync(i)) { if (fs.existsSync(ca)) {
caContent.push(fs.readFileSync(i, 'utf8')) caContent.push(fs.readFileSync(ca, 'utf8'))
} }
} }
let tlsOptions = { const tlsOptions = {
ca: caContent ca: caContent
} }
config.ldap.tlsOptions = config.ldap.tlsOptions ? Object.assign(config.ldap.tlsOptions, tlsOptions) : tlsOptions config.ldap.tlsOptions = config.ldap.tlsOptions ? Object.assign(config.ldap.tlsOptions, tlsOptions) : tlsOptions
@ -134,10 +134,10 @@ config.isGitlabSnippetsEnable = (!config.gitlab.scope || config.gitlab.scope ===
config.updateI18nFiles = (env === Environment.development) config.updateI18nFiles = (env === Environment.development)
// merge legacy values // merge legacy values
let keys = Object.keys(config) const keys = Object.keys(config)
const uppercase = /[A-Z]/ const uppercase = /[A-Z]/
for (let i = keys.length; i--;) { for (let i = keys.length; i--;) {
let lowercaseKey = keys[i].toLowerCase() const lowercaseKey = keys[i].toLowerCase()
// if the config contains uppercase letters // if the config contains uppercase letters
// and a lowercase version of this setting exists // and a lowercase version of this setting exists
// and the config with uppercase is not set // and the config with uppercase is not set

View File

@ -41,7 +41,7 @@ function getHistory (userid, callback) {
continue continue
} }
try { try {
let id = LZString.decompressFromBase64(history[i].id) const id = LZString.decompressFromBase64(history[i].id)
if (id && models.Note.checkNoteIdValid(id)) { if (id && models.Note.checkNoteIdValid(id)) {
history[i].id = models.Note.encodeNoteId(id) history[i].id = models.Note.encodeNoteId(id)
} }

View File

@ -32,9 +32,9 @@ exports.generateAvatarURL = function (name, email = '', big = true) {
} }
name = encodeURIComponent(name) name = encodeURIComponent(name)
let hash = crypto.createHash('md5') const hash = crypto.createHash('md5')
hash.update(email.toLowerCase()) hash.update(email.toLowerCase())
let hexDigest = hash.digest('hex') const hexDigest = hash.digest('hex')
if (email !== '' && config.allowGravatar) { if (email !== '' && config.allowGravatar) {
photo = 'https://www.gravatar.com/avatar/' + hexDigest photo = 'https://www.gravatar.com/avatar/' + hexDigest

View File

@ -165,15 +165,15 @@ module.exports = function (sequelize, DataTypes) {
} }
Note.encodeNoteId = function (id) { Note.encodeNoteId = function (id) {
// remove dashes in UUID and encode in url-safe base64 // remove dashes in UUID and encode in url-safe base64
let str = id.replace(/-/g, '') const str = id.replace(/-/g, '')
let hexStr = Buffer.from(str, 'hex') const hexStr = Buffer.from(str, 'hex')
return base64url.encode(hexStr) return base64url.encode(hexStr)
} }
Note.decodeNoteId = function (encodedId) { Note.decodeNoteId = function (encodedId) {
// decode from url-safe base64 // decode from url-safe base64
let id = base64url.toBuffer(encodedId).toString('hex') const id = base64url.toBuffer(encodedId).toString('hex')
// add dashes between the UUID string parts // add dashes between the UUID string parts
let idParts = [] const idParts = []
idParts.push(id.substr(0, 8)) idParts.push(id.substr(0, 8))
idParts.push(id.substr(8, 4)) idParts.push(id.substr(8, 4))
idParts.push(id.substr(12, 4)) idParts.push(id.substr(12, 4))
@ -196,7 +196,7 @@ module.exports = function (sequelize, DataTypes) {
} }
}).then(function (note) { }).then(function (note) {
if (note) { if (note) {
let filePath = path.join(config.docsPath, noteId + '.md') const filePath = path.join(config.docsPath, noteId + '.md')
if (Note.checkFileExist(filePath)) { if (Note.checkFileExist(filePath)) {
// if doc in filesystem have newer modified time than last change time // if doc in filesystem have newer modified time than last change time
// then will update the doc in db // then will update the doc in db
@ -421,20 +421,20 @@ module.exports = function (sequelize, DataTypes) {
if (ot.TextOperation.isRetain(op)) { if (ot.TextOperation.isRetain(op)) {
index += op index += op
} else if (ot.TextOperation.isInsert(op)) { } else if (ot.TextOperation.isInsert(op)) {
let opStart = index const opStart = index
let opEnd = index + op.length const opEnd = index + op.length
var inserted = false let inserted = false
// authorship format: [userId, startPos, endPos, createdAt, updatedAt] // authorship format: [userId, startPos, endPos, createdAt, updatedAt]
if (authorships.length <= 0) authorships.push([userId, opStart, opEnd, timestamp, timestamp]) if (authorships.length <= 0) authorships.push([userId, opStart, opEnd, timestamp, timestamp])
else { else {
for (let j = 0; j < authorships.length; j++) { for (let j = 0; j < authorships.length; j++) {
let authorship = authorships[j] const authorship = authorships[j]
if (!inserted) { if (!inserted) {
let nextAuthorship = authorships[j + 1] || -1 const nextAuthorship = authorships[j + 1] || -1
if ((nextAuthorship !== -1 && nextAuthorship[1] >= opEnd) || j >= authorships.length - 1) { if ((nextAuthorship !== -1 && nextAuthorship[1] >= opEnd) || j >= authorships.length - 1) {
if (authorship[1] < opStart && authorship[2] > opStart) { if (authorship[1] < opStart && authorship[2] > opStart) {
// divide // divide
let postLength = authorship[2] - opStart const postLength = authorship[2] - opStart
authorship[2] = opStart authorship[2] = opStart
authorship[4] = timestamp authorship[4] = timestamp
authorships.splice(j + 1, 0, [userId, opStart, opEnd, timestamp, timestamp]) authorships.splice(j + 1, 0, [userId, opStart, opEnd, timestamp, timestamp])
@ -460,13 +460,13 @@ module.exports = function (sequelize, DataTypes) {
} }
index += op.length index += op.length
} else if (ot.TextOperation.isDelete(op)) { } else if (ot.TextOperation.isDelete(op)) {
let opStart = index const opStart = index
let opEnd = index - op const opEnd = index - op
if (operation.length === 1) { if (operation.length === 1) {
authorships = [] authorships = []
} else if (authorships.length > 0) { } else if (authorships.length > 0) {
for (let j = 0; j < authorships.length; j++) { for (let j = 0; j < authorships.length; j++) {
let authorship = authorships[j] const authorship = authorships[j]
if (authorship[1] >= opStart && authorship[1] <= opEnd && authorship[2] >= opStart && authorship[2] <= opEnd) { if (authorship[1] >= opStart && authorship[1] <= opEnd && authorship[2] >= opStart && authorship[2] <= opEnd) {
authorships.splice(j, 1) authorships.splice(j, 1)
j -= 1 j -= 1
@ -491,12 +491,12 @@ module.exports = function (sequelize, DataTypes) {
} }
// merge // merge
for (let j = 0; j < authorships.length; j++) { for (let j = 0; j < authorships.length; j++) {
let authorship = authorships[j] const authorship = authorships[j]
for (let k = j + 1; k < authorships.length; k++) { for (let k = j + 1; k < authorships.length; k++) {
let nextAuthorship = authorships[k] const nextAuthorship = authorships[k]
if (nextAuthorship && authorship[0] === nextAuthorship[0] && authorship[2] === nextAuthorship[1]) { if (nextAuthorship && authorship[0] === nextAuthorship[0] && authorship[2] === nextAuthorship[1]) {
let minTimestamp = Math.min(authorship[3], nextAuthorship[3]) const minTimestamp = Math.min(authorship[3], nextAuthorship[3])
let maxTimestamp = Math.max(authorship[3], nextAuthorship[3]) const maxTimestamp = Math.max(authorship[3], nextAuthorship[3])
authorships.splice(j, 1, [authorship[0], authorship[1], nextAuthorship[2], minTimestamp, maxTimestamp]) authorships.splice(j, 1, [authorship[0], authorship[1], nextAuthorship[2], minTimestamp, maxTimestamp])
authorships.splice(k, 1) authorships.splice(k, 1)
j -= 1 j -= 1
@ -506,7 +506,7 @@ module.exports = function (sequelize, DataTypes) {
} }
// clear // clear
for (let j = 0; j < authorships.length; j++) { for (let j = 0; j < authorships.length; j++) {
let authorship = authorships[j] const authorship = authorships[j]
if (!authorship[0]) { if (!authorship[0]) {
authorships.splice(j, 1) authorships.splice(j, 1)
j -= 1 j -= 1
@ -537,11 +537,11 @@ module.exports = function (sequelize, DataTypes) {
var lengthBias = 0 var lengthBias = 0
for (let j = 0; j < patch.length; j++) { for (let j = 0; j < patch.length; j++) {
var operation = [] var operation = []
let p = patch[j] const p = patch[j]
var currIndex = p.start1 var currIndex = p.start1
var currLength = contentLength - bias var currLength = contentLength - bias
for (let i = 0; i < p.diffs.length; i++) { for (let i = 0; i < p.diffs.length; i++) {
let diff = p.diffs[i] const diff = p.diffs[i]
switch (diff[0]) { switch (diff[0]) {
case 0: // retain case 0: // retain
if (i === 0) { if (i === 0) {

View File

@ -744,8 +744,8 @@ function queueForConnect (socket) {
}) })
return socket.disconnect(true) return socket.disconnect(true)
} }
let note = notes[noteId] const note = notes[noteId]
let user = users[socket.id] const user = users[socket.id]
// update user color to author color // update user color to author color
if (note.authors[user.userid]) { if (note.authors[user.userid]) {
user.color = users[socket.id].color = note.authors[user.userid].color user.color = users[socket.id].color = note.authors[user.userid].color
@ -766,7 +766,7 @@ function queueForConnect (socket) {
socketClient.registerEventHandler() socketClient.registerEventHandler()
if (config.debug) { if (config.debug) {
let noteId = socket.noteId const noteId = socket.noteId
logger.info('SERVER connected a client to [' + noteId + ']:') logger.info('SERVER connected a client to [' + noteId + ']:')
logger.info(JSON.stringify(user)) logger.info(JSON.stringify(user))
// logger.info(notes); // logger.info(notes);

View File

@ -501,17 +501,17 @@ function githubActionGist (req, res, note) {
var title = models.Note.decodeTitle(note.title) var title = models.Note.decodeTitle(note.title)
var filename = title.replace('/', ' ') + '.md' var filename = title.replace('/', ' ') + '.md'
var gist = { var gist = {
'files': {} files: {}
} }
gist.files[filename] = { gist.files[filename] = {
'content': content content: content
} }
var gistUrl = 'https://api.github.com/gists' var gistUrl = 'https://api.github.com/gists'
request({ request({
url: gistUrl, url: gistUrl,
headers: { headers: {
'User-Agent': 'CodiMD', 'User-Agent': 'CodiMD',
'Authorization': 'token ' + accessToken Authorization: 'token ' + accessToken
}, },
method: 'POST', method: 'POST',
json: gist json: gist

View File

@ -7,7 +7,7 @@ exports.isSQLite = function isSQLite (sequelize) {
} }
exports.getImageMimeType = function getImageMimeType (imagePath) { exports.getImageMimeType = function getImageMimeType (imagePath) {
var fileExtension = /[^.]+$/.exec(imagePath) const fileExtension = /[^.]+$/.exec(imagePath)
switch (fileExtension[0]) { switch (fileExtension[0]) {
case 'bmp': case 'bmp':

View File

@ -6,7 +6,7 @@ const DropboxStrategy = require('passport-dropbox-oauth2').Strategy
const config = require('../../../config') const config = require('../../../config')
const { setReturnToFromReferer, passportGeneralCallback } = require('../utils') const { setReturnToFromReferer, passportGeneralCallback } = require('../utils')
let dropboxAuth = module.exports = Router() const dropboxAuth = module.exports = Router()
passport.use(new DropboxStrategy({ passport.use(new DropboxStrategy({
apiVersion: '2', apiVersion: '2',

View File

@ -11,7 +11,7 @@ const { setReturnToFromReferer } = require('../utils')
const { urlencodedParser } = require('../../utils') const { urlencodedParser } = require('../../utils')
const response = require('../../../response') const response = require('../../../response')
let emailAuth = module.exports = Router() const emailAuth = module.exports = Router()
passport.use(new LocalStrategy({ passport.use(new LocalStrategy({
usernameField: 'email' usernameField: 'email'

View File

@ -7,7 +7,7 @@ const FacebookStrategy = require('passport-facebook').Strategy
const config = require('../../../config') const config = require('../../../config')
const { setReturnToFromReferer, passportGeneralCallback } = require('../utils') const { setReturnToFromReferer, passportGeneralCallback } = require('../utils')
let facebookAuth = module.exports = Router() const facebookAuth = module.exports = Router()
passport.use(new FacebookStrategy({ passport.use(new FacebookStrategy({
clientID: config.facebook.clientID, clientID: config.facebook.clientID,

View File

@ -7,7 +7,7 @@ const config = require('../../../config')
const response = require('../../../response') const response = require('../../../response')
const { setReturnToFromReferer, passportGeneralCallback } = require('../utils') const { setReturnToFromReferer, passportGeneralCallback } = require('../utils')
let githubAuth = module.exports = Router() const githubAuth = module.exports = Router()
passport.use(new GithubStrategy({ passport.use(new GithubStrategy({
clientID: config.github.clientID, clientID: config.github.clientID,

View File

@ -7,7 +7,7 @@ const config = require('../../../config')
const response = require('../../../response') const response = require('../../../response')
const { setReturnToFromReferer, passportGeneralCallback } = require('../utils') const { setReturnToFromReferer, passportGeneralCallback } = require('../utils')
let gitlabAuth = module.exports = Router() const gitlabAuth = module.exports = Router()
passport.use(new GitlabStrategy({ passport.use(new GitlabStrategy({
baseURL: config.gitlab.baseURL, baseURL: config.gitlab.baseURL,

View File

@ -6,7 +6,7 @@ var GoogleStrategy = require('passport-google-oauth20').Strategy
const config = require('../../../config') const config = require('../../../config')
const { setReturnToFromReferer, passportGeneralCallback } = require('../utils') const { setReturnToFromReferer, passportGeneralCallback } = require('../utils')
let googleAuth = module.exports = Router() const googleAuth = module.exports = Router()
passport.use(new GoogleStrategy({ passport.use(new GoogleStrategy({
clientID: config.google.clientID, clientID: config.google.clientID,

View File

@ -10,7 +10,7 @@ const { setReturnToFromReferer } = require('../utils')
const { urlencodedParser } = require('../../utils') const { urlencodedParser } = require('../../utils')
const response = require('../../../response') const response = require('../../../response')
let ldapAuth = module.exports = Router() const ldapAuth = module.exports = Router()
passport.use(new LDAPStrategy({ passport.use(new LDAPStrategy({
server: { server: {

View File

@ -8,11 +8,11 @@ const OAuthStrategy = require('passport-oauth2').Strategy
const config = require('../../../config') const config = require('../../../config')
const { setReturnToFromReferer, passportGeneralCallback } = require('../utils') const { setReturnToFromReferer, passportGeneralCallback } = require('../utils')
let mattermostAuth = module.exports = Router() const mattermostAuth = module.exports = Router()
const mattermostClient = new MattermostClient() const mattermostClient = new MattermostClient()
let mattermostStrategy = new OAuthStrategy({ const mattermostStrategy = new OAuthStrategy({
authorizationURL: config.mattermost.baseURL + '/oauth/authorize', authorizationURL: config.mattermost.baseURL + '/oauth/authorize',
tokenURL: config.mattermost.baseURL + '/oauth/access_token', tokenURL: config.mattermost.baseURL + '/oauth/access_token',
clientID: config.mattermost.clientID, clientID: config.mattermost.clientID,

View File

@ -6,7 +6,7 @@ const { Strategy, InternalOAuthError } = require('passport-oauth2')
const config = require('../../../config') const config = require('../../../config')
const { setReturnToFromReferer, passportGeneralCallback } = require('../utils') const { setReturnToFromReferer, passportGeneralCallback } = require('../utils')
let oauth2Auth = module.exports = Router() const oauth2Auth = module.exports = Router()
class OAuth2CustomStrategy extends Strategy { class OAuth2CustomStrategy extends Strategy {
constructor (options, verify) { constructor (options, verify) {
@ -31,7 +31,7 @@ class OAuth2CustomStrategy extends Strategy {
return done(new Error('Failed to parse user profile')) return done(new Error('Failed to parse user profile'))
} }
let profile = parseProfile(json) const profile = parseProfile(json)
profile.provider = 'oauth2' profile.provider = 'oauth2'
done(null, profile) done(null, profile)
@ -76,7 +76,7 @@ OAuth2CustomStrategy.prototype.userProfile = function (accessToken, done) {
return done(new Error('Failed to parse user profile')) return done(new Error('Failed to parse user profile'))
} }
let profile = parseProfile(json) const profile = parseProfile(json)
profile.provider = 'oauth2' profile.provider = 'oauth2'
done(null, profile) done(null, profile)

View File

@ -9,7 +9,7 @@ const logger = require('../../../logger')
const { urlencodedParser } = require('../../utils') const { urlencodedParser } = require('../../utils')
const { setReturnToFromReferer } = require('../utils') const { setReturnToFromReferer } = require('../utils')
let openIDAuth = module.exports = Router() const openIDAuth = module.exports = Router()
passport.use(new OpenIDStrategy({ passport.use(new OpenIDStrategy({
returnURL: config.serverURL + '/auth/openid/callback', returnURL: config.serverURL + '/auth/openid/callback',

View File

@ -10,7 +10,7 @@ const { urlencodedParser } = require('../../utils')
const fs = require('fs') const fs = require('fs')
const intersection = function (array1, array2) { return array1.filter((n) => array2.includes(n)) } const intersection = function (array1, array2) { return array1.filter((n) => array2.includes(n)) }
let samlAuth = module.exports = Router() const samlAuth = module.exports = Router()
passport.use(new SamlStrategy({ passport.use(new SamlStrategy({
callbackUrl: config.serverURL + '/auth/saml/callback', callbackUrl: config.serverURL + '/auth/saml/callback',

View File

@ -7,7 +7,7 @@ const TwitterStrategy = require('passport-twitter').Strategy
const config = require('../../../config') const config = require('../../../config')
const { setReturnToFromReferer, passportGeneralCallback } = require('../utils') const { setReturnToFromReferer, passportGeneralCallback } = require('../utils')
let twitterAuth = module.exports = Router() const twitterAuth = module.exports = Router()
passport.use(new TwitterStrategy({ passport.use(new TwitterStrategy({
consumerKey: config.twitter.consumerKey, consumerKey: config.twitter.consumerKey,

View File

@ -32,16 +32,16 @@ exports.uploadImage = function (imagePath, callback) {
return return
} }
let key = path.join('uploads', path.basename(imagePath)) const key = path.join('uploads', path.basename(imagePath))
let protocol = config.minio.secure ? 'https' : 'http' const protocol = config.minio.secure ? 'https' : 'http'
minioClient.putObject(config.s3bucket, key, buffer, buffer.size, getImageMimeType(imagePath), function (err, data) { minioClient.putObject(config.s3bucket, key, buffer, buffer.size, getImageMimeType(imagePath), function (err, data) {
if (err) { if (err) {
callback(new Error(err), null) callback(new Error(err), null)
return return
} }
let hidePort = [80, 443].includes(config.minio.port) const hidePort = [80, 443].includes(config.minio.port)
let urlPort = hidePort ? '' : `:${config.minio.port}` const urlPort = hidePort ? '' : `:${config.minio.port}`
callback(null, `${protocol}://${config.minio.endPoint}${urlPort}/${config.s3bucket}/${key}`) callback(null, `${protocol}://${config.minio.endPoint}${urlPort}/${config.s3bucket}/${key}`)
}) })
}) })

View File

@ -26,7 +26,7 @@ exports.uploadImage = function (imagePath, callback) {
callback(new Error(err), null) callback(new Error(err), null)
return return
} }
let params = { const params = {
Bucket: config.s3bucket, Bucket: config.s3bucket,
Key: path.join('uploads', path.basename(imagePath)), Key: path.join('uploads', path.basename(imagePath)),
Body: buffer Body: buffer

View File

@ -69,8 +69,7 @@ UserRouter.get('/me/delete/:token?', function (req, res) {
// export the data of the authenticated user // export the data of the authenticated user
UserRouter.get('/me/export', function (req, res) { UserRouter.get('/me/export', function (req, res) {
if (req.isAuthenticated()) { if (req.isAuthenticated()) {
// let output = fs.createWriteStream(__dirname + '/example.zip'); const archive = archiver('zip', {
let archive = archiver('zip', {
zlib: { level: 3 } // Sets the compression level. zlib: { level: 3 } // Sets the compression level.
}) })
res.setHeader('Content-Type', 'application/zip') res.setHeader('Content-Type', 'application/zip')
@ -90,14 +89,14 @@ UserRouter.get('/me/export', function (req, res) {
ownerId: user.id ownerId: user.id
} }
}).then(function (notes) { }).then(function (notes) {
let filenames = {} const filenames = {}
async.each(notes, function (note, callback) { async.each(notes, function (note, callback) {
let basename = note.title.replace(/\//g, '-') // Prevent subdirectories const basename = note.title.replace(/\//g, '-') // Prevent subdirectories
let filename let filename
let suffix = '' let suffix = 0
do { do {
let seperator = typeof suffix === 'number' ? '-' : '' const separator = suffix === 0 ? '' : '-'
filename = basename + seperator + suffix + '.md' filename = basename + separator + suffix + '.md'
suffix++ suffix++
} while (filenames[filename]) } while (filenames[filename])
filenames[filename] = true filenames[filename] = true

View File

@ -13,7 +13,7 @@ process.on('message', function (data) {
} }
switch (data.msg) { switch (data.msg) {
case 'create patch': case 'create patch':
if (!data.hasOwnProperty('lastDoc') || !data.hasOwnProperty('currDoc')) { if (!Object.hasOwnProperty.call(data, 'lastDoc') || !Object.hasOwnProperty.call(data, 'currDoc')) {
return logger.error('dmp worker error: not enough data on create patch') return logger.error('dmp worker error: not enough data on create patch')
} }
try { try {
@ -33,7 +33,7 @@ process.on('message', function (data) {
} }
break break
case 'get revision': case 'get revision':
if (!data.hasOwnProperty('revisions') || !data.hasOwnProperty('count')) { if (!Object.hasOwnProperty.call(data, 'revisions') || !Object.hasOwnProperty.call(data, 'count')) {
return logger.error('dmp worker error: not enough data on get revision') return logger.error('dmp worker error: not enough data on get revision')
} }
try { try {
@ -77,12 +77,12 @@ function getRevision (revisions, count) {
if (count <= Math.round(revisions.length / 2)) { if (count <= Math.round(revisions.length / 2)) {
// start from top to target // start from top to target
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {
let revision = revisions[i] const revision = revisions[i]
if (i === 0) { if (i === 0) {
startContent = revision.content || revision.lastContent startContent = revision.content || revision.lastContent
} }
if (i !== count - 1) { if (i !== count - 1) {
let patch = dmp.patch_fromText(revision.patch) const patch = dmp.patch_fromText(revision.patch)
applyPatches = applyPatches.concat(patch) applyPatches = applyPatches.concat(patch)
} }
lastPatch = revision.patch lastPatch = revision.patch
@ -99,13 +99,13 @@ function getRevision (revisions, count) {
// start from bottom to target // start from bottom to target
var l = revisions.length - 1 var l = revisions.length - 1
for (var i = l; i >= count - 1; i--) { for (var i = l; i >= count - 1; i--) {
let revision = revisions[i] const revision = revisions[i]
if (i === l) { if (i === l) {
startContent = revision.lastContent startContent = revision.lastContent
authorship = revision.authorship authorship = revision.authorship
} }
if (revision.patch) { if (revision.patch) {
let patch = dmp.patch_fromText(revision.patch) const patch = dmp.patch_fromText(revision.patch)
applyPatches = applyPatches.concat(patch) applyPatches = applyPatches.concat(patch)
} }
lastPatch = revision.patch lastPatch = revision.patch

View File

@ -30,62 +30,61 @@
}, },
"dependencies": { "dependencies": {
"@hackmd/codemirror": "~5.46.2", "@hackmd/codemirror": "~5.46.2",
"@hackmd/diff-match-patch": "~1.1.1", "@hackmd/diff-match-patch": "~1.1.3",
"@hackmd/idle-js": "~1.0.1", "@hackmd/idle-js": "~1.0.1",
"@hackmd/imgur": "~0.4.1", "@hackmd/imgur": "~0.4.1",
"@hackmd/js-sequence-diagrams": "~0.0.1-alpha.3", "@hackmd/js-sequence-diagrams": "~0.0.1-alpha.3",
"@hackmd/lz-string": "~1.4.4", "@hackmd/lz-string": "~1.4.4",
"@hackmd/meta-marked": "~0.4.4", "@hackmd/meta-marked": "~0.4.4",
"@passport-next/passport-openid": "~1.0.0", "@passport-next/passport-openid": "~1.0.0",
"archiver": "~2.1.1", "archiver": "~3.1.1",
"async": "~2.1.4", "async": "~3.1.0",
"aws-sdk": "~2.345.0", "aws-sdk": "~2.503.0",
"azure-storage": "~2.10.2", "azure-storage": "~2.10.3",
"babel-polyfill": "~6.26.0", "babel-polyfill": "~6.26.0",
"base64url": "~3.0.0", "base64url": "~3.0.1",
"body-parser": "~1.18.3", "body-parser": "~1.19.0",
"bootstrap": "~3.4.0", "bootstrap": "~3.4.0",
"bootstrap-validator": "~0.11.8", "bootstrap-validator": "~0.11.8",
"chance": "~1.0.4", "chance": "~1.0.18",
"cheerio": "~0.22.0", "cheerio": "~0.22.0",
"compression": "~1.7.4",
"connect-flash": "~0.1.1", "connect-flash": "~0.1.1",
"connect-session-sequelize": "~6.0.0", "connect-session-sequelize": "~6.0.0",
"cookie": "~0.3.1", "cookie": "~0.4.0",
"cookie-parser": "~1.4.3", "cookie-parser": "~1.4.4",
"deep-freeze": "~0.0.1", "deep-freeze": "~0.0.1",
"ejs": "~2.5.5", "ejs": "~2.6.2",
"emojify.js": "~1.1.0", "emojify.js": "~1.1.0",
"express": "~4.16.4", "express": "~4.17.1",
"express-session": "~1.16.1", "express-session": "~1.16.2",
"file-saver": "~1.3.3", "file-saver": "~2.0.2",
"flowchart.js": "~1.12.0", "flowchart.js": "~1.12.2",
"fork-awesome": "~1.1.3", "fork-awesome": "~1.1.7",
"formidable": "~1.2.1", "formidable": "~1.2.1",
"gist-embed": "~2.6.0", "gist-embed": "~2.6.0",
"graceful-fs": "~4.1.11", "graceful-fs": "~4.2.1",
"handlebars": "~4.0.13", "handlebars": "~4.1.2",
"helmet": "~3.13.0", "helmet": "~3.20.0",
"highlight.js": "~9.12.0", "highlight.js": "~9.15.9",
"i18n": "~0.8.3", "i18n": "~0.8.3",
"ionicons": "~2.0.1", "ionicons": "~2.0.1",
"isomorphic-fetch": "~2.2.1", "isomorphic-fetch": "~2.2.1",
"jquery": "~3.1.1", "jquery": "~3.4.1",
"jquery-mousewheel": "~3.1.13", "jquery-mousewheel": "~3.1.13",
"jquery-ui": "~1.12.1", "jquery-ui": "~1.12.1",
"js-cookie": "~2.1.3", "js-cookie": "~2.2.0",
"js-yaml": "~3.13.1", "js-yaml": "~3.13.1",
"jsdom-nogyp": "~0.8.3", "jsdom-nogyp": "~0.8.3",
"keymaster": "~1.6.2", "keymaster": "~1.6.2",
"list.js": "~1.5.0", "list.js": "~1.5.0",
"lodash": "~4.17.11", "lodash": "~4.17.15",
"lutim": "~1.0.2", "lutim": "~1.0.2",
"markdown-it": "~8.2.2", "markdown-it": "~9.0.1",
"markdown-it-abbr": "~1.0.4", "markdown-it-abbr": "~1.0.4",
"markdown-it-container": "~2.0.0", "markdown-it-container": "~2.0.0",
"markdown-it-deflist": "~2.0.1", "markdown-it-deflist": "~2.0.3",
"markdown-it-emoji": "~1.3.0", "markdown-it-emoji": "~1.4.0",
"markdown-it-footnote": "~3.0.1", "markdown-it-footnote": "~3.0.2",
"markdown-it-imsize": "~2.0.1", "markdown-it-imsize": "~2.0.1",
"markdown-it-ins": "~2.0.0", "markdown-it-ins": "~2.0.0",
"markdown-it-mark": "~2.0.0", "markdown-it-mark": "~2.0.0",
@ -94,15 +93,15 @@
"markdown-it-sub": "~1.0.0", "markdown-it-sub": "~1.0.0",
"markdown-it-sup": "~1.0.0", "markdown-it-sup": "~1.0.0",
"markdown-pdf": "~9.0.0", "markdown-pdf": "~9.0.0",
"mathjax": "~2.7.0", "mathjax": "~2.7.5",
"mattermost-redux": "~5.9.0", "mattermost-redux": "~5.13.0",
"mermaid": "~8.2.3", "mermaid": "~8.2.3",
"method-override": "~2.3.7", "method-override": "~3.0.0",
"minimist": "~1.2.0", "minimist": "~1.2.0",
"minio": "~6.0.0", "minio": "~7.0.10",
"moment": "~2.24.0", "moment": "~2.24.0",
"morgan": "~1.9.1", "morgan": "~1.9.1",
"mysql": "~2.16.0", "mysql": "~2.17.1",
"passport": "~0.4.0", "passport": "~0.4.0",
"passport-dropbox-oauth2": "~1.1.0", "passport-dropbox-oauth2": "~1.1.0",
"passport-facebook": "~2.1.1", "passport-facebook": "~2.1.1",
@ -115,12 +114,12 @@
"passport-saml": "~1.0.0", "passport-saml": "~1.0.0",
"passport-twitter": "~1.0.4", "passport-twitter": "~1.0.4",
"passport.socketio": "~3.7.0", "passport.socketio": "~3.7.0",
"pdfobject": "~2.0.201604172", "pdfobject": "~2.1.1",
"pg": "~6.1.2", "pg": "~6.1.2",
"pg-hstore": "~2.3.2", "pg-hstore": "~2.3.2",
"plantuml-encoder": "^1.2.5", "plantuml-encoder": "^1.2.5",
"prismjs": "~1.6.0", "prismjs": "~1.17.1",
"randomcolor": "~0.5.3", "randomcolor": "~0.5.4",
"raphael": "~2.2.8", "raphael": "~2.2.8",
"readline-sync": "~1.4.7", "readline-sync": "~1.4.7",
"request": "~2.88.0", "request": "~2.88.0",
@ -128,24 +127,24 @@
"scrypt": "~6.0.3", "scrypt": "~6.0.3",
"select2": "~3.5.2-browserify", "select2": "~3.5.2-browserify",
"sequelize": "5.3.5", "sequelize": "5.3.5",
"shortid": "~2.2.8", "shortid": "~2.2.14",
"socket.io": "~2.1.1", "socket.io": "~2.2.0",
"socket.io-client": "~2.1.1", "socket.io-client": "~2.2.0",
"spin.js": "~2.3.2", "spin.js": "~4.0.0",
"sqlite3": "~4.0.1", "sqlite3": "~4.0.9",
"store": "~2.0.12", "store": "~2.0.12",
"tedious": "~6.1.0", "tedious": "~6.2.0",
"toobusy-js": "~0.5.1", "toobusy-js": "~0.5.1",
"turndown": "~5.0.1", "turndown": "~5.0.3",
"uuid": "~3.1.0", "uuid": "~3.3.2",
"validator": "~10.4.0", "validator": "~11.1.0",
"velocity-animate": "~1.4.0", "velocity-animate": "~1.5.2",
"visibilityjs": "~1.2.4", "visibilityjs": "~2.0.2",
"viz.js": "~1.7.0", "viz.js": "~2.1.2",
"winston": "~3.1.0", "winston": "~3.2.1",
"ws": "~6.0.0", "ws": "~7.1.1",
"wurl": "~2.5.3", "wurl": "~2.5.3",
"xss": "~1.0.3" "xss": "~1.0.6"
}, },
"devDependencies": { "devDependencies": {
"acorn": "~6.1.1", "acorn": "~6.1.1",
@ -176,14 +175,14 @@
"script-loader": "~0.7.2", "script-loader": "~0.7.2",
"sequelize-cli": "~5.4.0", "sequelize-cli": "~5.4.0",
"sinon": "~7.3.2", "sinon": "~7.3.2",
"standard": "~12.0.1", "standard": "~13.1.0",
"string-loader": "~0.0.1", "string-loader": "~0.0.1",
"style-loader": "~0.21.0", "style-loader": "~0.23.1",
"uglifyjs-webpack-plugin": "~1.2.7", "uglifyjs-webpack-plugin": "~1.2.7",
"url-loader": "~1.0.1", "url-loader": "~1.0.1",
"webpack": "~4.30.0", "webpack": "~4.39.0",
"webpack-cli": "~3.3.0", "webpack-cli": "~3.3.6",
"webpack-merge": "~4.1.4", "webpack-merge": "~4.2.1",
"webpack-parallel-uglify-plugin": "~1.1.0" "webpack-parallel-uglify-plugin": "~1.1.0"
}, },
"optionalDependencies": { "optionalDependencies": {
@ -207,7 +206,8 @@
"ignore": [ "ignore": [
"/public/build", "/public/build",
"/public/vendor", "/public/vendor",
"/lib/ot" "/lib/ot",
"webpack.*"
] ]
}, },
"nyc": { "nyc": {

View File

@ -10,7 +10,6 @@ module.exports = {
"moment": false, "moment": false,
"editor": false, "editor": false,
"ui": false, "ui": false,
"Spinner": false,
"modeType": false, "modeType": false,
"serverurl": false, "serverurl": false,
"key": false, "key": false,

View File

@ -350,7 +350,7 @@ export function finishView (view) {
$value.html('') $value.html('')
chart.drawSVG(value, { chart.drawSVG(value, {
'line-width': 2, 'line-width': 2,
'fill': 'none', fill: 'none',
'font-size': '16px', 'font-size': '16px',
'font-family': "'Andale Mono', monospace" 'font-family': "'Andale Mono', monospace"
}) })
@ -747,12 +747,12 @@ export function generateToc (id) {
target.html('') target.html('')
/* eslint-disable no-unused-vars */ /* eslint-disable no-unused-vars */
var toc = new window.Toc('doc', { var toc = new window.Toc('doc', {
'level': 3, level: 3,
'top': -1, top: -1,
'class': 'toc', class: 'toc',
'ulClass': 'nav', ulClass: 'nav',
'targetId': id, targetId: id,
'process': getHeaderContent process: getHeaderContent
}) })
/* eslint-enable no-unused-vars */ /* eslint-enable no-unused-vars */
if (target.text() === 'undefined') { target.html('') } if (target.text() === 'undefined') { target.html('') }
@ -835,7 +835,7 @@ const linkifyAnchors = (level, containingElement) => {
const headers = containingElement.getElementsByTagName(`h${level}`) const headers = containingElement.getElementsByTagName(`h${level}`)
for (let i = 0, l = headers.length; i < l; i++) { for (let i = 0, l = headers.length; i < l; i++) {
let header = headers[i] const header = headers[i]
if (header.getElementsByClassName('anchor').length === 0) { if (header.getElementsByClassName('anchor').length === 0) {
if (typeof header.id === 'undefined' || header.id === '') { if (typeof header.id === 'undefined' || header.id === '') {
// to escape characters not allow in css and humanize // to escape characters not allow in css and humanize
@ -894,12 +894,12 @@ export function renderTOC (view) {
const target = $(`#${id}`) const target = $(`#${id}`)
target.html('') target.html('')
/* eslint-disable no-unused-vars */ /* eslint-disable no-unused-vars */
let TOC = new window.Toc('doc', { const TOC = new window.Toc('doc', {
'level': 3, level: 3,
'top': -1, top: -1,
'class': 'toc', class: 'toc',
'targetId': id, targetId: id,
'process': getHeaderContent process: getHeaderContent
}) })
/* eslint-enable no-unused-vars */ /* eslint-enable no-unused-vars */
if (target.text() === 'undefined') { target.html('') } if (target.text() === 'undefined') { target.html('') }
@ -947,7 +947,7 @@ function highlightRender (code, lang) {
return result.value return result.value
} }
export let md = markdownit('default', { export const md = markdownit('default', {
html: true, html: true,
breaks: true, breaks: true,
langPrefix: '', langPrefix: '',
@ -1016,7 +1016,7 @@ md.use(markdownitContainer, 'spoiler', {
} }
}) })
let defaultImageRender = md.renderer.rules.image const defaultImageRender = md.renderer.rules.image
md.renderer.rules.image = function (tokens, idx, options, env, self) { md.renderer.rules.image = function (tokens, idx, options, env, self) {
tokens[idx].attrJoin('class', 'raw') tokens[idx].attrJoin('class', 'raw')
return defaultImageRender(...arguments) return defaultImageRender(...arguments)
@ -1061,26 +1061,26 @@ md.renderer.rules.fence = (tokens, idx, options, env, self) => {
} }
const makePlantumlURL = (umlCode) => { const makePlantumlURL = (umlCode) => {
let format = 'svg' const format = 'svg'
let code = plantumlEncoder.encode(umlCode) const code = plantumlEncoder.encode(umlCode)
return `${plantumlServer}/${format}/${code}` return `${plantumlServer}/${format}/${code}`
} }
// https://github.com/qjebbs/vscode-plantuml/tree/master/src/markdown-it-plantuml // https://github.com/qjebbs/vscode-plantuml/tree/master/src/markdown-it-plantuml
md.renderer.rules.plantuml = (tokens, idx) => { md.renderer.rules.plantuml = (tokens, idx) => {
let token = tokens[idx] const token = tokens[idx]
if (token.type !== 'plantuml') { if (token.type !== 'plantuml') {
return tokens[idx].content return tokens[idx].content
} }
let url = makePlantumlURL(token.content) const url = makePlantumlURL(token.content)
return `<img src="${url}" />` return `<img src="${url}" />`
} }
// https://github.com/qjebbs/vscode-plantuml/tree/master/src/markdown-it-plantuml // https://github.com/qjebbs/vscode-plantuml/tree/master/src/markdown-it-plantuml
md.core.ruler.push('plantuml', (state) => { md.core.ruler.push('plantuml', (state) => {
let blockTokens = state.tokens const blockTokens = state.tokens
for (let blockToken of blockTokens) { for (const blockToken of blockTokens) {
if (blockToken.type === 'fence' && blockToken.info === 'plantuml') { if (blockToken.type === 'fence' && blockToken.info === 'plantuml') {
blockToken.type = 'plantuml' blockToken.type = 'plantuml'
} }

View File

@ -144,7 +144,7 @@ export function writeHistory (title, tags) {
} }
function writeHistoryToStorage (title, tags) { function writeHistoryToStorage (title, tags) {
let data = store.get('notehistory') const data = store.get('notehistory')
let notehistory let notehistory
if (data && typeof data === 'string') { if (data && typeof data === 'string') {
notehistory = JSON.parse(data) notehistory = JSON.parse(data)
@ -260,7 +260,7 @@ function parseToHistory (list, notehistory, callback) {
for (let i = 0; i < notehistory.length; i++) { for (let i = 0; i < notehistory.length; i++) {
// migrate LZString encoded id to base64url encoded id // migrate LZString encoded id to base64url encoded id
try { try {
let id = LZString.decompressFromBase64(notehistory[i].id) const id = LZString.decompressFromBase64(notehistory[i].id)
if (id && checkNoteIdValid(id)) { if (id && checkNoteIdValid(id)) {
notehistory[i].id = encodeNoteId(id) notehistory[i].id = encodeNoteId(id)
} }

View File

@ -1,5 +1,5 @@
/* eslint-env browser, jquery */ /* eslint-env browser, jquery */
/* global CodeMirror, Cookies, moment, Spinner, serverurl, /* global CodeMirror, Cookies, moment, serverurl,
key, Dropbox, ot, hex2rgb, Visibility, inlineAttachment */ key, Dropbox, ot, hex2rgb, Visibility, inlineAttachment */
import TurndownService from 'turndown' import TurndownService from 'turndown'
@ -17,6 +17,8 @@ import List from 'list.js'
import Idle from '@hackmd/idle-js' import Idle from '@hackmd/idle-js'
import { Spinner } from 'spin.js'
import { import {
checkLoginStateChanged, checkLoginStateChanged,
setloginStateChangeEvent setloginStateChangeEvent
@ -83,6 +85,7 @@ require('../css/index.css')
require('../css/extra.css') require('../css/extra.css')
require('../css/slide-preview.css') require('../css/slide-preview.css')
require('../css/site.css') require('../css/site.css')
require('spin.js/spin.css')
require('highlight.js/styles/github-gist.css') require('highlight.js/styles/github-gist.css')
@ -260,7 +263,7 @@ let visibleMD = false
let visibleLG = false let visibleLG = false
const isTouchDevice = 'ontouchstart' in document.documentElement const isTouchDevice = 'ontouchstart' in document.documentElement
let currentStatus = statusType.offline let currentStatus = statusType.offline
let lastInfo = { const lastInfo = {
needRestore: false, needRestore: false,
cursor: null, cursor: null,
scroll: null, scroll: null,
@ -286,14 +289,14 @@ let lastInfo = {
let personalInfo = {} let personalInfo = {}
let onlineUsers = [] let onlineUsers = []
const fileTypes = { const fileTypes = {
'pl': 'perl', pl: 'perl',
'cgi': 'perl', cgi: 'perl',
'js': 'javascript', js: 'javascript',
'php': 'php', php: 'php',
'sh': 'bash', sh: 'bash',
'rb': 'ruby', rb: 'ruby',
'html': 'html', html: 'html',
'py': 'python' py: 'python'
} }
// editor settings // editor settings
@ -334,9 +337,7 @@ var opts = {
left: '50%' // Left position relative to parent left: '50%' // Left position relative to parent
} }
/* eslint-disable no-unused-vars */ new Spinner(opts).spin(ui.spinner[0])
var spinner = new Spinner(opts).spin(ui.spinner[0])
/* eslint-enable no-unused-vars */
// idle // idle
var idle = new Idle({ var idle = new Idle({
@ -955,8 +956,8 @@ ui.toolbar.export.dropbox.click(function () {
var options = { var options = {
files: [ files: [
{ {
'url': noteurl + '/download', url: noteurl + '/download',
'filename': filename filename: filename
} }
], ],
error: function (errorMessage) { error: function (errorMessage) {
@ -1787,29 +1788,29 @@ var authorMarks = {} // temp variable
var addTextMarkers = [] // temp variable var addTextMarkers = [] // temp variable
function updateInfo (data) { function updateInfo (data) {
// console.log(data); // console.log(data);
if (data.hasOwnProperty('createtime') && window.createtime !== data.createtime) { if (Object.hasOwnProperty.call(data, 'createtime') && window.createtime !== data.createtime) {
window.createtime = data.createtime window.createtime = data.createtime
updateLastChange() updateLastChange()
} }
if (data.hasOwnProperty('updatetime') && window.lastchangetime !== data.updatetime) { if (Object.hasOwnProperty.call(data, 'updatetime') && window.lastchangetime !== data.updatetime) {
window.lastchangetime = data.updatetime window.lastchangetime = data.updatetime
updateLastChange() updateLastChange()
} }
if (data.hasOwnProperty('owner') && window.owner !== data.owner) { if (Object.hasOwnProperty.call(data, 'owner') && window.owner !== data.owner) {
window.owner = data.owner window.owner = data.owner
window.ownerprofile = data.ownerprofile window.ownerprofile = data.ownerprofile
updateOwner() updateOwner()
} }
if (data.hasOwnProperty('lastchangeuser') && window.lastchangeuser !== data.lastchangeuser) { if (Object.hasOwnProperty.call(data, 'lastchangeuser') && window.lastchangeuser !== data.lastchangeuser) {
window.lastchangeuser = data.lastchangeuser window.lastchangeuser = data.lastchangeuser
window.lastchangeuserprofile = data.lastchangeuserprofile window.lastchangeuserprofile = data.lastchangeuserprofile
updateLastChangeUser() updateLastChangeUser()
updateOwner() updateOwner()
} }
if (data.hasOwnProperty('authors') && authors !== data.authors) { if (Object.hasOwnProperty.call(data, 'authors') && authors !== data.authors) {
authors = data.authors authors = data.authors
} }
if (data.hasOwnProperty('authorship') && authorship !== data.authorship) { if (Object.hasOwnProperty.call(data, 'authorship') && authorship !== data.authorship) {
authorship = data.authorship authorship = data.authorship
updateAuthorship() updateAuthorship()
} }
@ -1854,7 +1855,7 @@ function updateAuthorshipInner () {
authorMarks = {} authorMarks = {}
for (let i = 0; i < authorship.length; i++) { for (let i = 0; i < authorship.length; i++) {
var atom = authorship[i] var atom = authorship[i]
let author = authors[atom[0]] const author = authors[atom[0]]
if (author) { if (author) {
var prePos = editor.posFromIndex(atom[1]) var prePos = editor.posFromIndex(atom[1])
var preLine = editor.getLine(prePos.line) var preLine = editor.getLine(prePos.line)
@ -1872,7 +1873,7 @@ function updateAuthorshipInner () {
if (prePos.ch === preLine.length) { if (prePos.ch === preLine.length) {
startLine++ startLine++
} else if (prePos.ch !== 0) { } else if (prePos.ch !== 0) {
let mark = initMarkAndCheckGutter(authorMarks[prePos.line], author, atom[3]) const mark = initMarkAndCheckGutter(authorMarks[prePos.line], author, atom[3])
var _postPos = { var _postPos = {
line: prePos.line, line: prePos.line,
ch: preLine.length ch: preLine.length
@ -1889,7 +1890,7 @@ function updateAuthorshipInner () {
if (postPos.ch === 0) { if (postPos.ch === 0) {
endLine-- endLine--
} else if (postPos.ch !== postLine.length) { } else if (postPos.ch !== postLine.length) {
let mark = initMarkAndCheckGutter(authorMarks[postPos.line], author, atom[3]) const mark = initMarkAndCheckGutter(authorMarks[postPos.line], author, atom[3])
var _prePos = { var _prePos = {
line: postPos.line, line: postPos.line,
ch: 0 ch: 0
@ -1909,7 +1910,7 @@ function updateAuthorshipInner () {
} }
} }
} else { } else {
let mark = initMarkAndCheckGutter(authorMarks[prePos.line], author, atom[3]) const mark = initMarkAndCheckGutter(authorMarks[prePos.line], author, atom[3])
if (JSON.stringify(prePos) !== JSON.stringify(postPos)) { if (JSON.stringify(prePos) !== JSON.stringify(postPos)) {
mark.textmarkers.push({ mark.textmarkers.push({
userid: author.userid, userid: author.userid,
@ -1922,15 +1923,15 @@ function updateAuthorshipInner () {
} }
addTextMarkers = [] addTextMarkers = []
editor.eachLine(iterateLine) editor.eachLine(iterateLine)
var allTextMarks = editor.getAllMarks() const allTextMarks = editor.getAllMarks()
for (let i = 0; i < allTextMarks.length; i++) { for (let i = 0; i < allTextMarks.length; i++) {
let _textMarker = allTextMarks[i] const _textMarker = allTextMarks[i]
var pos = _textMarker.find() const pos = _textMarker.find()
var found = false let found = false
for (let j = 0; j < addTextMarkers.length; j++) { for (let j = 0; j < addTextMarkers.length; j++) {
let textMarker = addTextMarkers[j] const textMarker = addTextMarkers[j]
let author = authors[textMarker.userid] const author = authors[textMarker.userid]
let className = 'authorship-inline-' + author.color.substr(1) const className = 'authorship-inline-' + author.color.substr(1)
var obj = { var obj = {
from: textMarker.pos[0], from: textMarker.pos[0],
to: textMarker.pos[1] to: textMarker.pos[1]
@ -1948,12 +1949,12 @@ function updateAuthorshipInner () {
} }
} }
for (let i = 0; i < addTextMarkers.length; i++) { for (let i = 0; i < addTextMarkers.length; i++) {
let textMarker = addTextMarkers[i] const textMarker = addTextMarkers[i]
let author = authors[textMarker.userid] const author = authors[textMarker.userid]
const rgbcolor = hex2rgb(author.color) const rgbcolor = hex2rgb(author.color)
const colorString = `rgba(${rgbcolor.red},${rgbcolor.green},${rgbcolor.blue},0.7)` const colorString = `rgba(${rgbcolor.red},${rgbcolor.green},${rgbcolor.blue},0.7)`
const styleString = `background-image: linear-gradient(to top, ${colorString} 1px, transparent 1px);` const styleString = `background-image: linear-gradient(to top, ${colorString} 1px, transparent 1px);`
let className = `authorship-inline-${author.color.substr(1)}` const className = `authorship-inline-${author.color.substr(1)}`
const rule = `.${className} { ${styleString} }` const rule = `.${className} { ${styleString} }`
addStyleRule(rule) addStyleRule(rule)
editor.markText(textMarker.pos[0], textMarker.pos[1], { editor.markText(textMarker.pos[0], textMarker.pos[1], {
@ -1963,11 +1964,11 @@ function updateAuthorshipInner () {
} }
} }
function iterateLine (line) { function iterateLine (line) {
var lineNumber = line.lineNo() const lineNumber = line.lineNo()
var currMark = authorMarks[lineNumber] const currMark = authorMarks[lineNumber]
var author = currMark ? authors[currMark.gutter.userid] : null const author = currMark ? authors[currMark.gutter.userid] : null
if (currMark && author) { if (currMark && author) {
let className = 'authorship-gutter-' + author.color.substr(1) const className = 'authorship-gutter-' + author.color.substr(1)
const gutters = line.gutterMarkers const gutters = line.gutterMarkers
if (!gutters || !gutters['authorship-gutters'] || if (!gutters || !gutters['authorship-gutters'] ||
!gutters['authorship-gutters'].className || !gutters['authorship-gutters'].className ||
@ -1975,7 +1976,7 @@ function iterateLine (line) {
const styleString = `border-left: 3px solid ${author.color}; height: ${defaultTextHeight}px; margin-left: 3px;` const styleString = `border-left: 3px solid ${author.color}; height: ${defaultTextHeight}px; margin-left: 3px;`
const rule = `.${className} { ${styleString} }` const rule = `.${className} { ${styleString} }`
addStyleRule(rule) addStyleRule(rule)
var gutter = $('<div>', { const gutter = $('<div>', {
class: 'authorship-gutter ' + className, class: 'authorship-gutter ' + className,
title: author.name title: author.name
}) })
@ -1985,8 +1986,8 @@ function iterateLine (line) {
editor.setGutterMarker(line, 'authorship-gutters', null) editor.setGutterMarker(line, 'authorship-gutters', null)
} }
if (currMark && currMark.textmarkers.length > 0) { if (currMark && currMark.textmarkers.length > 0) {
for (var i = 0; i < currMark.textmarkers.length; i++) { for (let i = 0; i < currMark.textmarkers.length; i++) {
let textMarker = currMark.textmarkers[i] const textMarker = currMark.textmarkers[i]
if (textMarker.userid !== currMark.gutter.userid) { if (textMarker.userid !== currMark.gutter.userid) {
addTextMarkers.push(textMarker) addTextMarkers.push(textMarker)
} }
@ -1997,12 +1998,12 @@ editorInstance.on('update', function () {
$('.authorship-gutter:not([data-original-title])').tooltip({ $('.authorship-gutter:not([data-original-title])').tooltip({
container: '.CodeMirror-lines', container: '.CodeMirror-lines',
placement: 'right', placement: 'right',
delay: { 'show': 500, 'hide': 100 } delay: { show: 500, hide: 100 }
}) })
$('.authorship-inline:not([data-original-title])').tooltip({ $('.authorship-inline:not([data-original-title])').tooltip({
container: '.CodeMirror-lines', container: '.CodeMirror-lines',
placement: 'bottom', placement: 'bottom',
delay: { 'show': 500, 'hide': 100 } delay: { show: 500, hide: 100 }
}) })
// clear tooltip which described element has been removed // clear tooltip which described element has been removed
$('[id^="tooltip"]').each(function (index, element) { $('[id^="tooltip"]').each(function (index, element) {
@ -2063,7 +2064,7 @@ var cmClient = null
var synchronized_ = null var synchronized_ = null
function havePendingOperation () { function havePendingOperation () {
return !!((cmClient && cmClient.state && cmClient.state.hasOwnProperty('outstanding'))) return !!((cmClient && cmClient.state && Object.hasOwnProperty.call(cmClient.state, 'outstanding')))
} }
socket.on('doc', function (obj) { socket.on('doc', function (obj) {
@ -2223,7 +2224,7 @@ function updateOnlineStatus () {
break break
} }
} }
let id = items[i].values().id const id = items[i].values().id
if (found) { if (found) {
onlineUserList.get('id', id)[0].values(_onlineUsers[foundindex]) onlineUserList.get('id', id)[0].values(_onlineUsers[foundindex])
shortOnlineUserList.get('id', id)[0].values(_onlineUsers[foundindex]) shortOnlineUserList.get('id', id)[0].values(_onlineUsers[foundindex])
@ -2417,19 +2418,19 @@ function buildCursor (user) {
break break
} }
if ($('div[data-clientid="' + user.id + '"]').length <= 0) { if ($('div[data-clientid="' + user.id + '"]').length <= 0) {
let cursor = $('<div data-clientid="' + user.id + '" class="CodeMirror-other-cursor" style="display:none;"></div>') const cursor = $('<div data-clientid="' + user.id + '" class="CodeMirror-other-cursor" style="display:none;"></div>')
cursor.attr('data-line', user.cursor.line) cursor.attr('data-line', user.cursor.line)
cursor.attr('data-ch', user.cursor.ch) cursor.attr('data-ch', user.cursor.ch)
cursor.attr('data-offset-left', 0) cursor.attr('data-offset-left', 0)
cursor.attr('data-offset-top', 0) cursor.attr('data-offset-top', 0)
let cursorbar = $('<div class="cursorbar">&nbsp;</div>') const cursorbar = $('<div class="cursorbar">&nbsp;</div>')
cursorbar[0].style.height = defaultTextHeight + 'px' cursorbar[0].style.height = defaultTextHeight + 'px'
cursorbar[0].style.borderLeft = '2px solid ' + user.color cursorbar[0].style.borderLeft = '2px solid ' + user.color
var icon = '<i class="fa ' + iconClass + '"></i>' var icon = '<i class="fa ' + iconClass + '"></i>'
let cursortag = $('<div class="cursortag">' + icon + '&nbsp;<span class="name">' + user.name + '</span></div>') const cursortag = $('<div class="cursortag">' + icon + '&nbsp;<span class="name">' + user.name + '</span></div>')
// cursortag[0].style.background = color; // cursortag[0].style.background = color;
cursortag[0].style.color = user.color cursortag[0].style.color = user.color
@ -2485,15 +2486,15 @@ function buildCursor (user) {
checkCursorTag(coord, cursortag) checkCursorTag(coord, cursortag)
} else { } else {
let cursor = $('div[data-clientid="' + user.id + '"]') const cursor = $('div[data-clientid="' + user.id + '"]')
cursor.attr('data-line', user.cursor.line) cursor.attr('data-line', user.cursor.line)
cursor.attr('data-ch', user.cursor.ch) cursor.attr('data-ch', user.cursor.ch)
let cursorbar = cursor.find('.cursorbar') const cursorbar = cursor.find('.cursorbar')
cursorbar[0].style.height = defaultTextHeight + 'px' cursorbar[0].style.height = defaultTextHeight + 'px'
cursorbar[0].style.borderLeft = '2px solid ' + user.color cursorbar[0].style.borderLeft = '2px solid ' + user.color
let cursortag = cursor.find('.cursortag') const cursortag = cursor.find('.cursortag')
cursortag.find('i').removeClass().addClass('fa').addClass(iconClass) cursortag.find('i').removeClass().addClass('fa').addClass(iconClass)
cursortag.find('.name').text(user.name) cursortag.find('.name').text(user.name)
@ -2502,8 +2503,8 @@ function buildCursor (user) {
cursor[0].style.top = coord.top + 'px' cursor[0].style.top = coord.top + 'px'
} else { } else {
cursor.animate({ cursor.animate({
'left': coord.left, left: coord.left,
'top': coord.top top: coord.top
}, { }, {
duration: cursorAnimatePeriod, duration: cursorAnimatePeriod,
queue: false queue: false
@ -2712,8 +2713,8 @@ function restoreInfo () {
$(window).scrollLeft(lastInfo.edit.scroll.left) $(window).scrollLeft(lastInfo.edit.scroll.left)
$(window).scrollTop(lastInfo.edit.scroll.top) $(window).scrollTop(lastInfo.edit.scroll.top)
} else { } else {
let left = lastInfo.edit.scroll.left const left = lastInfo.edit.scroll.left
let top = lastInfo.edit.scroll.top const top = lastInfo.edit.scroll.top
editor.scrollIntoView() editor.scrollIntoView()
editor.scrollTo(left, top) editor.scrollTo(left, top)
} }
@ -2723,8 +2724,8 @@ function restoreInfo () {
$(window).scrollTop(lastInfo.view.scroll.top) $(window).scrollTop(lastInfo.view.scroll.top)
break break
case modeType.both: case modeType.both:
let left = lastInfo.edit.scroll.left const left = lastInfo.edit.scroll.left
let top = lastInfo.edit.scroll.top const top = lastInfo.edit.scroll.top
editor.scrollIntoView() editor.scrollIntoView()
editor.scrollTo(left, top) editor.scrollTo(left, top)
ui.area.view.scrollLeft(lastInfo.view.scroll.left) ui.area.view.scrollLeft(lastInfo.view.scroll.left)
@ -2846,8 +2847,8 @@ function partialUpdate (src, tar, des) {
for (let i = 0; i < tar.length; i++) { for (let i = 0; i < tar.length; i++) {
// copyAttribute(src[i], des[i], 'data-startline'); // copyAttribute(src[i], des[i], 'data-startline');
// copyAttribute(src[i], des[i], 'data-endline'); // copyAttribute(src[i], des[i], 'data-endline');
let rawSrc = cloneAndRemoveDataAttr(src[i]) const rawSrc = cloneAndRemoveDataAttr(src[i])
let rawTar = cloneAndRemoveDataAttr(tar[i]) const rawTar = cloneAndRemoveDataAttr(tar[i])
if (!rawSrc || !rawTar || rawSrc.outerHTML !== rawTar.outerHTML) { if (!rawSrc || !rawTar || rawSrc.outerHTML !== rawTar.outerHTML) {
start = i start = i
break break
@ -2859,8 +2860,8 @@ function partialUpdate (src, tar, des) {
for (let i = 0; i < src.length; i++) { for (let i = 0; i < src.length; i++) {
// copyAttribute(src[i], des[i], 'data-startline'); // copyAttribute(src[i], des[i], 'data-startline');
// copyAttribute(src[i], des[i], 'data-endline'); // copyAttribute(src[i], des[i], 'data-endline');
let rawSrc = cloneAndRemoveDataAttr(src[i]) const rawSrc = cloneAndRemoveDataAttr(src[i])
let rawTar = cloneAndRemoveDataAttr(tar[i]) const rawTar = cloneAndRemoveDataAttr(tar[i])
if (!rawSrc || !rawTar || rawSrc.outerHTML !== rawTar.outerHTML) { if (!rawSrc || !rawTar || rawSrc.outerHTML !== rawTar.outerHTML) {
start = i start = i
break break
@ -2868,12 +2869,12 @@ function partialUpdate (src, tar, des) {
} }
// tar end // tar end
for (let i = 1; i <= tar.length + 1; i++) { for (let i = 1; i <= tar.length + 1; i++) {
let srcLength = src.length const srcLength = src.length
let tarLength = tar.length const tarLength = tar.length
// copyAttribute(src[srcLength - i], des[srcLength - i], 'data-startline'); // copyAttribute(src[srcLength - i], des[srcLength - i], 'data-startline');
// copyAttribute(src[srcLength - i], des[srcLength - i], 'data-endline'); // copyAttribute(src[srcLength - i], des[srcLength - i], 'data-endline');
let rawSrc = cloneAndRemoveDataAttr(src[srcLength - i]) const rawSrc = cloneAndRemoveDataAttr(src[srcLength - i])
let rawTar = cloneAndRemoveDataAttr(tar[tarLength - i]) const rawTar = cloneAndRemoveDataAttr(tar[tarLength - i])
if (!rawSrc || !rawTar || rawSrc.outerHTML !== rawTar.outerHTML) { if (!rawSrc || !rawTar || rawSrc.outerHTML !== rawTar.outerHTML) {
tarEnd = tar.length - i tarEnd = tar.length - i
break break
@ -2881,12 +2882,12 @@ function partialUpdate (src, tar, des) {
} }
// src end // src end
for (let i = 1; i <= src.length + 1; i++) { for (let i = 1; i <= src.length + 1; i++) {
let srcLength = src.length const srcLength = src.length
let tarLength = tar.length const tarLength = tar.length
// copyAttribute(src[srcLength - i], des[srcLength - i], 'data-startline'); // copyAttribute(src[srcLength - i], des[srcLength - i], 'data-startline');
// copyAttribute(src[srcLength - i], des[srcLength - i], 'data-endline'); // copyAttribute(src[srcLength - i], des[srcLength - i], 'data-endline');
let rawSrc = cloneAndRemoveDataAttr(src[srcLength - i]) const rawSrc = cloneAndRemoveDataAttr(src[srcLength - i])
let rawTar = cloneAndRemoveDataAttr(tar[tarLength - i]) const rawTar = cloneAndRemoveDataAttr(tar[tarLength - i])
if (!rawSrc || !rawTar || rawSrc.outerHTML !== rawTar.outerHTML) { if (!rawSrc || !rawTar || rawSrc.outerHTML !== rawTar.outerHTML) {
srcEnd = src.length - i srcEnd = src.length - i
break break
@ -3317,22 +3318,22 @@ $(editor.getInputField())
'textComplete:show': function (e) { 'textComplete:show': function (e) {
$(this).data('autocompleting', true) $(this).data('autocompleting', true)
editor.setOption('extraKeys', { editor.setOption('extraKeys', {
'Up': function () { Up: function () {
return false return false
}, },
'Right': function () { Right: function () {
editor.doc.cm.execCommand('goCharRight') editor.doc.cm.execCommand('goCharRight')
}, },
'Down': function () { Down: function () {
return false return false
}, },
'Left': function () { Left: function () {
editor.doc.cm.execCommand('goCharLeft') editor.doc.cm.execCommand('goCharLeft')
}, },
'Enter': function () { Enter: function () {
return false return false
}, },
'Backspace': function () { Backspace: function () {
editor.doc.cm.execCommand('delCharBefore') editor.doc.cm.execCommand('delCharBefore')
} }
}) })

View File

@ -1,6 +1,6 @@
import modeType from './modeType' import modeType from './modeType'
let state = { const state = {
syncscroll: true, syncscroll: true,
currentMode: modeType.view, currentMode: modeType.view,
nightMode: false nightMode: false

View File

@ -1,4 +1,4 @@
let config = { const config = {
docmaxlength: null docmaxlength: null
} }

View File

@ -76,8 +76,8 @@ export default class Editor {
}, },
'Cmd-Left': 'goLineLeftSmart', 'Cmd-Left': 'goLineLeftSmart',
'Cmd-Right': 'goLineRight', 'Cmd-Right': 'goLineRight',
'Home': 'goLineLeftSmart', Home: 'goLineLeftSmart',
'End': 'goLineRight', End: 'goLineRight',
'Ctrl-C': function (cm) { 'Ctrl-C': function (cm) {
if (!isMac && cm.getOption('keyMap').substr(0, 3) === 'vim') { if (!isMac && cm.getOption('keyMap').substr(0, 3) === 'vim') {
document.execCommand('copy') document.execCommand('copy')
@ -513,6 +513,7 @@ export default class Editor {
this.jumpToAddressBarKeymapValue = null this.jumpToAddressBarKeymapValue = null
} }
} }
setOverrideBrowserKeymap () { setOverrideBrowserKeymap () {
var overrideBrowserKeymap = $( var overrideBrowserKeymap = $(
'.ui-preferences-override-browser-keymap label > input[type="checkbox"]' '.ui-preferences-override-browser-keymap label > input[type="checkbox"]'

View File

@ -4,17 +4,17 @@ export function wrapTextWith (editor, cm, symbol) {
if (!cm.getSelection()) { if (!cm.getSelection()) {
return CodeMirror.Pass return CodeMirror.Pass
} else { } else {
let ranges = cm.listSelections() const ranges = cm.listSelections()
for (let i = 0; i < ranges.length; i++) { for (let i = 0; i < ranges.length; i++) {
let range = ranges[i] const range = ranges[i]
if (!range.empty()) { if (!range.empty()) {
const from = range.from() const from = range.from()
const to = range.to() const to = range.to()
if (symbol !== 'Backspace') { if (symbol !== 'Backspace') {
let selection = cm.getRange(from, to) const selection = cm.getRange(from, to)
let anchorIndex = editor.indexFromPos(ranges[i].anchor) const anchorIndex = editor.indexFromPos(ranges[i].anchor)
let headIndex = editor.indexFromPos(ranges[i].head) const headIndex = editor.indexFromPos(ranges[i].head)
cm.replaceRange(symbol + selection + symbol, from, to, '+input') cm.replaceRange(symbol + selection + symbol, from, to, '+input')
if (anchorIndex > headIndex) { if (anchorIndex > headIndex) {
ranges[i].anchor.ch += symbol.length ranges[i].anchor.ch += symbol.length
@ -25,18 +25,18 @@ export function wrapTextWith (editor, cm, symbol) {
} }
cm.setSelections(ranges) cm.setSelections(ranges)
} else { } else {
let preEndPos = { const preEndPos = {
line: to.line, line: to.line,
ch: to.ch + symbol.length ch: to.ch + symbol.length
} }
let preText = cm.getRange(to, preEndPos) const preText = cm.getRange(to, preEndPos)
let preIndex = wrapSymbols.indexOf(preText) const preIndex = wrapSymbols.indexOf(preText)
let postEndPos = { const postEndPos = {
line: from.line, line: from.line,
ch: from.ch - symbol.length ch: from.ch - symbol.length
} }
let postText = cm.getRange(postEndPos, from) const postText = cm.getRange(postEndPos, from)
let postIndex = wrapSymbols.indexOf(postText) const postIndex = wrapSymbols.indexOf(postText)
// check if surround symbol are list in array and matched // check if surround symbol are list in array and matched
if (preIndex > -1 && postIndex > -1 && preIndex === postIndex) { if (preIndex > -1 && postIndex > -1 && preIndex === postIndex) {
cm.replaceRange('', to, preEndPos, '+delete') cm.replaceRange('', to, preEndPos, '+delete')
@ -49,25 +49,25 @@ export function wrapTextWith (editor, cm, symbol) {
} }
export function insertText (cm, text, cursorEnd = 0) { export function insertText (cm, text, cursorEnd = 0) {
let cursor = cm.getCursor() const cursor = cm.getCursor()
cm.replaceSelection(text, cursor, cursor) cm.replaceSelection(text, cursor, cursor)
cm.focus() cm.focus()
cm.setCursor({ line: cursor.line, ch: cursor.ch + cursorEnd }) cm.setCursor({ line: cursor.line, ch: cursor.ch + cursorEnd })
} }
export function insertLink (cm, isImage) { export function insertLink (cm, isImage) {
let cursor = cm.getCursor() const cursor = cm.getCursor()
let ranges = cm.listSelections() const ranges = cm.listSelections()
const linkEnd = '](https://)' const linkEnd = '](https://)'
const symbol = (isImage) ? '![' : '[' const symbol = (isImage) ? '![' : '['
for (let i = 0; i < ranges.length; i++) { for (let i = 0; i < ranges.length; i++) {
let range = ranges[i] const range = ranges[i]
if (!range.empty()) { if (!range.empty()) {
const from = range.from() const from = range.from()
const to = range.to() const to = range.to()
let anchorIndex = editor.indexFromPos(ranges[i].anchor) const anchorIndex = editor.indexFromPos(ranges[i].anchor)
let headIndex = editor.indexFromPos(ranges[i].head) const headIndex = editor.indexFromPos(ranges[i].head)
let selection = cm.getRange(from, to) let selection = cm.getRange(from, to)
selection = symbol + selection + linkEnd selection = symbol + selection + linkEnd
cm.replaceRange(selection, from, to) cm.replaceRange(selection, from, to)
@ -88,9 +88,9 @@ export function insertLink (cm, isImage) {
} }
export function insertHeader (cm) { export function insertHeader (cm) {
let cursor = cm.getCursor() const cursor = cm.getCursor()
let startOfLine = { line: cursor.line, ch: 0 } const startOfLine = { line: cursor.line, ch: 0 }
let startOfLineText = cm.getRange(startOfLine, { line: cursor.line, ch: 1 }) const startOfLineText = cm.getRange(startOfLine, { line: cursor.line, ch: 1 })
// See if it is already a header // See if it is already a header
if (startOfLineText === '#') { if (startOfLineText === '#') {
cm.replaceRange('#', startOfLine, startOfLine) cm.replaceRange('#', startOfLine, startOfLine)
@ -101,11 +101,11 @@ export function insertHeader (cm) {
} }
export function insertOnStartOfLines (cm, symbol) { export function insertOnStartOfLines (cm, symbol) {
let cursor = cm.getCursor() const cursor = cm.getCursor()
let ranges = cm.listSelections() const ranges = cm.listSelections()
for (let i = 0; i < ranges.length; i++) { for (let i = 0; i < ranges.length; i++) {
let range = ranges[i] const range = ranges[i]
if (!range.empty()) { if (!range.empty()) {
const from = range.from() const from = range.from()
const to = range.to() const to = range.to()

View File

@ -174,12 +174,12 @@ const buildMap = _.throttle(buildMapInner, buildMapThrottle)
// Optimizations are required only for big texts. // Optimizations are required only for big texts.
function buildMapInner (callback) { function buildMapInner (callback) {
if (!viewArea || !markdownArea) return if (!viewArea || !markdownArea) return
let i, offset, nonEmptyList, pos, a, b, _lineHeightMap, linesCount, acc, _scrollMap let i, pos, a, b, acc
offset = viewArea.scrollTop() - viewArea.offset().top const offset = viewArea.scrollTop() - viewArea.offset().top
_scrollMap = [] const _scrollMap = []
nonEmptyList = [] const nonEmptyList = []
_lineHeightMap = [] const _lineHeightMap = []
viewTop = 0 viewTop = 0
viewBottom = viewArea[0].scrollHeight - viewArea.height() viewBottom = viewArea[0].scrollHeight - viewArea.height()
@ -200,7 +200,7 @@ function buildMapInner (callback) {
acc += Math.round(h / lineHeight) acc += Math.round(h / lineHeight)
} }
_lineHeightMap.push(acc) _lineHeightMap.push(acc)
linesCount = acc const linesCount = acc
for (i = 0; i < linesCount; i++) { for (i = 0; i < linesCount; i++) {
_scrollMap.push(-1) _scrollMap.push(-1)
@ -350,11 +350,11 @@ export function syncScrollToView (event, preventAnimate) {
} }
if (viewScrolling) return if (viewScrolling) return
let lineNo, posTo let posTo
let topDiffPercent, posToNextDiff let topDiffPercent, posToNextDiff
const scrollInfo = editor.getScrollInfo() const scrollInfo = editor.getScrollInfo()
const textHeight = editor.defaultTextHeight() const textHeight = editor.defaultTextHeight()
lineNo = Math.floor(scrollInfo.top / textHeight) const lineNo = Math.floor(scrollInfo.top / textHeight)
// if reach the last line, will start lerp to the bottom // if reach the last line, will start lerp to the bottom
const diffToBottom = (scrollInfo.top + scrollInfo.clientHeight) - (scrollInfo.height - textHeight) const diffToBottom = (scrollInfo.top + scrollInfo.clientHeight) - (scrollInfo.height - textHeight)
if (scrollInfo.height > scrollInfo.clientHeight && diffToBottom > 0) { if (scrollInfo.height > scrollInfo.clientHeight && diffToBottom > 0) {

View File

@ -26,7 +26,7 @@ function extend () {
for (const source of arguments) { for (const source of arguments) {
for (const key in source) { for (const key in source) {
if (source.hasOwnProperty(key)) { if (Object.hasOwnProperty.call(source, key)) {
target[key] = source[key] target[key] = source[key]
} }
} }
@ -74,17 +74,17 @@ const defaultOptions = {
const meta = JSON.parse($('#meta').text()) const meta = JSON.parse($('#meta').text())
var options = meta.slideOptions || {} var options = meta.slideOptions || {}
if (options.hasOwnProperty('spotlight')) { if (Object.hasOwnProperty.call(options, 'spotlight')) {
defaultOptions.dependencies.push({ defaultOptions.dependencies.push({
src: `${serverurl}/build/reveal.js/plugin/spotlight/spotlight.js` src: `${serverurl}/build/reveal.js/plugin/spotlight/spotlight.js`
}) })
} }
if (options.hasOwnProperty('allottedTime') || options.hasOwnProperty('allottedMinutes')) { if (Object.hasOwnProperty.call(options, 'allottedTime') || Object.hasOwnProperty.call(options, 'allottedMinutes')) {
defaultOptions.dependencies.push({ defaultOptions.dependencies.push({
src: `${serverurl}/build/reveal.js/plugin/elapsed-time-bar/elapsed-time-bar.js` src: `${serverurl}/build/reveal.js/plugin/elapsed-time-bar/elapsed-time-bar.js`
}) })
if (options.hasOwnProperty('allottedMinutes')) { if (Object.hasOwnProperty.call(options, 'allottedMinutes')) {
options.allottedTime = options.allottedMinutes * 60 * 1000 options.allottedTime = options.allottedMinutes * 60 * 1000
} }
} }
@ -123,14 +123,14 @@ window.viewAjaxCallback = () => {
function renderSlide (event) { function renderSlide (event) {
if (window.location.search.match(/print-pdf/gi)) { if (window.location.search.match(/print-pdf/gi)) {
const slides = $('.slides') const slides = $('.slides')
let title = document.title const title = document.title
finishView(slides) finishView(slides)
document.title = title document.title = title
Reveal.layout() Reveal.layout()
} else { } else {
const markdown = $(event.currentSlide) const markdown = $(event.currentSlide)
if (!markdown.attr('data-rendered')) { if (!markdown.attr('data-rendered')) {
let title = document.title const title = document.title
finishView(markdown) finishView(markdown)
markdown.attr('data-rendered', 'true') markdown.attr('data-rendered', 'true')
document.title = title document.title = title

View File

@ -1,28 +1,24 @@
import base64url from 'base64url' import base64url from 'base64url'
let uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
export function checkNoteIdValid (id) { export function checkNoteIdValid (id) {
let result = id.match(uuidRegex) const result = id.match(uuidRegex)
if (result && result.length === 1) { return !!(result && result.length === 1)
return true
} else {
return false
}
} }
export function encodeNoteId (id) { export function encodeNoteId (id) {
// remove dashes in UUID and encode in url-safe base64 // remove dashes in UUID and encode in url-safe base64
let str = id.replace(/-/g, '') const str = id.replace(/-/g, '')
let hexStr = Buffer.from(str, 'hex') const hexStr = Buffer.from(str, 'hex')
return base64url.encode(hexStr) return base64url.encode(hexStr)
} }
export function decodeNoteId (encodedId) { export function decodeNoteId (encodedId) {
// decode from url-safe base64 // decode from url-safe base64
let id = base64url.toBuffer(encodedId).toString('hex') const id = base64url.toBuffer(encodedId).toString('hex')
// add dashes between the UUID string parts // add dashes between the UUID string parts
let idParts = [] const idParts = []
idParts.push(id.substr(0, 8)) idParts.push(id.substr(0, 8))
idParts.push(id.substr(8, 4)) idParts.push(id.substr(8, 4))
idParts.push(id.substr(12, 4)) idParts.push(id.substr(12, 4))

View File

@ -1,13 +1,13 @@
<% if(useCDN) { %> <% if(useCDN) { %>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.4.0/velocity.min.js" integrity="sha256-bhm0lgEt6ITaZCDzZpkr/VXVrLa5RP4u9v2AYsbzSUk=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.5.2/velocity.min.js" integrity="sha256-bhm0lgEt6ITaZCDzZpkr/VXVrLa5RP4u9v2AYsbzSUk=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.0/js/bootstrap.min.js" integrity="sha256-kJrlY+s09+QoWjpkOrXXwhxeaoDz9FW5SaxF8I0DibQ=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.0/js/bootstrap.min.js" integrity="sha256-kJrlY+s09+QoWjpkOrXXwhxeaoDz9FW5SaxF8I0DibQ=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/list.pagination.js/0.1.1/list.pagination.min.js" integrity="sha256-WwTza96H3BgcQTfEfxX7MFaFc/dZA0QrPRKDRLdFHJo=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/list.pagination.js/0.1.1/list.pagination.min.js" integrity="sha256-WwTza96H3BgcQTfEfxX7MFaFc/dZA0QrPRKDRLdFHJo=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.min.js" integrity="sha256-HzzZFiY4t0PIv02Tm8/R3CVvLpcjHhO1z/YAUCp4oQ4=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.min.js" integrity="sha256-HzzZFiY4t0PIv02Tm8/R3CVvLpcjHhO1z/YAUCp4oQ4=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment-with-locales.min.js" integrity="sha256-vvT7Ok9u6GbfnBPXnbM6FVDEO8E1kTdgHOFZOAXrktA=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js" integrity="sha256-vvT7Ok9u6GbfnBPXnbM6FVDEO8E1kTdgHOFZOAXrktA=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-url/2.3.0/url.min.js" integrity="sha256-HOZJz4x+1mn1Si84WT5XKXPtOlTytmZLnMb6n1v4+5Q=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/js-url/2.3.0/url.min.js" integrity="sha256-HOZJz4x+1mn1Si84WT5XKXPtOlTytmZLnMb6n1v4+5Q=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/1000hz-bootstrap-validator/0.11.8/validator.min.js" integrity="sha256-LHeY7YoYJ0SSXbCx7sR14Pqna+52moaH3bhv0Mjzd/M=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/1000hz-bootstrap-validator/0.11.8/validator.min.js" integrity="sha256-LHeY7YoYJ0SSXbCx7sR14Pqna+52moaH3bhv0Mjzd/M=" crossorigin="anonymous" defer></script>
<%- include ../build/cover-scripts %> <%- include ../build/cover-scripts %>
<% } else { %> <% } else { %>
<%- include ../build/cover-pack-scripts %> <%- include ../build/cover-pack-scripts %>
<% } %> <% } %>

View File

@ -13,8 +13,8 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.0/css/bootstrap.min.css" integrity="sha256-H0KfTigpUV+0/5tn2HXC0CPwhhDhWgSawJdnFd0CGCo=" crossorigin="anonymous" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.0/css/bootstrap.min.css" integrity="sha256-H0KfTigpUV+0/5tn2HXC0CPwhhDhWgSawJdnFd0CGCo=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fork-awesome/1.1.3/css/fork-awesome.min.css" integrity="sha256-ZhApazu+kejqTYhMF+1DzNKjIzP7KXu6AzyXcC1gMus=" crossorigin="anonymous" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fork-awesome/1.1.3/css/fork-awesome.min.css" integrity="sha256-ZhApazu+kejqTYhMF+1DzNKjIzP7KXu6AzyXcC1gMus=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-social/4.9.0/bootstrap-social.min.css" integrity="sha256-02JtFTurpwBjQJ6q13iJe82/NF0RbZlJroDegK5g87Y=" crossorigin="anonymous" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-social/4.9.0/bootstrap-social.min.css" integrity="sha256-02JtFTurpwBjQJ6q13iJe82/NF0RbZlJroDegK5g87Y=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2.min.css" integrity="sha256-ijlUKKj3hJCiiT2HWo1kqkI79NTEYpzOsw5Rs3k42dI=" crossorigin="anonymous" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2.min.css" integrity="sha256-ijlUKKj3hJCiiT2HWo1kqkI79NTEYpzOsw5Rs3k42dI=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2-bootstrap.min.css" integrity="sha256-NAWFcNIZdH+TS1xpWujF/EB/Y8gwBbEOCoaK/eqaer8=" crossorigin="anonymous" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.2/select2-bootstrap.min.css" integrity="sha256-NAWFcNIZdH+TS1xpWujF/EB/Y8gwBbEOCoaK/eqaer8=" crossorigin="anonymous" />
<%- include ../build/cover-header %> <%- include ../build/cover-header %>
<%- include ../shared/polyfill %> <%- include ../shared/polyfill %>
<% } else { %> <% } else { %>

View File

@ -16,7 +16,7 @@
<link rel="apple-touch-icon" href="<%- serverURL %>/apple-touch-icon.png"> <link rel="apple-touch-icon" href="<%- serverURL %>/apple-touch-icon.png">
<% if(useCDN) { %> <% if(useCDN) { %>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fork-awesome/1.1.3/css/fork-awesome.min.css" integrity="sha256-ZhApazu+kejqTYhMF+1DzNKjIzP7KXu6AzyXcC1gMus=" crossorigin="anonymous" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fork-awesome/1.1.7/css/fork-awesome.min.css" integrity="sha256-ZhApazu+kejqTYhMF+1DzNKjIzP7KXu6AzyXcC1gMus=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css" integrity="sha256-3iu9jgsy9TpTwXKb7bNQzqWekRX7pPK+2OLj3R922fo=" crossorigin="anonymous" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/ionicons/2.0.1/css/ionicons.min.css" integrity="sha256-3iu9jgsy9TpTwXKb7bNQzqWekRX7pPK+2OLj3R922fo=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.7.0/css/reveal.min.css" integrity="sha256-9+Wg2bcNeiOMGXOUNqBdceY2lAH/eCiTDcdzHhHIl48=" crossorigin="anonymous" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.7.0/css/reveal.min.css" integrity="sha256-9+Wg2bcNeiOMGXOUNqBdceY2lAH/eCiTDcdzHhHIl48=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/emojify.js/1.1.0/css/basic/emojify.min.css" integrity="sha256-UOrvMOsSDSrW6szVLe8ZDZezBxh5IoIfgTwdNDgTjiU=" crossorigin="anonymous" /> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/emojify.js/1.1.0/css/basic/emojify.min.css" integrity="sha256-UOrvMOsSDSrW6szVLe8ZDZezBxh5IoIfgTwdNDgTjiU=" crossorigin="anonymous" />
@ -90,20 +90,20 @@
<% if(useCDN) { %> <% if(useCDN) { %>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.7.0/lib/js/head.min.js" integrity="sha256-CTcwyen1cxIrm4hlqdxe0y7Hq6B0rpxAKLiXMD3dJv0=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.7.0/lib/js/head.min.js" integrity="sha256-CTcwyen1cxIrm4hlqdxe0y7Hq6B0rpxAKLiXMD3dJv0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.7.0/js/reveal.min.js" integrity="sha256-Xr6ZH+/kc7hDVReZLO5khBknteLqu5oen/xnSraXrVk=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/reveal.js/3.7.0/js/reveal.min.js" integrity="sha256-Xr6ZH+/kc7hDVReZLO5khBknteLqu5oen/xnSraXrVk=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.4.0/velocity.min.js" integrity="sha256-bhm0lgEt6ITaZCDzZpkr/VXVrLa5RP4u9v2AYsbzSUk=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.5.2/velocity.min.js" integrity="sha256-bhm0lgEt6ITaZCDzZpkr/VXVrLa5RP4u9v2AYsbzSUk=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.min.js" integrity="sha256-jnOjDTXIPqall8M0MyTSt98JetJuZ7Yu+1Jm7hLTF7U=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.min.js" integrity="sha256-jnOjDTXIPqall8M0MyTSt98JetJuZ7Yu+1Jm7hLTF7U=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/3.7.0/js-yaml.min.js" integrity="sha256-8PanqYAVOGlOct+i65R+HqibK3KPsXINnrSfxN+Y/J0=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/3.13.1/js-yaml.min.js" integrity="sha256-8PanqYAVOGlOct+i65R+HqibK3KPsXINnrSfxN+Y/J0=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js" integrity="sha256-yYfngbEKv4RENfGDvNUqJTqGFcKf31NJEe9OTnnMH3Y=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-yYfngbEKv4RENfGDvNUqJTqGFcKf31NJEe9OTnnMH3Y=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-immzXfCGLhnx3Zfi9F/dUcqxEM8K3o3oTFy9Bh6HCwg=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-immzXfCGLhnx3Zfi9F/dUcqxEM8K3o3oTFy9Bh6HCwg=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/config/Safe.js" integrity="sha256-0ygBUDksNDXZS4vm5HMNH1a33KUu6QT1cdNTN+ZLF+4=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/config/Safe.js" integrity="sha256-0ygBUDksNDXZS4vm5HMNH1a33KUu6QT1cdNTN+ZLF+4=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment-with-locales.min.js" integrity="sha256-vvT7Ok9u6GbfnBPXnbM6FVDEO8E1kTdgHOFZOAXrktA=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js" integrity="sha256-vvT7Ok9u6GbfnBPXnbM6FVDEO8E1kTdgHOFZOAXrktA=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/8.2.3/mermaid.min.js" integrity="sha256-4s3fF5e1iWRLtiV7mRev7n17oALqqDHbWrNqF3/r7jU=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/8.2.3/mermaid.min.js" integrity="sha256-4s3fF5e1iWRLtiV7mRev7n17oALqqDHbWrNqF3/r7jU=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/emojify.js/1.1.0/js/emojify.min.js" integrity="sha256-VAB5tAlKBvgaxw8oJ1crWMVbdmBVl4mP/2M8MNRl+4E=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/emojify.js/1.1.0/js/emojify.min.js" integrity="sha256-VAB5tAlKBvgaxw8oJ1crWMVbdmBVl4mP/2M8MNRl+4E=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.6/handlebars.min.js" integrity="sha256-1O3BtOwnPyyRzOszK6P+gqaRoXHV6JXj8HkjZmPYhCI=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.1.2/handlebars.min.js" integrity="sha256-1O3BtOwnPyyRzOszK6P+gqaRoXHV6JXj8HkjZmPYhCI=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js" integrity="sha256-/BfiIkHlHoVihZdc6TFuj7MmJ0TWcWsMXkeDFwhi0zw=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.9/highlight.min.js" integrity="sha256-/BfiIkHlHoVihZdc6TFuj7MmJ0TWcWsMXkeDFwhi0zw=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gist-embed/2.6.0/gist-embed.min.js" integrity="sha256-KyF2D6xPIJUW5sUDSs93vWyZm+1RzIpKCexxElmxl8g=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gist-embed/2.6.0/gist-embed.min.js" integrity="sha256-KyF2D6xPIJUW5sUDSs93vWyZm+1RzIpKCexxElmxl8g=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/viz.js/1.7.0/viz.js" integrity="sha256-8t+rndrF+TU4JtelmOH1lDHTMe2ovhO2UbzDArp5lY8=" crossorigin="anonymous" defer></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/viz.js/2.1.2/viz.js" integrity="sha256-8t+rndrF+TU4JtelmOH1lDHTMe2ovhO2UbzDArp5lY8=" crossorigin="anonymous" defer></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/abcjs/3.1.1/abcjs_basic-min.js" integrity="sha256-Sq1r2XXWXQoShQKsS0Wrf5r7fRkErd9Fat9vHYeU68s=" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/abcjs/3.1.1/abcjs_basic-min.js" integrity="sha256-Sq1r2XXWXQoShQKsS0Wrf5r7fRkErd9Fat9vHYeU68s=" crossorigin="anonymous"></script>
<%- include build/slide-scripts %> <%- include build/slide-scripts %>
<% } else { %> <% } else { %>

View File

@ -43,7 +43,7 @@ describe('Content security policies', function () {
// beginnging Tests // beginnging Tests
it('Disable CDN', function () { it('Disable CDN', function () {
let testconfig = defaultConfig const testconfig = defaultConfig
testconfig.useCDN = false testconfig.useCDN = false
mock('../lib/config', testconfig) mock('../lib/config', testconfig)
csp = mock.reRequire('../lib/csp') csp = mock.reRequire('../lib/csp')
@ -57,7 +57,7 @@ describe('Content security policies', function () {
}) })
it('Disable Google Analytics', function () { it('Disable Google Analytics', function () {
let testconfig = defaultConfig const testconfig = defaultConfig
testconfig.csp.addGoogleAnalytics = false testconfig.csp.addGoogleAnalytics = false
mock('../lib/config', testconfig) mock('../lib/config', testconfig)
csp = mock.reRequire('../lib/csp') csp = mock.reRequire('../lib/csp')
@ -66,7 +66,7 @@ describe('Content security policies', function () {
}) })
it('Disable Disqus', function () { it('Disable Disqus', function () {
let testconfig = defaultConfig const testconfig = defaultConfig
testconfig.csp.addDisqus = false testconfig.csp.addDisqus = false
mock('../lib/config', testconfig) mock('../lib/config', testconfig)
csp = mock.reRequire('../lib/csp') csp = mock.reRequire('../lib/csp')
@ -79,7 +79,7 @@ describe('Content security policies', function () {
}) })
it('Set ReportURI', function () { it('Set ReportURI', function () {
let testconfig = defaultConfig const testconfig = defaultConfig
testconfig.csp.reportURI = 'https://example.com/reportURI' testconfig.csp.reportURI = 'https://example.com/reportURI'
mock('../lib/config', testconfig) mock('../lib/config', testconfig)
csp = mock.reRequire('../lib/csp') csp = mock.reRequire('../lib/csp')
@ -88,7 +88,7 @@ describe('Content security policies', function () {
}) })
it('Set own directives', function () { it('Set own directives', function () {
let testconfig = defaultConfig const testconfig = defaultConfig
mock('../lib/config', defaultConfig) mock('../lib/config', defaultConfig)
csp = mock.reRequire('../lib/csp') csp = mock.reRequire('../lib/csp')
const unextendedCSP = csp.computeDirectives() const unextendedCSP = csp.computeDirectives()

View File

@ -9,7 +9,7 @@ describe('generateAvatarURL() gravatar enabled', function () {
let avatars let avatars
beforeEach(function () { beforeEach(function () {
// Reset config to make sure we don't influence other tests // Reset config to make sure we don't influence other tests
let testconfig = { const testconfig = {
allowGravatar: true, allowGravatar: true,
serverURL: 'http://localhost:3000', serverURL: 'http://localhost:3000',
port: 3000 port: 3000
@ -32,7 +32,7 @@ describe('generateAvatarURL() gravatar disabled', function () {
let avatars let avatars
beforeEach(function () { beforeEach(function () {
// Reset config to make sure we don't influence other tests // Reset config to make sure we don't influence other tests
let testconfig = { const testconfig = {
allowGravatar: false, allowGravatar: false,
serverURL: 'http://localhost:3000', serverURL: 'http://localhost:3000',
port: 3000 port: 3000

View File

@ -49,8 +49,8 @@ describe('cleanDanglingUser', function () {
connected: {} connected: {}
} }
} }
let user1Socket = makeMockSocket() const user1Socket = makeMockSocket()
let user2Socket = makeMockSocket() const user2Socket = makeMockSocket()
user1Socket.rooms.push('room1') user1Socket.rooms.push('room1')

View File

@ -124,7 +124,7 @@ describe('realtime#connection', function () {
const emitRefreshStub = sinon.stub(realtime, 'emitRefresh') const emitRefreshStub = sinon.stub(realtime, 'emitRefresh')
const failConnectionSpy = sinon.spy(realtime, 'failConnection') const failConnectionSpy = sinon.spy(realtime, 'failConnection')
let note = { const note = {
id: noteId, id: noteId,
authors: [ authors: [
{ {

View File

@ -57,7 +57,7 @@ describe('realtime#update note is dirty timer', function () {
socks: [] socks: []
} }
let note2 = { const note2 = {
server: { server: {
isDirty: true isDirty: true
}, },
@ -79,7 +79,7 @@ describe('realtime#update note is dirty timer', function () {
callback(null, note) callback(null, note)
}) })
let note = { const note = {
server: { server: {
isDirty: true isDirty: true
}, },
@ -109,7 +109,7 @@ describe('realtime#update note is dirty timer', function () {
}) })
} }
let note = { const note = {
server: { server: {
isDirty: true isDirty: true
}, },

View File

@ -35,7 +35,7 @@ describe('realtime#extractNoteIdFromSocket', function () {
}) })
it('return false if query not set and referer not set', function () { it('return false if query not set and referer not set', function () {
let noteId = realtime.extractNoteIdFromSocket(makeMockSocket({ const noteId = realtime.extractNoteIdFromSocket(makeMockSocket({
otherHeader: 1 otherHeader: 1
}, { }, {
otherQuery: 1 otherQuery: 1

View File

@ -274,7 +274,7 @@ describe('realtime#socket event', function () {
onlineUsersFunc() onlineUsersFunc()
assert(clientSocket.emit.called) assert(clientSocket.emit.called)
assert(clientSocket.emit.lastCall.args[0] === 'online users') assert(clientSocket.emit.lastCall.args[0] === 'online users')
let returnUserList = clientSocket.emit.lastCall.args[1].users const returnUserList = clientSocket.emit.lastCall.args[1].users
assert(returnUserList.length === 2) assert(returnUserList.length === 2)
assert(returnUserList[0].id === 10) assert(returnUserList[0].id === 10)
assert(returnUserList[1].id === 20) assert(returnUserList[1].id === 20)
@ -444,8 +444,8 @@ describe('realtime#socket event', function () {
}) })
describe('permission', function () { describe('permission', function () {
let ownerId = 'user1_id' const ownerId = 'user1_id'
let otherSignInUserId = 'user2_id' const otherSignInUserId = 'user2_id'
let otherClient let otherClient
let checkViewPermissionSpy let checkViewPermissionSpy
let permissionFunc let permissionFunc

View File

@ -53,7 +53,7 @@ describe('realtime#updateNote', function () {
const callback = sinon.stub() const callback = sinon.stub()
const note = { const note = {
tempUsers: { tempUsers: {
'user1': Date.now() user1: Date.now()
} }
} }
realtime.updateNote(note, callback) realtime.updateNote(note, callback)

View File

@ -238,7 +238,6 @@ module.exports = {
], ],
'index-pack': [ 'index-pack': [
'babel-polyfill', 'babel-polyfill',
'expose-loader?Spinner!spin.js',
'script-loader!jquery-ui-resizable', 'script-loader!jquery-ui-resizable',
'bootstrap-validator', 'bootstrap-validator',
'expose-loader?jsyaml!js-yaml', 'expose-loader?jsyaml!js-yaml',

2070
yarn.lock

File diff suppressed because it is too large Load Diff