tag2
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
"target": "es5",
|
"target": "es5",
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
|
"jsx": "preserve",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": [
|
"@/*": [
|
||||||
|
|||||||
@@ -15,7 +15,6 @@
|
|||||||
"crypto-js": "^4.1.1",
|
"crypto-js": "^4.1.1",
|
||||||
"escape-html": "^1.0.3",
|
"escape-html": "^1.0.3",
|
||||||
"file-saver": "^2.0.5",
|
"file-saver": "^2.0.5",
|
||||||
"html2canvas": "^1.4.1",
|
|
||||||
"jquery": "^3.6.0",
|
"jquery": "^3.6.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pako": "^2.0.4",
|
"pako": "^2.0.4",
|
||||||
@@ -23,6 +22,7 @@
|
|||||||
"view-design": "^4.0.0",
|
"view-design": "^4.0.0",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
"vue-axios": "^3.4.1",
|
"vue-axios": "^3.4.1",
|
||||||
|
"vue-contextmenu": "^1.5.11",
|
||||||
"vue-i18n": "^8.27.2",
|
"vue-i18n": "^8.27.2",
|
||||||
"vue-router": "^3.5.1"
|
"vue-router": "^3.5.1"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,7 +4,11 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||||
<link rel="icon" href="/favicon.png" />
|
<meta http-equiv="Expires" content="0">
|
||||||
|
<meta http-equiv="Pragma" content="no-cache">
|
||||||
|
<meta http-equiv="Cache-control" content="no-cache">
|
||||||
|
<meta http-equiv="Cache" content="no-cache">
|
||||||
|
<link rel="icon" href="/static/favicon.ico" />
|
||||||
<title>flagnote.com</title>
|
<title>flagnote.com</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
|
|||||||
@@ -4,8 +4,13 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
|
<meta name="theme-color" content="#ed4014"/>
|
||||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
<meta http-equiv="Expires" content="0">
|
||||||
|
<meta http-equiv="Pragma" content="no-cache">
|
||||||
|
<meta http-equiv="Cache-control" content="no-cache">
|
||||||
|
<meta http-equiv="Cache" content="no-cache">
|
||||||
|
<link rel="icon" href="/static/favicon.ico" />
|
||||||
|
<title>flagnote.com</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
background-color: #dddddd;
|
background-color: #dddddd;
|
||||||
|
|||||||
BIN
public/static/favicon.ico
Normal file
BIN
public/static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
public/static/favicon.png
Normal file
BIN
public/static/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
@@ -13,6 +13,11 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
|
.ivu-btn:focus {
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
#app {
|
#app {
|
||||||
font-family: 'Avenir', Helvetica, Arial, sans-serif;
|
font-family: 'Avenir', Helvetica, Arial, sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
@@ -58,6 +63,7 @@ body {
|
|||||||
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
||||||
/*min-height: 400px;*/
|
/*min-height: 400px;*/
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
border: 1px solid white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import Jquery from "jquery";
|
|||||||
import {getStoreKey} from "@/api/lock";
|
import {getStoreKey} from "@/api/lock";
|
||||||
import storage from "@/libs/storage";
|
import storage from "@/libs/storage";
|
||||||
|
|
||||||
|
const servicePath = 'https://service.flagnote.com';
|
||||||
|
|
||||||
export function saveNote(noteForm) {
|
export function saveNote(noteForm) {
|
||||||
let storeKey = getStoreKey(noteForm.key);
|
let storeKey = getStoreKey(noteForm.key);
|
||||||
let storeText = storage.local.getText(storeKey + '.text');
|
let storeText = storage.local.getText(storeKey + '.text');
|
||||||
@@ -14,7 +16,7 @@ export function saveNote(noteForm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return axios({
|
return axios({
|
||||||
url: '/note/' + noteForm.key,
|
url: servicePath+'/note/' + noteForm.key,
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: note
|
data: note
|
||||||
}
|
}
|
||||||
@@ -30,7 +32,7 @@ export function deleteNote(key) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return axios({
|
return axios({
|
||||||
url: '/note/' + key +'/delete',
|
url: servicePath+'/note/' + key +'/delete',
|
||||||
method: 'post',
|
method: 'post',
|
||||||
data: note
|
data: note
|
||||||
}
|
}
|
||||||
@@ -62,7 +64,7 @@ export function getNoteMeta(key) {
|
|||||||
let noteMeta = {};
|
let noteMeta = {};
|
||||||
Jquery.ajax({
|
Jquery.ajax({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/note/' + key + "/noteMeta",
|
url: servicePath+'/note/' + key + "/noteMeta",
|
||||||
async: false,
|
async: false,
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
noteMeta = eval(data); //eval("(" + data + ")");
|
noteMeta = eval(data); //eval("(" + data + ")");
|
||||||
@@ -74,11 +76,27 @@ export function getNoteMeta(key) {
|
|||||||
return noteMeta;
|
return noteMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getNote(key) {
|
||||||
|
let noteObject = {};
|
||||||
|
Jquery.ajax({
|
||||||
|
method: 'GET',
|
||||||
|
url: servicePath + '/note/' + key,
|
||||||
|
async: false,
|
||||||
|
success: function (data) {
|
||||||
|
noteObject = eval(data);
|
||||||
|
},
|
||||||
|
error: function () {
|
||||||
|
noteObject = null;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return noteObject;
|
||||||
|
}
|
||||||
|
|
||||||
export function getKeyMeta() {
|
export function getKeyMeta() {
|
||||||
let keyMeta = {};
|
let keyMeta = {};
|
||||||
Jquery.ajax({
|
Jquery.ajax({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
url: '/note/keyMeta',
|
url: servicePath+'/note/keyMeta',
|
||||||
async: false,
|
async: false,
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
keyMeta = eval(data); //eval("(" + data + ")");
|
keyMeta = eval(data); //eval("(" + data + ")");
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ const en = {
|
|||||||
ok: "OK",
|
ok: "OK",
|
||||||
yes: "Yes",
|
yes: "Yes",
|
||||||
no: "No",
|
no: "No",
|
||||||
|
selectAll: "Select All",
|
||||||
|
copy: "Copy",
|
||||||
|
copyAll: "Copy All",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
export default en;
|
export default en;
|
||||||
|
|||||||
@@ -9,6 +9,9 @@ const zh = {
|
|||||||
ok: "好的",
|
ok: "好的",
|
||||||
yes: "是的",
|
yes: "是的",
|
||||||
no: "不",
|
no: "不",
|
||||||
|
selectAll: "全选",
|
||||||
|
copy: "复制",
|
||||||
|
copyAll: "复制全部",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
export default zh;
|
export default zh;
|
||||||
|
|||||||
@@ -1,16 +1,24 @@
|
|||||||
import Vue from 'vue';
|
import Vue from "vue";
|
||||||
import VueI18n from 'vue-i18n';
|
import VueI18n from "vue-i18n";
|
||||||
Vue.use(VueI18n);
|
Vue.use(VueI18n);
|
||||||
|
|
||||||
import zh from './config/zh';
|
import zh from "./config/zh";
|
||||||
import en from './config/en';
|
import en from "./config/en";
|
||||||
|
|
||||||
const i18n = new VueI18n({
|
const i18n = new VueI18n({
|
||||||
locale: localStorage.getItem('locale') || 'en', // 语言标识
|
locale: getLocale(),
|
||||||
messages: {
|
messages: {
|
||||||
zh,
|
zh,
|
||||||
en,
|
en,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function getLocale(){
|
||||||
|
if(localStorage.getItem("locale")){
|
||||||
|
return localStorage.getItem("locale").substring(0,2);
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
return "en";
|
||||||
|
}
|
||||||
|
|
||||||
export default i18n;
|
export default i18n;
|
||||||
@@ -44,6 +44,6 @@ export function getEscapeText(text) {
|
|||||||
textEscape = textEscape.replace(new RegExp('\\r\\n','gm'), "<br/>");
|
textEscape = textEscape.replace(new RegExp('\\r\\n','gm'), "<br/>");
|
||||||
textEscape = textEscape.replace(new RegExp('\\r','gm'), "<br/>");
|
textEscape = textEscape.replace(new RegExp('\\r','gm'), "<br/>");
|
||||||
textEscape = textEscape.replace(new RegExp('\\n','gm'), "<br/>");
|
textEscape = textEscape.replace(new RegExp('\\n','gm'), "<br/>");
|
||||||
textEscape = textEscape.replace(new RegExp('\\t','gm'), " ");
|
textEscape = textEscape.replace(new RegExp('\\t','gm'), "<pre class=\"tab_pre\">	</pre>");
|
||||||
return textEscape;
|
return textEscape;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export function md5(word, keyWord = 'F1agn0te') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//加密
|
//加密
|
||||||
export function aesEncrypt(word, keyWord = 'F1agn0te') {
|
export function aesEncrypt(word, keyWord) {
|
||||||
let key = CryptoJS.enc.Utf8.parse(keyWord);
|
let key = CryptoJS.enc.Utf8.parse(keyWord);
|
||||||
let srcWords = CryptoJS.enc.Utf8.parse(word);
|
let srcWords = CryptoJS.enc.Utf8.parse(word);
|
||||||
let encrypted = CryptoJS.AES.encrypt(srcWords, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7});
|
let encrypted = CryptoJS.AES.encrypt(srcWords, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7});
|
||||||
@@ -22,7 +22,7 @@ export function aesEncrypt(word, keyWord = 'F1agn0te') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//解密
|
//解密
|
||||||
export function aesDecrypt(word, keyWord = 'F1agn0te') {
|
export function aesDecrypt(word, keyWord) {
|
||||||
let key = CryptoJS.enc.Utf8.parse(keyWord);
|
let key = CryptoJS.enc.Utf8.parse(keyWord);
|
||||||
let decrypt = CryptoJS.AES.decrypt(word, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7});
|
let decrypt = CryptoJS.AES.decrypt(word, key, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7});
|
||||||
return CryptoJS.enc.Utf8.stringify(decrypt).toString()
|
return CryptoJS.enc.Utf8.stringify(decrypt).toString()
|
||||||
|
|||||||
@@ -67,9 +67,8 @@ class Local {
|
|||||||
return 5 * 1024 * 1024 - storage.local.getUseSize();
|
return 5 * 1024 * 1024 - storage.local.getUseSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamicClear(ctt) {
|
dynamicClear() {
|
||||||
if (storage.local.getAvailableSize() < 1 * 1024 * 1024) {
|
if (storage.local.getAvailableSize() < 1 * 1024 * 1024) {
|
||||||
|
|
||||||
//remove commited
|
//remove commited
|
||||||
for (let i = 0, len = localStorage.length; i < len; i++) {
|
for (let i = 0, len = localStorage.length; i < len; i++) {
|
||||||
let key = localStorage.key(i);
|
let key = localStorage.key(i);
|
||||||
@@ -86,26 +85,42 @@ class Local {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//remove expired
|
dynamicDeepClear(ctt, excludeKey) {
|
||||||
if (storage.local.getAvailableSize() < 1 * 1024 * 1024) {
|
if (!ctt) {
|
||||||
for (let i = 0, len = localStorage.length; i < len; i++) {
|
return;
|
||||||
let key = localStorage.key(i);
|
}
|
||||||
if (null == key) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let value = localStorage.getItem(key);
|
|
||||||
|
|
||||||
if (key.length == 37 && key.endsWith(".text") && value.length > 50) {
|
//remove expired
|
||||||
let starray = value.split("|");
|
let availableSize = storage.local.getAvailableSize();
|
||||||
let fl = starray[2];
|
|
||||||
let ts = starray[3];
|
|
||||||
|
|
||||||
if (fl == "0") {
|
for (
|
||||||
if (ctt - ts > 3 * 24 * 3600 * 1000) {
|
let i = 0, len = localStorage.length;
|
||||||
localStorage.removeItem(key);
|
i < len && availableSize < 2 * 1024 * 1024;
|
||||||
}
|
i++
|
||||||
}
|
) {
|
||||||
|
let key = localStorage.key(i);
|
||||||
|
if (null == key) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.indexOf(excludeKey) >= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let value = localStorage.getItem(key);
|
||||||
|
|
||||||
|
if (key.length == 37 && key.endsWith(".text") && value.length > 50) {
|
||||||
|
let starray = value.split("|");
|
||||||
|
let fl = starray[2];
|
||||||
|
let ts = starray[3];
|
||||||
|
|
||||||
|
if (fl == "0") {
|
||||||
|
if (ctt - ts > 3 * 24 * 3600 * 1000) {
|
||||||
|
localStorage.removeItem(key);
|
||||||
|
availableSize = availableSize + value.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,3 +12,7 @@ export function isIE() {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getNoteUrl(key){
|
||||||
|
return "https://flagnote.com/" + key;
|
||||||
|
}
|
||||||
@@ -5,6 +5,15 @@ import axios from 'axios'
|
|||||||
import VueAxios from 'vue-axios'
|
import VueAxios from 'vue-axios'
|
||||||
import './plugins/iview.js'
|
import './plugins/iview.js'
|
||||||
import i18n from './i18n/'
|
import i18n from './i18n/'
|
||||||
|
import VueContextMenu from 'vue-contextmenu'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Vue.use(VueContextMenu)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
axios.defaults.baseURL="https://service.flagnote.com"
|
||||||
|
|
||||||
Vue.use(VueAxios, axios)
|
Vue.use(VueAxios, axios)
|
||||||
|
|
||||||
|
|||||||
@@ -23,40 +23,47 @@ function getNoteMetaParam() {
|
|||||||
|
|
||||||
function getNoteView() {
|
function getNoteView() {
|
||||||
let path = location.pathname;
|
let path = location.pathname;
|
||||||
if (null != keyMeta) {
|
let key = path.substring(1, path.length);
|
||||||
path = "/" + keyMeta.key;
|
|
||||||
|
if (keyMeta && keyMeta.key) {
|
||||||
|
key = keyMeta.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
let reg = /^\/[abcdefhikmnopqstuvwxyz23456789]{16}$/;
|
let regKey = /^[abcdefhikmnopqstuvwxyz23456789]{16}$/;
|
||||||
if (!reg.test(path)) {
|
if (!regKey.test(key)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let key = path.substr(1, path.length - 1);
|
if (keyMeta && keyMeta.key) {
|
||||||
|
//firstEdit
|
||||||
let storeKey = getStoreKey(key);
|
|
||||||
if (keyMeta && keyMeta.cipher) {
|
|
||||||
// storage.session.setObject(storeKey + '.keyMeta', keyMeta);
|
|
||||||
return EditNote;
|
return EditNote;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//set noteMeta
|
||||||
noteMeta = getNoteMeta(key);
|
noteMeta = getNoteMeta(key);
|
||||||
|
|
||||||
if (!noteMeta || !noteMeta.key) {
|
if (!noteMeta || !noteMeta.key) {
|
||||||
|
|
||||||
|
let storeKey = getStoreKey(key);
|
||||||
|
|
||||||
let storeText = storage.local.getText(storeKey + ".text");
|
let storeText = storage.local.getText(storeKey + ".text");
|
||||||
if (storeText) {
|
if (storeText) {
|
||||||
let starray = storeText.split("|");
|
let starray = storeText.split("|");
|
||||||
let commitFlag = starray[2];
|
let commitFlag = starray[2];
|
||||||
if (commitFlag == "1") {
|
if (commitFlag == "1") {
|
||||||
|
//timeout and clear local
|
||||||
storage.local.delete(storeKey + '.text');
|
storage.local.delete(storeKey + '.text');
|
||||||
return BlankNote;
|
return BlankNote;
|
||||||
} else {
|
} else {
|
||||||
|
//secondEdit
|
||||||
return EditNote;
|
return EditNote;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
//uncommited or timeout
|
||||||
return BlankNote;
|
return BlankNote;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// storage.session.setObject(storeKey + '.noteMeta', noteMeta);
|
// view in time
|
||||||
return ViewNote;
|
return ViewNote;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,10 +73,8 @@ function getHomeRedirect() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let km = getKeyMeta();
|
//setKeyMeta
|
||||||
km.isNew = true;
|
keyMeta = getKeyMeta();
|
||||||
//sessionStorage.setItem(km.getKey() + '.keyMeta', km);
|
|
||||||
keyMeta = km;
|
|
||||||
return "/" + keyMeta.key;
|
return "/" + keyMeta.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,6 +94,7 @@ const routes = [
|
|||||||
name: "note",
|
name: "note",
|
||||||
component: getNoteView(),
|
component: getNoteView(),
|
||||||
meta: { keyMeta: getKeyMetaParam(), noteMeta: getNoteMetaParam() },
|
meta: { keyMeta: getKeyMetaParam(), noteMeta: getNoteMetaParam() },
|
||||||
|
//alias:'/xxxx'
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<div style="background: white;width:100%;height:40px;">
|
<div style="background: white;width:100%;height:40px;">
|
||||||
<img style="height:40px;float:left;" src="favicon.png">
|
<img style="height:40px;float:left;" src="/static/favicon.png">
|
||||||
|
|
||||||
<div style="float:right;width:auto;">
|
<div style="float:right;width:auto;">
|
||||||
<Button-group size="large">
|
<Button-group size="large">
|
||||||
|
|||||||
@@ -60,119 +60,76 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.ivu-btn-text:focus {
|
||||||
|
margin-top: -3px;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="layout">
|
<div class="layout">
|
||||||
|
|
||||||
<Layout>
|
<Layout>
|
||||||
<Affix :offset-top="0">
|
|
||||||
|
<Header class="header">
|
||||||
|
<Row>
|
||||||
|
<Col :xs="{ span: 24, offset: 0 }" :sm="{ span: 22, offset: 1 }" :md="{ span: 20, offset: 2 }"
|
||||||
|
:lg="{ span: 18, offset: 3 }" :xl="{ span: 16, offset: 4 }" :xxl="{ span: 16, offset: 4 }">
|
||||||
|
|
||||||
|
<Affix :offset-top="0">
|
||||||
|
<div style="background: white;width:100%;height:40px;">
|
||||||
|
|
||||||
|
<img style="height:40px;float:left;" alt="refresh flagnote" src="/static/favicon.png">
|
||||||
|
|
||||||
|
<div style="float:left;width:auto;">
|
||||||
|
|
||||||
|
<Button-group size="large">
|
||||||
|
<Button aria-label="publish" type="error" :loading="loading"
|
||||||
|
style="margin-left:5px; border-radius: 0px;font-size: 24px;" @click="submitNote()"
|
||||||
|
icon="md-cloud-upload"></Button>
|
||||||
|
|
||||||
|
<Button aria-label="download text" v-show="model.showDownloadText" type="error"
|
||||||
|
style="margin-left:5px; border-radius: 0px; font-size: 22px;" @click="downLoadText()"
|
||||||
|
icon="md-download"></Button>
|
||||||
|
|
||||||
|
|
||||||
<Header class="header">
|
</Button-group>
|
||||||
<div>
|
|
||||||
<Row>
|
|
||||||
<Col :xs="{ span: 24, offset: 0 }" :sm="{ span: 22, offset: 1 }" :md="{ span: 20, offset: 2 }"
|
|
||||||
:lg="{ span: 18, offset: 3 }" :xl="{ span: 16, offset: 4 }" :xxl="{ span: 16, offset: 4 }">
|
|
||||||
|
|
||||||
<div id="textToTop" v-on:click="toTop()" :class="[toTopState?'showBlock':'hideBlock']"
|
</div>
|
||||||
style="width: 100%;height: 20px;position: absolute;top: 35px;"><div style="display:inline-block;cursor: pointer;padding:2px;"><Icon type="ios-arrow-up" size="28" color="#ed4014"/></div></div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style="background: white;width:100%;height:40px;">
|
|
||||||
<img style="height:40px;float:left;" src="favicon.png">
|
|
||||||
<div style="float:left;width:auto;">
|
|
||||||
|
|
||||||
<Button-group size="large">
|
|
||||||
<Button type="error" :loading="loading" style="margin-left:5px; border-radius: 0px;font-size: 24px;"
|
|
||||||
@click="submitNote()" icon="md-cloud-upload"></Button>
|
|
||||||
|
|
||||||
<Button v-show="model.showDownloadText" type="error"
|
|
||||||
style="margin-left:5px; border-radius: 0px; font-size: 22px;"
|
|
||||||
@click="downLoadText()" icon="md-download"></Button>
|
|
||||||
</Button-group>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div style="float:right;width:auto;">
|
|
||||||
|
|
||||||
<Button-group size="large">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Button type="error" style="margin-left:0px; border-radius: 0px;font-size: 24px;"
|
|
||||||
@click="createNote()" icon="md-add"></Button>
|
|
||||||
<Button type="error" style="margin-left:5px; border-radius: 0px;font-size: 24px;"
|
|
||||||
@click="showDeleteModel()" icon="md-trash"></Button>
|
|
||||||
|
|
||||||
</Button-group>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="float:right;width:auto;">
|
|
||||||
|
|
||||||
<Button-group size="large">
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
<Button v-show="!show" type="error" style="margin-left:5px; border-radius: 0px;font-size: 24px;"
|
|
||||||
@click="showNote()" icon="md-eye"></Button>
|
|
||||||
<Button v-show="show" type="error" style="margin-left:5px; border-radius: 0px;font-size: 24px;"
|
|
||||||
@click="hideNote()" icon="md-eye-off"></Button>
|
|
||||||
-->
|
|
||||||
|
|
||||||
</Button-group>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<div style="float:right;width:auto;">
|
<div style="float:right;width:auto;">
|
||||||
<Button-group size="default">
|
|
||||||
<Button type="error" @click="unLockNote()" icon="md-eye"></Button>
|
|
||||||
<Button type="error" @click="lockNote()" icon="md-eye-off"></Button>
|
|
||||||
<Button type="error" style="margin-left:5px; border-radius: 0px;font-size: 24px;"
|
|
||||||
@click="dropNote()" icon="md-trash"></Button> </Button-group>
|
|
||||||
|
|
||||||
|
<Button-group size="large">
|
||||||
|
|
||||||
|
<Button aria-label="to top" v-show="toTopState" type="text"
|
||||||
|
style="margin-left:0px; border-radius: 0px; font-size: 28px;color:red;line-height: 20px;"
|
||||||
|
@click="toTop()" icon="ios-arrow-up" ghost></Button>
|
||||||
|
|
||||||
|
|
||||||
|
<Button aria-label="create note" type="error"
|
||||||
|
style="margin-left:10px; border-radius: 0px;font-size: 24px;" @click="createNote()"
|
||||||
|
icon="md-add"></Button>
|
||||||
|
<Button aria-label="delete note" type="error"
|
||||||
|
style="margin-left:5px; border-radius: 0px;font-size: 24px;" @click="showDeleteModel()"
|
||||||
|
icon="md-trash"></Button>
|
||||||
|
|
||||||
|
</Button-group>
|
||||||
</div>
|
</div>
|
||||||
-->
|
</div>
|
||||||
|
</Affix>
|
||||||
|
|
||||||
<!--
|
|
||||||
<div style="width:auto;float:right;font-size: 24px;">
|
|
||||||
<Button-group vertical size="large" style="position:absolute;right;0px;top:0px;">
|
|
||||||
<Button type="error" style="border-radius: 0px;font-size: 24px;" icon="md-add"
|
|
||||||
@click="showExt = true"></Button>
|
|
||||||
<Button type="error" v-show="showExt" style="border-radius: 0px;font-size: 24px;"
|
|
||||||
icon="md-cloud-upload"></Button>
|
|
||||||
<Button type="error" v-show="showExt" style="border-radius: 0px;font-size: 24px;"
|
|
||||||
icon="logo-googleplus"></Button>
|
|
||||||
<Button type="error" v-show="showExt" style="border-radius: 0px;font-size: 24px;"
|
|
||||||
icon="logo-tumblr"></Button>
|
|
||||||
</Button-group>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
</Header>
|
||||||
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</div>
|
|
||||||
</Header>
|
|
||||||
</Affix>
|
|
||||||
<Content class="content">
|
<Content class="content">
|
||||||
<div style="min-height: 650px;">
|
<div style="min-height: 650px;">
|
||||||
<Row>
|
<Row>
|
||||||
@@ -183,11 +140,7 @@
|
|||||||
<div id="wrapper" style="border-left: 0px solid #FF3366;">
|
<div id="wrapper" style="border-left: 0px solid #FF3366;">
|
||||||
<Input element-id="noteText" type="textarea" :border="false" v-model="noteForm.text"
|
<Input element-id="noteText" type="textarea" :border="false" v-model="noteForm.text"
|
||||||
:autosize="{ minRows: 30, maxRows: 20480 }" placeholder="Enter something..." v-on:input="log"
|
:autosize="{ minRows: 30, maxRows: 20480 }" placeholder="Enter something..." v-on:input="log"
|
||||||
@on-keydown="down"/>
|
@on-keydown="down" />
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
</Card>
|
</Card>
|
||||||
@@ -212,13 +165,14 @@
|
|||||||
<p>Content of dialog</p>
|
<p>Content of dialog</p>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
<Modal v-model="model.showDelete" width="330" footer-hide class-name="fnmodal" :styles="{ borderRadius: 0 }">
|
<Modal v-model="model.showDelete" width="330" footer-hide class-name="fnmodal" :styles="{ borderRadius: 0 }">
|
||||||
<p style="text-align: center;font-size:medium ;margin-bottom: 20px;">
|
<p style="text-align: center;font-size:medium ;margin-bottom: 20px;">
|
||||||
{{$t("message.askTodelete")}}
|
{{ $t("message.askTodelete") }}
|
||||||
</p>
|
</p>
|
||||||
<p style="text-align: center;">
|
<p style="text-align: center;">
|
||||||
<Button type="error" :loading="model.deleting" style="border-radius: 0px;"
|
<Button type="error" :loading="model.deleting" style="border-radius: 0px;" @click="dropNote()">{{
|
||||||
@click="dropNote()" >{{$t("button.yes")}}</Button>
|
$t("button.yes")
|
||||||
|
}}</Button>
|
||||||
</p>
|
</p>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
@@ -265,46 +219,58 @@ export default {
|
|||||||
locking: 0,
|
locking: 0,
|
||||||
commited: 0
|
commited: 0
|
||||||
},
|
},
|
||||||
model:{
|
model: {
|
||||||
showDelete: false,
|
showDelete: false,
|
||||||
deleting: false,
|
deleting: false,
|
||||||
showDownloadText: false,
|
showDownloadText: false,
|
||||||
},
|
},
|
||||||
toTopState : false,
|
toTopState: false,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
// read $route
|
||||||
this.model.showDownloadText = !isWeixin();
|
|
||||||
|
|
||||||
this.noteForm.key = this.$route.params.name;
|
this.noteForm.key = this.$route.params.name;
|
||||||
let keyMeta = this.$route.meta.keyMeta;
|
let keyMeta = this.$route.meta.keyMeta;
|
||||||
|
|
||||||
|
//ipad chrome url not redirect
|
||||||
|
let path = location.pathname;
|
||||||
|
if ("/" == path) {
|
||||||
|
history.pushState('', '', '/' + this.noteForm.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
//wx does not show downloadText
|
||||||
|
this.model.showDownloadText = !isWeixin();
|
||||||
|
|
||||||
// let noteMeta = this.$route.meta.noteMeta;
|
// let noteMeta = this.$route.meta.noteMeta;
|
||||||
let storeKey = getStoreKey(this.noteForm.key);
|
let storeKey = getStoreKey(this.noteForm.key);
|
||||||
this.secret.storeKey = storeKey;
|
this.secret.storeKey = storeKey;
|
||||||
|
|
||||||
|
// first edit
|
||||||
if (keyMeta) {
|
if (keyMeta) {
|
||||||
this.state.lock = 0;
|
this.state.lock = 0;
|
||||||
this.secret.cipher = keyMeta.cipher;
|
this.secret.cipher = keyMeta.cipher;
|
||||||
this.secret.currentTime = keyMeta.currentTime;
|
this.secret.currentTime = keyMeta.currentTime;
|
||||||
|
// key init Time
|
||||||
this.noteForm.initTime = keyMeta.currentTime;
|
this.noteForm.initTime = keyMeta.currentTime;
|
||||||
storage.local.setText(storeKey + '.text', "0|" + this.secret.cipher + "|0|" + this.secret.currentTime + "|");
|
// clear
|
||||||
storage.session.setObject(storeKey + '.keyMeta', null);
|
storage.local.dynamicClear();
|
||||||
storage.local.dynamicClear(this.secret.currentTime);
|
|
||||||
|
//if local less 1m ,then deep clear,let local greater than 2m
|
||||||
|
// if (storage.local.getAvailableSize < 1 * 1024 * 1024) {
|
||||||
|
// storage.local.dynamicDeepClear(this.secret.currentTime, storeKey);
|
||||||
|
// }
|
||||||
|
|
||||||
|
storage.local.setText(storeKey + '.text', "0|" + this.secret.cipher + "|0|" + this.noteForm.initTime + "|");
|
||||||
} else {
|
} else {
|
||||||
|
// second edit
|
||||||
let storeText = storage.local.getText(storeKey + '.text');
|
let storeText = storage.local.getText(storeKey + '.text');
|
||||||
let starray = storeText.split('|');
|
let starray = storeText.split('|');
|
||||||
this.state.lock = parseInt(starray[0]);
|
this.state.lock = parseInt(starray[0]);
|
||||||
this.secret.cipher = starray[1];
|
this.secret.cipher = starray[1];
|
||||||
this.noteForm.initTime = parseInt(starray[3]);
|
this.noteForm.initTime = parseInt(starray[3]);
|
||||||
|
|
||||||
|
|
||||||
// this.secret.currentTime = noteMeta.currentTime;
|
|
||||||
// storage.local.dynamicClear(this.secret.currentTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: password lock
|
||||||
|
|
||||||
if (this.state.lock == 1) {
|
if (this.state.lock == 1) {
|
||||||
this.show = false;
|
this.show = false;
|
||||||
this.noteForm.text = "*****lock*****";
|
this.noteForm.text = "*****lock*****";
|
||||||
@@ -313,34 +279,9 @@ export default {
|
|||||||
this.loadText();
|
this.loadText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.bindCtrlAllEvent();
|
||||||
|
|
||||||
this.bindEvent();
|
this.bindToTopEvent();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let that = this;
|
|
||||||
window.onscroll = function () {
|
|
||||||
//变量scrollTop是滚动条滚动时,距离顶部的距离
|
|
||||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
|
||||||
// //变量windowHeight是可视区的高度
|
|
||||||
// var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
|
|
||||||
// //变量scrollHeight是滚动条的总高度
|
|
||||||
// var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
|
|
||||||
//滚动条到底部的条件
|
|
||||||
|
|
||||||
if (scrollTop >= 20) {
|
|
||||||
//写后台加载数据的函数
|
|
||||||
//console.log("距顶部" + scrollTop + "可视区高度" + windowHeight + "滚动条总高度" + scrollHeight);
|
|
||||||
|
|
||||||
that.toTopState = true;
|
|
||||||
} else {
|
|
||||||
//toTop.style.setProperty("display", "none")
|
|
||||||
that.toTopState = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -349,6 +290,20 @@ export default {
|
|||||||
|
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
const myObserver = new ResizeObserver(entries => {
|
||||||
|
// iterate over the entries, do something.
|
||||||
|
entries.forEach(entry => {
|
||||||
|
let affix = document.querySelector('.ivu-affix');
|
||||||
|
if (affix) {
|
||||||
|
affix.setAttribute("style", "top: 0px; width: " + entry.contentRect.width + "px;");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const someOtherEl = document.querySelector('#wrapper');
|
||||||
|
|
||||||
|
myObserver.observe(someOtherEl);
|
||||||
},
|
},
|
||||||
updated() {
|
updated() {
|
||||||
},
|
},
|
||||||
@@ -359,8 +314,13 @@ export default {
|
|||||||
computed: {},
|
computed: {},
|
||||||
watch: {},
|
watch: {},
|
||||||
methods: {
|
methods: {
|
||||||
toTop(){
|
|
||||||
window.scrollTo(0, 0);
|
toTop() {
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
let elent = document.querySelector('#noteText');
|
||||||
|
elent.selectionStart = 0;
|
||||||
|
elent.selectionEnd = 0;
|
||||||
|
elent.focus();
|
||||||
},
|
},
|
||||||
showInput() {
|
showInput() {
|
||||||
this.showPassword = true;
|
this.showPassword = true;
|
||||||
@@ -377,12 +337,11 @@ export default {
|
|||||||
cancel() {
|
cancel() {
|
||||||
|
|
||||||
},
|
},
|
||||||
downLoadText(){
|
downLoadText() {
|
||||||
var blob = new Blob([this.noteForm.text], {type: "application/octet-stream;charset=utf-8"});
|
var blob = new Blob([this.noteForm.text], { type: "application/octet-stream;charset=utf-8" });
|
||||||
saveAs(blob, this.noteForm.key+".txt");
|
saveAs(blob, this.noteForm.key + ".txt");
|
||||||
},
|
},
|
||||||
loadText() {
|
loadText() {
|
||||||
let secretKey = getSecretKey(this.noteForm.key);
|
|
||||||
let storeText = storage.local.getText(this.secret.storeKey + '.text');
|
let storeText = storage.local.getText(this.secret.storeKey + '.text');
|
||||||
|
|
||||||
if (null != storeText && '' != storeText) {
|
if (null != storeText && '' != storeText) {
|
||||||
@@ -395,12 +354,11 @@ export default {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//let cipher = storeText.substring(2,34)
|
|
||||||
|
|
||||||
storeText = starray[4];
|
storeText = starray[4];
|
||||||
|
|
||||||
if (storeText.length > 0) {
|
if (storeText.length > 0) {
|
||||||
storeText = unzip(storeText);
|
storeText = unzip(storeText);
|
||||||
|
let secretKey = getSecretKey(this.noteForm.key);
|
||||||
let plainText = aesDecrypt(storeText, secretKey);
|
let plainText = aesDecrypt(storeText, secretKey);
|
||||||
if (plainText.startsWith("FLAGNOTE#")) {
|
if (plainText.startsWith("FLAGNOTE#")) {
|
||||||
this.noteForm.text = plainText.substring(9);
|
this.noteForm.text = plainText.substring(9);
|
||||||
@@ -421,9 +379,10 @@ export default {
|
|||||||
},
|
},
|
||||||
down(event) {
|
down(event) {
|
||||||
if (event.keyCode == 9) {
|
if (event.keyCode == 9) {
|
||||||
let start = event.currentTarget.selectionStart, end = event.currentTarget.selectionEnd;
|
let start = event.currentTarget.selectionStart;
|
||||||
|
let end = event.currentTarget.selectionEnd;
|
||||||
let text = event.currentTarget.value;
|
let text = event.currentTarget.value;
|
||||||
let tab = ' ';//\t
|
let tab = '\t';//\t
|
||||||
text = text.substr(0, start) + tab + text.substr(start);
|
text = text.substr(0, start) + tab + text.substr(start);
|
||||||
event.currentTarget.value = text;
|
event.currentTarget.value = text;
|
||||||
event.currentTarget.selectionStart = start + tab.length;
|
event.currentTarget.selectionStart = start + tab.length;
|
||||||
@@ -435,21 +394,14 @@ export default {
|
|||||||
this.noteForm.text = event.currentTarget.value;
|
this.noteForm.text = event.currentTarget.value;
|
||||||
setStoreText(this.noteForm, this.secret);
|
setStoreText(this.noteForm, this.secret);
|
||||||
|
|
||||||
// html2canvas(document.body).then(function (canvas) {
|
|
||||||
// canvas;
|
|
||||||
// //document.body.appendChild(canvas);
|
|
||||||
// });
|
|
||||||
|
|
||||||
} else if (event.ctrlKey && (event.which == 13)) {
|
} else if (event.ctrlKey && (event.which == 13)) {
|
||||||
|
//save
|
||||||
let that = this;
|
let that = this;
|
||||||
this.save().then(res => {
|
this.save().then(res => {
|
||||||
if (res) {
|
if (res) {
|
||||||
|
|
||||||
let storeText = storage.local.getText(that.secret.storeKey + '.text');
|
let storeText = storage.local.getText(that.secret.storeKey + '.text');
|
||||||
let starray = storeText.split("|");
|
let starray = storeText.split("|");
|
||||||
storage.local.setText(that.secret.storeKey + '.text', starray[0] + '|' + starray[1] + '|1|'+ starray[3] +'|' + starray[4]);
|
storage.local.setText(that.secret.storeKey + '.text', starray[0] + '|' + starray[1] + '|1|' + starray[3] + '|' + starray[4]);
|
||||||
|
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -473,7 +425,7 @@ export default {
|
|||||||
if (res) {
|
if (res) {
|
||||||
let storeText = storage.local.getText(that.secret.storeKey + '.text');
|
let storeText = storage.local.getText(that.secret.storeKey + '.text');
|
||||||
let starray = storeText.split("|");
|
let starray = storeText.split("|");
|
||||||
storage.local.setText(that.secret.storeKey + '.text', starray[0] + '|' + starray[1] + '|1|'+ starray[3] +'|' + starray[4]);
|
storage.local.setText(that.secret.storeKey + '.text', starray[0] + '|' + starray[1] + '|1|' + starray[3] + '|' + starray[4]);
|
||||||
location.reload();
|
location.reload();
|
||||||
this.state.locking = 0;
|
this.state.locking = 0;
|
||||||
}
|
}
|
||||||
@@ -588,7 +540,20 @@ export default {
|
|||||||
location.reload();
|
location.reload();
|
||||||
|
|
||||||
},
|
},
|
||||||
bindEvent() {
|
bindToTopEvent() {
|
||||||
|
let that = this;
|
||||||
|
window.onscroll = function () {
|
||||||
|
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
||||||
|
if (scrollTop >= 20) {
|
||||||
|
that.toTopState = true;
|
||||||
|
} else {
|
||||||
|
that.toTopState = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//document.getElementsByClassName("ivu-affix")[0]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bindCtrlAllEvent() {
|
||||||
if (document.body.createTextRange) {
|
if (document.body.createTextRange) {
|
||||||
Jquery(document).keydown(function (e) {
|
Jquery(document).keydown(function (e) {
|
||||||
if ((e.ctrlKey || e.metaKey) && e.keyCode == 65) {
|
if ((e.ctrlKey || e.metaKey) && e.keyCode == 65) {
|
||||||
|
|||||||
@@ -62,12 +62,65 @@
|
|||||||
.layout-footer-center {
|
.layout-footer-center {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
.ivu-btn-text:focus {
|
||||||
|
margin-top: -3px;
|
||||||
|
box-shadow: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab_pre {
|
||||||
|
display: inline;
|
||||||
|
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab_pre::selection {
|
||||||
|
background: #ed4014;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab_pre::-moz-selection {
|
||||||
|
background: #ed4014;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.vue-contextmenu-listWrapper {
|
||||||
|
background: #ed4014 !important;
|
||||||
|
border-radius: 0px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vue-contextmenu-listWrapper .context-menu-list {
|
||||||
|
background: #ed4014 !important;
|
||||||
|
margin: 0px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu-list:hover {
|
||||||
|
background: #f16643 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-wrapper-simple {
|
||||||
|
height: 24px !important;
|
||||||
|
margin-top: 1px !important;
|
||||||
|
text-align: left !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-child-btn {
|
||||||
|
padding: 0px 10px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-name-right {
|
||||||
|
margin: 0px 20px 0px 5px !important;
|
||||||
|
color: #ffffff !important;
|
||||||
|
font-size: 14px !important;
|
||||||
|
line-height: 24px !important;
|
||||||
|
font-family: "Bitstream Vera Sans Mono", Consolas, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -78,103 +131,80 @@
|
|||||||
button span {
|
button span {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
margin-left: -1px !important;
|
margin-left: -1px !important;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="layout">
|
<div class="layout">
|
||||||
<Layout>
|
<Layout>
|
||||||
<Affix :offset-top="0">
|
|
||||||
|
|
||||||
|
|
||||||
<Header class="header">
|
<Header class="header">
|
||||||
<div>
|
<Row>
|
||||||
<Row>
|
<Col :xs="{ span: 24, offset: 0 }" :sm="{ span: 22, offset: 1 }" :md="{ span: 20, offset: 2 }"
|
||||||
<Col :xs="{ span: 24, offset: 0 }" :sm="{ span: 22, offset: 1 }" :md="{ span: 20, offset: 2 }"
|
:lg="{ span: 18, offset: 3 }" :xl="{ span: 16, offset: 4 }" :xxl="{ span: 16, offset: 4 }">
|
||||||
:lg="{ span: 18, offset: 3 }" :xl="{ span: 16, offset: 4 }" :xxl="{ span: 16, offset: 4 }">
|
<Affix :offset-top="0">
|
||||||
<div id="textToTop" v-on:click="toTop()" :class="[toTopState ? 'showBlock' : 'hideBlock']"
|
<div style="background: white;width:100%;height:40px;">
|
||||||
style="width: 100%;height: 20px;position: absolute;top: 35px;">
|
<img style="height:40px;float:left;" alt="refresh flagnote" src="/static/favicon.png">
|
||||||
<div style="display:inline-block;cursor: pointer;padding:2px;">
|
<div style="float:left;width:auto;">
|
||||||
<Icon type="ios-arrow-up" size="28" color="#ed4014" />
|
|
||||||
</div>
|
<Button-group size="large">
|
||||||
|
|
||||||
|
<Button aria-label="share" type="error"
|
||||||
|
style="margin-left:5px; border-radius: 0px;font-size: 24px; font-family: Arial, sans-serif"
|
||||||
|
@click="showShareModel()" icon="md-cloud-done">{{ noteForm.ttlDesc }}</Button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<Button aria-label="download text" v-show="model.showDownloadText" type="error"
|
||||||
|
style="margin-left:5px; border-radius: 0px; font-size: 22px;" @click="downLoadText()"
|
||||||
|
icon="md-download"></Button>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</Button-group>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div style="background: white;width:100%;height:40px;">
|
|
||||||
<img style="height:40px;float:left;" src="favicon.png">
|
|
||||||
<div style="float:left;width:auto;">
|
|
||||||
|
|
||||||
<Button-group size="large">
|
<div style="float:right;width:auto;">
|
||||||
|
<Button-group size="large">
|
||||||
|
<Button aria-label="to top" v-show="toTopState" type="text"
|
||||||
|
style="margin-left:0px; border-radius: 0px; font-size: 28px;color:red;line-height: 20px;"
|
||||||
|
@click="toTop()" icon="ios-arrow-up" ghost></Button>
|
||||||
|
|
||||||
<Button type="error"
|
<Button aria-label="create note" type="error"
|
||||||
style="margin-left:5px; border-radius: 0px;font-size: 24px; font-family: Arial, sans-serif"
|
style="margin-left:10px; border-radius: 0px;font-size: 24px;" @click="createNote()"
|
||||||
@click="showShareModel()" icon="md-cloud-done">{{ noteForm.ttlDesc }}</Button>
|
icon="md-add"></Button>
|
||||||
|
<Button aria-label="delete note" type="error"
|
||||||
<!--
|
style="margin-left:5px; border-radius: 0px;font-size: 24px;" @click="showDeleteModel()"
|
||||||
<Button type="error"
|
icon="md-trash"></Button>
|
||||||
style="margin-left:5px; border-radius: 0px; font-size: 22px;"
|
</Button-group>
|
||||||
@click="downLoadImage()" icon="md-download">.png</Button>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<Button v-show="model.showDownloadText" type="error"
|
|
||||||
style="margin-left:5px; border-radius: 0px; font-size: 22px;" @click="downLoadText()"
|
|
||||||
icon="md-download"></Button>
|
|
||||||
|
|
||||||
</Button-group>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div style="float:right;width:auto;">
|
|
||||||
<Button-group size="large">
|
|
||||||
<Button type="error" style="margin-left:0px; border-radius: 0px;font-size: 24px;"
|
|
||||||
@click="createNote()" icon="md-add"></Button>
|
|
||||||
<Button type="error" style="margin-left:5px; border-radius: 0px;font-size: 24px;"
|
|
||||||
@click="showDeleteModel()" icon="md-trash"></Button>
|
|
||||||
</Button-group>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<div style="width:auto;float:right;font-size: 24px;">
|
|
||||||
<Button-group vertical size="large" style="position:absolute;right;0px;top:0px;">
|
|
||||||
<Button type="error" style="border-radius: 0px;font-size: 24px;" icon="md-add"
|
|
||||||
@click="showExt = true"></Button>
|
|
||||||
<Button type="error" v-show="showExt" style="border-radius: 0px;font-size: 24px;"
|
|
||||||
icon="md-cloud-upload"></Button>
|
|
||||||
<Button type="error" v-show="showExt" style="border-radius: 0px;font-size: 24px;"
|
|
||||||
icon="logo-googleplus"></Button>
|
|
||||||
<Button type="error" v-show="showExt" style="border-radius: 0px;font-size: 24px;"
|
|
||||||
icon="logo-tumblr"></Button>
|
|
||||||
</Button-group>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</Affix>
|
||||||
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
</div>
|
</Col>
|
||||||
|
</Row>
|
||||||
</Header>
|
</Header>
|
||||||
|
|
||||||
</Affix>
|
|
||||||
<Content class="content">
|
<Content class="content">
|
||||||
<div style="min-height: 650px;">
|
<div style="min-height: 650px;">
|
||||||
<Row>
|
<Row>
|
||||||
<Col :xs="{ span: 24, offset: 0 }" :sm="{ span: 22, offset: 1 }" :md="{ span: 20, offset: 2 }"
|
<Col :xs="{ span: 24, offset: 0 }" :sm="{ span: 22, offset: 1 }" :md="{ span: 20, offset: 2 }"
|
||||||
:lg="{ span: 18, offset: 3 }" :xl="{ span: 16, offset: 4 }" :xxl="{ span: 16, offset: 4 }">
|
:lg="{ span: 18, offset: 3 }" :xl="{ span: 16, offset: 4 }" :xxl="{ span: 16, offset: 4 }">
|
||||||
<Card :padding="0">
|
<Card :padding="0">
|
||||||
<div style="border-left: 0px solid #FF3366;">
|
<div id="wrapper" style="border-left: 0px solid #FF3366;" @contextmenu="showMenu">
|
||||||
|
<vue-context-menu :contextMenuData="contextMenuData" @selectAllText="selectAllText"
|
||||||
|
@copySelectedText="copySelectedText" @copyAllText="copyAllText">
|
||||||
|
</vue-context-menu>
|
||||||
<div id="noteText" style="text-align: left;min-height: 650px;" class="monoFt"
|
<div id="noteText" style="text-align: left;min-height: 650px;" class="monoFt"
|
||||||
v-html="noteForm.escapeText"></div>
|
v-html="noteForm.escapeText">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
@@ -185,7 +215,9 @@ button span {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<Footer class="layout-footer-center">2022 © flagnote.com</Footer>
|
<Footer class="layout-footer-center">
|
||||||
|
2022 © flagnote.com
|
||||||
|
</Footer>
|
||||||
|
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
||||||
@@ -202,10 +234,11 @@ button span {
|
|||||||
|
|
||||||
<Modal v-model="model.showDelete" width="330" footer-hide class-name="fnmodal" :styles="{ borderRadius: 0 }">
|
<Modal v-model="model.showDelete" width="330" footer-hide class-name="fnmodal" :styles="{ borderRadius: 0 }">
|
||||||
<p style="text-align: center;font-size:medium;margin-bottom: 20px;">
|
<p style="text-align: center;font-size:medium;margin-bottom: 20px;">
|
||||||
{{$t("message.askTodelete")}}
|
{{ $t("message.askTodelete") }}
|
||||||
</p>
|
</p>
|
||||||
<p style="text-align: center;">
|
<p style="text-align: center;">
|
||||||
<Button type="error" :loading="model.delete" style="border-radius: 0px;" @click="dropNote()">{{$t("button.yes")}}</Button>
|
<Button type="error" :loading="model.delete" style="border-radius: 0px;" @click="dropNote()">{{ $t("button.yes")
|
||||||
|
}}</Button>
|
||||||
</p>
|
</p>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|
||||||
@@ -220,14 +253,13 @@ button span {
|
|||||||
import { aesDecrypt, md5, unzip } from "@/libs/secret";
|
import { aesDecrypt, md5, unzip } from "@/libs/secret";
|
||||||
import Jquery from "jquery";
|
import Jquery from "jquery";
|
||||||
import { getSecretKey, getStoreKey } from "@/api/lock";
|
import { getSecretKey, getStoreKey } from "@/api/lock";
|
||||||
import { deleteNote } from "@/api/note";
|
import { deleteNote, getNote } from "@/api/note";
|
||||||
import storage from "@/libs/storage";
|
import storage from "@/libs/storage";
|
||||||
import { getEscapeText } from "@/libs/noteStorage";
|
import { getEscapeText } from "@/libs/noteStorage";
|
||||||
import QRCode from "qrcode";
|
import QRCode from "qrcode";
|
||||||
import Clipboard from "clipboard";
|
import Clipboard from "clipboard";
|
||||||
import { saveAs } from 'file-saver';
|
import { saveAs } from 'file-saver';
|
||||||
import { isWeixin } from "@/libs/utils";
|
import { isWeixin, getNoteUrl } from "@/libs/utils";
|
||||||
// import html2canvas from 'html2canvas';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ViewNote',
|
name: 'ViewNote',
|
||||||
@@ -244,7 +276,7 @@ export default {
|
|||||||
md5: '',
|
md5: '',
|
||||||
lock: 0,
|
lock: 0,
|
||||||
ttl: 3600,
|
ttl: 3600,
|
||||||
ttlDesc: '',
|
ttlDesc: '-- : --',
|
||||||
},
|
},
|
||||||
secret: {
|
secret: {
|
||||||
storeKey: '',
|
storeKey: '',
|
||||||
@@ -263,24 +295,48 @@ export default {
|
|||||||
showDelete: false,
|
showDelete: false,
|
||||||
showShare: false,
|
showShare: false,
|
||||||
deleting: false,
|
deleting: false,
|
||||||
showDownloadText: true,
|
showDownloadText: false,
|
||||||
},
|
},
|
||||||
toTopState: false,
|
toTopState: false,
|
||||||
|
contextMenuData: {
|
||||||
|
menuName: 'textMenu',
|
||||||
|
//菜单显示的位置
|
||||||
|
axis: {
|
||||||
|
x: null,
|
||||||
|
y: null
|
||||||
|
},
|
||||||
|
//菜单选项
|
||||||
|
menulists: [{
|
||||||
|
fnHandler: 'selectAllText', //绑定事件
|
||||||
|
btnName: this.$t("button.selectAll") //菜单名称
|
||||||
|
}, {
|
||||||
|
fnHandler: 'copySelectedText',
|
||||||
|
btnName: this.$t("button.copy")
|
||||||
|
}, {
|
||||||
|
fnHandler: 'copyAllText',
|
||||||
|
btnName: this.$t("button.copyAll")
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
tempFragment: null,
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
// read $route
|
||||||
|
this.noteForm.key = this.$route.params.name;
|
||||||
|
let noteMeta = this.$route.meta.noteMeta;
|
||||||
|
|
||||||
|
//ipad chrome url not redirect
|
||||||
|
let path = location.pathname;
|
||||||
|
if ("/" == path) {
|
||||||
|
history.pushState('', '', '/' + this.noteForm.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
//wx does not show downloadText
|
||||||
this.model.showDownloadText = !isWeixin();
|
this.model.showDownloadText = !isWeixin();
|
||||||
|
|
||||||
|
this.noteForm.noteUrl = getNoteUrl(this.noteForm.key);
|
||||||
let noteMeta = this.$route.meta.noteMeta;
|
this.secret.storeKey = getStoreKey(this.noteForm.key);
|
||||||
this.noteForm.key = this.$route.params.name;
|
|
||||||
|
|
||||||
this.noteForm.noteUrl = "https://flagnote.com/" + this.noteForm.key;
|
|
||||||
let storeKey = getStoreKey(this.noteForm.key);
|
|
||||||
this.secret.storeKey = storeKey;
|
|
||||||
|
|
||||||
if (noteMeta) {
|
if (noteMeta) {
|
||||||
this.state.lock = noteMeta.lock;
|
this.state.lock = noteMeta.lock;
|
||||||
@@ -292,79 +348,79 @@ export default {
|
|||||||
this.noteForm.ttl = noteMeta.ttl;
|
this.noteForm.ttl = noteMeta.ttl;
|
||||||
|
|
||||||
this.startClock();
|
this.startClock();
|
||||||
|
|
||||||
|
storage.local.dynamicClear();
|
||||||
|
|
||||||
this.loadText();
|
this.loadText();
|
||||||
storage.local.dynamicClear(this.secret.currentTime);
|
|
||||||
|
this.bindCtrlAllEvent();
|
||||||
|
this.bindCopyUrlEvent();
|
||||||
|
this.bindToTopEvent();
|
||||||
|
this.bindMouseEvent();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
alert("Unconnected.");
|
||||||
}
|
}
|
||||||
this.bindEvent();
|
|
||||||
|
|
||||||
var clipboard = new Clipboard("#tag-copy")
|
|
||||||
let that = this;
|
|
||||||
clipboard.on('success', function () {
|
|
||||||
//console.log("url copied")
|
|
||||||
//that.$Message.success({content:'url copied',duration: 10,closable:true});
|
|
||||||
that.$Message.success({ content: 'url copied' });
|
|
||||||
});
|
|
||||||
|
|
||||||
clipboard.on('error', function () {
|
|
||||||
that.$Message.error('not allow to copy');
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
window.onscroll = function () {
|
|
||||||
//变量scrollTop是滚动条滚动时,距离顶部的距离
|
|
||||||
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
|
||||||
// //变量windowHeight是可视区的高度
|
|
||||||
// var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
|
|
||||||
// //变量scrollHeight是滚动条的总高度
|
|
||||||
// var scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
|
|
||||||
//滚动条到底部的条件
|
|
||||||
|
|
||||||
if (scrollTop >= 20) {
|
|
||||||
//写后台加载数据的函数
|
|
||||||
//console.log("距顶部" + scrollTop + "可视区高度" + windowHeight + "滚动条总高度" + scrollHeight);
|
|
||||||
|
|
||||||
that.toTopState = true;
|
|
||||||
} else {
|
|
||||||
//toTop.style.setProperty("display", "none")
|
|
||||||
that.toTopState = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
mounted() {
|
||||||
|
this.bindCopyTextEvent();
|
||||||
|
|
||||||
|
const myObserver = new ResizeObserver(entries => {
|
||||||
|
// iterate over the entries, do something.
|
||||||
|
entries.forEach(entry => {
|
||||||
|
let affix = document.querySelector('.ivu-affix');
|
||||||
|
if (affix) {
|
||||||
|
affix.setAttribute("style", "top: 0px; width: " + entry.contentRect.width + "px;");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const someOtherEl = document.querySelector('#wrapper');
|
||||||
|
myObserver.observe(someOtherEl);
|
||||||
|
|
||||||
|
},
|
||||||
|
updated() {
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
watch: {},
|
||||||
|
methods: {
|
||||||
|
selectAllText() {
|
||||||
|
var element = document.getElementById("noteText");
|
||||||
|
if (window.getSelection) {
|
||||||
|
let selection = window.getSelection();
|
||||||
|
let range = document.createRange();
|
||||||
|
range.selectNodeContents(element);
|
||||||
|
selection.removeAllRanges();
|
||||||
|
selection.addRange(range);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
copySelectedText() {
|
||||||
|
|
||||||
|
},
|
||||||
|
copyAllText() {
|
||||||
|
|
||||||
|
},
|
||||||
|
showMenu(event) {
|
||||||
|
event.preventDefault()
|
||||||
|
var x = event.clientX
|
||||||
|
var y = event.clientY
|
||||||
|
// Get the current location
|
||||||
|
this.contextMenuData.axis = {
|
||||||
|
x, y
|
||||||
|
}
|
||||||
|
},
|
||||||
downLoadText() {
|
downLoadText() {
|
||||||
var blob = new Blob([this.noteForm.text], { type: "application/octet-stream;charset=utf-8" });
|
var blob = new Blob([this.noteForm.text], { type: "application/octet-stream;charset=utf-8" });
|
||||||
saveAs(blob, this.noteForm.key + ".txt");
|
saveAs(blob, this.noteForm.key + ".txt");
|
||||||
},
|
|
||||||
downLoadImage() {
|
|
||||||
|
|
||||||
//let that = this;
|
|
||||||
|
|
||||||
//html2canvas(document.getElementById("noteText")).then(function(canvas) {
|
|
||||||
|
|
||||||
// var canvas = document.getElementById("my-canvas");
|
|
||||||
//canvas.toBlob(function(blob) {
|
|
||||||
// saveAs(blob, that.noteForm.key+".png");
|
|
||||||
// });
|
|
||||||
|
|
||||||
// alert(canvas)
|
|
||||||
// document.body.appendChild(canvas);
|
|
||||||
//});
|
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
toTop() {
|
toTop() {
|
||||||
window.scrollTo(0, 0);
|
window.scrollTo(0, 0);
|
||||||
this.downLoadImage();
|
|
||||||
},
|
},
|
||||||
startClock() {
|
startClock() {
|
||||||
let that = this;
|
let that = this;
|
||||||
@@ -403,7 +459,6 @@ export default {
|
|||||||
window.open("/");
|
window.open("/");
|
||||||
},
|
},
|
||||||
showShareModel() {
|
showShareModel() {
|
||||||
|
|
||||||
this.model.showShare = true;
|
this.model.showShare = true;
|
||||||
let qrimg = document.getElementById("qrimg");
|
let qrimg = document.getElementById("qrimg");
|
||||||
let qrurl = "https://flagnote.com/" + this.noteForm.key;
|
let qrurl = "https://flagnote.com/" + this.noteForm.key;
|
||||||
@@ -423,7 +478,6 @@ export default {
|
|||||||
},
|
},
|
||||||
showDeleteModel() {
|
showDeleteModel() {
|
||||||
this.model.showDelete = true;
|
this.model.showDelete = true;
|
||||||
|
|
||||||
},
|
},
|
||||||
dropNote() {
|
dropNote() {
|
||||||
this.model.deleting = true;
|
this.model.deleting = true;
|
||||||
@@ -431,7 +485,6 @@ export default {
|
|||||||
deleteNote(this.noteForm.key).then(res => {
|
deleteNote(this.noteForm.key).then(res => {
|
||||||
if (res) {
|
if (res) {
|
||||||
storage.local.delete(that.secret.storeKey + '.text');
|
storage.local.delete(that.secret.storeKey + '.text');
|
||||||
storage.session.delete(that.secret.storeKey + '.keyMeta');
|
|
||||||
location.reload();
|
location.reload();
|
||||||
} else {
|
} else {
|
||||||
that.model.deleting = false;
|
that.model.deleting = false;
|
||||||
@@ -439,25 +492,28 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
loadText() {
|
loadText() {
|
||||||
let password;
|
let password = '';
|
||||||
|
|
||||||
if (this.noteForm.lock == 1) {
|
if (this.noteForm.lock == 1) {
|
||||||
password = "FLAGNOTE"; //默认密码
|
password = "FLAGNOTE"; //默认密码
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!password) {
|
|
||||||
password = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
let secretKey = getSecretKey(this.noteForm.key, password);
|
let secretKey = getSecretKey(this.noteForm.key, password);
|
||||||
let storeText = storage.local.getText(this.secret.storeKey + '.text');
|
let storeText = storage.local.getText(this.secret.storeKey + '.text');
|
||||||
if (!storeText || (md5(storeText.substring(51)) != this.noteForm.md5)) {
|
if (!storeText || (md5(storeText.substring(51)) != this.noteForm.md5)) {
|
||||||
let note = this.getNote(this.noteForm.key);
|
// local is useless
|
||||||
storeText = this.noteForm.lock + '|' + this.secret.cipher + '|1|' + this.noteForm.currentTime + '|' + note.text;
|
let note = getNote(this.noteForm.key);
|
||||||
storage.local.setText(this.secret.storeKey + '.text', storeText);
|
// if lack of local , not set local
|
||||||
|
if (storage.local.getAvailableSize() > 1 * 1024 * 1024) {
|
||||||
|
storeText = this.noteForm.lock + '|' + this.secret.cipher + '|1|' + this.secret.currentTime + '|' + note.text;
|
||||||
|
storage.local.setText(this.secret.storeKey + '.text', storeText);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// local is usable, and set commited flag
|
||||||
var starray = storeText.split('|');
|
var starray = storeText.split('|');
|
||||||
storage.local.setText(this.secret.storeKey + '.text', starray[0] + "|" + starray[1] + "|1|" + starray[3] + "|" + starray[4]);
|
if ("0" == starray[2]) {
|
||||||
|
storage.local.setText(this.secret.storeKey + '.text', starray[0] + "|" + starray[1] + "|1|" + starray[3] + "|" + starray[4]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (storeText) {
|
if (storeText) {
|
||||||
@@ -465,36 +521,84 @@ export default {
|
|||||||
let plainText = aesDecrypt(storeText, secretKey);
|
let plainText = aesDecrypt(storeText, secretKey);
|
||||||
if (plainText.startsWith("FLAGNOTE#")) {
|
if (plainText.startsWith("FLAGNOTE#")) {
|
||||||
this.noteForm.text = plainText.substring(9);
|
this.noteForm.text = plainText.substring(9);
|
||||||
let escapeText = getEscapeText(this.noteForm.text);
|
this.noteForm.escapeText = getEscapeText(this.noteForm.text);
|
||||||
this.noteForm.escapeText = escapeText;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getNote(key) {
|
bindToTopEvent() {
|
||||||
let noteObject;
|
let that = this;
|
||||||
Jquery.ajax({
|
window.onscroll = function () {
|
||||||
url: '/note/' + key,
|
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
||||||
async: false,
|
if (scrollTop >= 20) {
|
||||||
success: function (data) {
|
that.toTopState = true;
|
||||||
noteObject = data;
|
} else {
|
||||||
|
that.toTopState = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
bindCopyUrlEvent() {
|
||||||
|
let that = this;
|
||||||
|
var clipboard = new Clipboard("#tag-copy")
|
||||||
|
clipboard.on('success', function () {
|
||||||
|
that.$Message.success({ content: 'url copied' });
|
||||||
|
});
|
||||||
|
|
||||||
|
clipboard.on('error', function () {
|
||||||
|
that.$Message.error('not allow to copy');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
bindCopyTextEvent() {
|
||||||
|
|
||||||
|
let ele1 = document.getElementsByClassName("vue-contextmenuName-textMenu")[0].children[1].children[0].children[0];
|
||||||
|
let ele2 = document.getElementsByClassName("vue-contextmenuName-textMenu")[0].children[2].children[0].children[0];
|
||||||
|
|
||||||
|
let that = this;
|
||||||
|
|
||||||
|
const clipboard1 = new Clipboard(ele1, { // 绑定需要的触发的dom
|
||||||
|
text: function () {
|
||||||
|
let fragment = that.tempFragment;
|
||||||
|
|
||||||
|
if (fragment) {
|
||||||
|
let copyText = "";
|
||||||
|
|
||||||
|
fragment.childNodes.forEach(element => {
|
||||||
|
if (3 == element.nodeType) {
|
||||||
|
copyText += element.textContent.replace(new RegExp('\u00a0', 'gm'), " ");
|
||||||
|
} else if (1 == element.nodeType) {
|
||||||
|
if ("BR" == element.nodeName) {
|
||||||
|
copyText += "\r\n";
|
||||||
|
} else if ("PRE" == element.nodeName) {
|
||||||
|
copyText += "\t";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return copyText;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return noteObject;
|
clipboard1.on('success', function () {
|
||||||
|
that.$Message.success({ content: 'selected text copied' });
|
||||||
|
});
|
||||||
|
clipboard1.on('error', function () {
|
||||||
|
that.$Message.error('not allow to copy');
|
||||||
|
});
|
||||||
|
|
||||||
|
const clipboard2 = new Clipboard(ele2, { // 绑定需要的触发的dom
|
||||||
|
text: function () {
|
||||||
|
return that.noteForm.text;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clipboard2.on('success', function () {
|
||||||
|
that.$Message.success({ content: 'text copied' });
|
||||||
|
});
|
||||||
|
clipboard2.on('error', function () {
|
||||||
|
that.$Message.error('not allow to copy');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
bindEvent() {
|
bindCtrlAllEvent() {
|
||||||
if (document.body.createTextRange) {
|
if (window.getSelection) {
|
||||||
Jquery(document).keydown(function (e) {
|
|
||||||
if ((e.ctrlKey || e.metaKey) && e.keyCode == 65) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
var element = document.getElementById("noteText");
|
|
||||||
let range = document.body.createTextRange();
|
|
||||||
range.moveToElementText(element);
|
|
||||||
range.select();
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else if (window.getSelection) {
|
|
||||||
|
|
||||||
Jquery(document).keydown(function (e) {
|
Jquery(document).keydown(function (e) {
|
||||||
if ((e.ctrlKey || e.metaKey) && e.keyCode == 65) {
|
if ((e.ctrlKey || e.metaKey) && e.keyCode == 65) {
|
||||||
@@ -511,11 +615,20 @@ export default {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
|
||||||
//alert('none');
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
bindMouseEvent() {
|
||||||
|
let that = this;
|
||||||
|
document.addEventListener('mouseup', function (e) {
|
||||||
|
if (e.button === 2) {
|
||||||
|
if (window.getSelection) {
|
||||||
|
let sel = window.getSelection();
|
||||||
|
if (sel.rangeCount > 0) {
|
||||||
|
that.tempFragment = sel.getRangeAt(0).cloneContents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ const { defineConfig } = require("@vue/cli-service");
|
|||||||
const CompressionPlugin = require("compression-webpack-plugin");
|
const CompressionPlugin = require("compression-webpack-plugin");
|
||||||
|
|
||||||
module.exports = defineConfig({
|
module.exports = defineConfig({
|
||||||
|
assetsDir:'static',
|
||||||
|
productionSourceMap: false,
|
||||||
configureWebpack: {
|
configureWebpack: {
|
||||||
|
devtool: false,
|
||||||
plugins: [
|
plugins: [
|
||||||
new CompressionPlugin({
|
new CompressionPlugin({
|
||||||
algorithm: "gzip", // 使用gzip压缩
|
algorithm: "gzip", // 使用gzip压缩
|
||||||
|
|||||||
24
yarn.lock
24
yarn.lock
@@ -920,7 +920,7 @@
|
|||||||
"@babel/types" "^7.4.4"
|
"@babel/types" "^7.4.4"
|
||||||
esutils "^2.0.2"
|
esutils "^2.0.2"
|
||||||
|
|
||||||
"@babel/runtime@^7.12.13", "@babel/runtime@^7.8.4":
|
"@babel/runtime@^7.12.13", "@babel/runtime@^7.13.10", "@babel/runtime@^7.8.4":
|
||||||
version "7.18.9"
|
version "7.18.9"
|
||||||
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.18.9.tgz"
|
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.18.9.tgz"
|
||||||
integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==
|
integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==
|
||||||
@@ -2323,7 +2323,7 @@ compressible@~2.0.16:
|
|||||||
|
|
||||||
compression-webpack-plugin@^10.0.0:
|
compression-webpack-plugin@^10.0.0:
|
||||||
version "10.0.0"
|
version "10.0.0"
|
||||||
resolved "https://registry.npmmirror.com/compression-webpack-plugin/-/compression-webpack-plugin-10.0.0.tgz#3496af1b0dc792e13efc474498838dbff915c823"
|
resolved "https://registry.npmmirror.com/compression-webpack-plugin/-/compression-webpack-plugin-10.0.0.tgz"
|
||||||
integrity sha512-wLXLIBwpul/ALcm7Aj+69X0pYT3BYt6DdPn3qrgBIh9YejV9Bju9ShhlAsjujLyWMo6SAweFIWaUoFmXZNuNrg==
|
integrity sha512-wLXLIBwpul/ALcm7Aj+69X0pYT3BYt6DdPn3qrgBIh9YejV9Bju9ShhlAsjujLyWMo6SAweFIWaUoFmXZNuNrg==
|
||||||
dependencies:
|
dependencies:
|
||||||
schema-utils "^4.0.0"
|
schema-utils "^4.0.0"
|
||||||
@@ -5898,6 +5898,13 @@ vue-cli-plugin-iview@^2.0.0:
|
|||||||
resolved "https://registry.npmmirror.com/vue-cli-plugin-iview/-/vue-cli-plugin-iview-2.0.0.tgz"
|
resolved "https://registry.npmmirror.com/vue-cli-plugin-iview/-/vue-cli-plugin-iview-2.0.0.tgz"
|
||||||
integrity sha512-aHkGrn4MKa4Tb2u14TI8t50bemcOyhxwuzeAZnTbJvs7o/v0AfdBMyMuAyUEeAl0hWCy+jveCfUEEO54SHHrsQ==
|
integrity sha512-aHkGrn4MKa4Tb2u14TI8t50bemcOyhxwuzeAZnTbJvs7o/v0AfdBMyMuAyUEeAl0hWCy+jveCfUEEO54SHHrsQ==
|
||||||
|
|
||||||
|
vue-contextmenu@^1.5.11:
|
||||||
|
version "1.5.11"
|
||||||
|
resolved "https://registry.npmmirror.com/vue-contextmenu/-/vue-contextmenu-1.5.11.tgz"
|
||||||
|
integrity sha512-H9CdXqiVMRJsUX+ah9k2olywZUiJ+sq6EkCGkLza+DFx0PChIJzZPlsVNPOMgcFInYkigh+QRw2S4Bu7nUXGlA==
|
||||||
|
dependencies:
|
||||||
|
vue "^2.6.9"
|
||||||
|
|
||||||
vue-eslint-parser@^8.0.1:
|
vue-eslint-parser@^8.0.1:
|
||||||
version "8.3.0"
|
version "8.3.0"
|
||||||
resolved "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz"
|
resolved "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-8.3.0.tgz"
|
||||||
@@ -5916,9 +5923,9 @@ vue-hot-reload-api@^2.3.0:
|
|||||||
resolved "https://registry.npmmirror.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz"
|
resolved "https://registry.npmmirror.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz"
|
||||||
integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==
|
integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==
|
||||||
|
|
||||||
vue-i18n@8.27.2:
|
vue-i18n@^8.27.2:
|
||||||
version "8.27.2"
|
version "8.27.2"
|
||||||
resolved "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-8.27.2.tgz#b649a65ff42b7d1a482679b732902f889965a068"
|
resolved "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-8.27.2.tgz"
|
||||||
integrity sha512-QVzn7u2WVH8F7eSKIM00lujC7x1mnuGPaTnDTmB01Hd709jDtB9kYtBqM+MWmp5AJRx3gnqAdZbee9MelqwFBg==
|
integrity sha512-QVzn7u2WVH8F7eSKIM00lujC7x1mnuGPaTnDTmB01Hd709jDtB9kYtBqM+MWmp5AJRx3gnqAdZbee9MelqwFBg==
|
||||||
|
|
||||||
vue-loader@^17.0.0:
|
vue-loader@^17.0.0:
|
||||||
@@ -5930,6 +5937,13 @@ vue-loader@^17.0.0:
|
|||||||
hash-sum "^2.0.0"
|
hash-sum "^2.0.0"
|
||||||
loader-utils "^2.0.0"
|
loader-utils "^2.0.0"
|
||||||
|
|
||||||
|
vue-resize@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.npmmirror.com/vue-resize/-/vue-resize-1.0.1.tgz#c120bed4e09938771d622614f57dbcf58a5147ee"
|
||||||
|
integrity sha512-z5M7lJs0QluJnaoMFTIeGx6dIkYxOwHThlZDeQnWZBizKblb99GSejPnK37ZbNE/rVwDcYcHY+Io+AxdpY952w==
|
||||||
|
dependencies:
|
||||||
|
"@babel/runtime" "^7.13.10"
|
||||||
|
|
||||||
vue-router@^3.5.1:
|
vue-router@^3.5.1:
|
||||||
version "3.5.4"
|
version "3.5.4"
|
||||||
resolved "https://registry.npmmirror.com/vue-router/-/vue-router-3.5.4.tgz"
|
resolved "https://registry.npmmirror.com/vue-router/-/vue-router-3.5.4.tgz"
|
||||||
@@ -5956,7 +5970,7 @@ vue-template-es2015-compiler@^1.9.0:
|
|||||||
resolved "https://registry.npmmirror.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz"
|
resolved "https://registry.npmmirror.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz"
|
||||||
integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
|
integrity sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==
|
||||||
|
|
||||||
vue@^2.6.14:
|
vue@^2.6.14, vue@^2.6.9:
|
||||||
version "2.7.7"
|
version "2.7.7"
|
||||||
resolved "https://registry.npmmirror.com/vue/-/vue-2.7.7.tgz"
|
resolved "https://registry.npmmirror.com/vue/-/vue-2.7.7.tgz"
|
||||||
integrity sha512-osfkncsGCWqtch+YWYxbqTNQ9hl/UQ6TFRkdmK/VqAjuMpxzr5QotFsYpmJ1AB1ez2LJeIKXDmtMkXUotMOTsA==
|
integrity sha512-osfkncsGCWqtch+YWYxbqTNQ9hl/UQ6TFRkdmK/VqAjuMpxzr5QotFsYpmJ1AB1ez2LJeIKXDmtMkXUotMOTsA==
|
||||||
|
|||||||
Reference in New Issue
Block a user