mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 13:01:31 +08:00 
			
		
		
		
	Merge remote-tracking branch 'origin/stable'
This commit is contained in:
		
						commit
						b51f5ac6fd
					
				| @ -251,8 +251,8 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|                     this.triggerCommand('setActiveScreen', {screen:'detail'}); | ||||
|                 } | ||||
|             }, | ||||
|             expand: (event, data) => this.setExpandedToServer(data.node.data.branchId, true), | ||||
|             collapse: (event, data) => this.setExpandedToServer(data.node.data.branchId, false), | ||||
|             expand: (event, data) => this.setExpanded(data.node.data.branchId, true), | ||||
|             collapse: (event, data) => this.setExpanded(data.node.data.branchId, false), | ||||
|             hotkeys: utils.isMobile() ? undefined : { keydown: await this.getHotKeys() }, | ||||
|             dnd5: { | ||||
|                 autoExpandMS: 600, | ||||
| @ -932,12 +932,13 @@ export default class NoteTreeWidget extends TabAwareWidget { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     async setExpandedToServer(branchId, isExpanded) { | ||||
|     async setExpanded(branchId, isExpanded) { | ||||
|         utils.assertArguments(branchId); | ||||
| 
 | ||||
|         const expandedNum = isExpanded ? 1 : 0; | ||||
|         const branch = treeCache.getBranch(branchId); | ||||
|         branch.isExpanded = isExpanded; | ||||
| 
 | ||||
|         await server.put('branches/' + branchId + '/expanded/' + expandedNum); | ||||
|         await server.put(`branches/${branchId}/expanded/${isExpanded ? 1 : 0}`); | ||||
|     } | ||||
| 
 | ||||
|     async reloadTreeFromCache() { | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| "use strict"; | ||||
| 
 | ||||
| const noteService = require('../../services/notes'); | ||||
| const protectedSessionService = require('../../services/protected_session'); | ||||
| const repository = require('../../services/repository'); | ||||
| const utils = require('../../services/utils'); | ||||
| @ -45,7 +44,9 @@ async function downloadNoteFile(noteId, res, contentDisposition = true) { | ||||
|     if (contentDisposition) { | ||||
|         // (one) reason we're not using the originFileName (available as label) is that it's not
 | ||||
|         // available for older note revisions and thus would be inconsistent
 | ||||
|         res.setHeader('Content-Disposition', utils.getContentDisposition(note.title || "untitled")); | ||||
|         const filename = utils.formatDownloadTitle(note.title, note.type, note.mime); | ||||
| 
 | ||||
|         res.setHeader('Content-Disposition', utils.getContentDisposition(filename)); | ||||
|     } | ||||
| 
 | ||||
|     res.setHeader('Content-Type', note.mime); | ||||
|  | ||||
| @ -38,13 +38,7 @@ async function getNoteRevision(req) { | ||||
|  * @return {string} | ||||
|  */ | ||||
| function getRevisionFilename(noteRevision) { | ||||
|     let filename = noteRevision.title || "untitled"; | ||||
| 
 | ||||
|     if (noteRevision.type === 'text') { | ||||
|         filename += '.html'; | ||||
|     } else if (['relation-map', 'search'].includes(noteRevision.type)) { | ||||
|         filename += '.json'; | ||||
|     } | ||||
|     let filename = utils.formatDownloadTitle(noteRevision.title, noteRevision.type, noteRevision.mime); | ||||
| 
 | ||||
|     const extension = path.extname(filename); | ||||
|     const date = noteRevision.dateCreated | ||||
|  | ||||
| @ -13,6 +13,7 @@ const Attribute = require('../entities/attribute'); | ||||
| const hoistedNoteService = require('../services/hoisted_note'); | ||||
| const protectedSessionService = require('../services/protected_session'); | ||||
| const log = require('../services/log'); | ||||
| const utils = require('../services/utils'); | ||||
| const noteRevisionService = require('../services/note_revisions'); | ||||
| const attributeService = require('../services/attributes'); | ||||
| const request = require('./request'); | ||||
| @ -276,9 +277,9 @@ async function downloadImage(noteId, imageUrl) { | ||||
| const downloadImagePromises = {}; | ||||
| 
 | ||||
| function replaceUrl(content, url, imageNote) { | ||||
|     const quoted = url.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); | ||||
|     const quotedUrl = utils.quoteRegex(url); | ||||
| 
 | ||||
|     return content.replace(new RegExp(`\\s+src=[\"']${quoted}[\"']`, "g"), ` src="api/images/${imageNote.noteId}/${imageNote.title}"`); | ||||
|     return content.replace(new RegExp(`\\s+src=[\"']${quotedUrl}[\"']`, "g"), ` src="api/images/${imageNote.noteId}/${imageNote.title}"`); | ||||
| } | ||||
| 
 | ||||
| async function downloadImages(noteId, content) { | ||||
|  | ||||
| @ -5,6 +5,7 @@ const randtoken = require('rand-token').generator({source: 'crypto'}); | ||||
| const unescape = require('unescape'); | ||||
| const escape = require('escape-html'); | ||||
| const sanitize = require("sanitize-filename"); | ||||
| const mimeTypes = require('mime-types'); | ||||
| 
 | ||||
| function newEntityId() { | ||||
|     return randomString(12); | ||||
| @ -166,10 +167,46 @@ function isStringNote(type, mime) { | ||||
|         || STRING_MIME_TYPES.includes(mime); | ||||
| } | ||||
| 
 | ||||
| function replaceAll(string, replaceWhat, replaceWith) { | ||||
|     const escapedWhat = replaceWhat.replace(/([\/,!\\^${}\[\]().*+?|<>\-&])/g, "\\$&"); | ||||
| function quoteRegex(url) { | ||||
|     return url.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); | ||||
| } | ||||
| 
 | ||||
|     return string.replace(new RegExp(escapedWhat, "g"), replaceWith); | ||||
| function replaceAll(string, replaceWhat, replaceWith) { | ||||
|     const quotedReplaceWhat = quoteRegex(replaceWhat); | ||||
| 
 | ||||
|     return string.replace(new RegExp(quotedReplaceWhat, "g"), replaceWith); | ||||
| } | ||||
| 
 | ||||
| function formatDownloadTitle(filename, type, mime) { | ||||
|     if (!filename) { | ||||
|         filename = "untitled"; | ||||
|     } | ||||
| 
 | ||||
|     if (type === 'text') { | ||||
|         return filename + '.html'; | ||||
|     } else if (['relation-map', 'search'].includes(type)) { | ||||
|         return filename + '.json'; | ||||
|     } else { | ||||
|         if (!mime) { | ||||
|             return filename; | ||||
|         } | ||||
| 
 | ||||
|         mime = mime.toLowerCase(); | ||||
|         const filenameLc = filename.toLowerCase(); | ||||
|         const extensions = mimeTypes.extensions[mime]; | ||||
| 
 | ||||
|         if (!extensions || extensions.length === 0) { | ||||
|             return filename; | ||||
|         } | ||||
| 
 | ||||
|         for (const ext of extensions) { | ||||
|             if (filenameLc.endsWith('.' + ext)) { | ||||
|                 return filename; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         return filename + '.' + extensions[0]; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| module.exports = { | ||||
| @ -198,5 +235,7 @@ module.exports = { | ||||
|     sanitizeFilenameForHeader, | ||||
|     getContentDisposition, | ||||
|     isStringNote, | ||||
|     replaceAll | ||||
|     quoteRegex, | ||||
|     replaceAll, | ||||
|     formatDownloadTitle | ||||
| }; | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 zadam
						zadam