From 7a343449b0413d249f5a83984dc6eff48e63e687 Mon Sep 17 00:00:00 2001 From: undefined Date: Mon, 3 May 2021 21:13:17 +0800 Subject: [PATCH] onlyoffice: init --- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/service/server.ts | 6 +- packages/onlyoffice/handler.ts | 9 ++ packages/onlyoffice/package.json | 8 ++ packages/onlyoffice/public/office.page.js | 44 +++++++++ packages/onlyoffice/setting.yaml | 5 + .../backendlib/markdown-it-media.js | 94 ++++++++++--------- packages/ui-default/package.json | 2 +- 8 files changed, 122 insertions(+), 48 deletions(-) create mode 100644 packages/onlyoffice/handler.ts create mode 100644 packages/onlyoffice/package.json create mode 100644 packages/onlyoffice/public/office.page.js create mode 100644 packages/onlyoffice/setting.yaml diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 11a04e3cb..66ba1acd9 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -1,6 +1,6 @@ { "name": "hydrooj", - "version": "2.24.4", + "version": "2.24.5", "bin": "bin/hydrooj.js", "main": "dist/loader.js", "typings": "dist/loader.d.ts", diff --git a/packages/hydrooj/src/service/server.ts b/packages/hydrooj/src/service/server.ts index 20776907d..8ccc4587b 100644 --- a/packages/hydrooj/src/service/server.ts +++ b/packages/hydrooj/src/service/server.ts @@ -275,7 +275,11 @@ export async function prepare() { })); } -export const UiContextBase = { +export interface UiContextBase { + cdn_prefix: string; + url_prefix: string; +} +export const UiContextBase: UiContextBase = { cdn_prefix: '/', url_prefix: '/', }; diff --git a/packages/onlyoffice/handler.ts b/packages/onlyoffice/handler.ts new file mode 100644 index 000000000..3e108bf24 --- /dev/null +++ b/packages/onlyoffice/handler.ts @@ -0,0 +1,9 @@ +import { UiContextBase } from 'hydrooj/dist/service/server'; +import * as system from 'hydrooj/dist/model/system'; + +declare module 'hydrooj/dist/service/server' { + interface UiContextBase { + onlyofficeApi: string; + } +} +UiContextBase.onlyofficeApi = system.get('onlyoffice.api'); diff --git a/packages/onlyoffice/package.json b/packages/onlyoffice/package.json new file mode 100644 index 000000000..9cbe7d3e6 --- /dev/null +++ b/packages/onlyoffice/package.json @@ -0,0 +1,8 @@ +{ + "name": "@hydrooj/onlyoffice", + "version": "1.0.0", + "main": "package.json", + "repository": "git@github.com:hydro-dev/Hydro.git", + "author": "undefined ", + "license": "AGPL-3.0-only" +} diff --git a/packages/onlyoffice/public/office.page.js b/packages/onlyoffice/public/office.page.js new file mode 100644 index 000000000..474053d97 --- /dev/null +++ b/packages/onlyoffice/public/office.page.js @@ -0,0 +1,44 @@ +(() => { + const { AutoloadPage } = window.Hydro; + const { $ } = window.node_modules; + const { request } = window.Hydro.utils; + + const page = new AutoloadPage('onlyoffice', async () => { + const res = $('div[data-doc]'); + if (res.length) { + await new Promise((resolve) => { + const scriptElement = document.createElement('script'); + scriptElement.src = UiContext.onlyofficeApi; + scriptElement.async = true; + document.head.appendChild(scriptElement); + scriptElement.onload = resolve; + }); + } + res.get().forEach(async (element) => { + const id = `doc-${Math.random().toString()}`; + $(element).attr('id', id); + const url = $(element).text(); + const t = new URL(url, window.location.href).pathname.split('.'); + const n = new URL(url, window.location.href).pathname.split('/'); + const res = await request.get(url); + const lang = UserContext.viewLang.includes('_') ? UserContext.viewLang.split('_')[0] : UserContext.viewLang; + // eslint-disable-next-line no-undef + window.editor = new DocsAPI.DocEditor(id, { + document: { + fileType: t[t.length - 1], + key: Math.random().toString(16), + title: n[n.length - 1], + url: new URL(res.url, window.location.href), + }, + editorConfig: { + lang, + mode: 'view', + }, + documentType: 'word', + height: '980px', + }); + }); + }); + + window.Hydro.extraPages.push(page); +})(); diff --git a/packages/onlyoffice/setting.yaml b/packages/onlyoffice/setting.yaml new file mode 100644 index 000000000..749078c7b --- /dev/null +++ b/packages/onlyoffice/setting.yaml @@ -0,0 +1,5 @@ +api: + type: text + name: api + desc: OnlyOffice API URL + default: https://documentserver/web-apps/apps/api/documents/api.js \ No newline at end of file diff --git a/packages/ui-default/backendlib/markdown-it-media.js b/packages/ui-default/backendlib/markdown-it-media.js index 27c0b3502..a3d7cb051 100644 --- a/packages/ui-default/backendlib/markdown-it-media.js +++ b/packages/ui-default/backendlib/markdown-it-media.js @@ -1,5 +1,8 @@ /* eslint-disable max-len */ /* eslint-disable prefer-destructuring */ + +const { escapeHtml } = require('vj/../../node_modules/markdown-it/lib/common/utils'); + /* eslint-disable no-restricted-properties */ const ytRegex = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#&?]*).*/; function youtubeParser(url) { @@ -41,49 +44,49 @@ function extractVideoParameters(url) { } function videoUrl(service, videoID, url, options) { switch (service) { - case 'youtube': { - const parameters = extractVideoParameters(url); - if (options.youtube.parameters) { - Object.keys(options.youtube.parameters).forEach((key) => { - parameters.set(key, options.youtube.parameters[key]); - }); - } - const timeParameter = parameters.get('t'); - if (timeParameter !== undefined) { - let startTime = 0; - const timeParts = timeParameter.match(/[0-9]+/g); - let j = 0; - while (timeParts.length > 0) { - startTime += Number(timeParts.pop()) * Math.pow(60, j); - j += 1; + case 'youtube': { + const parameters = extractVideoParameters(url); + if (options.youtube.parameters) { + Object.keys(options.youtube.parameters).forEach((key) => { + parameters.set(key, options.youtube.parameters[key]); + }); } - parameters.set('start', startTime); - parameters.delete('t'); + const timeParameter = parameters.get('t'); + if (timeParameter !== undefined) { + let startTime = 0; + const timeParts = timeParameter.match(/[0-9]+/g); + let j = 0; + while (timeParts.length > 0) { + startTime += Number(timeParts.pop()) * Math.pow(60, j); + j += 1; + } + parameters.set('start', startTime); + parameters.delete('t'); + } + parameters.delete('v'); + parameters.delete('feature'); + parameters.delete('origin'); + const parameterArray = Array.from(parameters, (p) => p.join('=')); + const parameterPos = videoID.indexOf('?'); + let finalUrl = 'https://www.youtube'; + if (options.youtube.nocookie || url.indexOf('youtube-nocookie.com') > -1) finalUrl += '-nocookie'; + finalUrl += `.com/embed/${parameterPos > -1 ? videoID.substr(0, parameterPos) : videoID}`; + if (parameterArray.length > 0) finalUrl += `?${parameterArray.join('&')}`; + return finalUrl; } - parameters.delete('v'); - parameters.delete('feature'); - parameters.delete('origin'); - const parameterArray = Array.from(parameters, (p) => p.join('=')); - const parameterPos = videoID.indexOf('?'); - let finalUrl = 'https://www.youtube'; - if (options.youtube.nocookie || url.indexOf('youtube-nocookie.com') > -1) finalUrl += '-nocookie'; - finalUrl += `.com/embed/${parameterPos > -1 ? videoID.substr(0, parameterPos) : videoID}`; - if (parameterArray.length > 0) finalUrl += `?${parameterArray.join('&')}`; - return finalUrl; - } - case 'vimeo': - return `https://player.vimeo.com/video/${videoID}`; - case 'vine': - return `https://vine.co/v/${videoID}/embed/${options.vine.embed}`; - case 'prezi': - return `https://prezi.com/embed/${videoID - }/?bgcolor=ffffff&lock_to_path=0&autoplay=0&autohide_ctrls=0&` + case 'vimeo': + return `https://player.vimeo.com/video/${videoID}`; + case 'vine': + return `https://vine.co/v/${videoID}/embed/${options.vine.embed}`; + case 'prezi': + return `https://prezi.com/embed/${videoID + }/?bgcolor=ffffff&lock_to_path=0&autoplay=0&autohide_ctrls=0&` + 'landing_data=bHVZZmNaNDBIWnNjdEVENDRhZDFNZGNIUE43MHdLNWpsdFJLb2ZHanI5N1lQVHkxSHFxazZ0UUNCRHloSXZROHh3PT0&' + 'landing_sign=1kD6c0N6aYpMUS0wxnQjxzSqZlEB8qNFdxtdjYhwSuI'; - case 'osf': - return `https://mfr.osf.io/render?url=https://osf.io/${videoID}/?action=download`; - default: - return service; + case 'osf': + return `https://mfr.osf.io/render?url=https://osf.io/${videoID}/?action=download`; + default: + return service; } } @@ -115,11 +118,13 @@ module.exports = function videoPlugin(md) { + ' }); '; } if (service === 'pdf') return ``; - return videoID === '' ? '' - : `
`; + if (service === 'video') { + return `
`; + } + return `
${escapeHtml(videoID)}
`; }; md.inline.ruler.before('emphasis', 'video', (state, silent) => { let token; @@ -140,7 +145,6 @@ module.exports = function videoPlugin(md) { else if (serviceLower === 'vine') videoID = vineParser(videoID); else if (serviceLower === 'prezi') videoID = preziParser(videoID); else if (serviceLower === 'osf') videoID = mfrParser(videoID); - else if (!options[serviceLower]) return false; if (videoID === ')') videoID = ''; const serviceStart = oldPos + 2; const serviceEnd = md.helpers.parseLinkLabel(state, oldPos + 1, false); diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index 0cf975105..915fbaf07 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -1,6 +1,6 @@ { "name": "@hydrooj/ui-default", - "version": "4.6.23", + "version": "4.6.24", "author": "undefined ", "license": "AGPL-3.0", "main": "hydro.js",