// ==UserScript==
// @name LushStories.com & LitErotica.com-去除文章选择、复制限制;添加朗读/听书功能
// @name:en LushStories.com & LitErotica.com-Enable Copy & Smart Read
// @namespace yoursatan
// @version 0.1.0
// @description LushStories.com & LitErotica.com:默认去除文章选择、复制限制;添加 Smart Read 按钮,实现语音朗读/听书功能,Esc-结束朗读;空格-暂定/继续(360安全浏览器急速模式(已测试),Chrome浏览器);
// @description www.qidian.com:左侧功能栏增加“听书”按钮,复制功能暂未实现o(╥﹏╥)o。
// @description:en LushStories.com & LitErotica.com:Default to remove the copy restriction of the site:www.lushStories.com & www.literotica.com;Add a Smart Read button to listen stories(Chrome:Esc to cancel & Space to psuse/resume.).
// @author yorusatan
// @include https://www.lushstories.com/stories/*
// @include https://www.literotica.com/s/*
// @include https://read.qidian.com/chapter/*
// @grant none
// @require https://code.jquery.com/jquery-2.1.4.min.js
// @license MIT License
// ==/UserScript==
// v0.1.0 增加 www.qidian.com 支持(在左侧侧边栏增加“听书”按钮,复制功能暂未实现o(╥﹏╥)o) ——2020-3-11
// v0.0.9 增加 www.LitErotica.com 支持 ——2020-3-10
// v0.0.8 修复一个格式化bug ——2020-3-9
// v0.0.7 1,移除 Enable Copy 按钮,“选择、复制,可划词以配合有道翻译”改为默认执行 ——2020-3-9
// v0.0.7 2,实现朗读时当前段落处于选中状态(蓝底白字) ——2020-3-9
// v0.0.6 完善 Smart Read 功能:Esc-结束朗读;空格-暂定/继续 ——2020-3-8
// v0.0.5 添加 Smart Read 按钮,实现语音朗读/听书功能 ——2020-3-8
// v0.0.4 修改介绍文字 -2020-3-7
// v0.0.3 更新按钮样式,统一按钮风格 ——2020-3-7
// v0.0.2 实现基本功能,点击可选,可复制,可划词使用有道翻译 ——2020-3-4
// v0.0.1 添加 Enable Copy 按钮,更改文章样式 ——2020-3-3
(function() {
"use strict";
// 用于获取story内文本的父元素全体
var storyAll = "";
// 用于获取story文本全体
var story = "";
// 用于存储格式化后story文本全体
var newStory = "";
if (
// https://www.lushstories.com/stories/ 网站支持
window.location.href.indexOf("https://www.lushstories.com/stories/") >
-1
) {
// 更改网站CSS样式
$(".blockselect").css({
"-moz-user-select": "-moz-text",
"-khtml-user-select": "text",
"-webkit-user-select": "text",
"user-select": "text"
});
$("#printer").css({
"-moz-user-select": "-moz-text",
"-khtml-user-select": "text",
"-webkit-user-select": "text",
"user-select": "text"
});
$(".onoffswitch").css({
"-moz-user-select": "-moz-text",
"-khtml-user-select": "text",
"-webkit-user-select": "text",
"user-select": "text"
});
// 打包story
$(".story").wrap("<div id='newCont'></div>");
// 打包storycontent
$(".storycontent").wrap("<div id='storycontent'></div>");
// 添加 Smart Read 按钮
$("#breadcrumb").append(
'<a id="btnSmartRead" type = "button" href = "#" title = "Smart Read" style="color:black;background:#e60022; width:150px;display: run-in ;margin:0 5px; padding: 0 5px;text-align:center ;font: 150% Trebuchet MS; border: 1px solid #e60022;-moz-border-radius: 3px;-webkit-border-radius: 3px;border-radius: 3px; height: 20px;">Smart Read</a>'
);
// 获取story文本并格式化;
// 原.story文本
storyAll = $(".story").html();
// 原.storycontent文本
story = $(".storycontent").html();
// 解除选择、复制限制,更改默认样式
$("#sticky-col").remove();
$(".story").remove();
$("#newCont").append(storyAll);
$(".storycontent").remove();
$("#newCont").css("width", "125%");
}
if (
// https://www.literotica.com/s/ 网站支持
window.location.href.indexOf("https://www.literotica.com/s/") > -1
) {
// 添加 Smart Read 按钮
$(".b-breadcrumbs").append(
'<a id="btnSmartRead" type = "button" href = "#" title = "Smart Read" style="color:black;background:#e60022; width:150px;display: run-in ;margin:0 5px; padding: 0 5px;text-align:center ;font: 150% Trebuchet MS; border: 1px solid #e60022;-moz-border-radius: 3px;-webkit-border-radius: 3px;border-radius: 3px; height: 20px;">Smart Read</a>'
);
// 打包.b-story-body-x div
$(".b-story-body-x div").wrap("<div id='storycontent'></div>");
// 获取story文本并格式化;
// 原#content文本
storyAll = $("#content").html();
// 原.b-story-body-x文本
story = $("#storycontent").html();
$("#storycontent").empty();
// 更改默认样式
$("#w").css({
width: "70%",
margin: "0 auto",
"max-width": "1033px",
"min-width": "789px"
});
$("#b-footer-body").css({
margin: "0 auto",
"max-width": "1033px",
"min-width": "789px",
width: "70%"
});
}
if (
// https://read.qidian.com/chapter/ 网站支持
window.location.href.indexOf("https://read.qidian.com/chapter/") > -1
) {
// 侧边栏添加 听书 按钮
$(".left-bar-list dl").append(
'<dd style="background:#e60022;"><a><i><em></em><span id ="btnSmartRead">听书</span></i></a><div class="guide-box"><cite></cite>听书</div></dd>'
);
// 获取文章内容
story = $(".read-content")
.html()
.replace(/<\/?p data-type="2">/gi, "\n")
.replace(/<\/p>/gi, "\n")
.replace(/<span class="content-wrap">/g, "\n")
.replace(/<i><cite><\/cite><\/i>/g, "\n")
.replace(/<span class="review-count.*data-segid=\"\d*\">\d*/g, "\n")
.replace(/<\/span>/g, "\n");
$(".read-content").empty();
$(".read-content").append("<div id='storycontent'></div>");
}
// hover 事件
$("#btnSmartRead").hover(
function() {
$("#btnSmartRead").css({ color: "white" });
},
function() {
$("#btnSmartRead").css({ color: "black" });
}
);
// 将原文本进行格式化,分割存储;
var storyArr = story
.replace(/<div class="hc">[\s\S].*<\/div>/gi, "")
.replace(/<\/?p>/gi, "\n")
.replace(/<\/?div>/gi, "\n")
.replace(/<br\s*\/?>/gi, "\n")
.replace(/\n(\n)*( )*(\n)*\n/g, "\n")
.replace(/\ /g, "")
.split(/\n/);
// 用于存储格式化后,并移除空行文本数组
var newStoryArr = [];
// 移除数组空项(文本空行)
const countPara = storyArr.length;
for (var i = 0; i < countPara; i++) {
storyArr[i] = storyArr[i].replace(/\s+/g, " ").trim();
if (storyArr[i] != "") {
newStory += "<p>" + storyArr[i] + "</p>";
newStoryArr.push(storyArr[i]);
}
}
// 重新加载文章内容,并更改默认样式
$("#storycontent").append(newStory);
$("#storycontent").css({
"font-family": "sans-serif",
"font-size": "1.5em",
"line-height": "1.8em",
"font-weight": 300
});
const newCountPara = newStoryArr.length;
// 用于逐段朗读
var flag = 0;
// 朗读
var speaker = new window.SpeechSynthesisUtterance();
speaker.rate = 1.24;
speaker.lang = "en-US";
speaker.voiceURI = "Microsoft Zira Desktop - English (United States)";
if (
// https://read.qidian.com/chapter/ 网站支持
window.location.href.indexOf("https://read.qidian.com/chapter/") > -1
) {
speaker.lang = "zh-CN";
speaker.voiceURI = "Microsoft Huihui Desktop - Chinese (Simplified)";
$("#storycontent").css("font-family", "PingFangSC-Regular");
}
// 多次尝试再for循环中无法循环朗读,故添加flag步进;利用setInterval进行循环。
$("#btnSmartRead").click(function() {
// 朗读文字数组
var storyAllRead = newStoryArr;
// 用于文字选中效果
var range = document.createRange();
var selection = window.getSelection();
// 朗读
var reading = setInterval(function() {
if (!window.speechSynthesis.speaking && flag < newCountPara) {
speaker.text = storyAllRead[flag];
window.speechSynthesis.speak(speaker);
flag += 1;
// 朗读段落文字选中效果
var referenceNode = document
.getElementById("storycontent")
.childNodes.item(flag - 1);
if (
// https://read.qidian.com/chapter/ 网站支持
window.location.href.indexOf(
"https://read.qidian.com/chapter/"
) > -1
) {
//$("#storycontent p").removeAttr("data-type");
//$("span.review-count").remove();
//$("span.content-wrap").removeClass("content-wrap");
$("#storycontent p")
.eq(flag - 1)
.css("color", "red");
if (flag - 1) {
$("#storycontent p")
.eq(flag - 2)
.css("color", "black");
}
// referenceNode = document
// .getElementById("storycontent")
// .childNodes.item(flag - 1).childNodes.item(1);
}
range.selectNodeContents(referenceNode);
selection.removeAllRanges();
selection.addRange(range);
} else if (flag >= newCountPara) {
// 朗读结束
// window.speechSynthesis.cancel();
clearInterval(reading);
selection.removeAllRanges();
if (
// https://read.qidian.com/chapter/ 网站支持
window.location.href.indexOf(
"https://read.qidian.com/chapter/"
) > -1
) {
$("#storycontent p")
.eq(flag - 1)
.css("color", "black");
}
flag = 0;
alert("The story is finished");
}
}, 500);
// 监听键盘:Esc/F5
$(document).keyup(function(event) {
if (event.keyCode == 27 || event.keyCode == 116) {
window.speechSynthesis.cancel();
clearInterval(reading);
selection.removeAllRanges();
if (
// https://read.qidian.com/chapter/ 网站支持
window.location.href.indexOf(
"https://read.qidian.com/chapter/"
) > -1
) {
$("#storycontent p")
.eq(flag - 1)
.css("color", "black");
}
flag = 0;
}
});
});
// 监听键盘:空格键
$(document).keyup(function(event) {
event.preventDefault();
if (event.keyCode == 32) {
if (window.speechSynthesis.speaking) {
window.speechSynthesis.pause();
}
if (window.speechSynthesis.paused) {
window.speechSynthesis.resume();
}
}
});
})();