diff --git a/static/css/myEdit.css b/static/css/myEdit.css
index b0cfe3f..59f6a7c 100644
--- a/static/css/myEdit.css
+++ b/static/css/myEdit.css
@@ -1,7 +1,54 @@
/* 字体 */
-:root {
- /* font-size: calc(0.5em + 1vw); */
- /*font-size: 62.5%;*/
+/*:root {*/
+/* font-size: calc(0.5em + 1vw); */
+/*font-size: 62.5%;*/
+/*}*/
+
+body, html {
+ width: 100%;
+ height: 100%;
+}
+
+/* border + padding + body = width */
+*, :after, :before {
+ box-sizing: border-box;
+
+ /*选中可编辑框是 外层隐藏黑线*/
+ outline: none;
+}
+
+html {
+ font-family: sans-serif;
+ line-height: 1.15;
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+ -ms-overflow-style: scrollbar;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0)
+}
+
+/*@-ms-viewport {*/
+/* width: device-width;*/
+/*}*/
+
+body {
+ color: #262626;
+ font-family: Chinese Quote, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Helvetica Neue, Helvetica, Arial, sans-serif;
+ font-variant: tabular-nums;
+ line-height: 1.5715;
+ background-color: #fff;
+ font-feature-settings: "tnum", "tnum";
+
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ /*background-color: #ffebc3;*/
+}
+
+hr {
+ box-sizing: content-box;
+ height: 0;
+ overflow: visible
}
/* style sheet for "A4" printing */
@@ -18,49 +65,86 @@
}
}
-* {
- /* margin: 1px 2px;
- padding: 1px 2px; */
- /*font-family: Roboto-Regular, PingFang SC, SF Pro SC, SF Pro Text, SF Pro Icons, Helvetica Neue, Roboto, Helvetica, Arial, sans-serif;*/
- outline: none;
- /* box-sizing: border-box; */
-}
-
-body {
- font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", Helvetica, Arial, "Microsoft YaHei", 微软雅黑, 黑体, Heiti, sans-serif, SimSun, 宋体, serif, SourceSansPro;
-
- display: flex;
- flex-direction: column;
- justify-content: center;
- /*align-items: center;*/
-
- /*background-color: #ffebc3;*/
-}
header {
- /*position: relative;*/
- /*top: 0;*/
+ position: fixed;
/*border: 1px yellow solid;*/
- /*!* height: 8rem; *!*/
- /*z-index: 9999;*/
- /*left: 0;*/
+ z-index: 9999;
+ top: 0;
+ left: 0;
/*right: 0;*/
- /*width: 100%;*/
+ width: 100%;
+ min-height: 580rem;
+
+ /*background-color: #ffebc3;*/
+ /*background-color: deepskyblue;*/
/*响应式*/
- /*display: flex;*/
- /*flex-direction:column;*/
- /*flex-wrap: nowrap;*/
-}
-
-main {
display: flex;
flex-direction: column;
align-items: center;
+ /*flex-wrap: nowrap;*/
}
-#noteshare {
- width: 80%;
+#head_top{
+ width: 100%;
+ height: 320rem;
+
+ border: 1px #f5f5f5 solid;
+ /*box-shadow: 0 40rem 80rem rgba(31, 35, 41, 0.1);*/
+ background-color: rgb(255, 255, 255);
+ /*background-color: blue;*/
+
+ font-size: 16px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+.fixStylePosition {
+ display: block;
+ width: 100%;
+ height: 260rem;
+
+ /*border: 1px #dee0e3 solid;*/
+ /*border: 1px orange solid;*/
+
+ background-color: rgb(255, 255, 255);
+ border: 1px #f5f5f5 solid;
+ /*box-shadow: 0 40rem 80rem rgba(31, 35, 41, 0.1);*/
+}
+
+.fixStyleOut {
+ /*border: 1px blue solid;*/
+ margin: 0 0;
+ width: auto;
+ /*height: 130rem;*/
+ padding: 50rem 50rem;
+
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ /*align-content: center;*/
+}
+
+.fixStyleInnerSpan {
+ margin: 0 80rem;
+}
+
+main {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ margin-top: 580rem;
+ /*min-height: 80%;*/
+
+ /*border: 1px greenyellow solid;*/
+}
+
+#yxl_note {
+ width: 60%;
/* width: 21cm; */
min-height: 2000rem;
/* font-size: 1.5rem; */
@@ -77,7 +161,7 @@ main {
}
-#noteshare p {
+#yxl_note p {
/*border: 1px rgb(248, 245, 245) solid;*/
margin: 0 0;
padding: 0 0;
@@ -109,86 +193,26 @@ main {
margin: 0 60rem;
}
-.childStyleStrong {
- font-weight: bold
-}
-
-.childStyleI {
- font-style: italic;
-}
-
-.childStyleU {
- text-decoration: underline;
- /*/ / 中划线 / / text-decoration: line-through;*/
-}
-
-.childStyleDel {
- text-decoration: line-through;
-}
-
-.childStyleColor {
- color: red;
+footer{
+ width: 100%;
}
-.fixStylePosition {
- display: none;
- position: fixed;
- z-index: 99;
- width: auto;
- /*height: 200rem;*/
+/*@media screen and ( max-width: 1024px ) {*/
+/* !*当屏幕尺寸小于768px时,应用下面的css样式*!*/
+/* .fixStylePosition {*/
+/* display: block;*/
+/* z-index: 99;*/
+/* top: 0;*/
+/* width: 100%;*/
+/* min-height: 200rem;*/
+/* margin-bottom: 3rem;*/
+/* }*/
- padding: 20rem 30rem;
- /*padding: 0.6rem 1rem 0.6rem 1rem;*/
- justify-content: center;
- align-items: center;
- align-content: center;
- border-radius: 80rem;
- border: 1px #dee0e3 solid;
- background-color: rgb(255, 255, 255);
- /*box-shadow: 0.1rem 0.1rem 0.1rem 0.1rem lightgrey;*/
- box-shadow: 0 40rem 80rem rgba(31, 35, 41, 0.1);
-}
+/* #_style_utils svg {*/
+/* width: 400rem;*/
+/* height: 400rem;*/
+/* margin: 50rem 0;*/
+/* }*/
-.fixStyleOut {
- /*border: 1px blue solid;*/
- margin: 0 0;
- width: auto;
- /*height: 130rem;*/
- /*padding: 20rem 20rem;*/
-
- display: flex;
- justify-content: center;
- align-items: center;
- align-content: center;
-}
-
-.fixStyleInnerSpan {
- margin: 0 80rem;
-}
-
-@media screen and ( max-width: 1024px ) {
- /*当屏幕尺寸小于768px时,应用下面的css样式*/
- .fixStylePosition {
- display: block;
- z-index: 99;
- top: 0;
- width: 100%;
- min-height: 200rem;
- margin-bottom: 3rem;
- }
-
- body {
- top: 1%;
- }
-
- #_style_utils svg {
- width: 400rem;
- height: 400rem;
- margin: 50rem 0;
- }
-
- main {
- margin-top: 500rem;
- }
-}
+/*}*/
diff --git a/static/css/myEdit.css.old b/static/css/myEdit.css.old
new file mode 100644
index 0000000..b0cfe3f
--- /dev/null
+++ b/static/css/myEdit.css.old
@@ -0,0 +1,194 @@
+/* 字体 */
+:root {
+ /* font-size: calc(0.5em + 1vw); */
+ /*font-size: 62.5%;*/
+}
+
+/* style sheet for "A4" printing */
+@media print and (width: 21cm) and (height: 29.7cm) {
+ @page {
+ margin: 3cm;
+ }
+}
+
+/* style sheet for "letter" printing */
+@media print and (width: 8.5in) and (height: 11in) {
+ @page {
+ margin: 1in;
+ }
+}
+
+* {
+ /* margin: 1px 2px;
+ padding: 1px 2px; */
+ /*font-family: Roboto-Regular, PingFang SC, SF Pro SC, SF Pro Text, SF Pro Icons, Helvetica Neue, Roboto, Helvetica, Arial, sans-serif;*/
+ outline: none;
+ /* box-sizing: border-box; */
+}
+
+body {
+ font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", Helvetica, Arial, "Microsoft YaHei", 微软雅黑, 黑体, Heiti, sans-serif, SimSun, 宋体, serif, SourceSansPro;
+
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ /*align-items: center;*/
+
+ /*background-color: #ffebc3;*/
+}
+
+header {
+ /*position: relative;*/
+ /*top: 0;*/
+ /*border: 1px yellow solid;*/
+ /*!* height: 8rem; *!*/
+ /*z-index: 9999;*/
+ /*left: 0;*/
+ /*right: 0;*/
+ /*width: 100%;*/
+
+ /*响应式*/
+ /*display: flex;*/
+ /*flex-direction:column;*/
+ /*flex-wrap: nowrap;*/
+}
+
+main {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+#noteshare {
+ width: 80%;
+ /* width: 21cm; */
+ min-height: 2000rem;
+ /* font-size: 1.5rem; */
+
+ /*border: 1px red solid;*/
+ margin: auto auto;
+ padding: 100rem 100rem;
+ /*box-shadow: 0 40rem 80rem rgba(31, 35, 41, 0.1);*/
+
+ /*响应式*/
+ /*display: flex;*/
+ /*flex-direction:column;*/
+ /*flex-wrap: nowrap;*/
+
+}
+
+#noteshare p {
+ /*border: 1px rgb(248, 245, 245) solid;*/
+ margin: 0 0;
+ padding: 0 0;
+ /* border: none; */
+
+ /*响应式*/
+ flex: 1 1 100%;
+}
+
+
+#testInput {
+ width: 60%;
+ min-height: 1000rem;
+ border: 1px rgb(0, 140, 255) solid;
+ margin: 20px auto;
+ justify-content: center;
+}
+
+::selection {
+ color: antiquewhite;
+ background-color: cadetblue;
+ text-shadow: #00a9ff;
+}
+
+.my-divider-item {
+ background-color: #e9e9eb;
+ width: 1px;
+ height: 180rem;
+ margin: 0 60rem;
+}
+
+.childStyleStrong {
+ font-weight: bold
+}
+
+.childStyleI {
+ font-style: italic;
+}
+
+.childStyleU {
+ text-decoration: underline;
+ /*/ / 中划线 / / text-decoration: line-through;*/
+}
+
+.childStyleDel {
+ text-decoration: line-through;
+}
+
+.childStyleColor {
+ color: red;
+}
+
+
+.fixStylePosition {
+ display: none;
+ position: fixed;
+ z-index: 99;
+ width: auto;
+ /*height: 200rem;*/
+
+ padding: 20rem 30rem;
+ /*padding: 0.6rem 1rem 0.6rem 1rem;*/
+ justify-content: center;
+ align-items: center;
+ align-content: center;
+ border-radius: 80rem;
+ border: 1px #dee0e3 solid;
+ background-color: rgb(255, 255, 255);
+ /*box-shadow: 0.1rem 0.1rem 0.1rem 0.1rem lightgrey;*/
+ box-shadow: 0 40rem 80rem rgba(31, 35, 41, 0.1);
+}
+
+.fixStyleOut {
+ /*border: 1px blue solid;*/
+ margin: 0 0;
+ width: auto;
+ /*height: 130rem;*/
+ /*padding: 20rem 20rem;*/
+
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ align-content: center;
+}
+
+.fixStyleInnerSpan {
+ margin: 0 80rem;
+}
+
+@media screen and ( max-width: 1024px ) {
+ /*当屏幕尺寸小于768px时,应用下面的css样式*/
+ .fixStylePosition {
+ display: block;
+ z-index: 99;
+ top: 0;
+ width: 100%;
+ min-height: 200rem;
+ margin-bottom: 3rem;
+ }
+
+ body {
+ top: 1%;
+ }
+
+ #_style_utils svg {
+ width: 400rem;
+ height: 400rem;
+ margin: 50rem 0;
+ }
+
+ main {
+ margin-top: 500rem;
+ }
+}
diff --git a/static/css/normalize.css b/static/css/normalize.css
index 443e1a6..9732f7e 100644
--- a/static/css/normalize.css
+++ b/static/css/normalize.css
@@ -405,7 +405,7 @@ select {
button,
html input[type="button"],
-/* 1 */
+ /* 1 */
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button;
diff --git a/static/js/common/MyRecovery.js b/static/js/common/MyRecovery.js
new file mode 100644
index 0000000..b5ae3fe
--- /dev/null
+++ b/static/js/common/MyRecovery.js
@@ -0,0 +1,28 @@
+"use strict";
+/**
+ * 恢复实体
+ */
+define(function (require, exports, module) {
+
+ class MyRecovery {
+ constructor(data, func) {
+ this.data = data;
+ this.func = func;
+ }
+
+ getData() {
+ return this.data;
+ }
+
+ getFun() {
+ return this.func;
+ }
+
+ recovery() {
+ this.func();
+ }
+ }
+
+ //导出
+ module.exports= MyRecovery;
+});
\ No newline at end of file
diff --git a/static/js/common/a4Utils.js b/static/js/common/a4Utils.js
new file mode 100644
index 0000000..ef6a17d
--- /dev/null
+++ b/static/js/common/a4Utils.js
@@ -0,0 +1,37 @@
+"use strict";
+define(function (require, exports, module) {
+ class A4Utils {
+ constructor() {
+ let dpi = this.GetDPI();
+ let width_mm = 210; // A4纸宽度,单位:毫米
+ let height_mm = 297; // A4纸高度,单位:毫米
+ let width_px = this.MmToPixel(width_mm, dpi);
+ let height_px = this.MmToPixel(height_mm, dpi);
+ this.width = width_px;
+ this.height = height_px;
+ }
+
+ /**
+ * A4纸
+ */
+ GetDPI() {
+ let tempDiv = document.createElement("div");
+ tempDiv.style.width = "1in";
+ tempDiv.style.visibility = "hidden";
+ document.body.appendChild(tempDiv);
+ let dpi = tempDiv.offsetWidth;
+ document.body.removeChild(tempDiv);
+ return dpi;
+ }
+
+ MmToPixel(mm, dpi) {
+ // 1 inch = 25.4 mm
+ let inches = mm / 25.4;
+ let pixels = inches * dpi;
+ return Math.round(pixels);
+ }
+ }
+
+
+ module.exports = new A4Utils();
+})
\ No newline at end of file
diff --git a/static/js/common/ctx.js b/static/js/common/ctx.js
new file mode 100644
index 0000000..91d1ef3
--- /dev/null
+++ b/static/js/common/ctx.js
@@ -0,0 +1,139 @@
+"use strict";
+define(function (require, exports, module) {
+ console.log(("import ctx"))
+
+ class MyCtx {
+ #MyRoot = null;
+
+ constructor() {
+ console.log(("ctx init"));
+
+ //可以修改的
+ let editFrontSize = localStorage.getItem('editFrontSize');
+ if (editFrontSize !== undefined && editFrontSize !== null) {
+ this.editFrontSize = editFrontSize;
+ } else {
+ this.editFrontSize = 14;
+ }
+
+ this.usn = "syjSyj";
+ this.docType = 0;
+
+ // 获取 User-Agent 字符串
+ const userAgent = window.navigator.userAgent;
+ // 判断是否是手机
+ this.isMobile = /mobi|android|iphone|ipad|ipod/i.test(userAgent.toLocaleLowerCase()) || this.getScreenWidth() < 768;
+ this.isIOS = /iphone|ipad|ipod/i.test(userAgent.toLocaleLowerCase()) || this.getScreenWidth() < 768;
+ this.isAndroid = /android/i.test(userAgent.toLocaleLowerCase()) || this.getScreenWidth() < 768;
+ // 判断是否是平板电脑
+ this.isTablet = /tablet/i.test(userAgent.toLocaleLowerCase()) || (this.getScreenWidth() >= 768 && this.getScreenWidth() < 1024);
+
+ //屏幕宽高
+ this.screenWidth = 0;
+ this.screenHeight = 0;
+
+ //默认a4 纸
+ const a4Utils = require('./a4Utils');
+ this.designWith = a4Utils.width;
+
+ //h5 this.MyRoot
+ //文档map
+ this.doc = new Map();
+ //行号
+ this.rowNo = 0;
+ //是否开始输入中文
+ this.inCompositionEvent = false;
+
+ //最近一次操作
+ this.latestOpDoc = null;
+
+
+ //初始化
+ }
+
+ MyRoot() {
+ if (this.#MyRoot === null) {
+ this.#MyRoot = document.getElementById("yxl_note");
+ }
+ return this.#MyRoot
+ }
+
+ getMapItem(orderNo) {
+ return this.docMap.get(orderNo);
+ }
+
+ incrementNumThenReturn() {
+ return this.rowNo++;
+ }
+
+ getScreenWidth() {
+ return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
+ }
+
+ getScreenHeight() {
+ return window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
+ }
+
+
+ /**
+ * 新增一个元素
+ * @param newParagraph
+ */
+ addNewParagraph(newParagraph) {
+ //docRoot
+ this.MyRoot.appendChild(newParagraph);
+
+ //mapRoot
+ let myP = new MyDocItem(newParagraph);
+ let curOrder = myP.parseOrder();
+ let uuid = myP.parseUuid();
+ this.doc.set(curOrder, new MyMapItem(uuid))
+
+ //收起选区到一个点,光标落在一个可编辑元素上
+ window.myEdit.utils.GetSelection().setPosition(newParagraph, 0);
+ }
+
+ /**
+ * 同步某一行数据到对应的 map节点
+ * @param docP
+ * @constructor
+ */
+ SyncMapItemChildrenStyle(docP) {
+ //子元素为空不处理
+ let items = docP.childNodes;
+ if (items.length <= 0) {
+ return
+ }
+
+ //构造参数
+ let curMyP = new MyDocItem(docP);
+ let mapItem = window.myEdit.ctx.getMapItem(curMyP.parseOrder());
+
+ //清空重置
+ // console.log(mapItem);
+ mapItem.getStyle().setChildrenStyleMapNull();
+ //遍历
+ for (let i = 0; i < items.length; i++) {
+ let curItem = items[i];
+ let tmpClassList = curItem.classList;
+ if (tmpClassList != null && tmpClassList.length > 0) {
+ mapItem.getStyle().setChildrenStyle(i, tmpClassList);
+ }
+ }
+
+ // console.log("sync docP : ", docP, " children: ", docP.children, " childrenMap: ", mapItem.getStyle().getChildrenStyleMap())
+ }
+
+ /**
+ *
+ */
+ showTestText() {
+
+ }
+
+ }
+
+
+ // 初始化一次
+ module.exports = new MyCtx();
+})
\ No newline at end of file
diff --git a/static/js/common/demo.js b/static/js/common/demo.js
new file mode 100644
index 0000000..3b14bfc
--- /dev/null
+++ b/static/js/common/demo.js
@@ -0,0 +1,19 @@
+"use strict";
+define(function (require, exports, module) {
+ console.log(("import common"))
+
+ class Demo {
+ constructor() {
+ console.log(("init"))
+ }
+
+ hello() {
+ console.log("hello")
+ }
+
+ }
+
+
+ module.exports = Demo;
+ // module.exports = new Utils();
+})
\ No newline at end of file
diff --git a/static/js/common/doc.js b/static/js/common/doc.js
new file mode 100644
index 0000000..41ee194
--- /dev/null
+++ b/static/js/common/doc.js
@@ -0,0 +1,41 @@
+"use strict";
+define(function (require, exports, module) {
+ console.log(("import common"))
+
+ class Doc {
+ #docType;
+ #docId;
+ #content;
+
+ constructor(docType, docId, title) {
+ this.#docType = docType;
+ this.#docId = docId;
+ this.title = title;
+ this.#content = new Map();
+ }
+
+ getDocType() {
+ return this.#docType;
+ }
+
+ getDocId() {
+ return this.#docId;
+ }
+
+ getContent() {
+ return this.#content;
+ }
+
+ getNode(rowNo) {
+ return this.#content.get(rowNo.toString());
+ }
+
+ setNode(rowNo, node) {
+ this.#content.set(rowNo.toString(), node);
+ }
+
+ }
+
+
+ module.exports = Doc;
+})
\ No newline at end of file
diff --git a/static/js/common/h5_newParagraph.js b/static/js/common/h5_newParagraph.js
new file mode 100644
index 0000000..bc5f0df
--- /dev/null
+++ b/static/js/common/h5_newParagraph.js
@@ -0,0 +1,13 @@
+"use strict";
+/**
+ * 使用样式事件
+ */
+define(function (require, exports, module) {
+
+ function handle(event) {
+
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/common/node.js b/static/js/common/node.js
new file mode 100644
index 0000000..927e0c7
--- /dev/null
+++ b/static/js/common/node.js
@@ -0,0 +1,41 @@
+"use strict";
+define(function (require, exports, module) {
+ console.log(("import common"))
+
+ class Node {
+ #id;
+ #source;
+ #innerStyleList;
+
+ constructor(nodeId, start, end, source, type = "yxu_p") {
+ this.#id = nodeId;
+ this.#source = source;
+ this.type = type;
+ this.start = start;
+ this.end = end;
+ this.collpseChildren = false;
+
+ //样式数组 [{"k1":"v1","k2":"k2"},{}]
+ this.#innerStyleList = [];
+ }
+
+ getNodeId() {
+ return this.#id;
+ }
+
+ getInnerStyleList() {
+ return this.#innerStyleList;
+ }
+
+ updateInnerStyleList(styleList) {
+ this.#innerStyleList = styleList;
+ }
+
+ updateSource(source) {
+ this.source = source;
+ }
+ }
+
+
+ module.exports = Node;
+})
\ No newline at end of file
diff --git a/static/js/common/utils.js b/static/js/common/utils.js
new file mode 100644
index 0000000..bf9ff93
--- /dev/null
+++ b/static/js/common/utils.js
@@ -0,0 +1,160 @@
+"use strict";
+define(function (require, exports, module) {
+ return {
+ /**
+ *
+ */
+ charSources: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_'.split(''),
+
+
+ /**
+ * 十进制 转 63进制
+ * @param val
+ * @constructor
+ */
+ Parse10To63(val) {
+ if (val <= 10) {
+ return (val - 1) + "";
+ }
+
+ let sources = this.charSources;
+ let result = [];
+ let num = 0;
+ let mx = 63, baseMix = 63;
+ let tmp = 0;
+ while (val > 0) {
+
+ let mod = val % mx;
+
+ if (num === 0) {
+ tmp = mod - 1;
+ result.push(sources[tmp])
+ val = val - mod;
+ } else {
+ tmp = mod / (mx / baseMix);
+ result.push(sources[tmp - 1])
+ val = val - mod;
+ }
+ // 递增
+ num++;
+ mx = mx * baseMix;
+
+ //log
+ // console.log("mod: ", mod, " mx: ", mx, " val: ", val, " tmp: ", tmp)
+ }
+
+ return result.reverse().join('')
+ },
+
+ /**
+ * 生成UUID
+ * @param usn
+ * @param docType
+ * @returns {string}
+ * @constructor
+ */
+ Uuid(usn, docType = 0) {
+ let sources = this.charSources;
+ let radix = sources.length;
+ let uuid = [];
+ let myCrypto = window.crypto;
+ //1. docIdPrefix长度3
+ let docIdPrefix = "";
+ if (myCrypto) {
+ //生成一个 8位的数组,长度是 3
+ let num = new Uint8Array(3);
+ //随机生成
+ myCrypto.getRandomValues(num);
+ // console.log("Your lucky numbers:");
+ for (let i = 0; i < 3; i++) {
+ uuid[i] = sources[num[i] >> 2]
+ }
+ // docId + uid + docType + ts
+ docIdPrefix = uuid.join('');
+ } else {
+ // Compact form
+ for (let i = 0; i < 3; i++) uuid[i] = sources[0 | Math.random() * radix];
+ docIdPrefix = uuid.join('');
+ }
+
+
+ //2. 基于 2024-11-03 16:37:38 1730623058 最大长度可自增
+ let curTs4Sec = Date.parse(new Date()) / 1000 - 1730623058;
+ let tsStr = this.Parse10To63(curTs4Sec);
+ // console.log("curTs4Sec : ", curTs4Sec, " tsStr: ", tsStr)
+ // docId(长度固定3) + uid(长度固定6) + docType(长度固定1) + ts(短期内1-6)
+ return docIdPrefix + docType + usn + tsStr;
+ },
+ /**
+ * 阻止默认事件
+ * @constructor
+ */
+ ProhibitDefaultEvent(event) {
+ event.preventDefault()
+ event.returnValue = false
+ },
+
+
+ /**
+ * 获取 触发事件的元素
+ * @param event
+ * @constructor
+ */
+ GetEventTarget(event) {
+ return event.target
+ },
+
+
+ ParseEvent(e) {
+ return e || window.event //标准化事件处理
+ },
+
+
+ GetKeyCode(event) {
+ return event.keyCode || event.which || event.charCode
+ },
+
+ /**
+ * 当前选区。 兼容不同浏览器
+ * @returns {Selection|*}
+ */
+ GetSelection() {
+ return window.getSelection() || document.selection
+ },
+
+ /**
+ * 是否是数字
+ * @param value
+ * @returns {boolean}
+ */
+ IsNum(value) {
+ return !isNaN(parseFloat(value)) && isFinite(value)
+ },
+
+ /**
+ * 在节点node后面插入新节点newNode
+ * @method InsertAfter
+ * @param { Node } node 目标节点
+ * @param { Node } newNode 新插入的节点, 该节点将置于目标节点之后
+ * @return { Node } 新插入的节点
+ */
+ InsertAfter(node, newNode) {
+ return node.nextSibling
+ ? node.parentNode.insertBefore(newNode, node.nextSibling)
+ : node.parentNode.appendChild(newNode)
+ },
+
+ TriggerFocus(selector) {
+ const targetElement = document.querySelector(selector);
+ if (document.createEvent) {
+ const event = document.createEvent('HTMLEvents');
+ event.initEvent('focus', true, false);
+ targetElement.dispatchEvent(event);
+ } else if (document.createEventObject) {
+ //兼容IE
+ targetElement.fireEvent('focus');
+ }
+ }
+
+ }
+});
\ No newline at end of file
diff --git a/static/js/event/MyEventListener.js b/static/js/event/MyEventListener.js
new file mode 100644
index 0000000..204ef25
--- /dev/null
+++ b/static/js/event/MyEventListener.js
@@ -0,0 +1,162 @@
+"use strict";
+define(function (require, exports, module) {
+ /**
+ * 解决事件监听 this 问题,这里 转接一下
+ */
+ class MyEventListener {
+
+ constructor() {
+ //resize
+ window.addEventListener('resize', this.RSizeListener, true);
+ window.addEventListener('pageshow', this.RSizeListener, true);
+ window.addEventListener('DOMContentLoaded', this.RSizeListener, true);
+ /**
+ * 窗口事件.
+ * js中的键盘事件只有三种:keydown、keyup、keypress。
+ * 它们触发的顺序是:keydown -> keypress -> keyup。
+ * 当按下一个键不放开,一般会重复地触发 keydown+keypress,直到放开后触发一个 keyup 事件。
+ */
+ window.addEventListener('keydown', this.KeydownListener, false);
+ //keyup
+ window.addEventListener('keyup', this.KeyUpListener, false);
+ // window.addEventListener('DOMsubtreeModified', function (e) {
+ // console.log("DOMsubtreeModified : ", e)
+ // });
+
+ let mutationHandle = require("./impl/MutationObserverImpl")
+ // 并将回调函数传给它
+ let MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
+ let observer = new MutationObserver(function (mutationList, observer) {
+ mutationHandle.handle(mutationList);
+ });
+
+ // 在 MutationObserver 实例上调用 `observe` 方法,
+ // 并将要观察的元素与选项传给此方法
+ observer.observe(document.getElementById("yxl_note"),
+ {
+ // 当元素的属性变化时触发回调(默认为 false)。
+ attributes: true,
+ //当目标节点的子节点被添加或删除时触发回调(默认为 false)。
+ childList: true,
+ // 当设置为 true 时,监视目标节点及其所有后代节点的变化(默认为 false)。
+ subtree: true,
+ // 当节点的文本内容变化时触发回调(默认为 false)。
+ characterData: true,
+ //当属性变化时,记录变化前的属性值(默认为 false)。
+ attributeOldValue: true,
+ // 当文本节点变化时,记录变化前的文本内容(默认为 false)。
+ characterDataOldValue: true
+ });
+
+
+ //这里监听鼠标按下事件
+ document.getElementById("_style_utils").addEventListener("mousedown", this.Mousedown, false);
+
+ //样式事件监听
+ let styleList = document.getElementsByClassName("fixStyleInnerSpan");
+ console.log("styleList : ", styleList);
+ if (styleList && styleList.length > 0) {
+ for (let i = 0; i < styleList.length; i++) {
+ console.log(styleList[i]);
+ styleList[i].addEventListener('click', this.ApplyStyleListener, false);
+ }
+ }
+
+
+ //+/-
+ document.getElementById("my_fontSize+").addEventListener("click", this.AdjustMyFontSize, true)
+ document.getElementById("my_fontSize-").addEventListener("click", this.AdjustMyFontSize, true)
+ document.getElementById("my_fontSize0").addEventListener("click", this.AdjustMyFontSize, true)
+ }
+
+ AdjustMyFontSize(e) {
+ const handle = require('./impl/AdjustMyFontSizeEventImpl');
+ handle.handle(e);
+ }
+
+ Mousedown(e) {
+ const handle = require('./impl/MouseDownEventImpl');
+ handle.handle(e);
+ }
+
+
+ /**
+ * 使用样式事件
+ * @param e
+ * @constructor
+ */
+ ApplyStyleListener(e) {
+ const handle = require('./impl/ApplyStyleEventImpl');
+ handle.handle(e);
+ }
+
+ /**
+ *
+ * @param {*} e
+ */
+ KeydownListener(e) {
+ const keyDownHandle = require('./impl/KeyDownEventImpl');
+ keyDownHandle.handle(e);
+ }
+
+ /**
+ *
+ * @param e
+ * @constructor
+ */
+ KeyUpListener(e) {
+ const keyUpHandle = require('./impl/KeyUpEventImpl');
+ keyUpHandle.handle(e);
+ }
+
+ /**
+ * 输入事件
+ * @param e
+ * @constructor
+ */
+ InputListener(e) {
+ const handle = require('./impl/InputEventImpl');
+ handle.handle(e);
+ }
+
+ /**
+ * 中文输入开始事件
+ * @param e
+ * @constructor
+ */
+ CompositionstartListener(e) {
+ const utils = require('../common/utils');
+ const event = utils.ParseEvent(e);
+ // window.myEdit.biz.compositionstartHandle(event);
+ }
+
+ /**
+ * 中文输入结束事件
+ * @param e
+ * @constructor
+ */
+ CompositionendListener(e) {
+ const utils = require('../common/utils');
+ const event = utils.ParseEvent(e);
+ console.log("Compositionend : ", event)
+ // window.myEdit.biz.compositionendHandle(event);
+ }
+
+ /**
+ * 尺寸变化事件
+ * @param e
+ * @constructor
+ */
+ RSizeListener(e) {
+ console.log("RSizeListener : ", e);
+ let handle = require("./impl/RSizeEventImpl");
+ handle.handle(e);
+ }
+
+
+ }
+
+ // 初始化一次
+ module.exports = new MyEventListener();
+});
+
diff --git a/static/js/event/impl/AdjustMyFontSizeEventImpl.js b/static/js/event/impl/AdjustMyFontSizeEventImpl.js
new file mode 100644
index 0000000..f37a5d4
--- /dev/null
+++ b/static/js/event/impl/AdjustMyFontSizeEventImpl.js
@@ -0,0 +1,34 @@
+"use strict";
+/**
+ * 使用样式事件
+ */
+define(function (require, exports, module) {
+
+ function handle(e) {
+ const ctx = require("../../common/ctx");
+ const utils = require("../../common/utils");
+
+ let event = utils.ParseEvent(e);
+ let curEl = utils.GetEventTarget(event);
+ let curId = curEl.getAttribute("id");
+ if (curId === "my_fontSize0") {
+ localStorage.clear();
+ location.reload();
+ return
+ } else if (curId === "my_fontSize+") {
+ ctx.editFrontSize++;
+ } else {
+ ctx.editFrontSize--;
+ }
+
+ //触发resize
+ let resizeImp = require("./RSizeEventImpl");
+ resizeImp.refreshEditFrontSize();
+
+ //保存在本地
+ localStorage.setItem('editFrontSize', ctx.editFrontSize);
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/event/impl/ApplyStyleEventImpl.js b/static/js/event/impl/ApplyStyleEventImpl.js
new file mode 100644
index 0000000..dc80a1d
--- /dev/null
+++ b/static/js/event/impl/ApplyStyleEventImpl.js
@@ -0,0 +1,157 @@
+"use strict";
+/**
+ * 使用样式事件
+ */
+define(function (require, exports, module) {
+
+ function handle(event) {
+ let utils = require("../../common/utils");
+ let curS = utils.GetSelection();
+
+ let curP = utils.GetEventTarget(event);
+ let styleK = curP.getAttribute("data-k");
+ let styleV = curP.getAttribute("data-v");
+ if (styleK === undefined || styleK === null) {
+ styleK = curP.closest("span").getAttribute("data-k");
+ styleV = curP.closest("span").getAttribute("data-v");
+ // console.log("closest: ", curP, curP.closest("span"))
+ }
+
+ for (let i = 0; i < curS.rangeCount; i++) {
+ let curRange = curS.getRangeAt(i);
+ let curCommonEle = curRange.commonAncestorContainer;
+ let start = curRange.startOffset;
+ let end = curRange.endOffset;
+ if (start > end) {
+ let tmpS = start;
+ start = end;
+ end = tmpS;
+ }
+ if (start === end) {
+ continue
+ }
+
+ // //一个元素节点,例如
和
。
+ // let curComIsSpan = curCommonEle.nodeType === 1 && curCommonEle.nodeName === "SPAN";
+ // let curComParentIsP = curCommonEle.parentNode.nodeType === 1 && curCommonEle.parentNode.nodeName === "P";
+ // let curComParentIsDiv = curCommonEle.parentNode.nodeType === 1 && curCommonEle.parentNode.nodeName === "DIV";
+ // let curComParentIsSpan = curCommonEle.parentNode.nodeType === 1 && (curCommonEle.parentNode.nodeName === 'SPAN"' || curCommonEle.parentNode.nodeName === 'SPAN');
+ // console.log(" 当前选区信息 : ", curRange,
+ // "\ncurCommonEle: ", curCommonEle,
+ // "\ncurCommonEleParent: ", curCommonEle.parentNode, curCommonEle.parentNode.nodeType, curCommonEle.parentNode.nodeName,
+ // "\ncurCommonEleParentParent: ", curCommonEle.parentNode.parentNode, curCommonEle.parentNode.parentNode.nodeType, curCommonEle.parentNode.parentNode.nodeName,
+ //
+ // "\ncurComParentIsSpan: ", curComParentIsSpan,
+ // "\ncurComParentIsP : ", curComParentIsP,
+ // "\ncurComParentIsDiv", curComParentIsDiv,
+ // "\ncurComIsSpan", curComIsSpan,
+ //
+ // "\nstyleK: ", styleK,
+ // "\nstyleV: ", styleV,
+ // "\ntart: ", start,
+ // "\nend: ", end);
+
+ let curSpanContent = curCommonEle;
+ if (curSpanContent.nodeName !== "SPAN" || curSpanContent.getAttribute("data-flag") !== "span_content") {
+ curSpanContent = curSpanContent.parentElement.closest("span[data-flag='span_content']");
+ }
+ console.log("curSpanContent : ", curSpanContent, curCommonEle);
+ if (curSpanContent.childNodes.length <= 0) {
+ continue
+ }
+ let firstItem = curSpanContent.childNodes[0];
+ console.log("curSpanContent : ", curSpanContent, curSpanContent.childNodes, firstItem.nodeName, firstItem.nodeType);
+ let isEmptyStyle = curSpanContent.childNodes.length === 1 && firstItem.nodeName === "#text" && firstItem.nodeType === 3;
+ if (isEmptyStyle) {
+ let copySpan = curSpanContent.cloneNode();
+ copySpan.innerHTML = "";
+ for (let j = 0; j < curSpanContent.innerText.length; j++) {
+ // console.log(curStartP.innerText.charAt(j))
+ if (j >= start && j < end) {
+ let tmpSpan = document.createElement("span");
+ tmpSpan.innerText = curSpanContent.innerText.charAt(j);
+ applySpanStyleKV(tmpSpan, styleK, styleV);
+ copySpan.append(tmpSpan);
+ } else {
+ let tmpSpan = document.createElement("span");
+ tmpSpan.innerText = curSpanContent.innerText.charAt(j);
+ copySpan.append(tmpSpan);
+ }
+ }
+
+ curSpanContent.innerHTML = copySpan.innerHTML;
+
+ //光标保持
+ let s = window.getSelection();
+ if (s.rangeCount > 0) s.removeAllRanges();
+ let newR = document.createRange();
+ //重新获取元素
+ let tmpP = curSpanContent;
+ let childrenSize = tmpP.childNodes.length;
+ console.log("debug007: ", tmpP, start, end, childrenSize)
+ newR.setStart(tmpP, start);
+ newR.setEnd(tmpP, end);
+ //区域 添加 到选区
+ s.addRange(newR);
+ } else {
+ let total = 0, effectNum = 0;
+ for (let j = 0; j < curSpanContent.childNodes.length; j++) {
+ let tmpSpan = curSpanContent.childNodes[j];
+ if (curS.containsNode(tmpSpan, true)) {
+ total++;
+ if (spanContainsStyleKV(tmpSpan, styleK, styleV)) {
+ console.dir(tmpSpan);
+ } else {
+ effectNum++;
+ applySpanStyleKV(tmpSpan, styleK, styleV);
+ }
+ }
+ }
+
+ //如果没有设置任何一个 则取消
+ if (effectNum === 0) {
+ for (let j = 0; j < curSpanContent.childNodes.length; j++) {
+ let tmpSpan = curSpanContent.childNodes[j];
+ if (curS.containsNode(tmpSpan, true)) {
+ removeSpanStyleKV(tmpSpan, styleK, styleV);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ function removeSpanStyleKV(span, styleK, styleV) {
+ let kList = styleK.toString().split(",");
+ let vList = styleV.toString().split(",");
+ for (let i = 0; i < kList.length; i++) {
+ if (span.style.getPropertyValue(kList[0]) === vList[0]) {
+ span.style.removeProperty(kList[0]);
+ }
+ }
+ }
+
+ function spanContainsStyleKV(span, styleK, styleV) {
+ let kList = styleK.toString().split(",");
+ let vList = styleV.toString().split(",");
+ let total = kList.length, match = 0;
+ for (let i = 0; i < kList.length; i++) {
+ if (span.style.getPropertyValue(kList[0]) === vList[0]) {
+ match++;
+ }
+ }
+
+ return total === match;
+ }
+
+ function applySpanStyleKV(span, styleK, styleV) {
+ let kList = styleK.toString().split(",");
+ let vList = styleV.toString().split(",");
+ for (let i = 0; i < kList.length; i++) {
+ span.style.setProperty(kList[i], vList[i]);
+ }
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/event/impl/CancelEventImpl.js b/static/js/event/impl/CancelEventImpl.js
new file mode 100644
index 0000000..f240e75
--- /dev/null
+++ b/static/js/event/impl/CancelEventImpl.js
@@ -0,0 +1,26 @@
+"use strict";
+/**
+ * 撤销事件
+ */
+define(function (require, exports, module) {
+
+ function handle(e) {
+ const utils = require('../../common/utils');
+ const ctx = require('../../common/ctx');
+ let event = utils.ParseEvent(e);
+ console.log('触发ctrl + Z 事件', event.target)
+ if (ctx.latestOpDoc !== undefined && ctx.latestOpDoc !== null) {
+ //恢复
+ ctx.latestOpDoc.recovery();
+ //测试展示
+ ctx.showTestText()
+ //阻止事件
+ utils.ProhibitDefaultEvent(event);
+ }
+
+ ctx.latestOpDoc = null
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/event/impl/CopyEventImpl.js b/static/js/event/impl/CopyEventImpl.js
new file mode 100644
index 0000000..4b551f6
--- /dev/null
+++ b/static/js/event/impl/CopyEventImpl.js
@@ -0,0 +1,13 @@
+"use strict";
+/**
+ * 拷贝事件
+ */
+define(function (require, exports, module) {
+
+ function handle(event) {
+
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/event/impl/DelEventImpl.js b/static/js/event/impl/DelEventImpl.js
new file mode 100644
index 0000000..a7f896c
--- /dev/null
+++ b/static/js/event/impl/DelEventImpl.js
@@ -0,0 +1,83 @@
+"use strict";
+
+/**
+ * 删除事件
+ */
+define(function (require, exports, module) {
+
+ function handle(event) {
+ const ctx = require("../../common/ctx");
+ const utils = require("../../common/utils");
+ const MyRecovery = require("../../common/MyRecovery");
+ let curP = utils.GetEventTarget(event);
+ let cNo = parseInt(curP.getAttribute("id"));
+
+ //维护最近一次编辑的内容
+ if (ctx.latestOpDoc === undefined
+ || ctx.latestOpDoc === null
+ || ctx.latestOpDoc.getData().getAttribute("data-id") !== curP.getAttribute("data-id")) {
+
+ //记录最近一次删除 for 撤销
+ ctx.latestOpDoc = new MyRecovery(curP.cloneNode(true), function () {
+ let cNo = parseInt(this.data.getAttribute("id"))
+ console.log("恢复", this.data, cNo, " this: ", this)
+ if (cNo > 1) {
+
+ utils.InsertAfter(this.data, document.getElementById((cNo - 1) + ""))
+ } else {
+ //添加元素到首位 todo_xxx
+ // ctx.MyRoot.insertBefore(this.data, ctx.MyRoot.children[0])
+ ctx.MyRoot().insertBefore(this.data, ctx.MyRoot.children[0]);
+ }
+
+ // 恢复该元素展示
+ ctx.getMapItem(cNo).setHidden(false);
+ })
+ }
+
+
+ //如果是第一行
+ let previousSibling = curP.previousSibling
+ // console.log(curP, previousSibling === undefined, previousSibling.id === undefined)
+ if (previousSibling === undefined || previousSibling.id === undefined) {
+ //显示用户的输入内容
+ ctx.showTestText();
+ return
+ }
+
+
+ console.log('触发删除', curP.innerHTML, cNo)
+ let curS = utils.GetSelection();
+ // console.log("当前内容: ", curP.innerHTML, " 当前选区 :", curS)
+ //处理前面没有内容,后面还有内容需要拼接到上层的场景
+ if ((curS.isCollapsed && curS.anchorOffset === 0) || curP.innerHTML === '
') {
+ let curNodeRetainHtml = curP.innerHTML
+ //阻止事件传递
+ utils.ProhibitDefaultEvent(event);
+ //设置该元素隐藏
+ ctx.MyDocMap.get(cNo).setHidden(true)
+ //删除当前元素
+ // curP.remove()
+ curP.innerHTML = "
"
+ let emptyRowNoList = ctx.getMapItem("emptyRowNoList");
+ if (emptyRowNoList === undefined || emptyRowNoList === null) {
+ emptyRowNoList = [];
+ ctx.MyDocMap.set("emptyRowNoList", emptyRowNoList);
+ }
+ emptyRowNoList.push(cNo);
+ //拼接
+ if (curNodeRetainHtml !== '
') {
+ previousSibling.innerHTML = previousSibling.innerHTML + curNodeRetainHtml
+ }
+
+ //收起选区到一个点,光标落在一个可编辑元素上
+ window.getSelection().setPosition(previousSibling, 1);
+ }
+
+ //显示用户的输入内容
+ ctx.showTestText();
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/event/impl/EmptyInputEventImpl.js b/static/js/event/impl/EmptyInputEventImpl.js
new file mode 100644
index 0000000..5a88e72
--- /dev/null
+++ b/static/js/event/impl/EmptyInputEventImpl.js
@@ -0,0 +1,115 @@
+"use strict";
+/**
+ * 输入内容为空,如# /- /1. /等 触发事件
+ */
+define(function (require, exports, module) {
+
+ function handle(event) {
+ const utils = require('../../common/utils');
+ const Node = require('../../common/node');
+ let curP = utils.GetEventTarget(event);
+ let myDocItem = new Node(curP);
+ // let inputLength = curP.innerText.length
+ // console.log("emptyKeyWorkHandler :", curP, " _'", curP.innerHTML, "'_'", curP.innerText, "'_",
+ // "\neq1", curP.innerHTML.startsWith(" # "),
+ // "\neq2", curP.innerHTML.startsWith(" # "),
+ // "\neq3", curP.innerHTML.startsWith("# "),
+ // "\neq4", curP.innerHTML.startsWith("# "),
+ //
+ // "\neqV1", curP.innerText.startsWith(" # "),
+ // "\neqV2", curP.innerText.startsWith(" # "),
+ // "\neqV3", curP.innerText.startsWith("# "),
+ // "\neqV4", curP.innerText.startsWith("# "),
+ //
+ // )
+ /**
+ * h1 ~ h6
+ */
+ if (curP.innerText.startsWith("#")) {
+ let curNo = myDocItem.parseOrder();
+ let mapNode = ctx.MyDocMap.get(curNo);
+ if (curP.innerHTML.startsWith("######")) {
+ mapNode.getStyle().setNodeType("h6")
+ curP.innerHTML = curP.innerHTML.replace("######", "")
+ this.becomeAnotherElement(curP, "h6")
+ } else if (curP.innerHTML.startsWith("#####")) {
+ mapNode.getStyle().setNodeType("h5")
+ curP.innerHTML = curP.innerHTML.replace("#####", "")
+ this.becomeAnotherElement(curP, "h5")
+ } else if (curP.innerHTML.startsWith("####")) {
+ mapNode.getStyle().setNodeType("h4")
+ curP.innerHTML = curP.innerHTML.replace("####", "")
+ this.becomeAnotherElement(curP, "h4")
+ } else if (curP.innerHTML.startsWith("###")) {
+ mapNode.getStyle().setNodeType("h3")
+ curP.innerHTML = curP.innerHTML.replace("###", "")
+ this.becomeAnotherElement(curP, "h3")
+ } else if (curP.innerHTML.startsWith("##")) {
+ mapNode.getStyle().setNodeType("h2")
+ curP.innerHTML = curP.innerHTML.replace("##", "")
+ this.becomeAnotherElement(curP, "h2")
+ } else {
+ mapNode.getStyle().setNodeType("h1")
+ curP.innerHTML = curP.innerHTML.replace("#", "")
+ this.becomeAnotherElement(curP, "h1")
+ }
+ }
+
+ /**
+ * 无序列表效果
+ */
+ if (curP.innerText.startsWith("-")) {
+ let curNo = myDocItem.parseOrder();
+ let mapNode = ctx.getMapItem(curNo);
+ mapNode.getStyle().setPreStyle("ul", true)
+
+ //clean
+ let historyContent = curP.innerHTML.replace("-", "");
+ mapNode.setSource(curP.innerText)
+
+ //根据上一层级元素动态选择 todo
+ curP.setAttribute("style", "padding-left: 1rem;")
+ //新增元素
+ let newParagraph = document.createElement("span");
+ newParagraph.setAttribute("contenteditable", "false");
+ //∙ vs ∘
+ newParagraph.innerHTML = "∙ "
+ curP.innerHTML = ""
+ curP.append(newParagraph);
+ curP.innerHTML = curP.innerHTML + historyContent
+
+ //收起选区到一个点,光标落在一个可编辑元素上
+ utils.GetSelection().collapse(curP, true)
+ }
+
+ /**
+ * 有序列表效果
+ */
+ let preContent = curP.innerText.split("\.")[0]
+ if (window.myEdit.utils.IsNum(preContent)) {
+ let curNo = myDocItem.parseOrder();
+ let mapNode = ctx.MyDocMap.get(curNo);
+ mapNode.getStyle().setPreStyle("ol", preContent)
+
+ //clean
+ let historyContent = curP.innerHTML.replace(preContent + ".", "");
+ mapNode.setSource(curP.innerText)
+ //todo
+ curP.setAttribute("style", "padding-left: 1rem;")
+ //新增元素
+ let newParagraph = document.createElement("span");
+ newParagraph.setAttribute("contenteditable", "false");
+ newParagraph.innerHTML = preContent + ". "
+ curP.innerHTML = ""
+ curP.append(newParagraph);
+ curP.innerHTML = curP.innerHTML + historyContent
+
+ //收起选区到一个点,光标落在一个可编辑元素上
+ utils.GetSelection().collapse(curP, true)
+ }
+
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/event/impl/EnterEventImpl.js b/static/js/event/impl/EnterEventImpl.js
new file mode 100644
index 0000000..4a053eb
--- /dev/null
+++ b/static/js/event/impl/EnterEventImpl.js
@@ -0,0 +1,18 @@
+"use strict";
+/**
+ * 回车事件
+ */
+define(function (require, exports, module) {
+
+ function handle(e) {
+ const utils = require('../../common/utils');
+ let event = utils.ParseEvent(e);
+ let curEl = utils.GetEventTarget(event);
+
+ // console.log("Enter event", event, "\ncurEl: ", curEl)
+
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/event/impl/InputEventImpl.js b/static/js/event/impl/InputEventImpl.js
new file mode 100644
index 0000000..08f6738
--- /dev/null
+++ b/static/js/event/impl/InputEventImpl.js
@@ -0,0 +1,34 @@
+"use strict";
+
+/**
+ * 输入事件
+ */
+define(function (require, exports, module) {
+
+ function handle(e) {
+ const utils = require('../../common/utils');
+ const event = utils.ParseEvent(e);
+ let curP = utils.GetEventTarget(e);
+
+ console.log("input : ", event,
+ "\ntext: '", event.data + "'"
+ , "\ncurP: ", curP)
+ let testDiv = document.getElementById("testDevice")
+ testDiv.innerText =
+ "\ninput: " + event.data + " isEmpty: " + (event.data === " ");
+
+
+ //更新内容
+
+ // this.updateText(curP)
+
+ //处理空行转换
+ if (event.data === " ") {
+ let emptyHandle = require("./EmptyInputEventImpl");
+ emptyHandle.handle(e);
+ }
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/event/impl/KeyDownEventImpl.js b/static/js/event/impl/KeyDownEventImpl.js
new file mode 100644
index 0000000..76795da
--- /dev/null
+++ b/static/js/event/impl/KeyDownEventImpl.js
@@ -0,0 +1,42 @@
+"use strict";
+/**
+ * 鼠标 keyDown 事件
+ */
+define(function (require, exports, module) {
+
+ function handle(e) {
+ const utils = require('../../common/utils')
+ const event = utils.ParseEvent(e);
+ let curP = utils.GetEventTarget(e);
+ const keyCode = utils.GetKeyCode(event);
+ const keyCombination = event.ctrlKey
+ const metaKey = event.metaKey
+
+ // console.log("keyDown : ", event,
+ // "\nevent.data: '", event.data + "'",
+ // "\nkeyCode: '", keyCode + "'"
+ // , "\ncurP: ", curP);
+
+ //支持全屏撤销
+ if (metaKey && keyCode === 90) {
+ // const cancelHandle = require('./CancelEventImpl')
+ // cancelHandle.handle(e);
+ return;
+ }
+
+ //回车事件,禁止处理。防止生成 div
+ if (keyCode === 13) {
+ // utils.ProhibitDefaultEvent(event);
+ }
+
+ //在鼠标按下的时候删除,体验更好
+ if (keyCode === 46 || keyCode === 8) {
+ // const delHandle = require('./DelEventImpl')
+ // delHandle.handle(e);
+ // return;
+ }
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/event/impl/KeyUpEventImpl.js b/static/js/event/impl/KeyUpEventImpl.js
new file mode 100644
index 0000000..470deee
--- /dev/null
+++ b/static/js/event/impl/KeyUpEventImpl.js
@@ -0,0 +1,49 @@
+"use strict";
+/**
+ * 鼠标 keyUp 事件
+ */
+define(function (require, exports, module) {
+
+ function handle(e) {
+ const utils = require('../../common/utils')
+ const event = utils.ParseEvent(e);
+ // console.log("this: ", this, e, e.target, "\n event: ", event)
+ const keyCode = utils.GetKeyCode(event);
+ const keyCombination = event.ctrlKey
+ const metaKey = event.metaKey
+
+ let curP = utils.GetEventTarget(e);
+ // console.log("键盘事件 ", event, keyCombination, metaKey, keyCode, "\ncurP: ", curP)
+
+
+ // ctrl + c 复制
+ if (keyCombination && keyCode === 67) {
+ // 阻止默认事件
+ // utils.ProhibitDefaultEvent(event);
+ // console.log('触发ctrl + c 事件', e.target)
+ }
+
+ //撤销
+ if (metaKey && keyCode === 90) {
+ // const cancelHandle = require('./CancelEventImpl')
+ // cancelHandle.handle(e);
+ return;
+ }
+
+ //删除
+ if (keyCode === 46 || keyCode === 8) {
+ //todo 什么也不处理
+ return;
+ }
+
+ //回车事件
+ if (keyCode === 13 /* && currentNode === key.lastElementChild */) {
+ // const enterHandle = require('./EnterEventImpl')
+ // enterHandle.handle(e);
+ // return;
+ }
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/event/impl/MouseDownEventImpl.js b/static/js/event/impl/MouseDownEventImpl.js
new file mode 100644
index 0000000..7159398
--- /dev/null
+++ b/static/js/event/impl/MouseDownEventImpl.js
@@ -0,0 +1,33 @@
+"use strict";
+/**
+ * 使用样式事件
+ */
+define(function (require, exports, module) {
+
+ function handle(e) {
+ const utils = require('../../common/utils');
+ const ctx = require('../../common/ctx');
+ const event = utils.ParseEvent(e);
+
+
+ let curElement = utils.GetEventTarget(event);
+ let id = curElement.getAttribute("id");
+ if (id !== "_style_utils") {
+ id = curElement.closest("#_style_utils").getAttribute("id");
+ }
+ console.log("mousedown: ", event,
+ "\ncurElement:", curElement,
+ "\nid : ", id)
+ //这里监听鼠标按下事件
+ // if (id === "_style_utils") {
+ // //阻止事件,for 应用 样式
+ // utils.ProhibitDefaultEvent(event);
+ // }
+ //阻止事件,for 应用 样式
+ utils.ProhibitDefaultEvent(event);
+
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/event/impl/MutationObserverImpl.js b/static/js/event/impl/MutationObserverImpl.js
new file mode 100644
index 0000000..eb37d43
--- /dev/null
+++ b/static/js/event/impl/MutationObserverImpl.js
@@ -0,0 +1,93 @@
+"use strict";
+/**
+ * 使用样式事件
+ */
+define(function (require, exports, module) {
+
+ function handle(mutationList) {
+ for (let mutation of mutationList) {
+
+
+ switch (mutation.type) {
+ case "childList":
+ addNewP(mutation);
+ break;
+ case "characterData":
+ updateText(mutation);
+ break;
+ default: {
+ other(mutation);
+ }
+ }
+ }
+ }
+
+ function other(mutation) {
+ console.log("mutation : ", mutation,
+ // 观察的变动类型(attributes、characterData或者childList)。
+ "\ntype", mutation.type,
+ //发生变动的DOM节点。
+ "\ntarget", mutation.target,
+ "\ntargetParent", mutation.target.parentElement, mutation.target.parentNode,
+ //新增的DOM节点。
+ "\naddedNodes", mutation.addedNodes,
+ //删除的DOM节点。
+ "\nremovedNodes", mutation.removedNodes,
+ //前一个同级节点,如果没有则返回null。
+ "\npreviousSibling", mutation.previousSibling,
+ //下一个同级节点,如果没有则返回null。
+ "\nnextSibling", mutation.nextSibling,
+ //发生变动的属性。如果设置了attributeFilter,则只返回预先指定的属性。
+ "\nattributeName", mutation.attributeName,
+ //变动前的值。这个属性只对attribute和characterData变动有效,如果发生childList变动,则返回null。
+ "\noldValue", mutation.oldValue);
+ }
+
+ function addNewP(mutation) {
+ let target = mutation.target;
+ if (target.nodeName === "DIV" && mutation.previousSibling !== null) {
+ console.log(
+ "target: ", target,
+ "\nnodeType: ", target.nodeType,
+ "\nnodeName: ", target.nodeName,
+ "\ndata: ", target.value,
+ "\n next: ", mutation.previousSibling.nextSibling
+ )
+
+ let utils = require("../../common/utils");
+ let ctx = require("../../common/ctx");
+ let curP = mutation.previousSibling.nextSibling;
+ if (curP !== undefined && curP !== null) {
+ curP.id = utils.Uuid(ctx.usn, ctx.docType);
+ curP.setAttribute("data-order", ctx.incrementNumThenReturn());
+ }
+ }
+
+ }
+
+ function updateText(mutation) {
+ let target = mutation.target;
+ if (target.nodeType === 3 && target.nodeName === "#text") {
+ // console.log(
+ // "target: ", target,
+ // "\nnodeType: ", target.nodeType,
+ // "\nnodeName: ", target.nodeName,
+ // "\ndata: ", target.value,
+ // "\nparentNode: ", target.parentNode,
+ // "\nparentNode_parentNode: ", target.parentNode.parentNode,
+ // )
+
+ // let curSpan = target.parentNode;
+ // let curP = target.parentNode.parentNode;
+
+
+
+
+ } else {
+ other(mutation);
+ }
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/event/impl/PasteEventImpl.js b/static/js/event/impl/PasteEventImpl.js
new file mode 100644
index 0000000..05ea9fe
--- /dev/null
+++ b/static/js/event/impl/PasteEventImpl.js
@@ -0,0 +1,13 @@
+"use strict";
+/**
+ * 粘贴事件
+ */
+define(function (require, exports, module) {
+
+ function handle(event) {
+
+ }
+
+ //导出
+ exports.handle = handle;
+});
\ No newline at end of file
diff --git a/static/js/event/impl/RSizeEventImpl.js b/static/js/event/impl/RSizeEventImpl.js
new file mode 100644
index 0000000..031716d
--- /dev/null
+++ b/static/js/event/impl/RSizeEventImpl.js
@@ -0,0 +1,103 @@
+"use strict";
+define(function (require, exports, module) {
+
+ function handle(e) {
+ const ctx = require("../../common/ctx");
+ let historyScreenW = ctx.screenWidth;
+ let curScreenW = ctx.getScreenWidth();
+ if (historyScreenW === curScreenW) {
+ return
+ }
+
+ //调整
+ refreshEditFrontSize()
+ refreshRootFrontSize();
+
+ //更新
+ ctx.screenWidth = ctx.getScreenWidth();
+ ctx.screenHeight = ctx.getScreenHeight();
+ }
+
+ /**
+ * 刷新跟节点 front-size
+ * @constructor
+ */
+ function refreshRootFrontSize() {
+ const ctx = require("../../common/ctx");
+ let curDoc = document.documentElement;//当前文档的 root 元素
+ let curClientW = ctx.getScreenWidth();
+ if (!curClientW) {
+ return
+ }
+
+ let designWidth = ctx.designWith;
+ //set 1rem = viewWidth/10 (支持响应式)
+ let nowFrontSize = ((curClientW / designWidth) / 10) + 'px';
+ curDoc.style.fontSize = nowFrontSize;
+ console.log("curClientW :", curClientW, "designWidth: ", designWidth, "-> ", nowFrontSize);
+ let testDiv = document.getElementById("testDevice");
+ testDiv.innerText += "\nnowFrontSize: " + nowFrontSize;
+ // testDiv.innerText = testDiv.innerText +
+ // // "\n navigator_userAgent :" + navigator.userAgent.toLocaleLowerCase() +
+ // "\n isMobile :" + /mobi|android|iphone|ipad|ipod/i.test(navigator.userAgent.toLocaleLowerCase()) +
+ // "\n isIOS :" + /iphone|ipad|ipod/.test(window.navigator.userAgent.toLocaleLowerCase()) +
+ // "\n isAndroid :" + /android/.test(window.navigator.userAgent.toLocaleLowerCase()) +
+ // "\n window.width :" + window.innerWidth +
+ // "\n curClientW :" + curClientW +
+ // " \n designWidth: " + designWidth +
+ // "\n 1rem = " + nowFrontSize;
+
+ }
+
+
+ function refreshEditFrontSize() {
+ const ctx = require("../../common/ctx");
+ let curClientW = ctx.getScreenWidth();
+ if (!curClientW) {
+ return
+ }
+
+ let dpr = window.devicePixelRatio || 1;//当前设置下 物理像素和虚拟像素的比值
+ if (!dpr) {
+ //devicePixelRatio这个属性是可以获取到设备的dpr
+ let devicePixelRatio = win?.devicePixelRatio;
+ //判断dpr是否为整数
+ let isRegularDpr = devicePixelRatio.toString().match(/^[1-9]\d*$/g)
+ if (isRegularDpr) {
+ // 对于是整数的dpr,对dpr进行操作
+ if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
+ dpr = 3;
+ } else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) {
+ dpr = 2;
+ } else {
+ dpr = 1;
+ }
+ } else {
+ // 其他设备下,仍旧使用1倍的方案
+ dpr = 1;
+ }
+ }
+
+ let myEditFrontSize = document.getElementById("myEdit_main");
+ // if (document.documentElement.clientWidth <= 720) {
+ // myEditFrontSize.style.fontSize = (window.myEdit.ctx.editFrontSize + 6) + 'px';
+ // } else {
+ // myEditFrontSize.style.fontSize = window.myEdit.ctx.editFrontSize * dpr + 'px';
+ // }
+ // myEditFrontSize.style.fontSize = window.myEdit.ctx.editFrontSize * dpr + 'px';
+ if (ctx.isTablet) {
+ myEditFrontSize.style.fontSize = ctx.editFrontSize * dpr + 'px';
+ } else {
+ myEditFrontSize.style.fontSize = ctx.editFrontSize + 'px';
+ }
+
+ // console.log("myEditFrontSize: ", myEditFrontSize.style.fontSize);
+ let testDiv = document.getElementById("testDevice");
+ testDiv.innerText = "\ndpr: " + dpr + "\nmyEditFrontSize: " + myEditFrontSize.style.fontSize;
+ }
+
+
+ //导出
+ exports.handle = handle;
+ exports.refreshEditFrontSize = refreshEditFrontSize;
+});
\ No newline at end of file
diff --git a/static/js/index.js b/static/js/index.js
new file mode 100644
index 0000000..8a5fb78
--- /dev/null
+++ b/static/js/index.js
@@ -0,0 +1,22 @@
+"use strict";
+define(function (require) {
+ const ctx = require('./common/ctx');
+ const eventListener = require('./event/MyEventListener')
+ const utils = require('./common/utils')
+ console.log("uuid1 -10 : ", utils.Uuid(ctx.usn));
+
+
+ // 初始化第一个输入框
+ let newParagraph = document.createElement("p");
+ //内置span
+ let span = document.createElement("span");
+ span.append(document.createElement("br"));
+ span.setAttribute("data-flag","span_content")
+ newParagraph.append(span);
+ //添加一行
+ ctx.MyRoot().append(newParagraph);
+ //收起选区到一个点,光标落在一个可编辑元素上
+ utils.GetSelection().setPosition(newParagraph, 0);
+
+
+})
\ No newline at end of file
diff --git a/static/js/init.go b/static/js/init.go
index d02753a..5a5d496 100644
--- a/static/js/init.go
+++ b/static/js/init.go
@@ -3,63 +3,72 @@ package js
import (
"embed"
"io/fs"
- "os"
)
import _ "embed"
-//go:embed */*/*.js
+//go:embed *.js
+var indexList embed.FS
+
+//go:embed */*.js
var jsList embed.FS
-//go:embed lib/main.js
-var jsMain embed.FS
+//go:embed event/impl/*
+var eventImplJs embed.FS
var jsMap = initJsMap()
func initJsMap() map[string][]byte {
var dataMap = make(map[string][]byte)
+ //index.js
+ btData, _ := indexList.ReadFile("index.js")
+ dataMap["index.js"] = btData
- btys, _ := jsMain.ReadFile("lib/main.js")
- dataMap["lib/main.js"] = btys
-
- list := initJsMapInner("lib/biz")
+ //eventImpl
+ list, err := eventImplJs.ReadDir("event/impl")
+ if err != nil {
+ panic(err)
+ return nil
+ }
if list != nil && len(list) > 0 {
for _, file := range list {
//读取配置文件
- data, err := jsList.ReadFile("lib/biz/" + file.Name())
+ data, err := eventImplJs.ReadFile("event/impl/" + file.Name())
if err == nil {
- dataMap["lib/biz/"+file.Name()] = data
+ dataMap["event/impl/"+file.Name()] = data
}
}
}
- list = initJsMapInner("lib/common")
+ list = initJsMapInner("lib")
if list != nil && len(list) > 0 {
for _, file := range list {
//读取配置文件
- data, err := jsList.ReadFile("lib/common/" + file.Name())
+ data, err := jsList.ReadFile("lib/" + file.Name())
if err == nil {
- dataMap["lib/common/"+file.Name()] = data
+ dataMap["lib/"+file.Name()] = data
}
}
}
- list = initJsMapInner("lib/event")
+
+ list = initJsMapInner("common")
if list != nil && len(list) > 0 {
for _, file := range list {
//读取配置文件
- data, err := jsList.ReadFile("lib/event/" + file.Name())
+ data, err := jsList.ReadFile("common/" + file.Name())
if err == nil {
- dataMap["lib/event/"+file.Name()] = data
+ dataMap["common/"+file.Name()] = data
}
}
}
- list = initJsMapInner("lib/model")
+
+ list = initJsMapInner("event")
if list != nil && len(list) > 0 {
for _, file := range list {
//读取配置文件
- data, err := jsList.ReadFile("lib/model/" + file.Name())
+ data, err := jsList.ReadFile("event/" + file.Name())
if err == nil {
- dataMap["lib/model/"+file.Name()] = data
+ dataMap["event/"+file.Name()] = data
}
}
}
@@ -70,7 +79,7 @@ func initJsMap() map[string][]byte {
func initJsMapInner(path string) []fs.DirEntry {
list, err := jsList.ReadDir(path)
if err != nil {
- os.Exit(-1)
+ panic(err)
return nil
}
diff --git a/static/js/lib/biz/MyBiz.js b/static/js/lib.old/biz/MyBiz.js
similarity index 100%
rename from static/js/lib/biz/MyBiz.js
rename to static/js/lib.old/biz/MyBiz.js
diff --git a/static/js/lib/common/MyUtils.js b/static/js/lib.old/common/MyUtils.js
similarity index 100%
rename from static/js/lib/common/MyUtils.js
rename to static/js/lib.old/common/MyUtils.js
diff --git a/static/js/lib/event/MyEventListener.js b/static/js/lib.old/event/MyEventListener.js
similarity index 100%
rename from static/js/lib/event/MyEventListener.js
rename to static/js/lib.old/event/MyEventListener.js
diff --git a/static/js/lib/main.js b/static/js/lib.old/main.js
similarity index 100%
rename from static/js/lib/main.js
rename to static/js/lib.old/main.js
diff --git a/static/js/lib/model/InnerStyle.js b/static/js/lib.old/model/InnerStyle.js
similarity index 100%
rename from static/js/lib/model/InnerStyle.js
rename to static/js/lib.old/model/InnerStyle.js
diff --git a/static/js/lib/model/MyDocItem.js b/static/js/lib.old/model/MyDocItem.js
similarity index 100%
rename from static/js/lib/model/MyDocItem.js
rename to static/js/lib.old/model/MyDocItem.js
diff --git a/static/js/lib/model/MyKV.js b/static/js/lib.old/model/MyKV.js
similarity index 100%
rename from static/js/lib/model/MyKV.js
rename to static/js/lib.old/model/MyKV.js
diff --git a/static/js/lib/model/MyMapItem.js b/static/js/lib.old/model/MyMapItem.js
similarity index 100%
rename from static/js/lib/model/MyMapItem.js
rename to static/js/lib.old/model/MyMapItem.js
diff --git a/static/js/lib/model/MyRecovery.js b/static/js/lib.old/model/MyRecovery.js
similarity index 100%
rename from static/js/lib/model/MyRecovery.js
rename to static/js/lib.old/model/MyRecovery.js
diff --git a/static/js/lib/todolist b/static/js/lib.old/todolist
similarity index 100%
rename from static/js/lib/todolist
rename to static/js/lib.old/todolist
diff --git a/static/js/lib/sea.js b/static/js/lib/sea.js
new file mode 100644
index 0000000..dd70294
--- /dev/null
+++ b/static/js/lib/sea.js
@@ -0,0 +1,2 @@
+/*! Sea.js 3.0.0 | seajs.org/LICENSE.md */
+!function(a,b){function c(a){return function(b){return{}.toString.call(b)=="[object "+a+"]"}}function d(){return A++}function e(a){return a.match(D)[0]}function f(a){for(a=a.replace(E,"/"),a=a.replace(G,"$1/");a.match(F);)a=a.replace(F,"/");return a}function g(a){var b=a.length-1,c=a.charCodeAt(b);return 35===c?a.substring(0,b):".js"===a.substring(b-2)||a.indexOf("?")>0||47===c?a:a+".js"}function h(a){var b=v.alias;return b&&x(b[a])?b[a]:a}function i(a){var b=v.paths,c;return b&&(c=a.match(H))&&x(b[c[1]])&&(a=b[c[1]]+c[2]),a}function j(a){var b=v.vars;return b&&a.indexOf("{")>-1&&(a=a.replace(I,function(a,c){return x(b[c])?b[c]:a})),a}function k(a){var b=v.map,c=a;if(b)for(var d=0,e=b.length;e>d;d++){var f=b[d];if(c=z(f)?f(a)||a:a.replace(f[0],f[1]),c!==a)break}return c}function l(a,b){var c,d=a.charCodeAt(0);if(J.test(a))c=a;else if(46===d)c=(b?e(b):v.cwd)+a;else if(47===d){var g=v.cwd.match(K);c=g?g[0]+a.substring(1):a}else c=v.base+a;return 0===c.indexOf("//")&&(c=location.protocol+c),f(c)}function m(a,b){if(!a)return"";a=h(a),a=i(a),a=h(a),a=j(a),a=h(a),a=g(a),a=h(a);var c=l(a,b);return c=h(c),c=k(c)}function n(a){return a.hasAttribute?a.src:a.getAttribute("src",4)}function o(a,b,c){var d;try{importScripts(a)}catch(e){d=e}b(d)}function p(a,b,c){var d=Y.createElement("script");if(c){var e=z(c)?c(a):c;e&&(d.charset=e)}q(d,b,a),d.async=!0,d.src=a,bb=d,ab?_.insertBefore(d,ab):_.appendChild(d),bb=null}function q(a,b,c){function d(c){a.onload=a.onerror=a.onreadystatechange=null,v.debug||_.removeChild(a),a=null,b(c)}var e="onload"in a;e?(a.onload=d,a.onerror=function(){C("error",{uri:c,node:a}),d(!0)}):a.onreadystatechange=function(){/loaded|complete/.test(a.readyState)&&d()}}function r(){if(bb)return bb;if(cb&&"interactive"===cb.readyState)return cb;for(var a=_.getElementsByTagName("script"),b=a.length-1;b>=0;b--){var c=a[b];if("interactive"===c.readyState)return cb=c}}function s(a){function b(){l=a.charAt(k++)}function c(){return/\s/.test(l)}function d(){return'"'==l||"'"==l}function e(){var c=k,d=l,e=a.indexOf(d,c);if(-1==e)k=m;else if("\\"!=a.charAt(e-1))k=e+1;else for(;m>k;)if(b(),"\\"==l)k++;else if(l==d)break;o&&(r.push(a.slice(c,k-1)),o=0)}function f(){for(k--;m>k;)if(b(),"\\"==l)k++;else{if("/"==l)break;if("["==l)for(;m>k;)if(b(),"\\"==l)k++;else if("]"==l)break}}function g(){return/[a-z_$]/i.test(l)}function h(){var b=a.slice(k-1),c=/^[\w$]+/.exec(b)[0];p={"if":1,"for":1,"while":1,"with":1}[c],n={"break":1,"case":1,"continue":1,"debugger":1,"delete":1,"do":1,"else":1,"false":1,"if":1,"in":1,"instanceof":1,"return":1,"typeof":1,"void":1}[c],o=/^require\s*\(\s*(['"]).+?\1\s*\)/.test(b),o?(c=/^require\s*\(\s*['"]/.exec(b)[0],k+=c.length-2):k+=/^[\w$]+(?:\s*\.\s*[\w$]+)*/.exec(b)[0].length-1}function i(){return/\d/.test(l)||"."==l&&/\d/.test(a.charAt(k))}function j(){var b=a.slice(k-1),c;c="."==l?/^\.\d+(?:E[+-]?\d*)?\s*/i.exec(b)[0]:/^0x[\da-f]*/i.test(b)?/^0x[\da-f]*\s*/i.exec(b)[0]:/^\d+\.?\d*(?:E[+-]?\d*)?\s*/i.exec(b)[0],k+=c.length-1,n=0}if(-1==a.indexOf("require"))return[];for(var k=0,l,m=a.length,n=1,o=0,p=0,q=[],r=[];m>k;)b(),c()||(d()?(e(),n=1):"/"==l?(b(),"/"==l?(k=a.indexOf("\n",k),-1==k&&(k=a.length)):"*"==l?(k=a.indexOf("*/",k),-1==k?k=m:k+=2):n?(f(),n=0):(k--,n=1)):g()?h():i()?j():"("==l?(q.push(p),n=1):")"==l?n=q.pop():(n="]"!=l,o=0));return r}function t(a,b){this.uri=a,this.dependencies=b||[],this.deps={},this.status=0,this._entry=[]}if(!a.seajs){var u=a.seajs={version:"3.0.0"},v=u.data={},w=c("Object"),x=c("String"),y=Array.isArray||c("Array"),z=c("Function"),A=0,B=v.events={};u.on=function(a,b){var c=B[a]||(B[a]=[]);return c.push(b),u},u.off=function(a,b){if(!a&&!b)return B=v.events={},u;var c=B[a];if(c)if(b)for(var d=c.length-1;d>=0;d--)c[d]===b&&c.splice(d,1);else delete B[a];return u};var C=u.emit=function(a,b){var c=B[a];if(c){c=c.slice();for(var d=0,e=c.length;e>d;d++)c[d](b)}return u},D=/[^?#]*\//,E=/\/\.\//g,F=/\/[^/]+\/\.\.\//,G=/([^:/])\/+\//g,H=/^([^/:]+)(\/.+)$/,I=/{([^{]+)}/g,J=/^\/\/.|:\//,K=/^.*?\/\/.*?\//;u.resolve=m;var L="undefined"==typeof window&&"undefined"!=typeof importScripts&&z(importScripts),M=/^(about|blob):/,N,O,P=!location.href||M.test(location.href)?"":e(location.href);if(L){var Q;try{var R=Error();throw R}catch(S){Q=S.stack.split("\n")}Q.shift();for(var T,U=/.*?((?:http|https|file)(?::\/{2}[\w]+)(?:[\/|\.]?)(?:[^\s"]*)).*?/i,V=/(.*?):\d+:\d+\)?$/;Q.length>0;){var W=Q.shift();if(T=U.exec(W),null!=T)break}var X;if(null!=T)var X=V.exec(T[1])[1];O=X,N=e(X||P),""===P&&(P=N)}else{var Y=document,Z=Y.scripts,$=Y.getElementById("seajsnode")||Z[Z.length-1];O=n($),N=e(O||P)}if(L)u.request=o;else{var Y=document,_=Y.head||Y.getElementsByTagName("head")[0]||Y.documentElement,ab=_.getElementsByTagName("base")[0],bb;u.request=p}var cb,db=u.cache={},eb,fb={},gb={},hb={},ib=t.STATUS={FETCHING:1,SAVED:2,LOADING:3,LOADED:4,EXECUTING:5,EXECUTED:6,ERROR:7};t.prototype.resolve=function(){for(var a=this,b=a.dependencies,c=[],d=0,e=b.length;e>d;d++)c[d]=t.resolve(b[d],a.uri);return c},t.prototype.pass=function(){for(var a=this,b=a.dependencies.length,c=0;c
f;f++){var g=a.deps[a.dependencies[f]];g.status0&&(d.remain+=e-1,a._entry.shift(),c--)}},t.prototype.load=function(){var a=this;if(!(a.status>=ib.LOADING)){a.status=ib.LOADING;var c=a.resolve();C("load",c);for(var d=0,e=c.length;e>d;d++)a.deps[a.dependencies[d]]=t.get(c[d]);if(a.pass(),a._entry.length)return a.onload(),b;var f={},g;for(d=0;e>d;d++)g=db[c[d]],g.statusb;b++){var d=a._entry[b];0===--d.remain&&d.callback()}delete a._entry},t.prototype.error=function(){var a=this;a.onload(),a.status=ib.ERROR},t.prototype.exec=function(){function a(b){var d=c.deps[b]||t.get(a.resolve(b));if(d.status==ib.ERROR)throw Error("module was broken: "+d.uri);return d.exec()}var c=this;if(c.status>=ib.EXECUTING)return c.exports;if(c.status=ib.EXECUTING,c._entry&&!c._entry.length&&delete c._entry,!c.hasOwnProperty("factory"))return c.non=!0,b;var e=c.uri;a.resolve=function(a){return t.resolve(a,e)},a.async=function(b,c){return t.use(b,c,e+"_async_"+d()),a};var f=c.factory,g=z(f)?f(a,c.exports={},c):f;return g===b&&(g=c.exports),delete c.factory,c.exports=g,c.status=ib.EXECUTED,C("exec",c),c.exports},t.prototype.fetch=function(a){function c(){u.request(g.requestUri,g.onRequest,g.charset)}function d(a){delete fb[h],gb[h]=!0,eb&&(t.save(f,eb),eb=null);var b,c=hb[h];for(delete hb[h];b=c.shift();)a===!0?b.error():b.load()}var e=this,f=e.uri;e.status=ib.FETCHING;var g={uri:f};C("fetch",g);var h=g.requestUri||f;return!h||gb.hasOwnProperty(h)?(e.load(),b):fb.hasOwnProperty(h)?(hb[h].push(e),b):(fb[h]=!0,hb[h]=[e],C("request",g={uri:f,requestUri:h,onRequest:d,charset:z(v.charset)?v.charset(h)||"utf-8":v.charset}),g.requested||(a?a[g.requestUri]=c:c()),b)},t.resolve=function(a,b){var c={id:a,refUri:b};return C("resolve",c),c.uri||u.resolve(c.id,b)},t.define=function(a,c,d){var e=arguments.length;1===e?(d=a,a=b):2===e&&(d=c,y(a)?(c=a,a=b):c=b),!y(c)&&z(d)&&(c=b===s?[]:s(""+d));var f={id:a,uri:t.resolve(a),deps:c,factory:d};if(!L&&!f.uri&&Y.attachEvent&&b!==r){var g=r();g&&(f.uri=g.src)}C("define",f),f.uri?t.save(f.uri,f):eb=f},t.save=function(a,b){var c=t.get(a);c.statusf;f++)b[f]=db[d[f]].exec();c&&c.apply(a,b),delete e.callback,delete e.history,delete e.remain,delete e._entry},e.load()},u.use=function(a,b){return t.use(a,b,v.cwd+"_use_"+d()),u},t.define.cmd={},a.define=t.define,u.Module=t,v.fetchedList=gb,v.cid=d,u.require=function(a){var b=t.get(t.resolve(a));return b.status
📒
-
+ content="width=device-width, height=device-height,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
+
-
+
+
+
+
-
-
-
-
-
-
-
-
-
+
-
-
-
- 测试编辑
-
-
-
-
-
+
+
+
+ 测试编辑
+
+
+
+
+
-
+
+
-
-
-
-
-
-