Add component, fix bugs

This commit is contained in:
the1812 2019-01-07 18:13:37 +08:00
parent 3331addec4
commit 652652d17c
11 changed files with 158 additions and 112 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -458,11 +458,15 @@
path: "min/download-danmaku.min.js",
dependencies: [
"videoInfo",
"danmakuConverter",
],
displayNames: {
"downloadDanmaku": "下载弹幕",
},
},
danmakuConverter: {
path: "min/danmaku-converter.min.js"
},
videoInfo: {
path: "min/video-info.min.js",
},
@ -592,7 +596,7 @@
displayNames: {
compactLayout: "首页使用紧凑布局",
}
}
},
};
Resource.root = "https://raw.githubusercontent.com/the1812/Bilibili-Evolved/preview/";
Resource.all = {};
@ -1099,7 +1103,7 @@
<span>$4</span>
</label>
</li>
`).replace(/<dropdown\s*?indent="(.+?)"\s*?key="(.+?)"\s*?dependencies="(.*?)">([^\0]*?)<\/dropdown>/g,`
`).replace(/<dropdown\s*?indent="(.+?)"\s*?key="(.+?)"\s*?dependencies="(.*?)">([^\0]*?)<\/dropdown>/g, `
<li class="indent-$1">
<label>
<span class="gui-settings-dropdown-span">$4</span>
@ -1196,50 +1200,50 @@
.concat(flattenStyles.map(it => Resource.all[it]))
.map(r => r.download())
)
.then(() =>
{
// +#Offline build placeholder
if (settings.useCache)
.then(() =>
{
const cache = this.loadCache(key);
if (cache !== null)
// +#Offline build placeholder
if (settings.useCache)
{
this.text = cache;
resolve(cache);
}
downloadText(this.url, text =>
{
this.text = this.type.preprocessor(text);
if (text === null)
const cache = this.loadCache(key);
if (cache !== null)
{
reject("download failed");
this.text = cache;
resolve(cache);
}
if (cache !== this.text)
{
if (cache === null)
{
resolve(this.text);
}
if (typeof offlineData === "undefined")
{
settings.cache[key] = this.text;
saveSettings(settings);
}
}
}, error => reject(error));
}
else
{
downloadText(this.url,
text =>
downloadText(this.url, text =>
{
this.text = this.type.preprocessor(text);
resolve(this.text);
},
error => reject(error));
}
// -#Offline build placeholder
});
if (text === null)
{
reject("download failed");
}
if (cache !== this.text)
{
if (cache === null)
{
resolve(this.text);
}
if (typeof offlineData === "undefined")
{
settings.cache[key] = this.text;
saveSettings(settings);
}
}
}, error => reject(error));
}
else
{
downloadText(this.url,
text =>
{
this.text = this.type.preprocessor(text);
resolve(this.text);
},
error => reject(error));
}
// -#Offline build placeholder
});
}
});
}

View File

@ -1,6 +1,6 @@
// ==UserScript==
// @name Bilibili Evolved
// @version 1.6.29
// @version 1.6.30
// @description 增强哔哩哔哩Web端体验: 修复界面瑕疵, 删除广告, 使用夜间模式浏览; 下载视频,封面,弹幕, 以及增加对触屏设备的支持等.
// @author Grant Howard, Coulomb-G
// @copyright 2018, Grant Howrad (https://github.com/the1812)
@ -458,11 +458,15 @@
path: "min/download-danmaku.min.js",
dependencies: [
"videoInfo",
"danmakuConverter",
],
displayNames: {
"downloadDanmaku": "下载弹幕",
},
},
danmakuConverter: {
path: "min/danmaku-converter.min.js"
},
videoInfo: {
path: "min/video-info.min.js",
},
@ -592,7 +596,7 @@
displayNames: {
compactLayout: "首页使用紧凑布局",
}
}
},
};
Resource.root = "https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/";
Resource.all = {};
@ -1099,7 +1103,7 @@
<span>$4</span>
</label>
</li>
`).replace(/<dropdown\s*?indent="(.+?)"\s*?key="(.+?)"\s*?dependencies="(.*?)">([^\0]*?)<\/dropdown>/g,`
`).replace(/<dropdown\s*?indent="(.+?)"\s*?key="(.+?)"\s*?dependencies="(.*?)">([^\0]*?)<\/dropdown>/g, `
<li class="indent-$1">
<label>
<span class="gui-settings-dropdown-span">$4</span>
@ -1196,50 +1200,50 @@
.concat(flattenStyles.map(it => Resource.all[it]))
.map(r => r.download())
)
.then(() =>
{
// +#Offline build placeholder
if (settings.useCache)
.then(() =>
{
const cache = this.loadCache(key);
if (cache !== null)
// +#Offline build placeholder
if (settings.useCache)
{
this.text = cache;
resolve(cache);
}
downloadText(this.url, text =>
{
this.text = this.type.preprocessor(text);
if (text === null)
const cache = this.loadCache(key);
if (cache !== null)
{
reject("download failed");
this.text = cache;
resolve(cache);
}
if (cache !== this.text)
{
if (cache === null)
{
resolve(this.text);
}
if (typeof offlineData === "undefined")
{
settings.cache[key] = this.text;
saveSettings(settings);
}
}
}, error => reject(error));
}
else
{
downloadText(this.url,
text =>
downloadText(this.url, text =>
{
this.text = this.type.preprocessor(text);
resolve(this.text);
},
error => reject(error));
}
// -#Offline build placeholder
});
if (text === null)
{
reject("download failed");
}
if (cache !== this.text)
{
if (cache === null)
{
resolve(this.text);
}
if (typeof offlineData === "undefined")
{
settings.cache[key] = this.text;
saveSettings(settings);
}
}
}, error => reject(error));
}
else
{
downloadText(this.url,
text =>
{
this.text = this.type.preprocessor(text);
resolve(this.text);
},
error => reject(error));
}
// -#Offline build placeholder
});
}
});
}
@ -1426,6 +1430,10 @@
styles.push("--custom-control-background-opacity:" + settings.customControlBackgroundOpacity);
this.applyStyleFromText(`<style id="bilibili-evolved-vaiables">html{${styles.join(";")}}</style>`);
}
import(compnentName)
{
return this.attributes[compnentName].export;
}
async fetchByKey(key)
{
const resource = Resource.all[key];

1
min/danmaku-converter.min.js vendored Normal file
View File

@ -0,0 +1 @@
(()=>{return(t,e)=>{class n{constructor(t,e,n,s,o){this.content=t;this.time=e;this.type=n;this.fontSize=s;this.color=o}}class s extends n{constructor({content:t,time:e,type:n,fontSize:s,color:o,timeStamp:i,pool:a,userHash:r,rowId:l}){super(t,e,n,s,o);this.timeStamp=i;this.pool=a;this.userHash=r;this.rowId=l;this.pDataArray=[e,n,s,o,i,a,r,l]}text(){const t=this.pDataArray.join(",");return`<d p="${t}">${this.content}</d>`}static parse(t){const e=t.getAttribute("p");const[n,o,i,a,r,l,c,h]=e.split(",");const u=t.innerText;return new s({content:u,time:n,type:o,fontSize:i,color:a,timeStamp:r,pool:l,userHash:c,rowId:h})}}class o{constructor(t){this.xml=t;const e=(new DOMParser).parseFromString(t,"application/xml").documentElement;this.danmakus=[...e.querySelectorAll("d[p]")].map(t=>s.parse(t))}}class i extends n{constructor({content:t,time:e,type:n,fontSize:s,color:o,typeTag:i,colorTag:a,endTime:r}){super(t,e,n,s,o);this.typeTag=i;this.colorTag=a;this.endTime=r}text(t){const e=t[this.fontSize].match(/Style:(.*?),/)[1].trim();return`Dialogue: 0,${this.time},${this.endTime},${e},,0,0,0,,{${this.typeTag}${this.colorTag}}${this.content}`}}class a{constructor({danmakus:t,title:e,fontStyles:n,blockTypes:s,resolution:o}){this.danmakus=t;this.title=e;this.fontStyles=n;this.blockTypes=s;this.resolution=o}generateAss(){const t=`\n[Script Info]\n; Script generated by Bilibili Evolved Danmaku Converter\n; https://github.com/the1812/Bilibili-Evolved/\nTitle: ${this.title}\nScriptType: v4.00+\nPlayResX: ${this.resolution.x}\nPlayResY: ${this.resolution.y}\nTimer: 10.0000\nWrapStyle: 2\nScaledBorderAndShadow: no\n\n[V4+ Styles]\nFormat: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding\n${Object.values(this.fontStyles).join("\n")}\n\n[Events]\nFormat: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\n `.trim();return t+"\n"+this.danmakus.map(t=>t.text(this.fontStyles,this.blockTypes)).filter(t=>t!=="").join("\n")}}class r{constructor(t,e){this.horizontal=[];this.vertical=[];this.canvas=document.createElement("canvas");this.context=this.canvas.getContext("2d");this.fontSizes={25:`36pt ${t}`,18:`26pt ${t}`};this.danmakuType={1:"normal",2:"normal",3:"normal",4:"bottom",5:"top",6:"reversed",7:"special",8:"special"}}getHorizonalTags(t){return`\\pos(0, -999)`}getVerticalTags(t){return`\\pos(0, -999)`}push(t){let e=null;let n=null;switch(this.danmakuType[t.type]){case"normal":case"reversed":{e=this.gegetHorizonalTagstTags(t);n=this.horizontal;break}case"top":case"bottom":{e=this.getVerticalTags(t);n=this.vertical;break}case"special":default:{throw new Error("Danmaku type not supported")}}const s={tags:e};n.push(s);return s}}class l{constructor({title:t,font:e,alpha:n,duration:s,blockTypes:o,resolution:i}){this.title=t;this.font=e;this.alpha=Math.round(n*100);this.duration=s;this.blockTypes=o;this.resolution=i;this.danmakuStack=new r(e,i)}get fontStyles(){return{25:`Medium,${this.font},36,&H${this.alpha}FFFFFF,&H${this.alpha}FFFFFF,&H${this.alpha}000000,&H${this.alpha}000000,0,0,0,0,100,100,0,0,1,1,0,5,0,0,0,0`,18:`Small,${this.font},26,&H${this.alpha}FFFFFF,&H${this.alpha}FFFFFF,&H${this.alpha}000000,&H${this.alpha}000000,0,0,0,0,100,100,0,0,1,1,0,5,0,0,0,0`}}convertToAssDocument(t){const e=[];for(const n of t.danmakus){if(this.blockTypes.concat(7,8).indexOf(n.type)!==-1){continue}const[t,s]=this.convertTime(n.time,this.duration);e.push(new i({content:n.content,time:t,endTime:s,type:n.type,fontSize:n.fontSize,color:n.color,typeTag:this.convertType(n),colorTag:this.convertColor(n.color)}))}return new a({danmakus:e,title:this.title,blockTypes:this.blockTypes,fontStyles:this.fontStyles,resolution:this.resolution})}convertType(t){return this.danmakuStack.push(t).tags}convertColor(t){const e=16777215;if(t===e){return""}const n=t.toString(16);const s=n.substring(4,6);const o=n.substring(2,4);const i=n.substring(0,2);return`\\c&H${i}${o}${s}&`}convertTime(t,e){function n(t){return Math.round(t*100)/100}function s(t){let e=0;let s=0;while(t>=60){t-=60;s++}while(s>=60){s-=60;e++}return`${e}:${s.toString().padStart(2,"0")}:${n(t).toString().padStart(4,"0")}`}return[s(t),s(t+e)]}}return{export:{AssDanmaku:i,AssDanmakuDocument:a,Danmaku:n,DanmakuConverter:l,DanmakuStack:r,XmlDanmaku:s,XmlDanmakuDocument:o}}}})();

2
min/dark.min.css vendored

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
(()=>{return(n,t)=>{const e=t.attributes.videoInfo.export.DanmakuInfo;async function a(n){const t=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","");const a=new e((unsafeWindow||window).cid);await a.fetchInfo();const o=new Blob([a.rawXML],{type:"text/plain"});const i=URL.createObjectURL(o);const c=$("#danmaku-link");const d=c.attr("href");if(d){URL.revokeObjectURL(d)}clearTimeout(n);document.querySelector("#download-danmaku>span").innerHTML="下载弹幕";c.attr("download",`${t}.xml`).attr("href",i).get(0).click()}return{widget:{content:`\n <button\n class="gui-settings-flat-button"\n id="download-danmaku">\n <i class="icon-danmaku"></i>\n <span>下载弹幕</span>\n <a id="danmaku-link" style="display:none"></a>\n </button>`,condition:async()=>{let n=await SpinQuery.condition(()=>(unsafeWindow||window).cid,n=>n!==undefined);return n!==undefined},success:()=>{const n=document.querySelector("#danmaku-link");$("#download-danmaku").on("click",t=>{if(t.target!==n){const n=setTimeout(()=>document.querySelector("#download-danmaku>span").innerHTML="请稍侯...",200);a(n)}})}}}}})();
(()=>{return(n,t)=>{const{DanmakuInfo:e}=t.import("videoInfo");const{DanmakuConverter:o,XmlDanmakuDocument:a}=t.import("danmakuConverter");async function i(n){const t=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","");const i=new e((unsafeWindow||window).cid);await i.fetchInfo();const c=new o({title:t,font:"Micorosoft Yahei UI",alpha:.6,duration:10,blockTypes:[],resolution:{x:1920,y:1080}});const d=c.convertToAssDocument(new a(i.rawXML));const s=new Blob([d.generateAss()],{type:"text/plain"});const u=URL.createObjectURL(s);const r=$("#danmaku-link");const l=r.attr("href");if(l){URL.revokeObjectURL(l)}clearTimeout(n);document.querySelector("#download-danmaku>span").innerHTML="下载弹幕";r.attr("download",`${t}.ass`).attr("href",u).get(0).click()}return{widget:{content:`\n <button\n class="gui-settings-flat-button"\n id="download-danmaku">\n <i class="icon-danmaku"></i>\n <span>下载弹幕</span>\n <a id="danmaku-link" style="display:none"></a>\n </button>`,condition:async()=>{let n=await SpinQuery.condition(()=>(unsafeWindow||window).cid,n=>n!==undefined);return n!==undefined},success:()=>{const n=document.querySelector("#danmaku-link");$("#download-danmaku").on("click",t=>{if(t.target!==n){const n=setTimeout(()=>document.querySelector("#download-danmaku>span").innerHTML="请稍侯...",200);i(n)}})}}}}})();

View File

@ -1 +1 @@
1.6.29
1.6.30

View File

@ -32,7 +32,7 @@
static parse(element)
{
const pData = element.getAttribute("p");
[time, type, fontSize, color, timeStamp, pool, userHash, rowId] = pData.split(",");
const [time, type, fontSize, color, timeStamp, pool, userHash, rowId] = pData.split(",");
const content = element.innerText;
return new XmlDanmaku({ content, time, type, fontSize, color, timeStamp, pool, userHash, rowId });
}
@ -43,7 +43,7 @@
{
this.xml = xml;
const document = new DOMParser().parseFromString(xml, "application/xml").documentElement;
this.danmakus = [...document.querySelectorAll("d[p]")].map(it => new XmlDanmaku(it));
this.danmakus = [...document.querySelectorAll("d[p]")].map(it => XmlDanmaku.parse(it));
}
}
class AssDanmaku extends Danmaku
@ -105,7 +105,7 @@ Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
this.horizontal = [];
this.vertical = [];
this.canvas = document.createElement("canvas");
this.context = canvas.getContext("2d");
this.context = this.canvas.getContext("2d");
// XML字体大小到实际大小的表
this.fontSizes = {
25: `36pt ${font}`,
@ -124,11 +124,13 @@ Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
}
getHorizonalTags(danmaku)
{
// TODO: place horizontal tags
return `\\pos(0, -999)`;
}
getVerticalTags(danmaku)
{
// TODO: place verizontal tags
return `\\pos(0, -999)`;
}
push(danmaku)
{

View File

@ -2,7 +2,8 @@
{
return (settings, resources) =>
{
const DanmakuInfo = resources.attributes.videoInfo.export.DanmakuInfo;
const { DanmakuInfo } = resources.import("videoInfo");
const { DanmakuConverter, XmlDanmakuDocument } = resources.import("danmakuConverter");
async function downloadDanmaku(timeout)
{
const title = document.title
@ -10,7 +11,19 @@
.replace("_番剧_bilibili_哔哩哔哩", "");
const danmaku = new DanmakuInfo((unsafeWindow || window).cid);
await danmaku.fetchInfo();
const blob = new Blob([danmaku.rawXML], {
const converter = new DanmakuConverter({
title,
font: "Micorosoft Yahei UI",
alpha: 0.6,
duration: 10,
blockTypes: [],
resolution: {
x: 1920,
y: 1080,
},
});
const assDocument = converter.convertToAssDocument(new XmlDanmakuDocument(danmaku.rawXML));
const blob = new Blob([assDocument.generateAss()], {
type: 'text/plain'
});
const url = URL.createObjectURL(blob);
@ -22,7 +35,7 @@
}
clearTimeout(timeout);
document.querySelector("#download-danmaku>span").innerHTML = "下载弹幕";
link.attr("download", `${title}.xml`).attr("href", url).get(0).click();
link.attr("download", `${title}.ass`).attr("href", url).get(0).click();
}
return {
widget: {