/**
* @modify daringuo
* @date 2017.06.14
*/
;(function(window, document) {
// 黑名单逻辑,对应blankListFunc
var blankList = ['richText', 'link', 'word'];
var blankListFunc = {
// richText: 富文本
richText: function () {
var textSelection = textObj.getTextSelection(), $anchor = textSelection.anchorNode, isRichFlag = false;
var isRich = function ($node) {
if (isRichFlag === false && $node !== document.body) {
var attrContenteditable = $node.getAttribute('contenteditable');
if (attrContenteditable === '' || attrContenteditable === 'true') {
isRichFlag = true;
} else {
isRich($node.parentElement);
}
}
};
isRich($anchor.parentElement);
return isRichFlag;
},
// link: 超链接
link: function () {
var textSelection = textObj.getTextSelection(), $anchor = textSelection.anchorNode, isRichFlag = false;
if ($anchor.parentElement && $anchor.parentElement.nodeName === 'A') {
return true;
} else {
return false;
}
},
// 纯字母,空格,字符之类的不出(避免和翻译插件的冲突)
word: function () {
var text = textObj.getSelectedText();
if (/[\u4e00-\u9fa5]/.test(text)) {
return false
} else {
if (!/[a-zA-Z]/.test(text)) {
return false;
}
return true;
}
}
};
function TextObj () {
var text;
// 获取选中的文本句柄,由于是插件,不用兼容IE
this.getTextSelection = function() {
var sel = window.getSelection();
if (sel && sel.focusNode && sel.focusNode.nodeType == 3 && sel.getRangeAt(0).commonAncestorContainer) {
return sel;
} else {
return null;
}
};
this.getSearchEl = function() {
var el = document.getElementById('qb-sougou-search');
if (el) {
return el;
}
el = document.createElement('div');
el.id = 'qb-sougou-search';
el.innerHTML = '<p>搜索</p><p class="last-btn">复制</p><iframe src=""></iframe>';
document.getElementsByTagName('body')[0].appendChild(el);
return el;
};
this.getSelectedText = function() {
var textSelection = this.getTextSelection();
if (textSelection) {
return textSelection.toString();
}
};
// 获取弹出坐标, gap参数为偏移值
this.getXY = function(screenX, screenY, outerWidth, outerHeight, gap) {
var _this = this;
// 简易冒泡
var sort = function (array, key) {
var i, j, flag, temp;
for (i = 0; i < array.length - 1 ;i++) {
flag = false;
for (j = array.length - 1 ;j > i ;j--) {
if (array[j][key] < array[j - 1][key]){
temp = array[j];
array[j] = array[j - 1];
array[j - 1] = temp;
flag = true;
}
}
if (flag == false) {
return;
}
}
};
// 获取选中区域边界点
var getAllRectPoint = function () {
var sel = _this.getTextSelection(),
pointArr = [], i, rects = sel.getRangeAt(0).getClientRects(), newRect = [],
fontSize = window.parseFloat(window.getComputedStyle(sel.anchorNode.parentElement)['font-size']);
var pickTop = function (item) {
// 取矩形上面的点
// 左上点
pointArr.push({
position: 'lt',
point: {
x: item.left,
y: item.top
}
});
// 右上点
pointArr.push({
position: 'rt',
point: {
x: item.right,
y: item.top
}
});
};
var pickBottom = function (item) {
// 取矩形下面的点
// 左下点
pointArr.push({
position: 'lb',
point: {
x: item.left,
y: item.bottom
}
});
// 右下点
pointArr.push({
position: 'rb',
point: {
x: item.right,
y: item.bottom
}
});
};
for (i = 0; i < rects.length; i++) {
// if (rects[i].width >= fontSize) {
newRect.push(rects[i]);
// }
}
pickTop(newRect[0]);
pickBottom(newRect[newRect.length - 1]);
return pointArr;
}
// 获取按距离鼠标松开距离排序得边界点数组
var getSortedPoint = function () {
var pointArr = getAllRectPoint();
pointArr.forEach(function (item) {
var distance = Math.pow(item.point.x - screenX, 2) + Math.pow(item.point.y - screenY, 2);
distance = Math.sqrt(distance);
item.distance = distance;
});
sort(pointArr, 'distance');
return pointArr;
}
// 获取弹出坐标
var getOriginPoint = function () {
var sortedPointArr = getSortedPoint(screenX, screenY),
scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft,
scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
screenHeight = document.documentElement.clientHeight,
screenWidth = document.documentElement.clientWidth,
originPoint;
sortedPointArr.forEach(function (item) {
if (originPoint) {
return;
}
var point = item.point;
// 判断
if (item.position.indexOf('t') >= 0) {
// 上面的点
if (point.y - outerHeight - gap > 0) {
originPoint = {
x: point.x + scrollLeft,
y: point.y + scrollTop - outerHeight - gap
};
}
}
if (item.position.indexOf('b') >= 0) {
// 下面的点
if (point.y + outerHeight + gap < screenHeight) {
originPoint = {
x: point.x + scrollLeft,
y: point.y + scrollTop + gap
};
}
}
});
if (originPoint.x <= 0) {
originPoint.x = gap;
}
if (originPoint.x + outerWidth >= screenWidth + scrollLeft) {
originPoint.x = screenWidth + scrollLeft - outerWidth - gap;
}
return originPoint;
};
return getOriginPoint();
};
this.pop = function(screenX, screenY) {
text = this.getSelectedText();
if (!text) {
return;
}
var rect;
var searchEl = this.getSearchEl();
var len;
text = text.replace(/[\n\r\t]/g, '');
len = this.getTextLength(text);
if (len && len <= 80) {
rect = this.getXY(screenX, screenY, 107, 26, 12);
searchEl.style.left = rect.x + 'px';
searchEl.style.top = rect.y + 'px';
searchEl.style.display = 'block';
searchEl.style.opacity = '1';
chrome.extension.sendMessage({
cmd: 'pop',
url: document.URL
});
// reportElt.contentWindow.postMessage({
// protocol: 8107,
// key: 200500,
// strV: document.URL
// }, '*');
}
};
this.close = function() {
var searchEl = this.getSearchEl();
searchEl.style.display = 'none';
searchEl.style.opacity = '0';
}
this.getTextLength = function(str) {
var len = str.length;
var lenStart, lenEnd;
str = escape(str.replace(/%/g, ''));
lenStart = str.length;
str = str.replace(/%/g, '');
lenEnd = str.length;
return len + lenStart - lenEnd;
};
this.getText = function() {
return text;
}
}
function initReport() {
var elt = document.createElement('iframe');
elt.id = 'qb-iframe-report';
elt.src = 'http://stdl.qq.com/stdl/qb9/extension-report/report.html';
elt.style.display = 'none';
document.body.appendChild(elt);
return elt;
}
var textObj = new TextObj();
var originX, originY, originElt;
// var reportElt = initReport();
document.addEventListener('mousedown', function (e) {
e = e || event;
originX = e.pageX || e.clientX;
originY = e.pageY || e.clientY;
originElt = e.target || e.srcElement || {};
}, false);
document.addEventListener('mouseup', function (e) {
var e = e || event;
var x = e.x || e.clientX;
var y = e.y || e.clientY;
var target = e.target || e.srcElement || {};
var blankTag = false;
try {
textObj.close();
if (/input|textarea/i.test(target.nodeName) || /input|textarea/i.test(originElt.nodeName)) {
return;
}
var textSelection = textObj.getTextSelection();
if (!textSelection) {
return;
}
var boundingClientRect = textSelection.getRangeAt(0).getBoundingClientRect();
if (boundingClientRect.top === boundingClientRect.bottom || boundingClientRect.left === boundingClientRect.right) {
return;
}
if (originX == x && originY == y) {
return;
}
// 黑名单逻辑(富文本,链接,包含单词的情况)
blankList.forEach(function (item) {
if (blankListFunc[item]() === true) {
blankTag = true;
}
});
if (blankTag) {
return;
}
setTimeout(function () {
textObj.pop(x, y);
}, 50);
} catch(e) {
}
}, false);
document.addEventListener('click', function (e) {
var target = e.srcElement || e.target;
var text = textObj.getText();
if (target.parentElement && target.parentElement.id == 'qb-sougou-search') {
if (target.innerHTML == '搜索') {
chrome.extension.sendMessage({cmd: 'search', text: text});
// reportElt.contentWindow.postMessage({
// protocol: 8107,
// key: 200501,
// strV: text
// }, '*');
}
else if (target.innerHTML == '复制') {
document.execCommand( 'Copy' );
chrome.extension.sendMessage({cmd: 'copy', text: text});
// reportElt.contentWindow.postMessage({
// protocol: 8107,
// key: 200502,
// strV: text
// }, '*');
}
}
}, false);
// 数据摸底
(function () {
var screenHeight = document.documentElement.clientHeight;
var srollHeight = document.body.scrollHeight;
var fnScroll = function (e) {
if (window.scrollY + screenHeight >= srollHeight) {
window.external.dataReport(8888, 313, 0, 1, 0, 0, window.location.href, '', '');
}
};
window.addEventListener('scroll', fnScroll, false);
}());
})(window, window.document);
console