hedgedoc/public/js/history.js
Sheogorath 4da68597f7
Fix eslint warnings
Since we are about to release it's time to finally fix our linting. This
patch basically runs eslint --fix and does some further manual fixes.
Also it sets up eslint to fail on every warning on order to make
warnings visable in the CI process.

There should no functional change be introduced.

Signed-off-by: Sheogorath <sheogorath@shivering-isles.com>
2019-05-31 00:30:29 +02:00

307 lines
8 KiB
JavaScript

/* eslint-env browser, jquery */
/* eslint no-console: ["error", { allow: ["warn", "error", "debug"] }] */
/* global serverurl, moment */
import store from 'store'
import S from 'string'
import LZString from 'lz-string'
import url from 'wurl'
import {
checkNoteIdValid,
encodeNoteId
} from './utils'
import {
checkIfAuth
} from './lib/common/login'
import {
urlpath
} from './lib/config'
window.migrateHistoryFromTempCallback = null
migrateHistoryFromTemp()
function migrateHistoryFromTemp () {
if (url('#tempid')) {
$.get(`${serverurl}/temp`, {
tempid: url('#tempid')
})
.done(data => {
if (data && data.temp) {
getStorageHistory(olddata => {
if (!olddata || olddata.length === 0) {
saveHistoryToStorage(JSON.parse(data.temp))
}
})
}
})
.always(() => {
let hash = location.hash.split('#')[1]
hash = hash.split('&')
for (let i = 0; i < hash.length; i++) {
if (hash[i].indexOf('tempid') === 0) {
hash.splice(i, 1)
i--
}
}
hash = hash.join('&')
location.hash = hash
if (window.migrateHistoryFromTempCallback) { window.migrateHistoryFromTempCallback() }
})
}
}
export function saveHistory (notehistory) {
checkIfAuth(
() => {
saveHistoryToServer(notehistory)
},
() => {
saveHistoryToStorage(notehistory)
}
)
}
function saveHistoryToStorage (notehistory) {
store.set('notehistory', JSON.stringify(notehistory))
}
function saveHistoryToServer (notehistory) {
$.post(`${serverurl}/history`, {
history: JSON.stringify(notehistory)
})
}
export function saveStorageHistoryToServer (callback) {
const data = store.get('notehistory')
if (data) {
$.post(`${serverurl}/history`, {
history: data
})
.done(data => {
callback(data)
})
}
}
export function clearDuplicatedHistory (notehistory) {
const newnotehistory = []
for (let i = 0; i < notehistory.length; i++) {
let found = false
for (let j = 0; j < newnotehistory.length; j++) {
const id = notehistory[i].id.replace(/=+$/, '')
const newId = newnotehistory[j].id.replace(/=+$/, '')
if (id === newId || notehistory[i].id === newnotehistory[j].id || !notehistory[i].id || !newnotehistory[j].id) {
const time = (typeof notehistory[i].time === 'number' ? moment(notehistory[i].time) : moment(notehistory[i].time, 'MMMM Do YYYY, h:mm:ss a'))
const newTime = (typeof newnotehistory[i].time === 'number' ? moment(newnotehistory[i].time) : moment(newnotehistory[i].time, 'MMMM Do YYYY, h:mm:ss a'))
if (time >= newTime) {
newnotehistory[j] = notehistory[i]
}
found = true
break
}
}
if (!found) { newnotehistory.push(notehistory[i]) }
}
return newnotehistory
}
function addHistory (id, text, time, tags, pinned, notehistory) {
// only add when note id exists
if (id) {
notehistory.push({
id,
text,
time,
tags,
pinned
})
}
return notehistory
}
export function removeHistory (id, notehistory) {
for (let i = 0; i < notehistory.length; i++) {
if (notehistory[i].id === id) {
notehistory.splice(i, 1)
i -= 1
}
}
return notehistory
}
// used for inner
export function writeHistory (title, tags) {
checkIfAuth(
() => {
// no need to do this anymore, this will count from server-side
// writeHistoryToServer(title, tags);
},
() => {
writeHistoryToStorage(title, tags)
}
)
}
function writeHistoryToStorage (title, tags) {
let data = store.get('notehistory')
let notehistory
if (data && typeof data === 'string') {
notehistory = JSON.parse(data)
} else {
notehistory = []
}
const newnotehistory = generateHistory(title, tags, notehistory)
saveHistoryToStorage(newnotehistory)
}
if (!Array.isArray) {
Array.isArray = arg => Object.prototype.toString.call(arg) === '[object Array]'
}
function renderHistory (title, tags) {
// console.debug(tags);
const id = urlpath ? location.pathname.slice(urlpath.length + 1, location.pathname.length).split('/')[1] : location.pathname.split('/')[1]
return {
id,
text: title,
time: moment().valueOf(),
tags
}
}
function generateHistory (title, tags, notehistory) {
const info = renderHistory(title, tags)
// keep any pinned data
let pinned = false
for (let i = 0; i < notehistory.length; i++) {
if (notehistory[i].id === info.id && notehistory[i].pinned) {
pinned = true
break
}
}
notehistory = removeHistory(info.id, notehistory)
notehistory = addHistory(info.id, info.text, info.time, info.tags, pinned, notehistory)
notehistory = clearDuplicatedHistory(notehistory)
return notehistory
}
// used for outer
export function getHistory (callback) {
checkIfAuth(
() => {
getServerHistory(callback)
},
() => {
getStorageHistory(callback)
}
)
}
function getServerHistory (callback) {
$.get(`${serverurl}/history`)
.done(data => {
if (data.history) {
callback(data.history)
}
})
.fail((xhr, status, error) => {
console.error(xhr.responseText)
})
}
export function getStorageHistory (callback) {
let data = store.get('notehistory')
if (data) {
if (typeof data === 'string') { data = JSON.parse(data) }
callback(data)
}
// eslint-disable-next-line standard/no-callback-literal
callback([])
}
export function parseHistory (list, callback) {
checkIfAuth(
() => {
parseServerToHistory(list, callback)
},
() => {
parseStorageToHistory(list, callback)
}
)
}
export function parseServerToHistory (list, callback) {
$.get(`${serverurl}/history`)
.done(data => {
if (data.history) {
parseToHistory(list, data.history, callback)
}
})
.fail((xhr, status, error) => {
console.error(xhr.responseText)
})
}
export function parseStorageToHistory (list, callback) {
let data = store.get('notehistory')
if (data) {
if (typeof data === 'string') { data = JSON.parse(data) }
parseToHistory(list, data, callback)
}
parseToHistory(list, [], callback)
}
function parseToHistory (list, notehistory, callback) {
if (!callback) return
else if (!list || !notehistory) callback(list, notehistory)
else if (notehistory && notehistory.length > 0) {
for (let i = 0; i < notehistory.length; i++) {
// migrate LZString encoded id to base64url encoded id
try {
let id = LZString.decompressFromBase64(notehistory[i].id)
if (id && checkNoteIdValid(id)) {
notehistory[i].id = encodeNoteId(id)
}
} catch (err) {
console.error(err)
}
// parse time to timestamp and fromNow
const timestamp = (typeof notehistory[i].time === 'number' ? moment(notehistory[i].time) : moment(notehistory[i].time, 'MMMM Do YYYY, h:mm:ss a'))
notehistory[i].timestamp = timestamp.valueOf()
notehistory[i].fromNow = timestamp.fromNow()
notehistory[i].time = timestamp.format('llll')
// prevent XSS
notehistory[i].text = S(notehistory[i].text).escapeHTML().s
notehistory[i].tags = (notehistory[i].tags && notehistory[i].tags.length > 0) ? S(notehistory[i].tags).escapeHTML().s.split(',') : []
// add to list
if (notehistory[i].id && list.get('id', notehistory[i].id).length === 0) { list.add(notehistory[i]) }
}
}
callback(list, notehistory)
}
export function postHistoryToServer (noteId, data, callback) {
$.post(`${serverurl}/history/${noteId}`, data)
.done(result => callback(null, result))
.fail((xhr, status, error) => {
console.error(xhr.responseText)
return callback(error, null)
})
}
export function deleteServerHistory (noteId, callback) {
$.ajax({
url: `${serverurl}/history${noteId ? '/' + noteId : ''}`,
type: 'DELETE'
})
.done(result => callback(null, result))
.fail((xhr, status, error) => {
console.error(xhr.responseText)
return callback(error, null)
})
}