diff options
-rw-r--r-- | src/EditorFactory.js | 9 | ||||
-rw-r--r-- | src/components/EditorWrapper.vue | 2 | ||||
-rw-r--r-- | src/components/MenuBar.vue | 2 | ||||
-rw-r--r-- | src/components/PublicFilesEditor.vue | 6 | ||||
-rw-r--r-- | src/files.js | 19 | ||||
-rw-r--r-- | src/helpers/files.js (renamed from src/helpers.js) | 72 | ||||
-rw-r--r-- | src/helpers/index.js | 55 | ||||
-rw-r--r-- | src/helpers/mime.js | 48 | ||||
-rw-r--r-- | src/public.js | 12 | ||||
-rw-r--r-- | src/publicPlugins.js | 67 |
10 files changed, 142 insertions, 150 deletions
diff --git a/src/EditorFactory.js b/src/EditorFactory.js index c03742123..3072b7c7b 100644 --- a/src/EditorFactory.js +++ b/src/EditorFactory.js @@ -43,8 +43,13 @@ import { MarkdownSerializer, defaultMarkdownSerializer } from 'prosemirror-markd const loadSyntaxHighlight = async(languages) => { let modules = {} for (let i = 0; i < languages.length; i++) { - const lang = await import('highlight.js/lib/languages/' + languages[i]) - modules[languages[i]] = lang.default + try { + const lang = await import('highlight.js/lib/languages/' + languages[i]) + modules[languages[i]] = lang.default + } catch (e) { + // No matching highlighing found, fallback to none + return undefined + } } if (Object.keys(modules).length === 0 && modules.constructor === Object) { return undefined diff --git a/src/components/EditorWrapper.vue b/src/components/EditorWrapper.vue index 9f082668a..77b0f897c 100644 --- a/src/components/EditorWrapper.vue +++ b/src/components/EditorWrapper.vue @@ -179,7 +179,7 @@ export default { return this.mime === 'text/markdown' }, fileExtension() { - return this.relativePath.split('/').pop().split('.').pop() + return this.relativePath ? this.relativePath.split('/').pop().split('.').pop() : 'txt' } }, watch: { diff --git a/src/components/MenuBar.vue b/src/components/MenuBar.vue index 798921977..06d162ccf 100644 --- a/src/components/MenuBar.vue +++ b/src/components/MenuBar.vue @@ -67,7 +67,7 @@ import { EditorMenuBar } from 'tiptap' import Tooltip from 'nextcloud-vue/dist/Directives/Tooltip' import menuBarIcons from './../mixins/menubar' -import { fetchFileInfo } from './../helpers' +import { fetchFileInfo } from './../helpers/files' import Actions from 'nextcloud-vue/dist/Components/Actions' import ActionButton from 'nextcloud-vue/dist/Components/ActionButton' diff --git a/src/components/PublicFilesEditor.vue b/src/components/PublicFilesEditor.vue index 6991ad37c..6e8cb3b73 100644 --- a/src/components/PublicFilesEditor.vue +++ b/src/components/PublicFilesEditor.vue @@ -23,7 +23,7 @@ <template> <modal v-if="active" :title="fileName" @close="close"> <editor-wrapper :file-id="fileId" :relative-path="relativePath" :active="active" - :share-token="shareToken" /> + :share-token="shareToken" :mime="mimeType" /> </modal> </template> @@ -52,6 +52,10 @@ export default { shareToken: { type: String, default: null + }, + mimeType: { + type: String, + default: null } }, computed: { diff --git a/src/files.js b/src/files.js index a25cc8791..d7bd69a85 100644 --- a/src/files.js +++ b/src/files.js @@ -21,25 +21,12 @@ */ import FilesEditor from './components/FilesEditor' -import { registerFileActionFallback, registerFileCreate } from './helpers' +import { registerFileActionFallback, registerFileCreate } from './helpers/files' +import { openMimetypesMarkdown, openMimetypesPlainText } from './helpers/mime' __webpack_nonce__ = btoa(OC.requestToken) // eslint-disable-line __webpack_public_path__ = OC.linkTo('text', 'js/') // eslint-disable-line -const supportedTextMimeTypes = [ - 'text/plain', - 'application/cmd', - 'application/javascript', - 'application/json', - 'application/xml', - 'application/x-empty', - 'application/x-msdos-program', - 'application/x-php', - 'application/x-pearl', - 'application/x-text', - 'application/yaml' -] - document.addEventListener('DOMContentLoaded', () => { if (typeof OCA.Viewer === 'undefined') { console.error('Viewer app is not installed') @@ -48,7 +35,7 @@ document.addEventListener('DOMContentLoaded', () => { } OCA.Viewer.registerHandler({ id: 'text', - mimes: ['text/markdown', ...supportedTextMimeTypes], + mimes: [...openMimetypesMarkdown, ...openMimetypesPlainText], component: FilesEditor, group: null }) diff --git a/src/helpers.js b/src/helpers/files.js index defbf4e1b..53c282a68 100644 --- a/src/helpers.js +++ b/src/helpers/files.js @@ -12,7 +12,7 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License @@ -26,36 +26,9 @@ */ import axios from 'axios' import { generateRemoteUrl } from 'nextcloud-server/dist/router' +import { openMimetypes } from './mime' -const openFileExtensions = [ - 'md', 'markdown', 'txt' -] - -const openMimetypes = [ - 'text/markdown', 'text/plain' -] - -const documentReady = function(callback) { - const fn = () => setTimeout(callback, 0) - if (document.attachEvent ? document.readyState === 'complete' : document.readyState !== 'loading') { - fn() - } else { - document.addEventListener('DOMContentLoaded', callback) - } -} - -const _baseUrl = OC.generateUrl('/apps/text') -const endpointUrl = (endpoint, isPublic = false) => { - if (isPublic) { - return `${_baseUrl}/public/${endpoint}` - } - return `${_baseUrl}/${endpoint}` -} - -const randomGuestNames = ['Artichoke', 'Arugula', 'Asparagus', 'Avocado', 'Bamboo Shoot', 'Bean Sprout', 'Bean', 'Beet', 'Belgian Endive', 'Bell Pepper', 'Bitter Melon', 'Bitter Gourd', 'Bok Choy', 'Broccoli', 'Brussels Sprout', 'Burdock Root', 'Cabbage', 'Calabash', 'Caper', 'Carrot', 'Cassava', 'Cauliflower', 'Celery', 'Celery Root', 'Celtuce', 'Chayote', 'Chinese Broccoli', 'Corn', 'Baby Corn', 'Cucumber', 'English Cucumber', 'Gherkin', 'Pickling Cucumber', 'Daikon Radish', 'Edamame', 'Eggplant', 'Elephant Garlic', 'Endive', 'Curly', 'Escarole', 'Fennel', 'Fiddlehead', 'Galangal', 'Garlic', 'Ginger', 'Grape Leave', 'Green Bean', 'Wax Bean', 'Green', 'Amaranth Leave', 'Beet Green', 'Collard Green', 'Dandelion Green', 'Kale', 'Kohlrabi Green', 'Mustard Green', 'Rapini', 'Spinach', 'Swiss Chard', 'Turnip Green', 'Hearts of Palm', 'Horseradish', 'Jerusalem Artichoke', 'Jícama', 'Kale', 'Curly', 'Lacinato', 'Ornamental', 'Kohlrabi', 'Leeks', 'Lemongrass', 'Lettuce', 'Butterhead', 'Iceberg', 'Leaf', 'Romaine', 'Lotus Root', 'Lotus Seed', 'Mushroom', 'Napa Cabbage', 'Nopales', 'Okra', 'Olive', 'Onion', 'Green Onion', 'Parsley', 'Parsley Root', 'Parsnip', 'Pepper', 'Plantain', 'Potato', 'Pumpkin', 'Purslane', 'Radicchio', 'Radish', 'Rutabaga', 'Shallots', 'Spinach', 'Squash', 'Sweet Potato', 'Swiss Chard', 'Taro', 'Tomatillo', 'Tomato', 'Turnip', 'Water Chestnut', 'Water Spinach', 'Watercress', 'Winter Melon', 'Yams', 'Zucchini'] -const getRandomGuestName = () => { - return randomGuestNames[Math.floor(Math.random() * randomGuestNames.length)] -} +const FILE_ACTION_IDENTIFIER = 'Edit with text app' const fetchFileInfo = async function(user, path) { const response = await axios({ @@ -117,21 +90,11 @@ const registerFileCreate = () => { fileType: 'file', actionHandler: function(name) { fileList.createFile(name).then(function(status, data) { - const fileExtension = name.split('.').pop() let fileInfoModel = new OCA.Files.FileInfoModel(data) - if (typeof OCA.Viewer !== 'undefined' && openFileExtensions.indexOf(fileExtension) > -1) { + if (typeof OCA.Viewer !== 'undefined') { OCA.Files.fileActions.triggerAction('view', fileInfoModel, fileList) - } else if (typeof OCA.Viewer === 'undefined' && openFileExtensions.indexOf(fileExtension) > -1) { - OCA.Files.fileActions.triggerAction('Edit with text', fileInfoModel, fileList) - } else if (typeof OCA.Files_Texteditor !== 'undefined') { - const dir = fileList.getCurrentDirectory() - OCA.Files_Texteditor._onEditorTrigger( - name, - { - fileList: fileList, - dir: dir - } - ) + } else if (typeof OCA.Viewer === 'undefined') { + OCA.Files.fileActions.triggerAction(FILE_ACTION_IDENTIFIER, fileInfoModel, fileList) } }) } @@ -151,14 +114,14 @@ const registerFileActionFallback = () => { document.body.appendChild(ViewerRoot) const registerAction = (mime) => OCA.Files.fileActions.register( mime, - 'Edit with text', + FILE_ACTION_IDENTIFIER, OC.PERMISSION_UPDATE | OC.PERMISSION_READ, OC.imagePath('core', 'actions/rename'), (filename) => { const file = window.FileList.findFile(filename) Promise.all([ import('vue'), - import('./components/PublicFilesEditor') + import('./../components/PublicFilesEditor') ]).then((imports) => { const path = window.FileList.getCurrentDirectory() + '/' + filename const Vue = imports[0].default @@ -172,7 +135,8 @@ const registerFileActionFallback = () => { fileId: file ? file.id : null, active: true, shareToken: sharingToken, - relativePath: path + relativePath: path, + mimeType: file.mimetype } }) }) @@ -181,20 +145,18 @@ const registerFileActionFallback = () => { }, t('text', 'Edit') ) - registerAction('text/markdown') - registerAction('text/plain') - OCA.Files.fileActions.setDefault('text/markdown', 'Edit with text') - OCA.Files.fileActions.setDefault('text/plain', 'Edit with text') + + for (let i = 0; i < openMimetypes; i++) { + registerAction(openMimetypes[i]) + OCA.Files.fileActions.setDefault(openMimetypes[i], FILE_ACTION_IDENTIFIER) + } } } export { - documentReady, - endpointUrl, - getRandomGuestName, fetchFileInfo, - openFileExtensions, openMimetypes, registerFileActionFallback, - registerFileCreate + registerFileCreate, + FILE_ACTION_IDENTIFIER } diff --git a/src/helpers/index.js b/src/helpers/index.js new file mode 100644 index 000000000..4e3d9d39d --- /dev/null +++ b/src/helpers/index.js @@ -0,0 +1,55 @@ +/* + * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/** + * Callback that should be executed after the document is ready + * @param callback + */ +import { generateUrl } from 'nextcloud-server/dist/router' + +const documentReady = function(callback) { + const fn = () => setTimeout(callback, 0) + if (document.attachEvent ? document.readyState === 'complete' : document.readyState !== 'loading') { + fn() + } else { + document.addEventListener('DOMContentLoaded', callback) + } +} + +const _baseUrl = generateUrl('/apps/text') +const endpointUrl = (endpoint, isPublic = false) => { + if (isPublic) { + return `${_baseUrl}/public/${endpoint}` + } + return `${_baseUrl}/${endpoint}` +} + +const randomGuestNames = ['Artichoke', 'Arugula', 'Asparagus', 'Avocado', 'Bamboo Shoot', 'Bean Sprout', 'Bean', 'Beet', 'Belgian Endive', 'Bell Pepper', 'Bitter Melon', 'Bitter Gourd', 'Bok Choy', 'Broccoli', 'Brussels Sprout', 'Burdock Root', 'Cabbage', 'Calabash', 'Caper', 'Carrot', 'Cassava', 'Cauliflower', 'Celery', 'Celery Root', 'Celtuce', 'Chayote', 'Chinese Broccoli', 'Corn', 'Baby Corn', 'Cucumber', 'English Cucumber', 'Gherkin', 'Pickling Cucumber', 'Daikon Radish', 'Edamame', 'Eggplant', 'Elephant Garlic', 'Endive', 'Curly', 'Escarole', 'Fennel', 'Fiddlehead', 'Galangal', 'Garlic', 'Ginger', 'Grape Leave', 'Green Bean', 'Wax Bean', 'Green', 'Amaranth Leave', 'Beet Green', 'Collard Green', 'Dandelion Green', 'Kale', 'Kohlrabi Green', 'Mustard Green', 'Rapini', 'Spinach', 'Swiss Chard', 'Turnip Green', 'Hearts of Palm', 'Horseradish', 'Jerusalem Artichoke', 'Jícama', 'Kale', 'Curly', 'Lacinato', 'Ornamental', 'Kohlrabi', 'Leeks', 'Lemongrass', 'Lettuce', 'Butterhead', 'Iceberg', 'Leaf', 'Romaine', 'Lotus Root', 'Lotus Seed', 'Mushroom', 'Napa Cabbage', 'Nopales', 'Okra', 'Olive', 'Onion', 'Green Onion', 'Parsley', 'Parsley Root', 'Parsnip', 'Pepper', 'Plantain', 'Potato', 'Pumpkin', 'Purslane', 'Radicchio', 'Radish', 'Rutabaga', 'Shallots', 'Spinach', 'Squash', 'Sweet Potato', 'Swiss Chard', 'Taro', 'Tomatillo', 'Tomato', 'Turnip', 'Water Chestnut', 'Water Spinach', 'Watercress', 'Winter Melon', 'Yams', 'Zucchini'] +const getRandomGuestName = () => { + return randomGuestNames[Math.floor(Math.random() * randomGuestNames.length)] +} + +export { + documentReady, + endpointUrl, + getRandomGuestName +} diff --git a/src/helpers/mime.js b/src/helpers/mime.js new file mode 100644 index 000000000..c09c44e0e --- /dev/null +++ b/src/helpers/mime.js @@ -0,0 +1,48 @@ +/* + * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> + * + * @author Julius Härtl <jus@bitgrid.net> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +const openMimetypesMarkdown = [ + 'text/markdown' +] + +const openMimetypesPlainText = [ + 'text', + 'text/plain', + 'application/cmd', + 'application/javascript', + 'application/json', + 'application/xml', + 'application/x-empty', + 'application/x-msdos-program', + 'application/x-php', + 'application/x-pearl', + 'application/x-text', + 'application/yaml' +] + +const openMimetypes = [...openMimetypesMarkdown, ...openMimetypesPlainText] + +export { + openMimetypes, + openMimetypesMarkdown, + openMimetypesPlainText +} diff --git a/src/public.js b/src/public.js index f04018068..aa87dfee8 100644 --- a/src/public.js +++ b/src/public.js @@ -1,9 +1,6 @@ -import { - documentReady, - registerFileActionFallback, - openMimetypes, - registerFileCreate -} from './helpers' +import { documentReady } from './helpers' +import { registerFileActionFallback, registerFileCreate } from './helpers/files' +import { openMimetypes } from './helpers/mime' __webpack_nonce__ = btoa(OC.requestToken) // eslint-disable-line __webpack_public_path__ = OC.linkTo('text', 'js/') // eslint-disable-line @@ -36,7 +33,8 @@ documentReady(() => { render: h => h(Editor, { props: { active: true, - shareToken: sharingToken + shareToken: sharingToken, + mimetype: mimetype } }) }) diff --git a/src/publicPlugins.js b/src/publicPlugins.js deleted file mode 100644 index 5c8f970c5..000000000 --- a/src/publicPlugins.js +++ /dev/null @@ -1,67 +0,0 @@ -/* - * @copyright Copyright (c) 2019 Julius Härtl <jus@bitgrid.net> - * - * @author Julius Härtl <jus@bitgrid.net> - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - */ - -const openFileExtensions = [ - 'md', 'markdown' -] - -const newFileMenuPlugin = { - attach: function(menu) { - var fileList = menu.fileList - - // only attach to main file list, public view is not supported yet - if (fileList.id !== 'files.public') { - return - } - - // register the new menu entry - menu.addMenuEntry({ - id: 'file', - displayName: t('text', 'New text document'), - templateName: t('text', 'New text document.md'), - iconClass: 'icon-filetype-text', - fileType: 'file', - actionHandler: function(name) { - fileList.createFile(name).then(function(status, data) { - const fileExtension = name.split('.').pop() - if (openFileExtensions.indexOf(fileExtension) > -1) { - let fileInfoModel = new OCA.Files.FileInfoModel(data) - OCA.Files.fileActions.triggerAction('Edit with text', fileInfoModel, fileList) - } else if (typeof OCA.Files_Texteditor !== 'undefined') { - const dir = fileList.getCurrentDirectory() - OCA.Files_Texteditor._onEditorTrigger( - name, - { - fileList: fileList, - dir: dir - } - ) - } - }) - } - }) - } -} - -export { - newFileMenuPlugin -} |