diff --git a/resources/assets/js/components/Flow.vue b/resources/assets/js/components/Flow.vue
index 43a851cc..1b1ac2c0 100644
--- a/resources/assets/js/components/Flow.vue
+++ b/resources/assets/js/components/Flow.vue
@@ -114,7 +114,9 @@
language = 'zh'
break;
}
- this.url = $A.originUrl('js/grapheditor/' + (this.readOnly ? 'viewer' : 'index') + '.html?lang=' + language);
+ let route = this.readOnly ? 'viewer' : 'index';
+ let theme = $A.dark.isDarkEnabled() ? 'dark' : 'light'
+ this.url = $A.originUrl('js/grapheditor/' + route + '.html?lang=' + language + '&theme=' + theme);
},
mounted() {
window.addEventListener('message', this.handleMessage)
diff --git a/resources/assets/js/components/OnlyOffice.vue b/resources/assets/js/components/OnlyOffice.vue
index 5c2bdbf9..2731efe9 100644
--- a/resources/assets/js/components/OnlyOffice.vue
+++ b/resources/assets/js/components/OnlyOffice.vue
@@ -159,7 +159,7 @@ export default {
"name": this.userInfo.nickname
},
"customization": {
- "uiTheme": "theme-classic-light",
+ "uiTheme": $A.dark.isDarkEnabled() ? "theme-dark" : "theme-classic-light",
},
"callbackUrl": 'http://nginx/api/file/content/office?id=' + fileKey + '&token=' + this.userToken,
}
diff --git a/resources/assets/js/components/TEditor.vue b/resources/assets/js/components/TEditor.vue
index 0ed48b25..37badff3 100755
--- a/resources/assets/js/components/TEditor.vue
+++ b/resources/assets/js/components/TEditor.vue
@@ -250,6 +250,7 @@
resize: !isFull,
convert_urls:false,
toolbar_mode: 'sliding',
+ content_css: $A.dark.isDarkEnabled() ? 'dark' : 'default',
setup: (editor) => {
editor.ui.registry.addMenuButton('uploadImages', {
text: this.$L('图片'),
diff --git a/resources/assets/js/functions/web.js b/resources/assets/js/functions/web.js
index d08c8ebc..437b7a7c 100755
--- a/resources/assets/js/functions/web.js
+++ b/resources/assets/js/functions/web.js
@@ -502,5 +502,176 @@
},
});
+ /**
+ * =============================================================================
+ * ********************************** dark *********************************
+ * =============================================================================
+ */
+
+ $.extend({
+ dark: {
+ utils: {
+ filter: '-webkit-filter: url(#dark-mode-filter) !important; filter: url(#dark-mode-filter) !important;',
+ reverseFilter: '-webkit-filter: url(#dark-mode-reverse-filter) !important; filter: url(#dark-mode-reverse-filter) !important;',
+ noneFilter: '-webkit-filter: none !important; filter: none !important;',
+
+ addExtraStyle() {
+ try {
+ return '';
+ } catch (e) {
+ return '';
+ }
+ },
+
+ addStyle(id, tag, css) {
+ tag = tag || 'style';
+ let doc = document, styleDom = doc.getElementById(id);
+ if (styleDom) return;
+ let style = doc.createElement(tag);
+ style.rel = 'stylesheet';
+ style.id = id;
+ tag === 'style' ? style.innerHTML = css : style.href = css;
+ document.head.appendChild(style);
+ },
+
+ getClassList(node) {
+ return node.classList || [];
+ },
+
+ addClass(node, name) {
+ this.getClassList(node).add(name);
+ return this;
+ },
+
+ removeClass(node, name) {
+ this.getClassList(node).remove(name);
+ return this;
+ },
+
+ hasClass(node, name) {
+ return this.getClassList(node).contains(name);
+ },
+
+ hasElementById(eleId) {
+ return document.getElementById(eleId);
+ },
+
+ removeElementById(eleId) {
+ let ele = document.getElementById(eleId);
+ ele && ele.parentNode.removeChild(ele);
+ },
+ },
+
+ createDarkFilter() {
+ if (this.utils.hasElementById('dark-mode-svg')) return;
+ let svgDom = '';
+ let div = document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
+ div.innerHTML = svgDom;
+ let frag = document.createDocumentFragment();
+ while (div.firstChild)
+ frag.appendChild(div.firstChild);
+ document.head.appendChild(frag);
+ },
+
+ createDarkStyle() {
+ this.utils.addStyle('dark-mode-style', 'style', `
+ @media screen {
+ html {
+ ${this.utils.filter}
+ }
+
+ /* Default Reverse rule */
+ img,
+ video,
+ iframe,
+ canvas,
+ :not(object):not(body) > embed,
+ object,
+ svg image,
+ [style*="background:url"],
+ [style*="background-image:url"],
+ [style*="background: url"],
+ [style*="background-image: url"],
+ [background],
+ twitterwidget,
+ .sr-reader,
+ .no-dark-mode,
+ .sr-backdrop {
+ ${this.utils.reverseFilter}
+ }
+
+ [style*="background:url"] *,
+ [style*="background-image:url"] *,
+ [style*="background: url"] *,
+ [style*="background-image: url"] *,
+ input,
+ [background] *,
+ twitterwidget .NaturalImage-image {
+ ${this.utils.noneFilter}
+ }
+
+ /* Text contrast */
+ html {
+ text-shadow: 0 0 0 !important;
+ }
+
+ /* Full screen */
+ .no-filter,
+ :-webkit-full-screen,
+ :-webkit-full-screen *,
+ :-moz-full-screen,
+ :-moz-full-screen *,
+ :fullscreen,
+ :fullscreen * {
+ ${this.utils.noneFilter}
+ }
+
+ /* Page background */
+ html {
+ background: #fff !important;
+ }
+ ${this.utils.addExtraStyle()}
+ }
+
+ @media print {
+ .no-print {
+ display: none !important;
+ }
+ }`);
+ },
+
+ enableDarkMode() {
+ if (this.isDarkEnabled()) {
+ return
+ }
+ this.createDarkFilter();
+ this.createDarkStyle();
+ this.utils.addClass(document.body, "dark-mode-reverse")
+ },
+
+ disableDarkMode() {
+ if (!this.isDarkEnabled()) {
+ return
+ }
+ this.utils.removeElementById('dark-mode-svg');
+ this.utils.removeElementById('dark-mode-style');
+ this.utils.removeClass(document.body, "dark-mode-reverse")
+ },
+
+ autoDarkMode() {
+ let darkScheme = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
+ if (darkScheme) {
+ this.enableDarkMode()
+ } else {
+ this.disableDarkMode()
+ }
+ },
+
+ isDarkEnabled() {
+ return this.utils.hasClass(document.body, "dark-mode-reverse")
+ },
+ }
+ });
+
window.$A = $;
})(window);
diff --git a/resources/assets/js/pages/manage.vue b/resources/assets/js/pages/manage.vue
index b53760a7..30c4ef52 100644
--- a/resources/assets/js/pages/manage.vue
+++ b/resources/assets/js/pages/manage.vue
@@ -22,6 +22,17 @@
:key="key"
:divided="!!item.divided"
:name="item.path">{{$L(item.name)}}
+
+
+
+
+
+ {{$L(item.name)}}
+
+