|
@@ -1,764 +0,0 @@
|
|
|
-<template>
|
|
|
- <div style="width: 100%; height: 100%; position: relative; overflow: hidden">
|
|
|
- <iframe
|
|
|
- v-if="type === 'pdf'"
|
|
|
- :src="src"
|
|
|
- width="100%"
|
|
|
- scrolling="no"
|
|
|
- height="100%"
|
|
|
- style="position: relative; border: medium none"
|
|
|
- ref="iframeRef"
|
|
|
- @load="onLoad"
|
|
|
- >
|
|
|
- </iframe>
|
|
|
- <div class="close-icon" @click="emits('close')" v-if="false">
|
|
|
- <CloseOutlined />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-<script setup>
|
|
|
-import { CloseOutlined } from '@ant-design/icons-vue';
|
|
|
-import { message } from 'ant-design-vue';
|
|
|
-import { nextTick } from 'vue';
|
|
|
-const iframeRef = ref(null);
|
|
|
-const emits = defineEmits(['close', 'outline', 'search', 'load']);
|
|
|
-const searchList = ref([]);
|
|
|
-const pageContent = ref([]);
|
|
|
-const pageText = ref([]);
|
|
|
-const props = defineProps({
|
|
|
- src: String
|
|
|
-});
|
|
|
-const type = ref('pdf');
|
|
|
-
|
|
|
-watch(
|
|
|
- () => props.src,
|
|
|
- (v) => {
|
|
|
- if (v.endsWith('.pdf')) {
|
|
|
- type.value = 'pdf';
|
|
|
- } else if (v.endsWith('.txt')) {
|
|
|
- type.value = 'txt';
|
|
|
- }
|
|
|
- },
|
|
|
- { immediate: true }
|
|
|
-);
|
|
|
-
|
|
|
-const onLoad = () => {
|
|
|
- const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
|
|
|
- //待定
|
|
|
- // var toolbar = doc.getElementsByClassName('toolbar');
|
|
|
- // if (toolbar && toolbar.length > 0) {
|
|
|
- // toolbar[0].style.display = 'none';
|
|
|
- // }
|
|
|
- setTimeout(() => {
|
|
|
- const script = doc.createElement('script');
|
|
|
- script.textContent = `
|
|
|
- window.addEventListener('message', (event) => {
|
|
|
- const message = event.data;
|
|
|
- if (message.action === 'locateElement') {
|
|
|
- const element= document.getElementById('hightlight-'+message.index);
|
|
|
- debugger;
|
|
|
- if(element!=null&&element.offsetParent){
|
|
|
- setTimeout(() => {
|
|
|
- element.scrollIntoView({ behavior: 'smooth', block: 'center' })
|
|
|
- }, 10);
|
|
|
- }
|
|
|
- }
|
|
|
- if (message.action === 'mlLocateElement') {
|
|
|
-
|
|
|
- const elements= document.getElementsByClassName(message.className);
|
|
|
- if(elements!=null){
|
|
|
- setTimeout(() => {
|
|
|
- elements[message.index].scrollIntoView({ behavior: 'smooth', block: 'center' })
|
|
|
- }, 50);
|
|
|
- }
|
|
|
- }
|
|
|
- });`;
|
|
|
- doc.body.appendChild(script);
|
|
|
- const style = doc.createElement('style');
|
|
|
- style.textContent = `
|
|
|
- #outerContainer{
|
|
|
- overflow: hidden;
|
|
|
- }
|
|
|
- #page-container{
|
|
|
- overflow: hidden;
|
|
|
- }
|
|
|
- #viewerContainer{
|
|
|
- overflow: hidden;
|
|
|
- }
|
|
|
- .canvasWrapper {
|
|
|
- position: relative;
|
|
|
- /* display: flex;
|
|
|
- justify-content: center; */
|
|
|
-}
|
|
|
-
|
|
|
-.textLayer {
|
|
|
- text-align: initial;
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- bottom: 0;
|
|
|
- overflow: hidden;
|
|
|
- opacity: 1;
|
|
|
- line-height: 1;
|
|
|
- text-size-adjust: none;
|
|
|
- forced-color-adjust: none;
|
|
|
-}
|
|
|
-.textLayer span,
|
|
|
-.textLayer br {
|
|
|
- color: transparent;
|
|
|
- position: absolute;
|
|
|
- white-space: pre;
|
|
|
- cursor: text;
|
|
|
- transform-origin: 0% 0%;
|
|
|
-}
|
|
|
-.highlight-layer {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- bottom: 0;
|
|
|
- pointer-events: none;
|
|
|
- opacity: 0.15;
|
|
|
- overflow: hidden;
|
|
|
-}
|
|
|
-.flash {
|
|
|
- animation: flashing 0.6s;
|
|
|
- animation-iteration-count: 2;
|
|
|
-}
|
|
|
-@keyframes flashing {
|
|
|
- 0% {
|
|
|
- opacity: 0;
|
|
|
- }
|
|
|
- 100% {
|
|
|
- opacity: 0.15;
|
|
|
- }
|
|
|
-}
|
|
|
-.highlight {
|
|
|
- background-color: #0076fa;
|
|
|
- position: absolute;
|
|
|
-}
|
|
|
- `;
|
|
|
- doc.head.appendChild(style);
|
|
|
- }, 400);
|
|
|
- setTimeout(() => {
|
|
|
- var el = doc.getElementsByClassName('page');
|
|
|
- // var singleHeight = 1263;
|
|
|
- var singleHeight = 1000;
|
|
|
- if (iframeRef.value.height != singleHeight * el.length) {
|
|
|
- iframeRef.value.height = singleHeight * el.length;
|
|
|
- }
|
|
|
- setTimeout(() => {
|
|
|
- pageText.value = [];
|
|
|
- pageContent.value = [];
|
|
|
- //获取每页数据
|
|
|
- var textDivs = doc.getElementsByClassName('textLayer');
|
|
|
- if (textDivs) {
|
|
|
- for (var i = 0; i < textDivs.length; i++) {
|
|
|
- var item = { page: i + 1, txt: textDivs[i].innerText };
|
|
|
- var items = [];
|
|
|
- for (var j = 0; j < textDivs[i].children.length; j++) {
|
|
|
- var citem = {
|
|
|
- str: textDivs[i].children[j].innerText,
|
|
|
- width: textDivs[i].children[j].getBoundingClientRect().width,
|
|
|
- top: textDivs[i].children[j].getBoundingClientRect().top,
|
|
|
- height: textDivs[i].children[j].getBoundingClientRect().height
|
|
|
- };
|
|
|
- items.push(citem);
|
|
|
- }
|
|
|
- pageContent.value.push({ page: i + 1, items: items });
|
|
|
- pageText.value.push(item);
|
|
|
- }
|
|
|
- }
|
|
|
- }, 1000);
|
|
|
- }, 1000);
|
|
|
-};
|
|
|
-const src = computed(() => {
|
|
|
- // return `/lib/pdfjs/web/viewer.html?file=${props.src}&t=` + new Date().getTime();
|
|
|
- return `/lib/pdfjs/web/viewer.html?file=${props.src}&t=` + new Date().getTime();
|
|
|
-
|
|
|
- // return `/lib/pdfjs/web/viewer.html?file=http://121.40.148.47:8530/doc/knowledge_base/download_doc/国土资源部 国家发展和改革委员会+财政部+住房和城乡建设部农业部+中国人民银行+国家林业局+中国银行业监督管理委员会关于扩大国有土地有偿使用范围的意见%28279-283%29.pdf`
|
|
|
-});
|
|
|
-const scrollTo = (item) => {
|
|
|
- nextTick(() => {
|
|
|
- setTimeout(() => {
|
|
|
- if (item.top) {
|
|
|
- locateElement(item.cs, item.index, 1);
|
|
|
- } else {
|
|
|
- //搜索
|
|
|
- locateElement(item.cs, item.index);
|
|
|
- //改变选中颜色 其他黄色
|
|
|
- searchList.value.forEach((citem, cindex) => {
|
|
|
- const iframeDocument =
|
|
|
- iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
|
|
|
- const highlightedSpan = iframeDocument.getElementById('hightlight-' + cindex);
|
|
|
- if (cindex == item.index) {
|
|
|
- highlightedSpan.parentNode.innerHTML = highlightedSpan.parentNode.innerHTML.replace(
|
|
|
- 'lightblue',
|
|
|
- 'yellow'
|
|
|
- );
|
|
|
- } else {
|
|
|
- highlightedSpan.parentNode.innerHTML = highlightedSpan.parentNode.innerHTML.replace(
|
|
|
- 'yellow',
|
|
|
- 'lightblue'
|
|
|
- );
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }, 10);
|
|
|
- });
|
|
|
-};
|
|
|
-const locateElement = (className, index, type) => {
|
|
|
- const message = {
|
|
|
- action: type ? 'mlLocateElement' : 'locateElement',
|
|
|
- className: className,
|
|
|
- index: index
|
|
|
- };
|
|
|
- iframeRef.value.contentWindow.postMessage(message, '*');
|
|
|
-};
|
|
|
-const gotoElement = (element) => {
|
|
|
- nextTick(() => {
|
|
|
- element.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
|
- });
|
|
|
-};
|
|
|
-const highlightText = (str) => {
|
|
|
- setTimeout(() => {
|
|
|
- removeHighlight();
|
|
|
- heightSingle(str);
|
|
|
- }, 100);
|
|
|
-};
|
|
|
-const goLocation = (txt, flag) => {
|
|
|
- removeHighlight();
|
|
|
- searchList.value = [];
|
|
|
- heightSingle(txt, flag);
|
|
|
-};
|
|
|
-//ai 问答
|
|
|
-const goSourceLocation = (content, type) => {
|
|
|
- //获取页面
|
|
|
- removeSourceHightLight();
|
|
|
- const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
|
|
|
-
|
|
|
- var pageNumber = 0;
|
|
|
- if (content.indexOf('-') > -1 && content.indexOf('-') < 3) {
|
|
|
- content = content.substring(content.indexOf('-') + 1);
|
|
|
- }
|
|
|
- var text = content;
|
|
|
- var ptText = text.replaceAll('\n', '');
|
|
|
- ptText = ptText.replaceAll(' ', '');
|
|
|
- console.log(ptText);
|
|
|
- pageText.value.forEach((item) => {
|
|
|
- item.txt = item.txt.replaceAll('\n', '');
|
|
|
- item.txt = item.txt.replaceAll(' ', '');
|
|
|
- console.log('==页=' + item.txt);
|
|
|
- console.log('==t=' + ptText);
|
|
|
- if (ptText.length > 30) {
|
|
|
- if (item.txt.indexOf(ptText.substring(30, 48)) > -1) {
|
|
|
- pageNumber = item.page;
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (item.txt.indexOf(ptText.substring(0, 18)) > -1) {
|
|
|
- pageNumber = item.page;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- text = text.replaceAll('\n', '');
|
|
|
- text = text.replaceAll(' ', '');
|
|
|
- if (text.endsWith('。') || text.endsWith(',') || text.endsWith('、')) {
|
|
|
- text = text.substring(0, text.length - 1);
|
|
|
- }
|
|
|
- if (pageNumber == 0) {
|
|
|
- message.info('未匹配到相关内容!');
|
|
|
- return;
|
|
|
- }
|
|
|
- //'left: 133.17px; top: 152.408px; font-size: 31.3597px; font-family: sans-serif; transform: scaleX(1.01878);'
|
|
|
- var arr = doc.getElementsByClassName('textLayer')[pageNumber - 1].getElementsByTagName('span');
|
|
|
- if (arr) {
|
|
|
- var hightList = [];
|
|
|
- var startIndex = 0;
|
|
|
- var endIndex = 0;
|
|
|
- var thirdIndex = 0;
|
|
|
- startIndex = getStartIndex(arr, text, text.length);
|
|
|
- endIndex = getEndIndex(arr, text, text.length, startIndex);
|
|
|
- if (startIndex && endIndex && endIndex < startIndex) {
|
|
|
- endIndex = startIndex + text.length;
|
|
|
- }
|
|
|
- var currentPageIndex = 0;
|
|
|
- var nextArr = [];
|
|
|
- var thirdArr = [];
|
|
|
- if (endIndex == undefined) {
|
|
|
- currentPageIndex = arr.length;
|
|
|
- if (doc.getElementsByClassName('textLayer')[pageNumber]) {
|
|
|
- nextArr = doc.getElementsByClassName('textLayer')[pageNumber].getElementsByTagName('span');
|
|
|
- endIndex = getEndIndex(nextArr, text, text.length, startIndex);
|
|
|
- if (endIndex == undefined && doc.getElementsByClassName('textLayer')[pageNumber + 1]) {
|
|
|
- thirdArr = doc
|
|
|
- .getElementsByClassName('textLayer')
|
|
|
- [pageNumber + 1].getElementsByTagName('span');
|
|
|
- thirdIndex = getEndIndex(thirdArr, text, text.length, 0);
|
|
|
- }
|
|
|
- } else {
|
|
|
- endIndex = undefined;
|
|
|
- }
|
|
|
- } else {
|
|
|
- currentPageIndex = endIndex;
|
|
|
- if (type == 1) {
|
|
|
- if (endIndex && startIndex && endIndex > startIndex + content.length) {
|
|
|
- currentPageIndex = startIndex + content.length;
|
|
|
- }
|
|
|
- //中间标点匹配问题
|
|
|
- // var len = startIndex + content.length + 5;
|
|
|
- // if (startIndex && endIndex && endIndex > (startIndex + content.length + 5)) {
|
|
|
- // currentPageIndex = len;
|
|
|
- // }
|
|
|
- }
|
|
|
- }
|
|
|
- if (!startIndex) {
|
|
|
- startIndex = 0;
|
|
|
- }
|
|
|
- for (var i = startIndex; i < currentPageIndex + 1; i++) {
|
|
|
- var element = arr[i];
|
|
|
- if (!element) {
|
|
|
- break;
|
|
|
- }
|
|
|
- var hItem = {};
|
|
|
- var cssText = element.style.cssText;
|
|
|
-
|
|
|
- var spanText = element.innerText;
|
|
|
- var s = spanText.replaceAll(' ', '');
|
|
|
- var d = spanText.endsWith('。') ? spanText.replaceAll('。', '') : spanText;
|
|
|
-
|
|
|
- console.log(spanText);
|
|
|
- if (
|
|
|
- text.includes(spanText) ||
|
|
|
- (s && text.includes(s)) ||
|
|
|
- (d && text.includes(d)) ||
|
|
|
- (spanText.substring(2) && text.includes(spanText.substring(2)))
|
|
|
- ) {
|
|
|
- var topLabel = cssText.split('top: ')[1].split(';')[0];
|
|
|
- var leftLabel = cssText.split('left: ')[1].split(';')[0];
|
|
|
- var currentItems = [];
|
|
|
- pageContent.value.forEach((item) => {
|
|
|
- if (item.page == pageNumber) {
|
|
|
- currentItems = item.items;
|
|
|
- }
|
|
|
- });
|
|
|
- for (var m = 0; m < currentItems.length; m++) {
|
|
|
- // citem.str=citem.str.replaceAll(' ','');
|
|
|
- var citem = currentItems[m];
|
|
|
- if (citem.str == spanText) {
|
|
|
- hItem.width = parseFloat(citem.width);
|
|
|
- hItem.height = parseFloat(citem.height);
|
|
|
- hItem.text = spanText;
|
|
|
- hItem.left = leftLabel;
|
|
|
- hItem.top = topLabel;
|
|
|
- hightList.push(hItem);
|
|
|
- if (hightList.length == 1) {
|
|
|
- gotoElement(element);
|
|
|
- }
|
|
|
- if (text.endsWith(citem.str)) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (type == 1 && hightList.length == 0) {
|
|
|
- message.info('未匹配到相关内容!');
|
|
|
- }
|
|
|
- // if (type == 2) {
|
|
|
- var nextHightList = [];
|
|
|
- //跨页 目前只考虑跨1页
|
|
|
- if (endIndex != undefined) {
|
|
|
- for (var i = 0; i < nextArr.length; i++) {
|
|
|
- var element = nextArr[i];
|
|
|
- var hItem = {};
|
|
|
- var cssText = element.style.cssText;
|
|
|
- var spanText = element.innerText;
|
|
|
- console.log(spanText);
|
|
|
- if (text.includes(spanText)) {
|
|
|
- var topLabel = cssText.split('top: ')[1].split(';')[0];
|
|
|
- var leftLabel = cssText.split('left: ')[1].split(';')[0];
|
|
|
- var currentItems = [];
|
|
|
- pageContent.value.forEach((item) => {
|
|
|
- if (item.page == pageNumber + 1) {
|
|
|
- currentItems = item.items;
|
|
|
- }
|
|
|
- });
|
|
|
- for (var l = 0; l < currentItems.length; l++) {
|
|
|
- var citem = currentItems[l];
|
|
|
- if (citem.str == spanText) {
|
|
|
- hItem.width = parseFloat(citem.width);
|
|
|
- hItem.height = parseFloat(citem.height);
|
|
|
- hItem.text = spanText;
|
|
|
- hItem.left = leftLabel;
|
|
|
- hItem.top = topLabel;
|
|
|
- nextHightList.push(hItem);
|
|
|
- if (text.endsWith(citem.str)) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (text.endsWith(spanText)) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- //跨页 目前只考虑跨2页
|
|
|
- for (var i = 0; i < nextArr.length; i++) {
|
|
|
- var element = nextArr[i];
|
|
|
- var hItem = {};
|
|
|
- var cssText = element.style.cssText;
|
|
|
- var spanText = element.innerText;
|
|
|
- console.log(spanText);
|
|
|
-
|
|
|
- var topLabel = cssText.split('top: ')[1].split(';')[0];
|
|
|
- var leftLabel = cssText.split('left: ')[1].split(';')[0];
|
|
|
- var currentItems = [];
|
|
|
- pageContent.value.forEach((item) => {
|
|
|
- if (item.page == pageNumber + 1) {
|
|
|
- currentItems = item.items;
|
|
|
- }
|
|
|
- });
|
|
|
- for (var l = 0; l < currentItems.length; l++) {
|
|
|
- var citem = currentItems[l];
|
|
|
- if (citem.str == spanText) {
|
|
|
- hItem.width = parseFloat(citem.width);
|
|
|
- hItem.height = parseFloat(citem.height);
|
|
|
- hItem.text = spanText;
|
|
|
- hItem.left = leftLabel;
|
|
|
- hItem.top = topLabel;
|
|
|
- nextHightList.push(hItem);
|
|
|
- if (text.endsWith(citem.str)) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- var thirdHightList = [];
|
|
|
- if (thirdIndex != 0 && thirdIndex != undefined) {
|
|
|
- for (var z = 0; z < thirdIndex + 1; z++) {
|
|
|
- var element = thirdArr[z];
|
|
|
- var hItem = {};
|
|
|
- var cssText = element.style.cssText;
|
|
|
- var spanText = element.innerText;
|
|
|
- console.log(spanText);
|
|
|
- if (text.includes(spanText)) {
|
|
|
- var topLabel = cssText.split('top: ')[1].split(';')[0];
|
|
|
- var leftLabel = cssText.split('left: ')[1].split(';')[0];
|
|
|
- var currentItems = [];
|
|
|
- pageContent.value.forEach((item) => {
|
|
|
- if (item.page == pageNumber + 2) {
|
|
|
- currentItems = item.items;
|
|
|
- }
|
|
|
- });
|
|
|
- for (var l = 0; l < currentItems.length; l++) {
|
|
|
- var citem = currentItems[l];
|
|
|
- if (citem.str == spanText) {
|
|
|
- hItem.width = parseFloat(citem.width);
|
|
|
- hItem.height = parseFloat(citem.height);
|
|
|
- hItem.text = spanText;
|
|
|
- hItem.left = leftLabel;
|
|
|
- hItem.top = topLabel;
|
|
|
- thirdHightList.push(hItem);
|
|
|
- if (text.endsWith(citem.str)) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (text.endsWith(spanText)) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //渲染
|
|
|
- var canvas = doc.getElementsByClassName(`page`)[pageNumber - 1];
|
|
|
- const hightDiv = document.createElement('div');
|
|
|
- hightDiv.className = 'highlight-layer flash';
|
|
|
- hightList.forEach((it) => {
|
|
|
- const hDiv = document.createElement('div');
|
|
|
- hDiv.className = 'highlight';
|
|
|
- // 设置内联样式
|
|
|
- hDiv.style.width = it.width + 'px';
|
|
|
- hDiv.style.height = it.height * 1.4 + 'px';
|
|
|
- hDiv.style.left = it.left;
|
|
|
- hDiv.style.top = parseFloat(it.top.split('%')[0]) - 0.5 + '%';
|
|
|
- hightDiv.appendChild(hDiv);
|
|
|
- });
|
|
|
- canvas.appendChild(hightDiv);
|
|
|
- if (nextHightList && nextHightList.length > 0) {
|
|
|
- //渲染
|
|
|
- var nextCanvas = doc.getElementsByClassName(`page`)[pageNumber];
|
|
|
- const hightDiv = document.createElement('div');
|
|
|
- hightDiv.className = 'highlight-layer flash';
|
|
|
- nextHightList.forEach((it) => {
|
|
|
- const hDiv = document.createElement('div');
|
|
|
- hDiv.className = 'highlight';
|
|
|
- // 设置内联样式
|
|
|
- hDiv.style.width = it.width + 'px';
|
|
|
- hDiv.style.height = it.height * 1.4 + 'px';
|
|
|
- hDiv.style.left = it.left;
|
|
|
- hDiv.style.top = parseFloat(it.top.split('%')[0]) - 0.5 + '%';
|
|
|
- hightDiv.appendChild(hDiv);
|
|
|
- });
|
|
|
- nextCanvas.appendChild(hightDiv);
|
|
|
- }
|
|
|
- if (thirdHightList && thirdHightList.length > 0) {
|
|
|
- //渲染
|
|
|
- var thirdCanvas = doc.getElementsByClassName(`page`)[pageNumber + 1];
|
|
|
- const hightDiv = document.createElement('div');
|
|
|
- hightDiv.className = 'highlight-layer flash';
|
|
|
- thirdHightList.forEach((it) => {
|
|
|
- const hDiv = document.createElement('div');
|
|
|
- hDiv.className = 'highlight';
|
|
|
- // 设置内联样式
|
|
|
- hDiv.style.width = it.width + 'px';
|
|
|
- hDiv.style.height = it.height * 1.4 + 'px';
|
|
|
- hDiv.style.left = it.left;
|
|
|
- hDiv.style.top = parseFloat(it.top.split('%')[0]) - 0.5 + '%';
|
|
|
- hightDiv.appendChild(hDiv);
|
|
|
- });
|
|
|
- thirdCanvas.appendChild(hightDiv);
|
|
|
- }
|
|
|
- // }
|
|
|
- }
|
|
|
-};
|
|
|
-//交集
|
|
|
-function commonContent(str1, str2) {
|
|
|
- let result = '';
|
|
|
- for (let i = 0; i < str1.length; i++) {
|
|
|
- if (str2.includes(str1[i])) {
|
|
|
- result += str1[i];
|
|
|
- }
|
|
|
- }
|
|
|
- return result;
|
|
|
-}
|
|
|
-const getStartIndex = (arr, text, total) => {
|
|
|
- var indexs = [];
|
|
|
- for (var i = 0; i < arr.length; i++) {
|
|
|
- var element = arr[i];
|
|
|
- var spanText = element.innerText;
|
|
|
- console.log('===' + spanText);
|
|
|
-
|
|
|
- if (
|
|
|
- (spanText && text.startsWith(spanText)) ||
|
|
|
- (spanText && spanText.substring(2) && spanText && text.startsWith(spanText.substring(2))) ||
|
|
|
- (spanText.indexOf('。') > -1 &&
|
|
|
- spanText.split('。')[1] &&
|
|
|
- text.startsWith(spanText.split('。')[1])) ||
|
|
|
- (spanText.endsWith('。') &&
|
|
|
- spanText.split('。')[0] &&
|
|
|
- text.startsWith(spanText.split('。')[0]))
|
|
|
- ) {
|
|
|
- indexs.push(i);
|
|
|
- // return i;
|
|
|
- }
|
|
|
- }
|
|
|
- if (indexs.length == 0) {
|
|
|
- return 0;
|
|
|
- } else if (indexs.length == 2) {
|
|
|
- console.log(JSON.stringify(indexs));
|
|
|
- return indexs[0] == 0 ? indexs[1] : indexs[0];
|
|
|
- } else {
|
|
|
- return indexs[0];
|
|
|
- }
|
|
|
- //todo 有问题
|
|
|
- // if (count == arr.length) {
|
|
|
- // start.value = start.value + 1;
|
|
|
- // text = text.substring(start.value, total);
|
|
|
- // getStartIndex(arr, text, total);
|
|
|
- // }
|
|
|
-};
|
|
|
-const getEndIndex = (arr, text, total, startIndex) => {
|
|
|
- for (var i = 0; i < arr.length; i++) {
|
|
|
- var element = arr[i];
|
|
|
- var spanText = element.innerText;
|
|
|
- var e = '';
|
|
|
- if (spanText.endsWith('。')) {
|
|
|
- spanText = spanText.substring(0, spanText.lastIndexOf('。'));
|
|
|
- }
|
|
|
- if (spanText.indexOf('。') > -1) {
|
|
|
- e = spanText.substring(0, spanText.lastIndexOf('。'));
|
|
|
- }
|
|
|
- console.log('===' + spanText);
|
|
|
- if (
|
|
|
- (spanText && text.endsWith(spanText) && spanText.length > 0) ||
|
|
|
- (spanText && spanText.indexOf(text) > -1) ||
|
|
|
- (e && text.endsWith(e))
|
|
|
- ) {
|
|
|
- return i;
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
-const heightSingle = (str, flag) => {
|
|
|
- const iframeDocument = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
|
|
|
-
|
|
|
- const searchText = str;
|
|
|
- var highlightColor = 'lightblue';
|
|
|
-
|
|
|
- // 使用DOM操作在iframe中搜索并高亮文本
|
|
|
- const textNodes = iframeDocument.evaluate(
|
|
|
- ".//text()[contains(., '" + searchText + "')]",
|
|
|
- iframeDocument,
|
|
|
- null,
|
|
|
- XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
|
|
|
- null
|
|
|
- );
|
|
|
- var firstFlag = false;
|
|
|
- for (let i = 0, length = textNodes.snapshotLength; i < length; i++) {
|
|
|
- const content = textNodes.snapshotItem(i);
|
|
|
- const textNode = content.textContent;
|
|
|
-
|
|
|
- const regex = new RegExp(searchText, 'gi');
|
|
|
- var newContent = textNode.replace(regex, (match) => {
|
|
|
- if (match == searchText) {
|
|
|
- if (!firstFlag) {
|
|
|
- firstFlag = true;
|
|
|
- highlightColor = 'yellow';
|
|
|
- } else {
|
|
|
- highlightColor = 'lightblue';
|
|
|
- }
|
|
|
- return `<span id='hightlight-${searchList.value.length}' style="background-color: ${highlightColor};color: #333;margin-top:-3px;border-radius: 3px;">${match}</span>`;
|
|
|
- }
|
|
|
- });
|
|
|
- if (content.parentNode) {
|
|
|
- var n = content.parentNode;
|
|
|
- console.log('====' + n.offsetTop);
|
|
|
- newContent = '<' + newContent.split('<')[1] + '</span>';
|
|
|
- var h = content.parentNode.innerHTML;
|
|
|
- if (!flag) {
|
|
|
- content.parentNode.innerHTML = h.replace(searchText, newContent);
|
|
|
- }
|
|
|
- if (n) {
|
|
|
- searchList.value.push({
|
|
|
- cs: n.parentNode.className,
|
|
|
- index: searchList.value.length,
|
|
|
- n: n.parentNode
|
|
|
- });
|
|
|
- if (searchList.value.length == 1) {
|
|
|
- // if (!flag) {
|
|
|
- // locateElement(searchList.value[0].cs, 0);
|
|
|
- // }
|
|
|
- gotoElement(n);
|
|
|
- }
|
|
|
- //大纲只定位一次
|
|
|
- if (flag) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (!flag) {
|
|
|
- if (i == textNodes.snapshotLength - 1) {
|
|
|
- //查询结束
|
|
|
- emits('search', searchList.value);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
-const removeSourceHightLight = () => {
|
|
|
- //获取页面 ai定位移除
|
|
|
- const doc = iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
|
|
|
-
|
|
|
- const arr = doc.getElementsByClassName('highlight-layer');
|
|
|
- const l = arr.length;
|
|
|
- for (let i = l - 1; i >= 0; i--) {
|
|
|
- if (arr[i] != null) {
|
|
|
- arr[i].parentNode.removeChild(arr[i]);
|
|
|
- }
|
|
|
- }
|
|
|
-};
|
|
|
-const removeHighlight = () => {
|
|
|
- removeSourceHightLight();
|
|
|
- if (searchList.value) {
|
|
|
- searchList.value.forEach((item, index) => {
|
|
|
- const iframeDocument =
|
|
|
- iframeRef.value.contentDocument || iframeRef.value.contentWindow.document;
|
|
|
- const highlightedSpan = iframeDocument.getElementById('hightlight-' + index);
|
|
|
- if (highlightedSpan != null) {
|
|
|
- const span = highlightedSpan;
|
|
|
- console.log(span.innerHTML);
|
|
|
- setTimeout(() => {
|
|
|
- span.parentNode.replaceChild(document.createTextNode(span.textContent), span);
|
|
|
- }, 10);
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- searchList.value = [];
|
|
|
- emits('search', searchList.value);
|
|
|
-};
|
|
|
-defineExpose({ highlightText, removeHighlight, scrollTo, goLocation, goSourceLocation, location });
|
|
|
-</script>
|
|
|
-
|
|
|
-<style scoped lang="scss">
|
|
|
-.close-icon {
|
|
|
- position: absolute;
|
|
|
-
|
|
|
- top: 8px;
|
|
|
- right: 12px;
|
|
|
- cursor: pointer;
|
|
|
-}
|
|
|
-</style>
|
|
|
-<style>
|
|
|
-/* 不能用scoped,因为动态创建的元素不会被编译带上hash */
|
|
|
-/* 不加上这些css修饰,元素会错位,样式来自vue-pdf-embed这个库 */
|
|
|
-.canvasWrapper {
|
|
|
- position: relative;
|
|
|
- /* display: flex;
|
|
|
- justify-content: center; */
|
|
|
-}
|
|
|
-.page {
|
|
|
- position: relative;
|
|
|
- box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.08);
|
|
|
- margin: 30px auto;
|
|
|
-}
|
|
|
-.textLayer {
|
|
|
- text-align: initial;
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- bottom: 0;
|
|
|
- overflow: hidden;
|
|
|
- opacity: 0.2;
|
|
|
- line-height: 1;
|
|
|
- text-size-adjust: none;
|
|
|
- forced-color-adjust: none;
|
|
|
-}
|
|
|
-.textLayer span,
|
|
|
-.textLayer br {
|
|
|
- color: transparent;
|
|
|
- position: absolute;
|
|
|
- white-space: pre;
|
|
|
- cursor: text;
|
|
|
- transform-origin: 0% 0%;
|
|
|
-}
|
|
|
-.highlight-layer {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- bottom: 0;
|
|
|
- pointer-events: none;
|
|
|
- opacity: 0.15;
|
|
|
- overflow: hidden;
|
|
|
-}
|
|
|
-.flash {
|
|
|
- animation: flashing 0.6s;
|
|
|
- animation-iteration-count: 2;
|
|
|
-}
|
|
|
-@keyframes flashing {
|
|
|
- 0% {
|
|
|
- opacity: 0;
|
|
|
- }
|
|
|
- 100% {
|
|
|
- opacity: 0.15;
|
|
|
- }
|
|
|
-}
|
|
|
-.highlight {
|
|
|
- background-color: #0076fa;
|
|
|
- position: absolute;
|
|
|
-}
|
|
|
-</style>
|