|
@@ -197,6 +197,487 @@ yzPageManager.prototype = {
|
|
|
this._delEvent();
|
|
|
|
|
|
this._contentchangeEvent();
|
|
|
+
|
|
|
+ // 框内事件菜单
|
|
|
+ this._borderEvent();
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * function 框相关事件
|
|
|
+ */
|
|
|
+ _borderEvent: function () {
|
|
|
+ let _this = this;
|
|
|
+ const $textElem = this.$el;
|
|
|
+ Jquery($textElem[0]).on('contextmenu','.js-lsiten-border', (e) => {
|
|
|
+ this._createContextMenu(e);
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * fucntion 创建菜单
|
|
|
+ * @param {event} e 事件对象
|
|
|
+ * @param {array} menus 数组对象
|
|
|
+ */
|
|
|
+ _createContextMenu: function (e, menus) {
|
|
|
+ let $target = $(e.target);
|
|
|
+ let $border = getParentByClassname($target, 'js-lsiten-border');
|
|
|
+ let movex=e.pageX;
|
|
|
+ let movey=e.pageY;
|
|
|
+ !menus && (menus = []);
|
|
|
+ this._createMenu(movex, movey, $border, menus);
|
|
|
+ e.preventDefault();
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * function 创建菜单列表
|
|
|
+ * @param {number} x x轴坐标
|
|
|
+ * @param {number} y y轴坐标
|
|
|
+ * @param {DomElement} $border 该框
|
|
|
+ * @param {array} menus 数组对象
|
|
|
+ */
|
|
|
+ _createMenu: function (x, y, $border, menus) {
|
|
|
+ let $menu = $('<div class="js-lsiten-contentmenus"></div>');
|
|
|
+ $menu.css('width', '100px')
|
|
|
+ .css('height', 'auto')
|
|
|
+ .css('background', '#fff')
|
|
|
+ .css('position', 'absolute')
|
|
|
+ .css('z-index', '9999')
|
|
|
+ .css('outline', 'none')
|
|
|
+ .css('top', y + 'px')
|
|
|
+ .css('border', '1px solid #e4dddd')
|
|
|
+ .css('padding', '0')
|
|
|
+ .css('box-shadow', '0 3px 7px rgba(0, 0, 0, 0.1)')
|
|
|
+ .css('left', x + 'px');
|
|
|
+ $menu.attr('tabIndex', 1);
|
|
|
+
|
|
|
+ menus.forEach(item => {
|
|
|
+ let $menuItem = $('<div>' + item.name + '</div>');
|
|
|
+ $menuItem.css('cursor', 'pointer')
|
|
|
+ .css('text-align', 'center')
|
|
|
+ .css('border-bottom', '1px solid #e8e3e3')
|
|
|
+ .css('padding', '5px 0');
|
|
|
+ $menu.append($menuItem);
|
|
|
+ if (item.click && typeof item.click === 'function') {
|
|
|
+ item.click($menuItem);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this._commonMenus($menu, $border);
|
|
|
+ $(document.body).append($menu);
|
|
|
+ $menu.focus();
|
|
|
+ Jquery($menu[0]).on('blur', (e) => {
|
|
|
+ $menu && $menu.remove();
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * function 创建菜单列表
|
|
|
+ * @param {DomElement} $menu menu的dom
|
|
|
+ * @param {DomElement} $border 框的dom
|
|
|
+ */
|
|
|
+ _commonMenus: function ($menu, $border) {
|
|
|
+ // 添加文本框开始
|
|
|
+ let $addText = $('<div>加文本框</div>');
|
|
|
+ $addText.css('cursor', 'pointer')
|
|
|
+ .css('text-align', 'center')
|
|
|
+ .css('border-bottom', '1px solid #e8e3e3')
|
|
|
+ .css('padding', '5px 0');
|
|
|
+ $menu.append($addText);
|
|
|
+ $addText.on('click', () => {
|
|
|
+ this._checkNeedBackStatus = true;
|
|
|
+ let $prevBorders = this._findPrevBorders($border);
|
|
|
+ let lastBorderIndex = $prevBorders.length - 1;
|
|
|
+ let $baiscBorder = lastBorderIndex >= 0 ? $($prevBorders[lastBorderIndex]) : $border;
|
|
|
+ let $currentParagraph = getParentByClassname($baiscBorder, 'js-paragraph-view');
|
|
|
+ if ($currentParagraph) {
|
|
|
+ let index = $currentParagraph.attr('data-index');
|
|
|
+ let pageIndex = parseInt(index.split('-')[0]);
|
|
|
+ if (pageIndex > -1) {
|
|
|
+ let currentPage = this.pages[pageIndex];
|
|
|
+ if (currentPage) {
|
|
|
+ let $paragraph = $('<div class="js-paragraph-view"></div>');
|
|
|
+ $paragraph.append(gennerOneLine());
|
|
|
+ $paragraph.css('margin', 0)
|
|
|
+ .css('padding', '0 25px')
|
|
|
+ .css('outline', 'none')
|
|
|
+ .css('box-sizing', 'border-box')
|
|
|
+ .css('white-space', 'pre-wrap')
|
|
|
+ .css('line-height', '1.75')
|
|
|
+ .css('text-align', 'left');
|
|
|
+ let index = pageIndex + '-' + currentPage.paragraphIndex++;
|
|
|
+ $paragraph.attr('data-index', index);
|
|
|
+ $paragraph.insertBefore($currentParagraph);
|
|
|
+ setTimeout(() => {
|
|
|
+ $paragraph.focus();
|
|
|
+ }, 100)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.log('error');
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ console.log('error')
|
|
|
+ }
|
|
|
+
|
|
|
+ $menu[0].blur();
|
|
|
+ })
|
|
|
+ // 添加文本框结束
|
|
|
+ // 删除开始
|
|
|
+ // let $delete = $('<div>删除框</div>');
|
|
|
+ // $delete.css('cursor', 'pointer')
|
|
|
+ // .css('text-align', 'center')
|
|
|
+ // .css('padding', '5px 0');
|
|
|
+ // $menu.append($delete);
|
|
|
+
|
|
|
+ // $delete.on('click', () => {
|
|
|
+ // this._checkNeedBackStatus = true;
|
|
|
+ // // 如果是第一栏第一个框不允许删除
|
|
|
+ // let $currentParagraph = getParentByClassname($border, 'js-paragraph-view');
|
|
|
+ // let currentParagphChilds = $currentParagraph[0].childNodes;
|
|
|
+ // if (currentParagphChilds.length === 1 && $(currentParagphChilds[0]).equal($border)) {
|
|
|
+ // let $currentColumn = getParentByClassname($border, 'js-column');
|
|
|
+ // let $paragraphs = $currentColumn.find('.js-paragraph-view');
|
|
|
+ // let firstParagraph = this._cycleFindParagraph($paragraphs[0]);
|
|
|
+ // if (firstParagraph && $(firstParagraph).equal($currentParagraph)) {
|
|
|
+ // let pageIndex = parseInt($currentColumn.attr('data-column-i'));
|
|
|
+ // if (this.pages.length === 1 && pageIndex === 0) {
|
|
|
+ // this.editor.message.showMessage('第一页第一个框不能删除!');
|
|
|
+ // $menu[0].blur();
|
|
|
+ // return false;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // let $prevBorders = this._findPrevBorders($border);
|
|
|
+ // let $nextBorders = this._findNextBorders($border);
|
|
|
+ // let lastBorderIndex = $prevBorders.length - 1;
|
|
|
+
|
|
|
+ // $prevBorders.forEach(item => {
|
|
|
+ // let $item = $(item);
|
|
|
+ // let $paragraphItem = $item.parent();
|
|
|
+ // $item.remove();
|
|
|
+ // if (isEmptyElement($paragraphItem)) {
|
|
|
+ // $paragraphItem.remove();
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+
|
|
|
+ // $nextBorders.forEach(item => {
|
|
|
+ // let $item = $(item);
|
|
|
+ // let $paragraphItem = $item.parent();
|
|
|
+ // $item.remove();
|
|
|
+ // if (isEmptyElement($paragraphItem)) {
|
|
|
+ // $paragraphItem.remove();
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+
|
|
|
+ // let $paragraphBorderItem = $border.parent();
|
|
|
+
|
|
|
+ // $border.remove();
|
|
|
+ // if (isEmptyElement($paragraphBorderItem)) {
|
|
|
+ // $paragraphBorderItem.remove();
|
|
|
+ // }
|
|
|
+ // $menu[0].blur();
|
|
|
+
|
|
|
+ // this._checkRemovePage();
|
|
|
+
|
|
|
+ // setTimeout(() => {
|
|
|
+ // this._checkoutContentChangeByFun();
|
|
|
+ // }, 100)
|
|
|
+ // })
|
|
|
+
|
|
|
+ // 删除结束
|
|
|
+ },
|
|
|
+ /**
|
|
|
+ * function 获取前一栏
|
|
|
+ */
|
|
|
+ _getPrevColumn: function ($column) {
|
|
|
+ let prev = $column[0].previousSibling;
|
|
|
+ let pageIndex = parseInt($column.attr('data-column-page')) - 1;
|
|
|
+ if (prev) {
|
|
|
+ if (prev.className && prev.className.indexOf('js-column') > -1) {
|
|
|
+ return $(prev);
|
|
|
+ } else {
|
|
|
+ if (pageIndex < 0) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ let prevPage = this.pages[pageIndex];
|
|
|
+ let lastColumnIndex = prevPage.$colums.length - 1;
|
|
|
+ return prevPage.$colums[lastColumnIndex] || false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (pageIndex < 0) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ let prevPage = this.pages[pageIndex];
|
|
|
+ let lastColumnIndex = prevPage.$colums.length - 1;
|
|
|
+ return prevPage.$colums[lastColumnIndex] || false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 获得该框以上的框
|
|
|
+ _findPrevBorders: function ($border) {
|
|
|
+ let $paragraph = getParentByClassname($border, 'js-paragraph-view');
|
|
|
+ let index = $paragraph.attr('data-index');
|
|
|
+ // 如果上一段在同一栏,则返回空
|
|
|
+ let prevParagraph = $paragraph[0].previousSibling;
|
|
|
+ if (prevParagraph && prevParagraph.className && prevParagraph.className.indexOf('js-paragraph-view') > -1) {
|
|
|
+ let firstContent = prevParagraph.firstChild;
|
|
|
+ if (firstContent && firstContent.className && firstContent.className.indexOf('js-answer-header') < 0) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 获取上一栏的最后一段
|
|
|
+ let $lastParagraph = this._getPrevColumnLastParagraph($paragraph);
|
|
|
+
|
|
|
+ if (!$lastParagraph) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ let prevIndex = $lastParagraph.attr('data-index');
|
|
|
+ let prevLastParagraph = $lastParagraph.attr('class');
|
|
|
+
|
|
|
+
|
|
|
+ if (index === prevIndex) {
|
|
|
+ let borders = [];
|
|
|
+ let lastBorder = $lastParagraph[0].lastChild;
|
|
|
+ borders.push(lastBorder);
|
|
|
+ if ($lastParagraph[0].childNodes.length === 1 && lastBorder.className && lastBorder.className.indexOf('js-lsiten-border') > -1 && prevLastParagraph.indexOf('js-split-paragraph') > -1) {
|
|
|
+ let prevBorders = this._findPrevBorders($(lastBorder));
|
|
|
+ borders = borders.concat(prevBorders);
|
|
|
+ }
|
|
|
+ return borders;
|
|
|
+ } else {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ // 获取该框以上的问题
|
|
|
+ _findPrevQustions: function ($border, type) {
|
|
|
+ if ( type === 4) {
|
|
|
+ let $title = $border.find('.lsiten-title');
|
|
|
+ if ($title.length) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let $paragraph = getParentByClassname($border, 'js-paragraph-view');
|
|
|
+ let index = $paragraph.attr('data-index');
|
|
|
+ // 如果上一段在同一栏,则返回空
|
|
|
+ let prevParagraph = $paragraph[0].previousSibling;
|
|
|
+ if (prevParagraph && prevParagraph.className && prevParagraph.className.indexOf('js-paragraph-view') > -1) {
|
|
|
+ let firstContent = prevParagraph.firstChild;
|
|
|
+ if (firstContent && firstContent.className && firstContent.className.indexOf('js-answer-header') < 0) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // 获取上一栏的最后一段
|
|
|
+ let $lastParagraph = this._getPrevColumnLastParagraph($paragraph);
|
|
|
+
|
|
|
+ if (!$lastParagraph) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ let prevIndex = $lastParagraph.attr('data-index');
|
|
|
+ let prevLastParagraph = $lastParagraph.attr('class');
|
|
|
+
|
|
|
+ if (index === prevIndex) {
|
|
|
+ let lastBorder = $lastParagraph[0].lastChild;
|
|
|
+ let borderContent = lastBorder.firstChild;
|
|
|
+ if (borderContent) {
|
|
|
+ let lastQuestion = borderContent.lastChild;
|
|
|
+ let questionType = parseInt(lastQuestion.getAttribute('data-type'));
|
|
|
+ let questions = [];
|
|
|
+ if (type === questionType) {
|
|
|
+ questions.push(lastQuestion);
|
|
|
+
|
|
|
+ if (borderContent.childNodes.length === 1 && prevLastParagraph.indexOf('js-split-paragraph') > -1) {
|
|
|
+ let prevQuestions = this._findPrevQustions($(lastBorder), type);
|
|
|
+ questions = questions.concat(prevQuestions);
|
|
|
+ }
|
|
|
+ return questions;
|
|
|
+ } else {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ // 获取上一栏的最后一段
|
|
|
+ _getPrevColumnLastParagraph: function ($paragraph) {
|
|
|
+ let $colum = getParentByClassname($paragraph, 'js-column');
|
|
|
+ if (!$colum) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ let $prevColumn = this._getPrevColumn($colum);
|
|
|
+
|
|
|
+ if (!$prevColumn) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ let $paragraphs = $prevColumn.find('.js-paragraph-view');
|
|
|
+
|
|
|
+ if (!$paragraphs.length) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ let lastIndex = $paragraphs.length - 1;
|
|
|
+
|
|
|
+ let lastParagraph = $paragraphs[lastIndex];
|
|
|
+
|
|
|
+ let first = lastParagraph.firstChild;
|
|
|
+ if (first.className && first.className.indexOf('js-answer-header') > -1) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $(lastParagraph);
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ _findNextBorders: function ($border) {
|
|
|
+ let $paragraph = getParentByClassname($border, 'js-paragraph-view');
|
|
|
+ let index = $paragraph.attr('data-index');
|
|
|
+ // 如果上一段在同一栏,则返回空
|
|
|
+ let nextParagraph = $paragraph[0].nextSibling;
|
|
|
+ if (nextParagraph && nextParagraph.className && nextParagraph.className.indexOf('js-paragraph-view') > -1) {
|
|
|
+ let firstContent = nextParagraph.firstChild;
|
|
|
+ if (firstContent && firstContent.className && firstContent.className.indexOf('js-answer-header') < 0) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取下一栏的第一段
|
|
|
+ let $firstParagraph = this._getNextColumnfirstParagraph($paragraph);
|
|
|
+
|
|
|
+ if (!$firstParagraph) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ let nextIndex = $firstParagraph.attr('data-index');
|
|
|
+
|
|
|
+ let nextFirstParagraph = $firstParagraph.attr('class');
|
|
|
+
|
|
|
+ if (index === nextIndex) {
|
|
|
+ let borders = [];
|
|
|
+ let firstBorder = $firstParagraph[0].firstChild;
|
|
|
+ borders.push(firstBorder);
|
|
|
+ if ($firstParagraph[0].childNodes.length === 1 && firstBorder.className && firstBorder.className.indexOf('js-lsiten-border') > -1 && nextFirstParagraph.indexOf('js-split-paragraph') > -1) {
|
|
|
+ let nextBorders = this._findNextBorders($(firstBorder));
|
|
|
+ borders = borders.concat(nextBorders);
|
|
|
+ }
|
|
|
+ return borders;
|
|
|
+ } else {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 获取该框以下的问题
|
|
|
+ _findNextQustions: function ($border, type) {
|
|
|
+ let $paragraph = getParentByClassname($border, 'js-paragraph-view');
|
|
|
+ let index = $paragraph.attr('data-index');
|
|
|
+ // 如果上一段在同一栏,则返回空
|
|
|
+ let nextParagraph = $paragraph[0].nextSibling;
|
|
|
+ if (nextParagraph && nextParagraph.className && nextParagraph.className.indexOf('js-paragraph-view') > -1) {
|
|
|
+ let firstContent = nextParagraph.firstChild;
|
|
|
+ if (firstContent && firstContent.className && firstContent.className.indexOf('js-answer-header') < 0) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取下一栏的第一段
|
|
|
+ let $firstParagraph = this._getNextColumnfirstParagraph($paragraph);
|
|
|
+
|
|
|
+ if (!$firstParagraph) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ let nextIndex = $firstParagraph.attr('data-index');
|
|
|
+
|
|
|
+ let nextFirstParagraph = $firstParagraph.attr('class');
|
|
|
+
|
|
|
+ if (index === nextIndex) {
|
|
|
+ let firstBorder = $firstParagraph[0].firstChild;
|
|
|
+ let borderContent = firstBorder.firstChild;
|
|
|
+ if (borderContent) {
|
|
|
+ let firstQuestion = borderContent.firstChild;
|
|
|
+ let questionType = parseInt(firstQuestion.getAttribute('data-type'));
|
|
|
+ let questions = [];
|
|
|
+ if (type === questionType) {
|
|
|
+ questions.push(firstQuestion);
|
|
|
+
|
|
|
+ if (borderContent.childNodes.length === 1 && nextFirstParagraph.indexOf('js-split-paragraph') > -1) {
|
|
|
+ let nextQuestions = this._findNextQustions($(firstBorder), type);
|
|
|
+ questions = questions.concat(nextQuestions);
|
|
|
+ }
|
|
|
+ return questions;
|
|
|
+ } else {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 获取下一栏的第一段
|
|
|
+ _getNextColumnfirstParagraph: function ($paragraph) {
|
|
|
+ let $colum = getParentByClassname($paragraph, 'js-column');
|
|
|
+ if (!$colum) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ let $nextColumn = this._getNextColumn($colum);
|
|
|
+
|
|
|
+ if (!$nextColumn) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ let $paragraphs = $nextColumn.find('.js-paragraph-view');
|
|
|
+
|
|
|
+ if (!$paragraphs.length) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ let firstParagraph = this._cycleFindParagraph($paragraphs[0]);
|
|
|
+ if (!firstParagraph) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ let firstContent = firstParagraph.firstChild;
|
|
|
+ if (firstContent && firstContent.className && firstContent.className.indexOf('js-answer-header') > -1) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $(firstParagraph);
|
|
|
+ },
|
|
|
+
|
|
|
+
|
|
|
+ // 循环查找段落
|
|
|
+ _cycleFindParagraph: function (paragraph) {
|
|
|
+ if (!paragraph) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ let i = 0;
|
|
|
+ while (i < 100 && (!paragraph.className || paragraph.className.indexOf('js-paragraph-view') < 0)) {
|
|
|
+ let temp = paragraph.nextSibling;
|
|
|
+ paragraph.parentNode.removeChild(paragraph);
|
|
|
+ paragraph = temp;
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ let firstContent = paragraph.firstChild;
|
|
|
+ if (firstContent && firstContent.className && firstContent.className.indexOf('js-answer-header') > -1) {
|
|
|
+ let temp = paragraph.nextSibling;
|
|
|
+ paragraph = temp;
|
|
|
+ return this._cycleFindParagraph(paragraph);
|
|
|
+ }
|
|
|
+ return paragraph || null;
|
|
|
},
|
|
|
/**
|
|
|
* function 内容变化事件监听
|