lsiten 6 years ago
parent
commit
554a39c5a9

+ 2 - 2
package.json

@@ -1,6 +1,6 @@
 {
-  "name": "lsiten-editor-new",
-  "version": "2.0.0",
+  "name": "lsiten-editor-v2",
+  "version": "1.0.9",
   "description": "answer sheet",
   "main": "src/js/yzWebeditor.js",
   "scripts": {

+ 9 - 6
src/config.js

@@ -20,17 +20,20 @@ const config = {
         'justify',
         // 'quote',
         // 'emoticon',
+        'lineheight',
+        // 'addline',
         'image',
+        'format',
         // 'table',
         // 'video',
         // 'code',
         // 'undo',
         // 'redo',
-        'questiontype',
-        'questionBorder',
-        'questionHead',
-        'questionData',
-        'addPage',
+        // 'questiontype',
+        // 'questionBorder',
+        // 'questionHead',
+        // 'questionData',
+        // 'addPage',
 
         // 'questiontypes',
         // 'questionborder',
@@ -257,7 +260,7 @@ const config = {
     //     // insert 是获取图片 url 后,插入到编辑器的方法
     //     insert(imgUrl)
     // }
-    policyUrl: 'http://api.hostdev.ennjoy.cn/YinKe/Api/public/UploadFile/Policy'
+    policyUrl: 'https://api.teacher.ennjoy.cn/Api/public/UploadFile/Policy'
 }
 
 export default config

+ 669 - 55
src/data.json

@@ -1,147 +1,761 @@
 {
-	"schoolId": "108",
-	"id": "459",
-	"subjectId": "1635",
+	"schoolId": "110",
+	"id": "546",
+	"subjectId": "1844",
 	"paperSize": "A3",
 	"layoutType": "2",
 	"sourceType": "2",
 	"prohibitType": "1",
 	"noMode": "2",
-	"noCount": "9",
+	"noCount": "6",
 	"noBoth": "0",
-	"qrCode": "cm",
-	"alias": "test-lsiten 高二 语文",
+	"qrCode": "fQ",
+	"alias": "lsiten 高一 理综",
 	"cardJson": null,
 	"cardHtml": "",
 	"attention": null,
-	"examPageCnt": "1",
+	"examPageCnt": "0",
 	"pageQus": [{
-		"sort": "1",
+		"sort": "5",
 		"attribute": null,
 		"content": null,
 		"annexable": "1",
 		"group": "0",
-		"pIndex": "1",
+		"pIndex": "",
 		"pros": [{
-			"proId": "852",
-			"score": 70.0,
-			"pureObjective": "1",
+			"proId": "1624",
+			"score": 20.0,
+			"pureObjective": "2",
+			"content": "",
+			"sort": "14",
+			"pnum": "25",
+			"group": "0",
+			"qus": [{
+				"quId": "2937",
+				"score": 8.0,
+				"quType": "解答题",
+				"nums": null,
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2938",
+				"score": 12.0,
+				"quType": "解答题",
+				"nums": null,
+				"content": "",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}]
+		}]
+	}, {
+		"sort": "6",
+		"attribute": null,
+		"content": null,
+		"annexable": "1",
+		"group": "0",
+		"pIndex": "",
+		"pros": [{
+			"proId": "1604",
+			"score": 14.0,
+			"pureObjective": "2",
+			"content": "",
+			"sort": "15",
+			"pnum": "26",
+			"group": "0",
+			"qus": [{
+				"quId": "2888",
+				"score": 4.0,
+				"quType": "填空题",
+				"nums": "2",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2889",
+				"score": 6.0,
+				"quType": "填空题",
+				"nums": "3",
+				"content": "",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2890",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "2",
+				"content": "",
+				"pnum": "(3)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2891",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(4)",
+				"visible": true,
+				"rIndex": "0"
+			}]
+		}]
+	}, {
+		"sort": "7",
+		"attribute": null,
+		"content": null,
+		"annexable": "1",
+		"group": "0",
+		"pIndex": "",
+		"pros": [{
+			"proId": "1605",
+			"score": 15.0,
+			"pureObjective": "2",
+			"content": "",
+			"sort": "16",
+			"pnum": "27",
+			"group": "0",
+			"qus": [{
+				"quId": "2892",
+				"score": 3.0,
+				"quType": "多选题",
+				"nums": "5",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2893",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2894",
+				"score": 2.0,
+				"quType": "解答题",
+				"nums": null,
+				"content": "",
+				"pnum": "(3)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2895",
+				"score": 3.0,
+				"quType": "填空题",
+				"nums": "2",
+				"content": "",
+				"pnum": "(4)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2896",
+				"score": 5.0,
+				"quType": "填空题",
+				"nums": "3",
+				"content": "",
+				"pnum": "(5)",
+				"visible": true,
+				"rIndex": "0"
+			}]
+		}]
+	}, {
+		"sort": "8",
+		"attribute": null,
+		"content": null,
+		"annexable": "1",
+		"group": "0",
+		"pIndex": "",
+		"pros": [{
+			"proId": "1606",
+			"score": 14.0,
+			"pureObjective": "2",
 			"content": "",
-			"sort": "1",
-			"pnum": "5",
+			"sort": "17",
+			"pnum": "28",
 			"group": "0",
 			"qus": [{
-				"quId": "1402",
-				"score": 20.0,
+				"quId": "2897",
+				"score": 2.0,
 				"quType": "单选题",
-				"nums": "4",
+				"nums": "3",
 				"content": "",
 				"pnum": "(1)",
 				"visible": true,
-				"rIndex": "1-1"
+				"rIndex": "0"
 			}, {
-				"quId": "1403",
-				"score": 20.0,
+				"quId": "2898",
+				"score": 2.0,
 				"quType": "单选题",
 				"nums": "4",
 				"content": "",
 				"pnum": "(2)",
 				"visible": true,
-				"rIndex": "1-1"
+				"rIndex": "0"
+			}, {
+				"quId": "2899",
+				"score": 4.0,
+				"quType": "填空题",
+				"nums": "2",
+				"content": "",
+				"pnum": "(3)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2900",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(4)",
+				"visible": true,
+				"rIndex": "0"
 			}, {
-				"quId": "1404",
-				"score": 30.0,
+				"quId": "2901",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(5)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2902",
+				"score": 2.0,
 				"quType": "单选题",
 				"nums": "4",
 				"content": "",
-				"pnum": "(3)",
+				"pnum": "(6)",
 				"visible": true,
-				"rIndex": "1-1"
+				"rIndex": "0"
 			}]
 		}]
 	}, {
-		"sort": "2",
+		"sort": "9",
 		"attribute": null,
 		"content": null,
 		"annexable": "1",
 		"group": "0",
-		"pIndex": "1",
+		"pIndex": "",
 		"pros": [{
-			"proId": "1087",
-			"score": 20.0,
+			"proId": "1597",
+			"score": 8.0,
 			"pureObjective": "2",
 			"content": "",
-			"sort": "1",
-			"pnum": "",
+			"sort": "18",
+			"pnum": "29",
 			"group": "0",
 			"qus": [{
-				"quId": "1848",
-				"score": 20.0,
+				"quId": "2861",
+				"score": 4.0,
+				"quType": "填空题",
+				"nums": "2",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2862",
+				"score": 4.0,
+				"quType": "填空题",
+				"nums": "2",
+				"content": "",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}]
+		}]
+	}, {
+		"sort": "10",
+		"attribute": null,
+		"content": null,
+		"annexable": "1",
+		"group": "0",
+		"pIndex": "",
+		"pros": [{
+			"proId": "1598",
+			"score": 12.0,
+			"pureObjective": "2",
+			"content": "",
+			"sort": "19",
+			"pnum": "30",
+			"group": "0",
+			"qus": [{
+				"quId": "2863",
+				"score": 6.0,
+				"quType": "填空题",
+				"nums": "3",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2864",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2865",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(3)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2866",
+				"score": 2.0,
 				"quType": "填空题",
 				"nums": "1",
 				"content": "",
-				"pnum": "1",
+				"pnum": "(4)",
 				"visible": true,
 				"rIndex": "0"
 			}]
 		}]
 	}, {
-		"sort": "3",
+		"sort": "11",
 		"attribute": null,
 		"content": null,
 		"annexable": "1",
 		"group": "0",
-		"pIndex": "1",
+		"pIndex": "",
 		"pros": [{
-			"proId": "1088",
-			"score": 20.0,
+			"proId": "1599",
+			"score": 8.0,
 			"pureObjective": "2",
 			"content": "",
-			"sort": "2",
-			"pnum": "",
+			"sort": "20",
+			"pnum": "31",
 			"group": "0",
 			"qus": [{
-				"quId": "1849",
-				"score": 20.0,
+				"quId": "2867",
+				"score": 4.0,
+				"quType": "填空题",
+				"nums": "2",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2868",
+				"score": 2.0,
 				"quType": "填空题",
 				"nums": "1",
 				"content": "",
-				"pnum": "2",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2869",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(3)",
 				"visible": true,
 				"rIndex": "0"
 			}]
 		}]
 	}, {
-		"sort": "4",
+		"sort": "12",
 		"attribute": null,
 		"content": null,
 		"annexable": "1",
 		"group": "0",
-		"pIndex": "1",
+		"pIndex": "",
 		"pros": [{
-			"proId": "934",
-			"score": 40.0,
+			"proId": "1600",
+			"score": 11.0,
 			"pureObjective": "2",
 			"content": "",
-			"sort": "3",
-			"pnum": "",
+			"sort": "21",
+			"pnum": "32",
 			"group": "0",
 			"qus": [{
-				"quId": "1523",
-				"score": 20.0,
+				"quId": "2870",
+				"score": 4.0,
+				"quType": "填空题",
+				"nums": "2",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2871",
+				"score": 7.0,
+				"quType": "填空题",
+				"nums": "4",
+				"content": "",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}]
+		}]
+	}, {
+		"sort": "13",
+		"attribute": null,
+		"content": null,
+		"annexable": "1",
+		"group": "1",
+		"pIndex": "",
+		"pros": [{
+			"proId": "1622",
+			"score": 15.0,
+			"pureObjective": "2",
+			"content": "",
+			"sort": "22",
+			"pnum": "33",
+			"group": "1",
+			"qus": [{
+				"quId": "2932",
+				"score": 5.0,
+				"quType": "多选题",
+				"nums": "5",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2933",
+				"score": 10.0,
+				"quType": "解答题",
+				"nums": null,
+				"content": "",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}]
+		}, {
+			"proId": "1621",
+			"score": 15.0,
+			"pureObjective": "2",
+			"content": "",
+			"sort": "23",
+			"pnum": "34",
+			"group": "1",
+			"qus": [{
+				"quId": "2930",
+				"score": 5.0,
+				"quType": "多选题",
+				"nums": "5",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2931",
+				"score": 10.0,
+				"quType": "解答题",
+				"nums": null,
+				"content": "",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}]
+		}, {
+			"proId": "1614",
+			"score": 15.0,
+			"pureObjective": "2",
+			"content": "",
+			"sort": "24",
+			"pnum": "35",
+			"group": "1",
+			"qus": [{
+				"quId": "2921",
+				"score": 5.0,
+				"quType": "多选题",
+				"nums": "5",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2922",
+				"score": 10.0,
+				"quType": "解答题",
+				"nums": null,
+				"content": "",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}]
+		}]
+	}, {
+		"sort": "14",
+		"attribute": null,
+		"content": null,
+		"annexable": "1",
+		"group": "2",
+		"pIndex": "",
+		"pros": [{
+			"proId": "1607",
+			"score": 15.0,
+			"pureObjective": "2",
+			"content": "",
+			"sort": "25",
+			"pnum": "36",
+			"group": "2",
+			"qus": [{
+				"quId": "2903",
+				"score": 5.0,
+				"quType": "填空题",
+				"nums": "3",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2904",
+				"score": 4.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2905",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(3)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2906",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(4)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2907",
+				"score": 2.0,
+				"quType": "多选题",
+				"nums": "4",
+				"content": "",
+				"pnum": "(5)",
+				"visible": true,
+				"rIndex": "0"
+			}]
+		}, {
+			"proId": "1608",
+			"score": 15.0,
+			"pureObjective": "2",
+			"content": "",
+			"sort": "26",
+			"pnum": "37",
+			"group": "2",
+			"qus": [{
+				"quId": "2908",
+				"score": 4.0,
+				"quType": "填空题",
+				"nums": "2",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2909",
+				"score": 4.0,
+				"quType": "填空题",
+				"nums": "2",
+				"content": "",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2910",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(3)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2911",
+				"score": 5.0,
+				"quType": "解答题",
+				"nums": null,
+				"content": "",
+				"pnum": "(4)",
+				"visible": true,
+				"rIndex": "0"
+			}]
+		}, {
+			"proId": "1612",
+			"score": 15.0,
+			"pureObjective": "2",
+			"content": "",
+			"sort": "27",
+			"pnum": "38",
+			"group": "2",
+			"qus": [{
+				"quId": "2915",
+				"score": 4.0,
+				"quType": "填空题",
+				"nums": "2",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2916",
+				"score": 2.0,
 				"quType": "解答题",
 				"nums": null,
 				"content": "",
-				"pnum": "3",
+				"pnum": "(2)",
 				"visible": true,
 				"rIndex": "0"
 			}, {
-				"quId": "1524",
-				"score": 20.0,
+				"quId": "2917",
+				"score": 3.0,
 				"quType": "解答题",
 				"nums": null,
 				"content": "",
-				"pnum": "4",
+				"pnum": "(3)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2918",
+				"score": 4.0,
+				"quType": "解答题",
+				"nums": null,
+				"content": "",
+				"pnum": "(4)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2919",
+				"score": 2.0,
+				"quType": "解答题",
+				"nums": null,
+				"content": "",
+				"pnum": "(5)",
+				"visible": true,
+				"rIndex": "0"
+			}]
+		}]
+	}, {
+		"sort": "15",
+		"attribute": null,
+		"content": null,
+		"annexable": "1",
+		"group": "3",
+		"pIndex": "",
+		"pros": [{
+			"proId": "1601",
+			"score": 15.0,
+			"pureObjective": "2",
+			"content": "",
+			"sort": "28",
+			"pnum": "39",
+			"group": "3",
+			"qus": [{
+				"quId": "2872",
+				"score": 1.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2873",
+				"score": 4.0,
+				"quType": "填空题",
+				"nums": "2",
+				"content": "",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2874",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(3)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2875",
+				"score": 6.0,
+				"quType": "填空题",
+				"nums": "3",
+				"content": "",
+				"pnum": "(4)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2876",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(5)",
+				"visible": true,
+				"rIndex": "0"
+			}]
+		}, {
+			"proId": "1602",
+			"score": 15.0,
+			"pureObjective": "2",
+			"content": "",
+			"sort": "29",
+			"pnum": "40",
+			"group": "3",
+			"qus": [{
+				"quId": "2877",
+				"score": 1.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(1)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2878",
+				"score": 4.0,
+				"quType": "填空题",
+				"nums": "2",
+				"content": "",
+				"pnum": "(2)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2879",
+				"score": 8.0,
+				"quType": "填空题",
+				"nums": "4",
+				"content": "",
+				"pnum": "(3)",
+				"visible": true,
+				"rIndex": "0"
+			}, {
+				"quId": "2880",
+				"score": 2.0,
+				"quType": "填空题",
+				"nums": "1",
+				"content": "",
+				"pnum": "(4)",
 				"visible": true,
 				"rIndex": "0"
 			}]

+ 151 - 134
src/index.js

@@ -4,153 +4,170 @@ import $ from './js/util/dom-core.js';
 import data from './data.json';
 let editor = new yzWebeditor({dom:document.getElementById('pages-box'), data: data});
 
-// let conmands = [];
+let conmands = [];
 
-// const selection = editor.selection;
+const selection = editor.selection;
 
-// let cardHtml = data.cardHtml || '';
-// if (cardHtml.length > 0) {
-//   cardHtml = JSON.parse(data.cardHtml);
-//   editor.page.parseCardHtml(cardHtml);
-// } else {
-//   let borders = data.pageQus;
+let cardHtml = data.cardHtml || '';
+if (cardHtml.length > 0) {
+  cardHtml = JSON.parse(data.cardHtml);
+  editor.page.parseCardHtml(cardHtml);
+} else {
+  let borders = data.pageQus;
 
-//   let length = borders.length;
-//   for (let i = 0; i < length; i++) {
-//     let borderItem = borders[i];
-//     let pros = borderItem.pros;
-//     let plength = pros.length;
-//     borderItem.pureObject = true;
-//     for (let j = 0; j < plength; j++) {
-//       let prosItem = pros[j];
-//       if (parseInt(prosItem.pureObjective) ===2) {
-//         borderItem.pureObject = false;
-//       }
-//     }
-//   }
+  let length = borders.length;
+  for (let i = 0; i < length; i++) {
+    let borderItem = borders[i];
+    let pros = borderItem.pros;
+    let plength = pros.length;
+    borderItem.pureObject = true;
+    for (let j = 0; j < plength; j++) {
+      let prosItem = pros[j];
+      if (parseInt(prosItem.pureObjective) ===2) {
+        borderItem.pureObject = false;
+      }
+    }
+  }
   
   
-//   for (let i = 0; i < length; i ++) {
-//     let borderItem = borders[i];
-//     let borderData = {
-//       annexable: borderItem.annexable,
-//       attribute: borderItem.attribute,
-//       content: borderItem.content,
-//       group: borderItem.group,
-//       pureObject: borderItem.pureObject,
-//       pros: borderItem.pros,
-//       sort: borderItem.sort
-//     }
-//     if (borderItem.pureObject) {
-//       let conmandItem = {
-//         exc: 'border',
-//         params: {
-//           type: 1,
-//           data: borderData
-//         }
-//       }
-//       conmands.push(conmandItem);
-//     } else {
-//       let conmandItem = {
-//         exc: 'border',
-//         params: {
-//           type: 2,
-//           data: borderData
-//         }
-//       }
-//       conmands.push(conmandItem);
-//     }
+  for (let i = 0; i < length; i ++) {
+    let borderItem = borders[i];
+    let borderData = {
+      annexable: borderItem.annexable,
+      attribute: borderItem.attribute,
+      content: borderItem.content,
+      group: borderItem.group,
+      pureObject: borderItem.pureObject,
+      pros: borderItem.pros,
+      sort: borderItem.sort
+    }
+    if (borderItem.pureObject) {
+      let conmandItem = {
+        exc: 'border',
+        params: {
+          type: 1,
+          data: borderData
+        }
+      }
+      conmands.push(conmandItem);
+    } else {
+      let conmandItem = {
+        exc: 'border',
+        params: {
+          type: 2,
+          data: borderData
+        }
+      }
+      conmands.push(conmandItem);
+    }
   
-//     let pros = borderItem.pros;
-//     let plength = pros.length;
-//     let maxNum = 0;
-//     let questcount = 0;
-//     for (let j = 0; j < plength; j++) {
-//       let prosItem = pros[j];
-//       let qus = prosItem.qus;
-//       let klength = qus.length;
-//       for (let k = 0; k < klength; k++) {
-//         let qusItem = JSON.parse(JSON.stringify(qus[k]));
-//         qusItem.proId = prosItem.proId;
-//         qusItem.proData = {
-//           content: prosItem.content,
-//           proId: prosItem.proId,
-//           pnum: prosItem.pnum,
-//           pureObjective: prosItem.pureObjective,
-//           score: prosItem.score,
-//           sort: prosItem.sort
-//         };
-//         let qNums = parseInt(qusItem.nums);
-//         qNums > maxNum && (maxNum = qNums);
-//         parseQuestion(qusItem);
-//         questcount++;
-//       }
-//     }
+    let pros = borderItem.pros;
+    let plength = pros.length;
+    let maxNum = 0;
+    let questcount = 0;
+    for (let j = 0; j < plength; j++) {
+      let prosItem = pros[j];
+      let qus = prosItem.qus;
+      let klength = qus.length;
+      for (let k = 0; k < klength; k++) {
+        let qusItem = JSON.parse(JSON.stringify(qus[k]));
+        qusItem.proId = prosItem.proId;
+        qusItem.proData = {
+          content: prosItem.content,
+          proId: prosItem.proId,
+          pnum: prosItem.pnum,
+          pureObjective: prosItem.pureObjective,
+          score: prosItem.score,
+          sort: prosItem.sort
+        };
+        let qNums = parseInt(qusItem.nums);
+        qNums > maxNum && (maxNum = qNums);
+        if (qusItem.visible) {
+          parseQuestion(qusItem);
+          questcount++;
+        }
+      }
+    }
   
-//     if (borderItem.pureObject) {
-//       let columns = 1;
-//       if (maxNum > 4) {
-//         columns = 2;
-//       } else {
-//         columns = 3;
-//       }
+    if (borderItem.pureObject) {
+      let columns = 1;
+      if (maxNum > 4) {
+        columns = 2;
+      } else {
+        columns = 3;
+      }
   
-//       let rows = Math.ceil(questcount / columns / 5);
-//       borderData.row = rows;
-//       borderData.column = columns;
-//     }
-//   }
-//   let commondsLength = conmands.length;
-//   asynExecCommand(0, commondsLength);
-// }
+      if (questcount <= 0 ) {
+        console.log(conmands);
+        conmands.pop();
+      } else {
+        let rows = Math.ceil(questcount / columns / 5);
+        borderData.row = rows;
+        borderData.column = columns;
+      }
+    }
 
-// async function asynExecCommand (i, length) {
-//   if (i < length) {
-//     setTimeout(() => {
-//       editor.cmd.do(conmands[i].exc, conmands[i].params);
-//       asynExecCommand(++i, length);
-//     }, 0)
-//   }
-// }
+    let conmandItem = {
+      exc: 'checkOut',
+      params: {}
+    }
+    conmands.push(conmandItem);
+  }
+  let commondsLength = conmands.length;
+  asynExecCommand(0, commondsLength);
+}
 
-// function parseQuestion (qitem) {
-//   let type = qitem.quType;
-//   switch(type) {
-//     case '单选题':
-//     case '多选题':
-//     let conmandItem1 = {
-//       exc: 'questiontype',
-//       params: {type: 1, data: qitem}
-//     }
-//     conmands.push(conmandItem1);
-//     break;
-//     case '判断题':
+async function asynExecCommand (i, length) {
+  if (i < length) {
+    setTimeout(() => {
+      if (editor.page._checkPageOutStatus) {
+        asynExecCommand(i, length);
+      } else {
+        editor.cmd.do(conmands[i].exc, conmands[i].params);
+        asynExecCommand(++i, length);
+      }
+    }, 0)
+  }
+}
 
-//     let conmandItem2 = {
-//       exc: 'questiontype',
-//       params: {type: 2, data: qitem}
-//     }
-//     conmands.push(conmandItem2);
-//     break;
+function parseQuestion (qitem) {
+  let type = qitem.quType;
+  switch(type) {
+    case '单选题':
+    case '多选题':
+    let conmandItem1 = {
+      exc: 'questiontype',
+      params: {type: 1, data: qitem}
+    }
+    conmands.push(conmandItem1);
+    break;
+    case '判断题':
 
-//     case '填空题':
-//     case '解答题':
-//     let conmandItem3 = {
-//       exc: 'questiontype',
-//       params: {type: 3, data: qitem}
-//     }
-//     conmands.push(conmandItem3);
-//     break;
+    let conmandItem2 = {
+      exc: 'questiontype',
+      params: {type: 2, data: qitem}
+    }
+    conmands.push(conmandItem2);
+    break;
 
-//     case '作文题':
-//     let conmandItem4 = {
-//       exc: 'questiontype',
-//       params: {type: 4, data: qitem}
-//     }
-//     conmands.push(conmandItem4);
-//     break;
-//   }
-// }
+    case '填空题':
+    case '解答题':
+    let conmandItem3 = {
+      exc: 'questiontype',
+      params: {type: 3, data: qitem}
+    }
+    conmands.push(conmandItem3);
+    break;
+
+    case '作文题':
+    let conmandItem4 = {
+      exc: 'questiontype',
+      params: {type: 4, data: qitem}
+    }
+    conmands.push(conmandItem4);
+    break;
+  }
+}
 
 
 console.log(editor);

+ 1 - 1
src/js/command/index.js

@@ -20,7 +20,7 @@ Command.prototype = {
         const editor = this.editor
         // 使用 styleWithCSS
         if (!editor._useStyleWithCSS) {
-            document.execCommand('styleWithCSS', null, true)
+            document.execCommand('styleWithCSS', false, true)
             editor._useStyleWithCSS = true
         }
 

+ 50 - 0
src/js/menus/addline/index.js

@@ -0,0 +1,50 @@
+/*
+    underline-menu
+*/
+import $ from '../../util/dom-core.js'
+
+// 构造函数
+function Addline(editor) {
+    this.editor = editor
+    this.$elem = $(
+        `<div class="lsiten-e-menu">
+           加线
+        </div>`
+    )
+    this.type = 'click'
+
+    // 当前是否 active 状态
+    this._active = false
+}
+
+// 原型
+Addline.prototype = {
+    constructor: Addline,
+
+    // 点击事件
+    onClick: function (e) {
+      // 点击菜单将触发这里
+      const selection = this.editor.selection;
+      if (isSeleEmpty) {
+        // 选区是空的,插入并选中一个“固定宽度的下划线”
+        
+      } else {
+
+      }
+    },
+
+    // 试图改变 active 状态
+    tryChangeActive: function (e) {
+        const editor = this.editor
+        const $elem = this.$elem
+        if (editor.cmd.queryCommandState('underline')) {
+            this._active = true
+            $elem.addClass('lsiten-e-active')
+        } else {
+            this._active = false
+            $elem.removeClass('lsiten-e-active')
+        }
+    }
+}
+
+export default Addline

+ 51 - 0
src/js/menus/format/index.js

@@ -0,0 +1,51 @@
+/*
+    underline-menu
+*/
+import $ from '../../util/dom-core.js'
+import { getParentByClassname } from '../../util/util.js'
+
+// 构造函数
+function Format(editor) {
+    this.editor = editor
+    this.$elem = $(
+        `<div class="lsiten-e-menu">
+            清空样式
+        </div>`
+    )
+    this.type = 'click'
+
+    // 当前是否 active 状态
+    this._active = false
+}
+
+// 原型
+Format.prototype = {
+    constructor: Format,
+
+    // 点击事件
+    onClick: function (e) {
+        // 点击菜单将触发这里
+        let pagemanage = this.editor.page;
+        let $currentLine = pagemanage.editorPosition.currentLine;
+        let $textElem = pagemanage.$el;
+        if (!$currentLine) {
+          console.log("%c请在框内操作!", "color:red");
+          return '';
+        }
+        let $border = getParentByClassname($currentLine, 'js-lsiten-border');
+        if (!$border) {
+          console.log("%c请在框内添操作!", "color:red");
+          return '';
+        }
+        $currentLine[0].innerHTML = $currentLine[0].innerText;
+        pagemanage._updatePositionInfo(false, $currentLine);
+        this.editor.selection.getRange().setStart($currentLine[0], 0);
+        $currentLine[0].focus();    
+    },
+
+    // 试图改变 active 状态
+    tryChangeActive: function (e) {
+    }
+}
+
+export default Format

+ 7 - 4
src/js/menus/img/index.js

@@ -23,13 +23,17 @@ Image.prototype = {
     constructor: Image,
 
     onClick: function () {
-        let $selectionElem = this.editor.selection.getSelectionContainerElem();
+        this.$border = null;                
+        let $selectionElem = this.editor.page.editorPosition.currentLine;
         let borderText = getParentByClassname($selectionElem, 'js-lsiten-border');
         if (borderText) { 
           let size = borderText.getSizeData();
+          this.$border = borderText;
           this._createFileForm(size);
+          this.$input[0].value = '';
           this.$input[0].click();
         } else {
+          this.$border = null;          
           this.editor.message.showMessage('请在框内进行图片编辑');
         }
     },
@@ -88,9 +92,8 @@ Image.prototype = {
           imageTool.resizeByRatio(ratio);
         }
         let html = $('<img class="lsiten-js-image-class" style="width: ' + imageTool.size.w + 'px; height: ' + imageTool.size.h + 'px" src="' + img.src + '" data-store = "' +img.store+ '"/>');
-        _this.editor.cmd.do('insertElem', html);
-        _this.editor.selection.getRange().setStart(html[0], 0);
-        _this.editor.page._checkoutContentChangeByFun();
+        html.css('position', 'absolute').css('top', '0').css('left', '0');
+        _this.$border.append(html);      
       }
     },
     // 试图改变 active 状态

+ 71 - 0
src/js/menus/lineheight/index.js

@@ -0,0 +1,71 @@
+/*
+    menu - justify
+*/
+import $ from '../../util/dom-core.js';
+import DropList from '../droplist.js';
+import {getParentByClassname} from '../../util/util.js';
+import Jquery from 'jquery';
+
+// 构造函数
+function Lineheight(editor) {
+    this.editor = editor
+    this.$elem = $('<div class="lsiten-e-menu"><i class="lsiten-e-icon-text-heigh"></i></div>')
+    this.type = 'droplist'
+
+    // 当前是否 active 状态
+    this._active = false
+
+    // 初始化 droplist
+    this.droplist = new DropList(this, {
+        width: 100,
+        $title: $('<p>行高</p>'),
+        type: 'list', // droplist 以列表形式展示
+        list: [
+            { $elem: $('<span>18px</span>'), value: '18' },
+            { $elem: $('<span>20px</span>'), value: '20' },
+            { $elem: $('<span>25px</span>'), value: '25' },
+            { $elem: $('<span>30px</span>'), value: '30' },
+            { $elem: $('<span>38px</span>'), value: '38' },
+            { $elem: $('<span>44px</span>'), value: '44' },
+            { $elem: $('<span>50px</span>'), value: '50' }
+        ],
+        onClick: (value) => {
+          // 注意 this 是指向当前的 List 对象
+          value = parseInt(value);
+          if (!value) {
+              return '';
+          }
+          let pagemanage = this.editor.page;
+          let $currentLine = pagemanage.editorPosition.currentLine;
+          let $textElem = pagemanage.$el;
+          if (!$currentLine) {
+            console.log("%c请在框内操作!", "color:red");
+            return '';
+          }
+          let $border = getParentByClassname($currentLine, 'js-lsiten-border');
+          if (!$border) {
+            console.log("%c请在框内添操作!", "color:red");
+            return '';
+          }
+          let lineheightValue = value;
+          $border.attr('data-blineheight', lineheightValue);
+          $border.find('.js-lsiten-line').css('line-height', lineheightValue + 'px');
+          Jquery($textElem[0]).trigger('addContent', () => {
+            Jquery($textElem[0]).trigger('removeContent');
+          });
+        }
+    })
+}
+
+// 原型
+Lineheight.prototype = {
+    constructor: Lineheight,
+
+    // 执行命令
+    _command: function (value) {
+        const editor = this.editor
+        editor.cmd.do(value)
+    }
+}
+
+export default Lineheight

+ 12 - 0
src/js/menus/menu-list.js

@@ -79,5 +79,17 @@ MenuConstructors.questionData = QuestionData
 
 import AddPage from './addpage/index.js'
 MenuConstructors.addPage = AddPage
+
+
+
+import Lineheight from './lineheight/index.js'
+MenuConstructors.lineheight = Lineheight
+
+
+import Addline from './addline/index.js'
+MenuConstructors.addline = Addline
+
+import Format from './format/index.js'
+MenuConstructors.format = Format
 // 吐出所有菜单集合
 export default MenuConstructors

+ 37 - 20
src/js/menus/underline/index.js

@@ -24,7 +24,6 @@ Underline.prototype = {
     // 点击事件
     onClick: function (e) {
         // 点击菜单将触发这里
-        
         const editor = this.editor
         const isSeleEmpty = editor.selection.isSelectionEmpty()
 
@@ -32,26 +31,44 @@ Underline.prototype = {
             // 选区是空的,插入并选中一个“空白”
             editor.selection.createEmptyRange()
         }
-        let text =editor.selection.getRange();
-        let startText = text.startContainer;
-        if (startText.nodeType === 3) {
-          let parentNode = startText.parentNode;
-          let nextNode =startText.nextSibling;
-          let span = document.createElement('span');
-          span.style.textDecoration = 'underline';
-          span.appendChild(startText);
-          if (nextNode) {
-            parentNode.insertBefore(span, nextNode);
-          } else {
-            parentNode.appendChild(span);
-          }
-          // 最后,恢复选取保证光标在原来的位置闪烁
-          editor.selection.getRange().setStart(span, 1);
-        } else {
-          let html = '<span style="text-decoration: underline;">&#8203;</span>';
-          editor.cmd.do('insertHTML', html);
-        }
+        // 恢复选中文字
+        editor.selection.restoreSelection();
+        editor.cmd.do('underline');
+        // let text =editor.selection.getRange();
+        
+        // let startText = text.startContainer;
+        // let endText = text.endContainer;
+        // if (startText !== endText) {
+        //   console.log('error');
+        //   editor.message.showMessage('该页已经有答题卡头!');
+        //   return '';
+        // }
+        // if (startText.nodeType === 3) {
+        //   startText.splitText(text.startOffset);
+        //   startText = startText.nextSibling;
+        //   startText.splitText(text.endOffset);
+        //   let parentNode = startText.parentNode;
+        //   let nextNode =startText.nextSibling;
+        //   let span = document.createElement('span');
+        //   span.style.textDecoration = 'underline';
+        //   span.appendChild(startText);
+        //   if (nextNode) {
+        //     parentNode.insertBefore(span, nextNode);
+        //   } else {
+        //     parentNode.appendChild(span);
+        //   }
+        //   // 最后,恢复选取保证光标在原来的位置闪烁
+        //   editor.selection.getRange().setStart(span, 1);
+        // } else {
+        //   let html = '<span style="text-decoration: underline;">&#8203;</span>';
+        //   editor.cmd.do('insertHTML', html);
+        // }
         editor.selection.saveRange();
+        let text =editor.selection.getRange();
+        let $text = $(
+            text.startContainer.nodeType === 1 ? text.startContainer : text.startContainer.parentNode
+        );
+        $text.css('text-decoration', 'underline');
         editor.selection.restoreSelection();
         // 执行 underline 命令
         // let result = editor.cmd.do('underline');

+ 3 - 1
src/js/plugin/commands/border.js

@@ -31,6 +31,7 @@ function objectBorder (editor, data) {
         .css('padding', '0')
         .css('margin', '10px 0')
         .css('overflow', 'hidden')
+        .css('position', 'relative')
         .css('height', 'auto')
         .css('width', '100%')
         .css('box-sizing', 'border-box')
@@ -87,6 +88,7 @@ function subjectBorder (editor, data) {
   let sortIndex = data.sort;
   let border = $('<div class="js-lsiten-border lsiten-question-subject"><div class="border-content"></div></div>');
   border.attr('data-type', 2);
+  border.attr('data-blineheight', 25);
   border.attr('data-sort', sortIndex);
   border.attr('tabindex', 1);
   border.attr('data-id', uuid());
@@ -96,6 +98,7 @@ function subjectBorder (editor, data) {
   border.css('border', '1px solid #000')
   .css('padding', '10px 15px')
   .css('height', 'auto')
+  .css('position', 'relative')
   .css('margin', '10px 0')
   .css('width', '100%')
   .css('box-sizing', 'border-box')
@@ -161,7 +164,6 @@ let Border = function (params) {
     subjectBorder(editor, data);
     break;
   }
-  Jquery(editor.page.$el[0]).trigger('addContent');
  }
  export default {
    _border: Border

+ 8 - 0
src/js/plugin/commands/checkOut.js

@@ -0,0 +1,8 @@
+import Jquery from 'jquery';
+let checkOut = function () {
+  Jquery(this.editor.page.$el[0]).trigger('addContent');
+}
+
+export default {
+  _checkOut: checkOut
+}

+ 0 - 1
src/js/plugin/commands/questiontype.js

@@ -29,7 +29,6 @@ let Questiontype = function (params) {
     questionGenerate.generateWriting(border, data, editor);
     break;
   }
-  Jquery(editor.page.$el[0]).trigger('addContent');
  }
  export default {
    _questiontype: Questiontype

+ 3 - 1
src/js/question/choice.js

@@ -114,11 +114,13 @@ let generateChoice = function ($border, data, editor) {
       return '';
     }
 
+    $questionItem.css('margin', '0');    
     let questionBox = getParentByClassname($currentLine, 'js-lsiten-question');
     if (questionBox) {
       $currentLine = parseInt(questionBox.attr('data-type')) > 2 ? questionBox : questionBox.parent();
     }
-    let $newLine = gennerOneLine();
+    let lineHeight = $borderContent.parent()[0].getAttribute('data-blineheight');
+    let $newLine = gennerOneLine(false, lineHeight);
     $($newLine[0].firstChild).remove();
     $newLine.append($questionItem);
     $newLine.insertAfter($currentLine);

+ 3 - 2
src/js/question/judge.js

@@ -106,8 +106,9 @@ import { gennerOneLine } from '../util/lineUtil.js';
     if (questionBox) {
       $currentLine = parseInt(questionBox.attr('data-type')) > 2 ? questionBox : questionBox.parent();
     }
-
-    let $newLine = gennerOneLine();
+    $questionItem.css('margin', '0');
+    let lineHeight = $borderContent.parent()[0].getAttribute('data-blineheight');
+    let $newLine = gennerOneLine(false, lineHeight);
     $($newLine[0].firstChild).remove();
     $newLine.append($questionItem);
     $newLine.insertAfter($currentLine);

+ 2 - 1
src/js/question/subject.js

@@ -25,7 +25,6 @@ let generateSubjectBox = function ($border, data, editor) {
 
   let $box = $('<div class = "lsiten-subject-box js-lsiten-question"></div>');
   $box.attr('data-type', 3);
-  gennerOneLines(4, $box, pnum);
   // 在主观题内添加
   let $currentLine = editor.page.editorPosition.currentLine;
   if (!$currentLine) {
@@ -37,6 +36,8 @@ let generateSubjectBox = function ($border, data, editor) {
     console.log("%c请在框内添加该题!", "color:red");
     return '';
   }
+  let lineHeight = $borderContent.parent()[0].getAttribute('data-blineheight');  
+  gennerOneLines(4, $box, pnum, lineHeight);
   let questionBox = getParentByClassname($currentLine, 'js-lsiten-question');
   if (questionBox) {
     $currentLine = parseInt(questionBox.attr('data-type')) > 2 ? questionBox : questionBox.parent();

+ 8 - 6
src/js/question/writing.js

@@ -26,12 +26,6 @@ let generateWriting = function ($border, data, editor) {
   // 1、生成题号区
   let $title = $('<div class="lsiten-title"></div>');
   $title.css('padding', '0 15px');
-  gennerOneLines(1, $title, pnum);
-  $box.append($title);
-  // 2、生成格子区域
-  let column = getColumnCount(editor);
-  let $grid = generateGrid(column, total);
-  $box.append($grid);
   // 在主观题内添加
   let $currentLine = editor.page.editorPosition.currentLine;
   if (!$currentLine) {
@@ -43,6 +37,14 @@ let generateWriting = function ($border, data, editor) {
     console.log("%c请在框内添加该题!", "color:red");
     return '';
   }
+  let lineHeight = $borderContent.parent()[0].getAttribute('data-blineheight');
+  gennerOneLines(1, $title, pnum, lineHeight);
+  $box.append($title);
+  // 2、生成格子区域
+  let column = getColumnCount(editor);
+  let $grid = generateGrid(column, total);
+  $box.append($grid);
+  
   let questionBox = getParentByClassname($currentLine, 'js-lsiten-question');
   if (questionBox) {
     $currentLine = parseInt(questionBox.attr('data-type')) > 2 ? questionBox : questionBox.parent();

+ 7 - 5
src/js/util/lineUtil.js

@@ -3,18 +3,20 @@
 */
 import $ from './dom-core'
 // 生成行
-export function gennerOneLine(pnum) {
-  let content = pnum || '<br/>'
+export function gennerOneLine(pnum, lineheight) {
+  let content = pnum || '<br/>';
+  lineheight = lineheight || 25;
   let line = $('<div class="js-lsiten-line" contenteditable="true">' + content + '</div>');
-  line.css('outline', 'none').css('width', '100%').css('height', '25px').css('line-height', '25px').css('overflow', 'hidden').css('white-space', 'nowrap');
+  line.css('outline', 'none').css('width', '100%').css('height', 'auto').css('line-height', lineheight + 'px').css('overflow', 'hidden').css('white-space', 'nowrap');
   return line;
 }
 
 /** 
  * function 生成多行
 */
-export function gennerOneLines(num, $content, pnum) {
+export function gennerOneLines(num, $content, pnum, lineheight) {
+  lineheight = lineheight || 25;
   for (let i =0; i < num; i++) {
-    i === 0 ? $content.append(gennerOneLine((pnum + '、'))) : $content.append(gennerOneLine());
+    i === 0 ? $content.append(gennerOneLine((pnum + '、'), lineheight)) : $content.append(gennerOneLine());
   }
 }

+ 105 - 112
src/js/util/question.js

@@ -10,16 +10,16 @@ questionUtils.prototype = {
   /**
    * function 切分题目框
    * @param {DomElement} $border 题框
-   * @param {Object} csize 栏size
+   * @param {DomElement} $column 栏dom
    */
-  _splitBorder: function ($border, csize) {
+  _splitBorder: function ($border, $column) {
     let type = parseInt($border.attr('data-type'));
     switch (type) {
       case 1:
-      return this._spiltObjectBorder($border, csize);
+      return this._spiltObjectBorder($border,  $column);
       break;
       case 2:
-      return this._spiltSubjectBorder($border, csize);      
+      return this._spiltSubjectBorder($border,  $column);      
       break;
     }
   },
@@ -27,45 +27,33 @@ questionUtils.prototype = {
    * function 切分客观题框
    * @param {DomElement} $border 题框
    */
-  _spiltObjectBorder: function ($border, csize) {
+  _spiltObjectBorder: function ($border,  $column) {
     let $nextBorder = $border.clone(false);
     let childs = $border.childNodes();
     let cLength = childs.length;
-    if (cLength > 0) {
-      let i = cLength - 1;
-      while (i >= 0) {
-        let bSizeBorder = $border.getSizeData();
-        let row = childs[i];
-        let $row = $(row);
-        let $nextRow = $row.clone(false);
-        if (bSizeBorder.bottom >= csize.bottom) {
-          this._splitObjectRow($nextRow, $row, $border, csize);
-          if ($nextRow.childNodes().length > 0) {
-            if ($nextBorder.childNodes().length > 0) {
-              let firstChildNode = $nextBorder[0].firstChild;
-              $nextBorder[0].insertBefore($nextRow[0], firstChildNode);
-              $(firstChildNode).removeClass('js-split-row' + (i+1));
-              $nextRow.addClass('js-split-row' + i);
-              $row.addClass('js-split-row'  + i)
-            } else {
-              $nextBorder.append($nextRow);
-              $nextRow.addClass('js-split-row' + i);
-              $row.addClass('js-split-row'  + i)
+    let i = cLength - 1;
+    while (i >= 0) {
+      if (childs[i]) {
+        if (childs[i].nodeType === 3) {
+          $border[0].removeChild(childs[i]);
+        } else {
+          let $child = $(childs[i]);
+          let classname = $child.attr('class');
+          if (classname && classname.indexOf('js-options-row') > -1) {
+            let $nextRow = $child.clone(false);
+            this._splitObjectRow($nextRow, $child, $border, $column);
+            if (!isEmptyElement($nextRow[0])) {
+              this.insertDom($nextBorder, $nextRow);
             }
+          } else {
+            $child.remove();
           }
         }
-        i--;
-        if (!$row.childNodes().length) {
-          $nextRow.removeClass('js-split-row' + i);
-          $row.remove();
-        }
       }
+      i--;
     }
-    if (isEmptyElement($border[0])) {
-      $border.remove();
-    }
-    if ($nextBorder.childNodes().length > 0) {
-      $nextBorder[0].firstChild.style.borderTop = 'none';
+
+    if (!isEmptyElement($nextBorder[0])) {
       return $nextBorder;
     } else {
       return false;
@@ -76,73 +64,67 @@ questionUtils.prototype = {
    * @param {DomElement} $nextDiv 下一段的div
    * @param {DomElement} $item 文本节点
    * @param {DomElement} $border 所在框
-   * @param {Object} csize 栏size
+   * @param {DomElement} $bigColumn 栏dom
    */
-  _splitObjectRow: function ($nextDiv, $item, $border, csize) {
-    let childs = $item.childNodes();
-    let nextDivContentChilds =  [];
-    let nextDivContentChildsLength =  0;
-    nextDivContentChilds = $nextDiv.childNodes();
-    nextDivContentChilds.length > 0 && (nextDivContentChildsLength = nextDivContentChilds.length);
-    let cLength = childs.length;
-    let firstColumn = childs[0];
-    if (!firstColumn) {
-      return '';
-    }
-    let $firstColumn = $(firstColumn);
-    let lastQuestion = parseInt($firstColumn.attr('data-question-count')) - 1;
-    lastQuestion < 0 ? lastQuestion = 0 : '';
-    for (let i =0; i < cLength; i++) {
-      let child = childs[i].firstChild; //栏下有一个内容div
-      let $child = $(child);
-      if (nextDivContentChildsLength > 0) {
-        if (!nextDivContentChilds[i]) {
-          console.log("%c数据错误!", "color:red");          
-          return '';
-        }
-        let $nextContent = $(nextDivContentChilds[i].firstChild);
-        let childsQuestion = $child.childNodes();
-        let nextQuestion =  childsQuestion ? childsQuestion[lastQuestion] : null;
-        if (nextQuestion) {
-          $nextContent[0].insertBefore(nextQuestion, $nextContent[0].firstChild);
-          let $childColumn = $(childs[i]);
-          let columnQuestion = parseInt($childColumn.attr('data-question-count')) - 1;
-          columnQuestion < 0 ? columnQuestion = 0: '';
-          $childColumn.attr('data-question-count', columnQuestion);
-        }
-      } else {
-        let $nextColum = $(childs[i]).clone(false);
-        let $nextContent = $child.clone(false);
-        let childsQuestion = $child.childNodes();
-        let nextQuestion =  childsQuestion ? childsQuestion[lastQuestion] : null;
-        if (nextQuestion) {
-          $nextContent.append($(nextQuestion));
-          let $childColumn = $(childs[i]);
-          let columnQuestion = parseInt($childColumn.attr('data-question-count')) - 1;
-          columnQuestion < 0 ? columnQuestion = 0: '';
-          $childColumn.attr('data-question-count', columnQuestion);
-          $nextColum.append($nextContent);
-        } else {
-          i === 0 ? $nextColum.append($child) : $nextColum.append($nextContent);
-        }
-        $nextDiv.append($nextColum);
-      }
-
-      if (i === 0) {
-        if (!child || isEmptyElement(child)) {
-          $item.html('');
+  _splitObjectRow: function ($nextDiv, $item, $border, $bigColumn) {
+    let borderSize =  $border.getSizeData();
+    let csize = $bigColumn.getSizeData();
+    if (borderSize.bottom >= csize.bottom) {
+      let i = 0;
+      let firstColumn = $item[0].firstChild;
+      if (firstColumn) {
+        let lastKey = $(firstColumn.firstChild).childNodes().length - 1;
+        if (lastKey > -1) {
+          $item.childNodes().forEach(column => {
+            this._insertLastRow($nextDiv, column, i++, lastKey);
+          });
+          if (!this._isEmptyRow($item)) {
+            // 更新栏高
+            let cententHeight = 0;
+            $item.find('.js-option-column').forEach(column => {
+              let contentSize = $(column.firstChild).getSizeData();
+              cententHeight = contentSize.height;
+              $(column).css('min-height', cententHeight + 'px');
+            });
+            this._splitObjectRow($nextDiv, $item, $border,  $bigColumn);
+          } else {
+            $item.remove();
+          }
+          
         }
       }
     }
-    if (firstColumn.firstChild) {
-      let contentSize = $(firstColumn.firstChild).getSizeData();
-      $item.find('.js-option-column').css('min-height', contentSize.height + 'px');
+  },
+  /**
+   * function 插入该row的最后一行
+   */
+  _insertLastRow: function ($nextRow, column, key, lastKey) {
+    let nextColumns = $nextRow.childNodes();
+    let questions = $(column.firstChild).find('.js-lsiten-question');
+    let $nextColumnContent = null;
+    if (nextColumns[key]) {
+      $nextColumnContent = $(nextColumns[key].firstChild);
+    } else {
+      let $nextColumn = $(column).clone(false);
+      $nextColumnContent = $(column.firstChild).clone(false);
+      $nextColumn.append($nextColumnContent);
+      $nextRow.append($nextColumn);
     }
-    let bSizeBorder = $border.getSizeData();
-    if (bSizeBorder.bottom >= csize.bottom) {
-      this._splitObjectRow($nextDiv, $item, $border, csize);
+    if (questions[lastKey]) {
+      this.insertDom($nextColumnContent, $(questions[lastKey]));
     }
-
+  },
+  /**
+   * function 判断行是否为空
+   */
+  _isEmptyRow: function ($row) {
+    let status = true;
+    $row.childNodes().forEach(column => {
+      if (!isEmptyElement(column)) {
+        status = false;
+      }
+    })
+    return status;
   },
   /**
    * function 插入dom
@@ -160,9 +142,9 @@ questionUtils.prototype = {
     /**
    * function 切分主观题框
    * @param {DomElement} $border 题框
-   * @param {Object} csize 栏size
+   * @param {Object} $bigColumn 栏size
    */
-  _spiltSubjectBorder: function ($border, csize) {
+  _spiltSubjectBorder: function ($border, $bigColumn) {
     let $nextBorder = $border.clone(false);
     let $content = $($border[0].firstChild);
     if ($content.attr('class') === 'border-content') {
@@ -176,6 +158,7 @@ questionUtils.prototype = {
             // 普通一行或者是单选题可判断题
             let $line = $(line);
             let borderSize = $border.getSizeData();
+            let csize = $bigColumn.getSizeData();
             if (borderSize.bottom >= csize.bottom) {
               this.insertDom($nextContent, $line);
             }
@@ -183,6 +166,7 @@ questionUtils.prototype = {
             // 选作题组
             let $line = $(line);
             let borderSize = $border.getSizeData();
+            let csize = $bigColumn.getSizeData();
             if (borderSize.bottom >= csize.bottom) {
               this.insertDom($nextContent, $line);
             }
@@ -191,16 +175,16 @@ questionUtils.prototype = {
             let questionType = parseInt($line.attr('data-type'));
             switch (questionType) {
               case 1:
-              this._handleChoice($line, $nextContent, csize);
+              this._handleChoice($line, $nextContent, $bigColumn);
               break;
               case 2:
-              this._handleJudge($line, $nextContent, csize);              
+              this._handleJudge($line, $nextContent, $bigColumn);              
               break;
               case 3:
-              this._handleSubject($line, $nextContent, $border, csize);              
+              this._handleSubject($line, $nextContent, $border, $bigColumn);              
               break;
               case 4:
-              this._handleWritting($line, $nextContent, $border, csize);              
+              this._handleWritting($line, $nextContent, $border, $bigColumn);              
               break;
             }
           }
@@ -231,12 +215,14 @@ questionUtils.prototype = {
    * function 处理选择题div
    * @param {DomElement} $item 纯普通div
    * @param {DomElement} $nextContent 下一个框暂存
-   * @param {Object} csize 栏size
+   * @param {DomElement} $bigColumn 栏dom
    */
-  _handleChoice: function ($item, $nextContent, csize) {
+  _handleChoice: function ($item, $nextContent, $bigColumn) {
     let lineSize = $item.getSizeData();
+    let csize = $bigColumn.getSizeData();
     if (lineSize.top >= csize.bottom) {
-      let newLine = gennerOneLine();
+      let lineHeight = $nextContent.parent()[0].getAttribute('data-blineheight');      
+      let newLine = gennerOneLine(false, lineHeight);
       newLine.append($item);
       $nextContent.append(newLine);
     }
@@ -245,12 +231,14 @@ questionUtils.prototype = {
    * function 处理判断题div
    * @param {DomElement} $item 纯普通div
    * @param {DomElement} $nextContent 下一个框暂存
-   * @param {Object} csize 栏size
+   * @param {DomElement} $bigColumn 栏size
    */
-  _handleJudge: function ($item, $nextContent, csize) {
+  _handleJudge: function ($item, $nextContent, $bigColumn) {
     let lineSize = $item.getSizeData();
+    let csize = $bigColumn.getSizeData();
     if (lineSize.top >= csize.bottom) {
-      let newLine = gennerOneLine();
+      let lineHeight = $nextContent.parent()[0].getAttribute('data-blineheight');            
+      let newLine = gennerOneLine(false, lineHeight);
       newLine.append($item);
       $nextContent.append(newLine);
     }
@@ -260,9 +248,9 @@ questionUtils.prototype = {
    * @param {DomElement} $item 纯普通div
    * @param {DomElement} $nextContent 下个框暂存
    * @param {DomElement} $border 所在框
-   * @param {Object} csize 栏size
+   * @param {DomElement} $bigColumn 栏dom
    */
-  _handleSubject: function ($item, $nextContent, $border, csize) {
+  _handleSubject: function ($item, $nextContent, $border, $bigColumn) {
     let $nextSubject = $item.clone(false);
     let childs = $item.childNodes();
     let index = childs.length - 1;
@@ -273,6 +261,7 @@ questionUtils.prototype = {
           // 普通一行
           let $line = $(line);
           let bSize = $border.getSizeData();
+          let csize = $bigColumn.getSizeData();
           if (bSize.bottom >= csize.bottom) {
             this.insertDom($nextSubject, $line);
           }
@@ -300,16 +289,18 @@ questionUtils.prototype = {
    * @param {DomElement} $item 纯普通div
    * @param {DomElement} $nextContent 下个框暂存
    * @param {DomElement} $border 所在框
-   * @param {Object} csize 栏size
+   * @param {DomElement} $bigColumn 栏dom
    */
-  _handleWritting: function ($item, $nextContent, $border, csize) {
+  _handleWritting: function ($item, $nextContent, $border, $bigColumn) {
     let childs = $item.childNodes();
     let cLength = childs.length;
+    let csize = $bigColumn.getSizeData();
     let $nextWritting = $item.clone(false);
     if (cLength > 0) {
       let i = cLength - 1;
       while (i >= 0) {
         let bSize = $border.getSizeData();
+        csize = $bigColumn.getSizeData();
         let child = childs[i];
         let $child = $(child);
         if (bSize.bottom >= csize.bottom) {
@@ -326,6 +317,7 @@ questionUtils.prototype = {
                     // 普通一行
                     let $line = $(line);
                     bSize = $border.getSizeData();
+                    csize = $bigColumn.getSizeData();
                     if (bSize.bottom >= csize.bottom) {
                       this.insertDom($nextLsitenTitle, $line);
                     }
@@ -352,6 +344,7 @@ questionUtils.prototype = {
               let k = rowLength - 1;
               while ( k >= 0 ) {
                 let bSizeBorder = $border.getSizeData();
+                csize = $bigColumn.getSizeData();
                 if (bSizeBorder.bottom >= csize.bottom) {
                   let $rowItem = $(rows[k]);
                   this.insertDom($nextLsitenBorder, $rowItem);

+ 1 - 1
src/js/util/util.js

@@ -90,7 +90,7 @@ export function getParentByClassname($el, classname) {
       return null;
     }
     if ($el.getNodeName().toLowerCase() === 'body' ) {
-      return null
+      return null;
     }
     let eclassname = $el.attr('class')
     if (eclassname && eclassname.indexOf(classname) > -1) {

+ 86 - 24
src/js/yzPage.js

@@ -60,7 +60,6 @@ yzPage.prototype = {
         // $columItem.attr('contenteditable', true);
         $columItem.css('height', height);
         $columItem.css('position', 'relative');
-        $columItem.css('overflow', 'hidden');
         $columItem.css('float', 'left');
         $columItem.css('width', widthColumn);
       }
@@ -95,10 +94,20 @@ yzPage.prototype = {
     if (!$currentParagraph && !$column[0].childNodes.length) {
       $column.append($paragraph);
     } else {
-      if (this.manage.editorPosition.currentParagraph !== this.$el) {
+      let $paragraphs = this.$textElem.find('.js-paragraph-view');
+      if (!$paragraphs.length) {
         $column.append($paragraph);
       } else {
-        $paragraph.insertAfter($currentParagraph);
+        $currentParagraph = this._findCurrentparagraphLastDom($currentParagraph);
+        if ($currentParagraph) {
+          $paragraph.insertAfter($currentParagraph);
+        } else {
+          if ($column[0].contains(this.manage.editorPosition.currentParagraph[0])) {
+            $paragraph.insertAfter(this.manage.editorPosition.currentParagraph);          
+          } else {
+            $column.append($paragraph);
+          }
+        }
       }
     }
     return $paragraph;
@@ -106,7 +115,52 @@ yzPage.prototype = {
   // 更新头部
   updateHeader: function () {
   },
+  /**
+   * function 找到该段的最后一个dom
+   * @param {DomElement} $paragraph
+   */
+  _findCurrentparagraphLastDom: function ($paragraph) {
+    
+    if (!$paragraph || !$paragraph.length) {
+      return false;
+    }
+    if (this.isHeadParagraph($paragraph)) {
+      let tempParagraph = this._cycleFindParagraph($paragraph[0]);
+      if (tempParagraph) {
+        $paragraph = $(tempParagraph);
+      } else {
+        return false;
+      }
+    }
+    let nextParagraph = $paragraph[0].nextSibling;
+    if (nextParagraph && nextParagraph.className && nextParagraph.className.indexOf('js-paragraph-view') > -1) {
+      return $paragraph;
+    }
+    let $currentColumn = getParentByClassname($paragraph, 'js-column');
+    if (!$currentColumn) {
+      return false;
+    }
+    let pageIndex = parseInt($currentColumn.attr('data-column-page'));
+    let $nextColumn = this.manage.pages[pageIndex]._getNextColumn_v2($currentColumn);
+    if (!$nextColumn) {
+      return $paragraph;
+    }
+    let nextColumn = $nextColumn[0];
+    let firstParagh = nextColumn.firstChild;
+    firstParagh = this._cycleFindParagraph(firstParagh);
 
+    if (!firstParagh) {
+      return $paragraph;
+    }
+    
+    let currentIndex = $paragraph.attr('data-index');
+    let nextIndex = $(firstParagh).attr('data-index');
+    if (currentIndex === nextIndex) {
+      return this._findCurrentparagraphLastDom($(firstParagh));
+    } else {
+      return $paragraph;
+    }
+  },
   _placeholderTemplate: function () {
     let $postionDom = $('<div></div>');
     $postionDom.css('background-color', '#000');
@@ -247,12 +301,12 @@ yzPage.prototype = {
   */
   _checkColumnOut($column) {
     let $paragraphs = $column.find('.js-paragraph-view');
-      let cSize = $column.getSizeData();
       let i = $paragraphs.length - 1;
       let $moves = [];
       while (i >=0 ) {
         let $paragraph = $($paragraphs[i]);
         let pSize = $paragraph.getSizeData();
+        let cSize = $column.getSizeData();        
         if (pSize.top >= cSize.bottom) {
           $moves.push($paragraph);
         } else if (pSize.bottom >= cSize.bottom) {
@@ -263,30 +317,31 @@ yzPage.prototype = {
       if ($moves.length > 0) {
         let nextColumn = this._getNextColumn($column, true);
         if (nextColumn.column) {
-          let $firsParagraph = this._getFirstPargraph(nextColumn.column);
-          if ($firsParagraph) {
-            $moves.forEach(item => {
+          $moves.forEach(item => {
+            let $firsParagraph = this._getFirstPargraph(nextColumn.column);
+            if ($firsParagraph) {
               this._insertParagraph(item, $firsParagraph);
-            })
-          } else {
-            let moveIndex = $moves.length - 1;
-            while (moveIndex >=0 ) {
-              nextColumn.column.append($moves[moveIndex]);
-              moveIndex--;
+            } else {
+              nextColumn.column.append($(item));
             }
-          }
+          })
+          
           nextColumn.page._checkColumnOut(nextColumn.column);
           // 跨栏符检测
           let $lastParagraph = $paragraphs[$paragraphs.length - 1];
           if (isEmptyElement($lastParagraph)) {
             $lastParagraph.remove();
           }
-          this._checkIsCross($firsParagraph, nextColumn.column);  
+          let nextFirstParagraph = this._cycleFindParagraph(nextColumn.column.find('.js-paragraph-view')[0])
+          if (nextFirstParagraph) {
+            nextColumn.page._checkIsCross($(nextFirstParagraph), nextColumn.column);  
+          } else {
+            nextColumn.page._checkIsCross($firsParagraph, nextColumn.column);  
+          }
           this._updateCrossColumn(nextColumn.column);
           this._updateObjectColumnHeight(nextColumn.column[0]);       
         }
-        // 跨栏符检测
-        this._checkIsCross($($paragraphs[$paragraphs.length - 1]), $column);          
+        // 跨栏符检测  
         this._updateCrossColumn($column);
       }
 
@@ -307,7 +362,7 @@ yzPage.prototype = {
   /**
   * function 更新客观题栏行线
   */
- _updateObjectColumnHeightByBorder: function (border) {
+ _updateObjectColumnHeightByBorder: function (border, isFirst) {
   let cententHeight = 0;
   $(border).find('.js-option-column').forEach(column => {
     let contentSize = $(column.firstChild).getSizeData();
@@ -323,6 +378,8 @@ yzPage.prototype = {
     $(border).find('.js-options-row').forEach(row => {
       if (rowIndex > 0) {
         $(row).css('border-top', '1px solid #000');
+      } else {
+        $(row).css('border-top', 'none');
       }
       rowIndex++;
     })
@@ -340,7 +397,11 @@ yzPage.prototype = {
       let firstFirst = $firsParagraph[0].firstChild;
       this._mergeSplitParagraph(insertLast, firstFirst, $insertParagraph);
     } else {
-      $insertParagraph.insertBefore($firsParagraph);
+      if (firstClass && firstClass.indexOf('js-split-paragraph') >-1) {
+        $insertParagraph.insertAfter($firsParagraph);
+      } else {
+        $insertParagraph.insertBefore($firsParagraph);
+      }
     }
   },
   /**
@@ -1454,12 +1515,13 @@ yzPage.prototype = {
           // 普通一行
           let $line = $(line);
           let lineSize = $line.getSizeData();
-          if (lineSize.top >= cSize.bottom) {
+          let columnSize = $column.getSizeData();
+          if (lineSize.top >= columnSize.bottom) {
             this.insertDom($nextParagraph, $line);
           }
         } else if (line.className.indexOf('js-lsiten-border') > -1) {
           // 题框
-          this._splitBorder($nextParagraph, $(line), cSize);
+          this._splitBorder($nextParagraph, $(line), $column);
         } else {
           $(line).remove();
         }
@@ -1517,10 +1579,10 @@ yzPage.prototype = {
    * function 拆分框
    * @param $nextParagraph {DomElement} 下一段暂存
    * @param $border {DomElement} 需要切分的框
-   * @param cSize {Object} 段落尺寸数据
+   * @param  $column {DomElement} check栏Dom
    */
-  _splitBorder: function ($nextParagraph, $border, cSize) {
-    let $splitBorder = this.questionTools._splitBorder($border, cSize);
+  _splitBorder: function ($nextParagraph, $border, $column) {
+    let $splitBorder = this.questionTools._splitBorder($border,  $column);
     if ($splitBorder) {
       this.insertDom($nextParagraph, $splitBorder);
     }

+ 760 - 8
src/js/yzPageManager.js

@@ -1,8 +1,10 @@
 import $ from './util/dom-core.js';
 import { gennerOneLine } from './util/lineUtil.js';
+import { getPasteImgs } from './util/paste-handle.js';
+import imgUtl from './util/imageUtil.js'
 import Jquery from 'jquery';
 import yzPage from './yzPage.js';
-import { UA, isFunction, replaceHtmlSymbol, getParentByClassname, trim, throttle, isEmptyElement, getParentNodeByClass } from './util/util.js';
+import { UA, arrForEach, isFunction, replaceHtmlSymbol, getParentByClassname, trim, throttle, isEmptyElement, getParentNodeByClass, uploadToAliyun } from './util/util.js';
 
 let yzPageManager = function (editor) {
   this.editor = editor;
@@ -34,6 +36,8 @@ yzPageManager.prototype = {
       this._addPage();
     }
     this._initEvents();
+
+    this._initDrageDiv();
   },
   /**
    * function 初始化编辑后的数据
@@ -61,6 +65,25 @@ yzPageManager.prototype = {
     this.$el.html('');
     this.pageIndex = 0;
   },
+  getPagePlaceholderTemlpate: function (pageIndex) {
+    // 添加分页显示效果
+    let $breakDiv = $('<div class="page-break" data-page-id="' + (pageIndex) + '"></div>');
+    let $topSpan = $('<div class="spanMark topSpan">&#8203;</div>');
+    $topSpan.css('display', 'block').css('height', '71.5px');
+    // 分页符
+    let $middleSpan = $('<div class="spanMark middleSpan lsiten-page-break-span">&#8203;</div>');
+    $middleSpan.css('page-break-before', 'always');
+    $middleSpan.css('display', 'block').css('height', '0');  
+    let $bottomSpan = $('<div class="spanMark bottomSpan">&#8203;</div>');
+    $bottomSpan.css('height', '71.5px').css('display', 'block');
+
+    // 添加页眉页脚   
+    $breakDiv.append($topSpan);
+    $breakDiv.append($middleSpan);
+    $breakDiv.append($bottomSpan);
+    $breakDiv.css('height', '153px');
+    return $breakDiv;
+  },
   /**
    * function 初始化页面的样式
    */
@@ -132,7 +155,7 @@ yzPageManager.prototype = {
     this.$el.css('height', height + 'px');
   },
 
-  _checkEveryPageOut: function () {
+  _checkEveryPageOut: function (callback) {
     if (this._checkPageOutStatus) {
       return false;
     }
@@ -141,13 +164,16 @@ yzPageManager.prototype = {
     pages.forEach(page => {
       page._checkContentOut();
     });
+    if (typeof callback === 'function') {
+      callback();
+    }
     this._checkPageOutStatus = false;
   },
 
   /**
    * function 检测是否有空页并删除
    */
-  _checkEveryPageBack: function () {
+  _checkEveryPageBack: function (callback) {
     if (this._checkPageBackStatus) {
       return false;
     }
@@ -156,6 +182,9 @@ yzPageManager.prototype = {
     pages.forEach(page => {
       page._checkContentBack();
     });
+    if (typeof callback === 'function') {
+      callback();
+    }
     this._checkPageBackStatus = false;
   },
 
@@ -200,6 +229,14 @@ yzPageManager.prototype = {
 
     // 框内事件菜单
     this._borderEvent();
+
+
+    this._writtingHandleEvent();
+
+    this._imgHandle();
+    this._scrollEvent();
+    this._resizeEvent();
+    this._dragEvent();
   },
   /**
    * function 框相关事件
@@ -272,6 +309,8 @@ yzPageManager.prototype = {
    */
   _commonMenus: function ($menu, $border) {
     // 添加文本框开始
+    const message = this.editor.message;
+    const $textElem = this.$el;
     let $addText = $('<div>加文本框</div>');
     $addText.css('cursor', 'pointer')
            .css('text-align', 'center')
@@ -316,6 +355,58 @@ yzPageManager.prototype = {
       $menu[0].blur();
     })
     // 添加文本框结束
+
+    // 更改框行高开始
+    let $addLineHeight = $('<div>修改行高</div>');
+    $addLineHeight.css('cursor', 'pointer')
+           .css('text-align', 'center')
+           .css('border-bottom', '1px solid #e8e3e3')
+           .css('padding', '5px 0');
+    $menu.append($addLineHeight);
+    $addLineHeight.on('click', () => {
+       //  表单
+       let lineheight = parseInt($border[0].getAttribute('data-blineheight'));
+       lineheight = lineheight ? lineheight : 25;
+       let $form = $('<form class="form"></form>');
+       let $item1 = $('<div class="form-item"><span class="label">行高:</span><select name="blineheight">\
+                        <option value="18" ' + ((lineheight === 18) ? 'selected' : '') + '>18px</option>\
+                        <option value="20" ' + ((lineheight === 20) ? 'selected' : '') + '>20px</option>\
+                        <option value="25" ' + ((lineheight === 25) ? 'selected' : '') + '>25px</option>\
+                        <option value="30" ' + ((lineheight === 30) ? 'selected' : '') + '>30px</option>\
+                        <option value="38" ' + ((lineheight === 38) ? 'selected' : '') + '>38px</option>\
+                        <option value="44" ' + ((lineheight === 44) ? 'selected' : '') + '>44px</option>\
+                        <option value="50" ' + ((lineheight === 50) ? 'selected' : '') + '>50px</option>\
+                        </select></div>');
+       $form.append($item1);
+       // button 
+       let $buttons = [];
+       let $cancel = $('<span class="lsiten-message-button lsiten-message-cancel-button">取消</span>');
+       $cancel.on('click', function () {
+         message.hideMessage();
+       })
+       let $success = $('<span class="lsiten-message-button lsiten-message-success-button">确定</span>');
+       $success.on('click', () => {
+        let lineheightValue = $item1.find('select').val();
+        $border.attr('data-blineheight', lineheightValue);
+        $border.find('.js-lsiten-line').css('line-height', lineheightValue + 'px');
+        Jquery($textElem[0]).trigger('addContent', () => {
+          Jquery($textElem[0]).trigger('removeContent');
+        });
+        message.hideMessage();
+       })
+       $buttons.push($cancel);
+       $buttons.push($success);
+       // 2、打开对话框,填写修改的字数
+       message.showMessage({options:{
+          type: 'dialog',
+          $buttons: $buttons,
+          title: '框行高-修改',
+          width: 500,
+          content: $form
+        }})
+      $menu[0].blur();
+    })
+    // 添加文本框结束
     // 删除开始
     // let $delete = $('<div>删除框</div>');
     // $delete.css('cursor', 'pointer')
@@ -408,6 +499,32 @@ yzPageManager.prototype = {
       return prevPage.$colums[lastColumnIndex] || false;
     }
   },
+    /**
+   * function 获取下一栏
+   */
+  _getNextColumn: function ($column) {
+    let next = $column[0].nextSibling;
+    let pageIndex = parseInt($column.attr('data-column-page')) + 1;
+    if (next) {
+      if (next.className && next.className.indexOf('js-column') > -1) {
+        return $(next);
+      } else {
+        if (this.pages.length <= pageIndex) {
+          return false;
+        }
+  
+        let nextPage = this.pages[pageIndex];
+        return nextPage.$colums[0] || false;
+      }
+    } else {
+      if (this.pages.length <= pageIndex) {
+        return false;
+      }
+
+      let nextPage = this.pages[pageIndex];
+      return nextPage.$colums[0] || false;
+    }
+  },
   // 获得该框以上的框
   _findPrevBorders: function ($border) {
     let $paragraph = getParentByClassname($border, 'js-paragraph-view');
@@ -686,12 +803,12 @@ yzPageManager.prototype = {
     const $textElem = this.$el;
     const editor =this.editor;
     let _this = this;
-    Jquery($textElem[0]).on('addContent', function (e) {
-      _this._checkEveryPageOut();
+    Jquery($textElem[0]).on('addContent', function (e, callback) {
+      _this._checkEveryPageOut(callback);
     })
 
-    Jquery($textElem[0]).on('removeContent', function (e) {
-      _this._checkEveryPageBack();
+    Jquery($textElem[0]).on('removeContent', function (e, callback) {
+      _this._checkEveryPageBack(callback);
     })
   },
   /** 
@@ -701,14 +818,24 @@ yzPageManager.prototype = {
     const $textElem = this.$el;
     const editor =this.editor;
     let _this = this;
-    Jquery($textElem[0]).on('keydown', function (e) {       
+    Jquery($textElem[0]).on('keydown', function (e) {    
       if (e.keyCode !== 46) {
         // 不是回车键
         return '';
       }
+      if (_this._$handleImg) {
+        _this._$handleImg.remove();
+        _this._$handleImg = null;
+        _this._$drageDiv.hide();
+        e.preventDefault();
+        return '';
+      }
       if (getParentByClassname($(e.target), 'js-answer-header-title')) {
         return '';
       }
+      if (getParentByClassname($(e.target), 'lsiten-e-message-body-content')) {
+        return '';
+      }
       let $currentLine = _this.editorPosition.currentLine;
       if ($currentLine) {
         let selection = _this.editor.selection;
@@ -739,9 +866,20 @@ yzPageManager.prototype = {
         // 不是回车键
         return '';
       }
+      if (_this._$handleImg) {
+        _this._$handleImg.remove();
+        _this._$handleImg = null;
+        _this._$drageDiv.hide();
+        e.preventDefault();
+        return '';
+      }
       if (getParentByClassname($(e.target), 'js-answer-header-title')) {
         return '';
       }
+
+      if (getParentByClassname($(e.target), 'lsiten-e-message-body-content')) {
+        return '';
+      }
       let $currentLine = _this.editorPosition.currentLine;
       if ($currentLine) {
         if (isEmptyElement($currentLine[0])) {
@@ -778,6 +916,11 @@ yzPageManager.prototype = {
       let $currentLine = _this.editorPosition.currentLine;
       if ($currentLine) {
         let $newLine = gennerOneLine();
+        let $borderContent = getParentByClassname($currentLine, 'js-lsiten-border');
+        if ($borderContent) {
+          let lineHeight = $borderContent[0].getAttribute('data-blineheight');
+          $newLine = gennerOneLine(false, lineHeight);
+        }
         $newLine.insertAfter($currentLine);
         $newLine.focus();
       }
@@ -812,6 +955,605 @@ yzPageManager.prototype = {
         Jquery($textElem[0]).off('mouseleave', realTimeSave);
     })
   },
+
+  // 作文题处理
+  _writtingHandleEvent: function () {
+    // 为图片增加 selected 样式
+    Jquery(this.editor.$editorArea[0]).on('contextmenu','.lsiten-question-writing', (e) => {
+      let ele = e.target || e.srcElement;
+      let message = this.editor.message;
+      let _this = this;
+      let writting = getParentNodeByClass(ele, 'lsiten-question-writing');
+      if (writting) {
+        let $writting = $(writting);
+        let menus = [
+          {
+            name: "修改",
+            click: function ($el) {
+              $el.on('click', () => {
+                let pnum = $writting.attr('data-pnum');
+                let total = parseInt($writting.attr('data-total'));
+                //  表单
+                let $form = $('<form class="form"></form>');
+                let $item1 = $('<div class="form-item"><span class="label">题号:</span><span>' + pnum + '</span></div>');
+                let $item2 = $('<div class="form-item"><span class="label">格子数:</span><input value = " ' + total + ' " type="text" placeholder="请输入总共多少个格子" class="block"/></div>');
+                $form.append($item1);
+                $form.append($item2);
+                // button 
+                let $buttons = [];
+                let $cancel = $('<span class="lsiten-message-button lsiten-message-cancel-button">取消</span>');
+                $cancel.on('click', function () {
+                  message.hideMessage();
+                })
+                let $success = $('<span class="lsiten-message-button lsiten-message-success-button">确定</span>');
+
+                function sureClick () {
+                  message.hideMessage();
+                  let total = parseInt($item2.find('input').val());
+                  if (total > 3000 || total < 1) {
+                    message.showMessage('错误:字数应在1-3000内');
+                    return false;
+                  }
+                  // 重新生成作文题框
+
+                  // 找到整个题框,并删除
+                  //   1、判断是否是跨栏框
+                  let writingClass = $writting.attr('class');
+
+                  if (writingClass.indexOf('js-split-question') > -1) {
+                    let $prevQuestions = _this._findPrevQustions($writting, 4);
+                    let $nextQuestions = _this._findNextQustions($writting, 4);
+                    let lastIndex = $prevQuestions.length - 1;
+                    let questionBasic = lastIndex >= 0 ? $prevQuestions[lastIndex] : $writting[0];
+                    let $borderBasic = $(questionBasic).parent();
+                    let lineHeight = $borderBasic.parent()[0].getAttribute('data-blineheight');
+                    $prevQuestions.forEach(item => {
+                      let $item = $(item);
+                      let $borderContent = $item.parent();
+                      $item.remove();
+                      if (isEmptyElement($borderContent)) {
+                        let $border = $borderContent.parent();
+                        if (!$borderBasic.equal($borderContent)) {
+                          let $paragraphTemp = $border.parent();
+                          $border.remove();
+                          if (isEmptyElement($paragraphTemp)) {
+                            $paragraphTemp.remove();
+                          }
+                        }
+                      }
+                    })
+                    $nextQuestions.forEach(item => {
+                      let $item = $(item);
+                      let $borderContent = $item.parent();
+                      $item.remove();
+                      if (isEmptyElement($borderContent)) {
+                        let $paragraphTemp = $borderContent.parent().parent();
+                        $borderContent.parent().remove();
+                        if (isEmptyElement($paragraphTemp)) {
+                          $paragraphTemp.remove();
+                        }
+                      }
+                    })
+
+                    let $borderWrittingContent = $writting.parent();
+                    $writting.remove();
+                    if (isEmptyElement($borderWrittingContent)) {
+                      let $borderWritting = $borderWrittingContent.parent()
+                      if (!$borderBasic.equal($borderWrittingContent)) {
+                        let $paragraphTemp = $borderWritting.parent();
+                        $borderWritting.remove();
+                        if (isEmptyElement($paragraphTemp)) {
+                          $paragraphTemp.remove();
+                        }
+                      }
+                    }
+
+                    _this._checkRemovePage();
+                    let $onelineBasic = gennerOneLine(false, lineHeight);
+                    $borderBasic.append($onelineBasic);
+                    _this._updatePositionInfo(null, $onelineBasic);
+                  } else {
+                    let $borderWrittingContent = $writting.parent();
+                    $writting.remove();
+                    let $onelineBasic = gennerOneLine(false, lineHeight);
+                    $borderWrittingContent.append($onelineBasic);
+                    _this._updatePositionInfo(null, $onelineBasic);
+                  }
+
+                  _this.editor.cmd.do('questiontype', {type: 4, data: {
+                      pnum: pnum,
+                      nums: total,
+                      visible: true
+                  }});
+                }
+                $success.on('click', function () {
+                  sureClick();
+                })
+                Jquery(document).on('keydown', function(event) {   
+                  if (event.keyCode !== 13) {
+                    // 不是回车键
+                    return '';
+                  }                          
+                  if (Jquery(message.$el[0]).css('display') === 'block') {
+                    sureClick();
+                    event.preventDefault();
+                    return true;
+                  }
+                })
+                $buttons.push($cancel);
+                $buttons.push($success);
+                // 1、关闭右击menu
+                let $contentMenu = getParentByClassname($el, 'js-lsiten-contentmenus');
+                // 2、打开对话框,填写修改的字数
+                message.showMessage({options:{
+                  type: 'dialog',
+                  $buttons: $buttons,
+                  title: '作文题-修改',
+                  width: 500,
+                  content: $form
+                }})
+                if ($contentMenu.length) {
+                  try {
+                    $contentMenu.remove();
+                  } catch (error) {
+                    // console.log(error);
+                  }
+                }
+              })
+            }
+          }
+        ]
+        this._createContextMenu(e, menus);
+        e.stopImmediatePropagation();
+      } else {
+        console.log('c%error: no writting box', 'color:red');
+      }
+    })
+  },
+
+  // 滚动事件监听 
+  _scrollEvent: function () {
+    let _this = this;
+    Jquery(this.editor.$editorArea[0]).on('scroll', () => {
+      if (_this._$handleImg) {
+        _this._$handleImg = null;
+        _this._$drageDiv.hide();
+      }
+    })
+  },
+  // 滚动事件监听 
+  _resizeEvent: function () {
+    let _this = this;
+    Jquery(window).on('resize', () => {
+      if (_this._$handleImg) {
+        _this._$handleImg = null;
+        _this._$drageDiv.hide();
+      }
+    })
+  },
+
+
+  _gennerateDragBox: function ($dom) {
+    let position = $dom.getSizeData();
+    let $drag = this._$drageDiv;
+    $drag.css('left', (position.x - 3) + 'px')
+         .css('top', (position.y - 3) + 'px')
+         .css('width', (position.width + 6) + 'px')
+         .css('height', (position.height + 6) + 'px');
+    $drag.show();
+  },
+  // 图片处理
+  _imgHandle: function () {
+    const $textElem = this.$el;
+    const _this = this;
+    const editor = this.editor;
+    Jquery($textElem[0]).on('dragstart, dragend', 'img', function (e) {
+      e.preventDefault();
+    })
+    // 为图片增加 selected 样式
+    $textElem.on('click', 'img', function (e) {
+      let ele = e.target || e.srcElement;
+      let $img = $(ele);
+      if (ele.className && ele.className.indexOf('lsiten-js-image-class') > -1) {
+        _this._$handleImg = $img;
+        _this._gennerateDragBox($img);
+      }
+    })
+    // 去掉图片的 selected 样式
+    $textElem.on('click  keyup', e => {
+      if (e.target.matches('img')) {
+        // 点击的是图片,忽略
+        return '';
+      }
+      let $drag = this._$drageDiv;
+      _this._$handleImg = null;
+      $drag.hide();
+    })
+    // 粘贴图片、文本的事件,每次只能执行一个
+    // 判断该次粘贴事件是否可以执行
+    let pasteTime = 0
+    function canDo() {
+        var now = Date.now()
+        var flag = false
+        if (now - pasteTime >= 100) {
+            // 间隔大于 100 ms ,可以执行
+            flag = true
+        }
+        pasteTime = now
+        return flag
+    }
+    // 粘贴图片
+    $textElem.on('paste', e => {
+        if (UA.isIE()) {
+            return '';
+        } else {
+            e.preventDefault();
+        }
+
+        // 粘贴图片和文本,只能同时使用一个
+        if (!canDo()) {
+            return '';
+        }
+
+        // 获取粘贴的图片
+        const pasteFiles = getPasteImgs(e);
+        if (!pasteFiles || !pasteFiles.length) {
+            return '';
+        }
+
+        // 获取当前的元素
+        const $currentLine = this.editorPosition.currentLine;
+        if (!$currentLine) {
+            return '';
+        }
+
+        // 上传图片
+        _this._uploadFiles(pasteFiles);
+    })
+  },
+
+  /**
+   * function 上传图片
+   * @param {array} files 图片兑现数组 
+   */
+  _uploadFiles: function (files) {
+    if (!files || !files.length) {
+        return '';
+    }
+    const editor = this.editor;
+    let policyUrl = editor.config.policyUrl;
+    const message = editor.message;
+    // 获取当前的元素
+    const $currentLine = this.editorPosition.currentLine;
+    if (!$currentLine) {
+        return '';
+    }
+    let borderText = getParentByClassname($currentLine, 'js-lsiten-border');
+    let size = null;
+    if (borderText) {
+      size = borderText.getSizeData();
+    } else {
+      return '';
+    }
+    
+    arrForEach(files, file => {
+      uploadToAliyun(file, policyUrl).then(data => {
+        if (data.result === '00') {
+          let src = data.data.url;
+          let srcStore = data.data.urlStore;
+          this._doInsertImage({
+            src: src,
+            store: srcStore,
+            bsize: size,
+            border: borderText
+          }); 
+        } else {
+           message.showMessage(data.msg || '上传出错,请重试!');
+        }
+     })
+    })
+
+  },
+  _doInsertImage: function (img) {
+    let imageTool = new imgUtl(img.src);
+    let _this = this;
+    imageTool.getSize(complete);
+    function complete() {
+      let owidth = imageTool.owidth;
+      let bsize = img.bsize;
+      let bwidth = bsize.width - 30;
+      if (owidth >= bwidth) {
+        let ratio = bwidth / owidth;
+        imageTool.resizeByRatio(ratio);
+      }
+      let oheight = imageTool.size.h;
+      let bheight = bsize.height - 22;
+      if (oheight > bheight) {
+        let ratio = bheight / oheight;
+        imageTool.resizeByRatio(ratio);
+      }
+      let html = $('<img class="lsiten-js-image-class" style="width: ' + imageTool.size.w + 'px; height: ' + imageTool.size.h + 'px" src="' + img.src + '" data-store = "' +img.store+ '"/>');
+      html.css('position', 'absolute').css('top', '0').css('left', '0');
+      img.border.append(html);      
+    }
+  },
+  // 初始化拖拽框
+  _initDrageDiv: function () {
+    this._$drageDiv = $('<div class="js-lsiten-dragbox"></div>');
+    this._$drageDiv.css('height', '0')
+                   .css('width', '0')
+                   .css('position', 'fixed')
+                   .css('z-index', '9998')
+                   .css('cursor', 'move')
+                   .css('display', 'none')                   
+                   .css('border', '1px dashed #5b3838');
+    let $delete = $('<div class="js-lsiten-dragbox-delete">删除</div>');
+    $delete.css('height', '14px')
+         .css('width', 'auto')
+         .css('cursor', 'pointer')
+         .css('right', '-20px')
+         .css('font-size', '12px')
+         .css('bottom', '-20px')
+         .css('position', 'absolute');
+    let $left = $('<div class="js-lsiten-dragbox-left"></div>');
+    $left.css('height', '14px')
+         .css('width', '14px')
+         .css('background', '#e1dcdc')
+         .css('cursor', 'nw-resize')
+         .css('left', '-7px')
+         .css('top', '-7px')
+         .css('position', 'absolute');
+    
+    let $leftBottom = $('<div class="js-lsiten-dragbox-left-bottom"></div>');
+    $leftBottom.css('height', '14px')
+         .css('width', '14px')
+         .css('background', '#e1dcdc')
+         .css('left', '-7px')
+         .css('bottom', '-7px')
+         .css('cursor', 'sw-resize')
+         .css('position', 'absolute');
+
+    let $right = $('<div class="js-lsiten-dragbox-right"></div>');
+    $right.css('height', '14px')
+         .css('width', '14px')
+         .css('background', '#e1dcdc')
+         .css('right', '-7px')
+         .css('top', '-7px')
+         .css('cursor', 'ne-resize')
+         .css('position', 'absolute');
+
+    
+    let $rightBottom = $('<div class="js-lsiten-dragbox-right-bottom"></div>');
+    $rightBottom.css('height', '14px')
+         .css('width', '14px')
+         .css('background', '#e1dcdc')
+         .css('right', '-7px')
+         .css('bottom', '-7px')
+         .css('cursor', 'se-resize')
+         .css('position', 'absolute');
+    this._$drageDiv.append($left);
+    this._$drageDiv.append($right);
+    this._$drageDiv.append($leftBottom);
+    this._$drageDiv.append($rightBottom);
+    this._$drageDiv.append($delete);
+    
+    let _this = this;
+    let templatePosition = {
+      x: 0,
+      y: 0,
+      type: 0
+    }
+    $delete.on('click', () => {
+      if (_this._checkCrossing || _this._contentChangeStatus) {
+        _this._$handleImg = null;
+        _this._$drageDiv.hide();
+        return false;
+      }
+      let $img = _this._$handleImg;
+      if ($img) {
+        $img.remove();
+        _this._$handleImg = null;
+        _this._$drageDiv.hide();
+        return true;
+      } else {
+        _this._$handleImg = null;
+        _this._$drageDiv.hide();
+        return false;
+      }
+    })
+    this._$drageDiv.on('mousedown', function (e) {
+      templatePosition = {
+        type: 5,
+        x: e.pageX,
+        y: e.pageY,
+        oPosition: {
+          x: e.pageX,
+          y: e.pageY,
+        }
+      }
+      e.preventDefault();
+    })
+    $delete.on('mousedown', function (e) {
+      e.stopPropagation();
+    })
+    $left.on('mousedown', function (e) {
+      templatePosition = {
+        type: 1,
+        x: e.pageX,
+        y: e.pageY,
+        oPosition: {
+          x: e.pageX,
+          y: e.pageY,
+        }
+      }
+      e.stopPropagation();
+    })
+
+    $leftBottom.on('mousedown', function (e) {
+      templatePosition = {
+        type: 2,
+        x: e.pageX,
+        y: e.pageY,
+        oPosition: {
+          x: e.pageX,
+          y: e.pageY,
+        }
+      }
+      e.stopPropagation();      
+    })
+
+    $right.on('mousedown', function (e) {
+      templatePosition = {
+        type: 3,
+        x: e.pageX,
+        y: e.pageY,
+        oPosition: {
+          x: e.pageX,
+          y: e.pageY,
+        }
+      }
+      e.stopPropagation();      
+    })
+
+    $rightBottom.on('mousedown', function (e) {
+      templatePosition = {
+        type: 4,
+        x: e.pageX,
+        y: e.pageY,
+        oPosition: {
+          x: e.pageX,
+          y: e.pageY,
+        }
+      }
+      e.stopPropagation();      
+    })
+    $(document).on('mousemove', function (e) {
+      if (templatePosition.type === 0) {
+        return false;
+      }
+      let diffX = parseInt(e.pageX - templatePosition.x);
+      let diffY = parseInt(e.pageY - templatePosition.y);
+      let borderSize = _this._$drageDiv.getSizeData();
+
+      switch (templatePosition.type) {
+        case 1:
+
+        let bleft = parseInt(borderSize.left) + diffX;
+        let btop = parseInt(borderSize.top) + diffY;
+        let width = parseInt(borderSize.width) - diffX;
+        let height = parseInt(borderSize.height) - diffY;
+        if (width < 0 || height < 0) {
+          return false;
+        }
+        templatePosition.x = e.pageX;
+        templatePosition.y = e.pageY;
+        _this._$drageDiv.css('left', bleft + 'px').css('top', btop + 'px').css('width', width + 'px').css('height', height + 'px');
+        break;
+        case 2:
+
+        let bleft2 = parseInt(borderSize.left) + diffX;
+        let bbottom2 = parseInt(borderSize.bottom) - diffY;
+        let width2 = parseInt(borderSize.width) - diffX;
+        let height2 = parseInt(borderSize.height) + diffY;
+        if (width2 < 0 || height2 < 0) {
+          return false;
+        }
+        templatePosition.x = e.pageX;
+        templatePosition.y = e.pageY;
+        _this._$drageDiv.css('left', bleft2 + 'px').css('bottom', bbottom2 + 'px').css('width', width2 + 'px').css('height', height2 + 'px');
+        break;
+        case 3:
+        let bright = parseInt(borderSize.right) - diffX;
+        let btop3 = parseInt(borderSize.top) + diffY;
+        let width3 = parseInt(borderSize.width) + diffX;
+        let height3 = parseInt(borderSize.height) - diffY;
+        if (width3 < 0 || height3 < 0) {
+          return false;
+        }
+        templatePosition.x = e.pageX;
+        templatePosition.y = e.pageY;
+        _this._$drageDiv.css('right', bright + 'px').css('top', btop3 + 'px').css('width', width3 + 'px').css('height', height3 + 'px');
+        break;
+        case 4:
+        let bright2 = parseInt(borderSize.right) - diffX;
+        let bbottom4 = parseInt(borderSize.top) - diffY;
+        let width4 = parseInt(borderSize.width) + diffX;
+        let height4 = parseInt(borderSize.height) + diffY;
+        if (width4 < 0 || height4 < 0) {
+          return false;
+        }
+        templatePosition.x = e.pageX;
+        templatePosition.y = e.pageY;
+        _this._$drageDiv.css('right', bright2 + 'px').css('bottom', bbottom4 + 'px').css('width', width4 + 'px').css('height', height4 + 'px');
+        break;
+        case 5:
+        let bx = parseInt(borderSize.left) + diffX;
+        let by = parseInt(borderSize.top) + diffY;
+        templatePosition = {
+          type: 5,
+          x: e.pageX,
+          y: e.pageY,
+          oPosition: templatePosition.oPosition
+        }
+        _this._$drageDiv.css('left', bx + 'px').css('top', by + 'px');
+        break;
+      }
+    })
+    $(document).on('mouseup', function (e) {
+      if (templatePosition.type === 0) {
+        return false;
+      }
+      if (_this._checkCrossing || _this._contentChangeStatus) {
+        _this._$handleImg = null;
+        _this._$drageDiv.hide();
+        return false;
+      }
+      let $img = _this._$handleImg;
+
+      if ($img) {
+        let $border = getParentByClassname($img, 'js-lsiten-border');
+        let borderBoxSize = $border.getSizeData();
+        let borderImgBoxSize = $img.getSizeData();
+        let $drag = _this._$drageDiv;        
+        let borderSize = $drag.getSizeData();
+        if (templatePosition.type === 5) {
+          let imageLeft = parseInt(borderSize.left - borderBoxSize.left);
+          let imageTop =  parseInt(borderSize.top - borderBoxSize.top);
+          $img.css('left', imageLeft + 'px').css('top', imageTop + 'px');
+        } else {
+          let width = parseInt(borderSize.width) - 6;
+          let prevHeight = _this.getPrevHeight($img, $border);
+          let height = parseInt(borderSize.height) - 6;
+          let borderHeight = borderBoxSize.height - prevHeight;
+          let borderwidth = borderBoxSize.width;
+          width = width > borderwidth ? (borderwidth - 30) : width;
+          height = height > borderHeight ? (borderHeight - 22) : height;
+          $img.css('width', width + 'px').css('height', height + 'px');
+        }
+
+
+        let position = $img.getSizeData();
+        $drag.css('left', (position.x - 3) + 'px')
+            .css('top', (position.y - 3) + 'px');
+        _this._$handleImg = null;
+        _this._$drageDiv.hide();
+      }
+
+      templatePosition = {
+        x: 0,
+        y: 0,
+        type: 0
+      }
+    })
+    this.editor.$container.append(this._$drageDiv);
+  },
+  // 获取dom元素前面的高度
+  getPrevHeight: function ($dom, $border) {
+    let domSize = $dom.getSizeData();
+    let borderSize = $border.getSizeData();
+    let diff = domSize.top - borderSize.top;
+    return diff > 0 ? diff : 0;
+  },
   /**
    * 更新当前编辑信息
    */
@@ -858,6 +1600,16 @@ yzPageManager.prototype = {
       selection.setEmptyRange();
     }
   },
+  /**
+   * function 拖拽事件
+   */
+  _dragEvent: function () {
+    // 禁用 document 拖拽事件
+    const $document = $(document)
+    $document.on('dragleave drop dragenter dragover', function (e) {
+        e.preventDefault()
+    })
+  },
   _pagesWidth: {
     'A4': '793px',
     'A3': '1587px'

+ 23 - 0
src/less/message.less

@@ -61,6 +61,29 @@
         text-align: right;
         padding-right: 5px;
       }
+      select {
+        flex: 1;
+        border: none;
+        border-bottom: 1px solid #ccc;
+        font-size: 14px;
+        height: 25px;
+        color: #333;
+        text-align: left;
+        outline: none;
+        option::-ms-expand{ display: none; }
+        option{
+            -moz-appearance:none; /* Firefox */
+            -webkit-appearance:none; /* Safari 和 Chrome */
+            appearance:none;
+            height: 25px;
+            line-height: 25px;
+            margin-top: 5px;
+        }
+        option:hover{
+            color:#fff;
+            background-color:#1E90FF;
+        }
+      }
       input[type=text] {
         flex: 1;
         border: none;