mirror of
https://github.com/torappinfo/uweb.git
synced 2024-08-14 23:54:59 +00:00
418 lines
14 KiB
JavaScript
418 lines
14 KiB
JavaScript
/**
|
||
(id,元素的tag,父元素,创建时顺便添加的class:可以多个)
|
||
获取一个指定id的元素如果没用就在服元素创建这个元素
|
||
*/
|
||
function getByID(id, tag, father) {
|
||
let t = document.getElementById(id);
|
||
if (!t) {
|
||
t = document.createElement(tag);
|
||
t.id = id;
|
||
for (let i = 3; i < arguments.length; i++) {
|
||
if (arguments[i]) {
|
||
t.classList.add(arguments[i]);
|
||
}
|
||
}
|
||
father.appendChild(t);
|
||
}
|
||
return t;
|
||
}
|
||
function getByClass(className, tag, father) {
|
||
let t = father.getElementsByClassName(className)[0];
|
||
if (!t) {
|
||
t = document.createElement(tag);
|
||
t.classList.add(className);
|
||
for (let i = 3; i < arguments.length; i++) {
|
||
if (arguments[i]) {
|
||
t.classList.add(arguments[i]);
|
||
}
|
||
}
|
||
father.appendChild(t);
|
||
}
|
||
return t;
|
||
}
|
||
|
||
function test(test) {
|
||
porserArguments(test.arguments);
|
||
}
|
||
|
||
var throttling = {
|
||
"maxNumUserMessagesInConversation": 0,
|
||
"numUserMessagesInConversation": 0
|
||
};
|
||
|
||
//解析type2的item
|
||
function porserType2Item(item){
|
||
let chatDiv = document.getElementById('chat');
|
||
if(item.result){
|
||
let result = item.result;
|
||
if(result.value=='Success'){
|
||
|
||
}else if (result.value == 'Throttled') {
|
||
addError(result.message);
|
||
addError('24消息请求数达到了限制!');
|
||
}else{
|
||
addError(result.message);
|
||
addError('发生未知错误!');
|
||
}
|
||
}
|
||
if (item.throttling) {
|
||
throttling = item.throttling;
|
||
}
|
||
if (item.messages) {
|
||
let nextFather = getByID(item.requestId, 'div', chatDiv, 'bing');
|
||
porserMessages(item.messages, nextFather);
|
||
}
|
||
|
||
}
|
||
/**
|
||
* 解析arguments
|
||
* 解析聊天消息,将消息添加到页面
|
||
* **/
|
||
function porserArguments(argumentss) {
|
||
for (let i = 0; i < argumentss.length; i++) {
|
||
porserType2Item(argumentss[i]);
|
||
}
|
||
}
|
||
|
||
/*
|
||
解析messages
|
||
*/
|
||
function porserMessages(messages, father) {
|
||
for (let i = 0; i < messages.length; i++) {
|
||
let message = messages[i];
|
||
if(message.author=='user'){
|
||
continue;//不解析用户的消息
|
||
}
|
||
|
||
//解析adaptiveCards 也就是聊天消息部分 下面类型的都是带有adaptiveCards的
|
||
if (!message.messageType && message.adaptiveCards) {//如果是正常的聊天
|
||
let adaptiveCardsFatherDIV = getByID(message.messageId, 'div', father, 'adaptiveCardsFatherDIV');
|
||
porserAdaptiveCards(message.adaptiveCards, adaptiveCardsFatherDIV);
|
||
|
||
//解析sourceAttributions 也就是引用链接部分
|
||
if (message.sourceAttributions) {
|
||
if (message.sourceAttributions.length > 0) {
|
||
let sourceAttributionsDIV = getByID(message.messageId + 'sourceAttributions', 'div', father, 'sourceAttributions');
|
||
porserSourceAttributions(message.sourceAttributions, sourceAttributionsDIV);
|
||
}
|
||
}
|
||
//解析suggestedResponses 建议发送的消息,聊天建议
|
||
if (message.suggestedResponses) {
|
||
porserSuggestedResponses(message.suggestedResponses);
|
||
}
|
||
|
||
} else if (message.messageType == 'InternalSearchQuery') { //如果是收索消息
|
||
let div = getByID(message.messageId, 'div', father, 'InternalSearchQuery');
|
||
porserLineTextBlocks(message.text, div);
|
||
|
||
} else if (message.messageType == 'InternalLoaderMessage') { //如果是加载消息
|
||
let div = getByID(message.messageId, 'div', father, 'InternalLoaderMessage');
|
||
porserLineTextBlocks(message.text, div);
|
||
|
||
} else if (message.messageType == 'GenerateContentQuery') {//如果是生成内容查询
|
||
let div = getByID(message.messageId, 'div', father, 'GenerateContentQuery');
|
||
generateContentQuery(message, div);
|
||
|
||
}else if (message.messageType == 'RenderCardRequest'){//渲染卡片请求,目前不知道有什么用
|
||
renderCardRequest(message, father);
|
||
|
||
}else if(message.messageType == 'Disengaged'){
|
||
let div = getByID(message.messageId, 'div', chat, 'error');
|
||
div.innerHTML = `
|
||
${message.hiddenText}<br>聊天中断!试试开始新主题?
|
||
`;
|
||
|
||
}else if(message.contentOrigin == 'TurnLimiter'){
|
||
addError(message.text);
|
||
addError('聊天被限制了,试试开始新主题?');
|
||
|
||
} else {
|
||
console.log('发现一个另类message', JSON.stringify(message));
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
/*
|
||
解析渲染卡片请求,暂时不知道如何解析这个请求,就先判断里面有没有内容吧!没有就不显示。
|
||
*/
|
||
function renderCardRequest(message,father){
|
||
if(father[message.messageId+'renderCardRequest']){//防止解析多次
|
||
return;
|
||
}
|
||
father[message.messageId+'renderCardRequest'] = true;
|
||
|
||
let url = 'https://www.bing.com/search?'
|
||
let theUrls = new URLSearchParams();
|
||
theUrls.append("showselans",1);
|
||
theUrls.append("q",message.text);
|
||
theUrls.append("iframeid",message.messageId);
|
||
let src = url+theUrls.toString();
|
||
|
||
fetch(src).then(async (ret)=>{
|
||
let html = await ret.text();
|
||
// b_poleContent pc设备 || b_ans b_imgans 移动设备
|
||
if(html.indexOf('class="b_poleContent"')>=0 || html.indexOf('class="b_ans')>=0){
|
||
let div = getByID(message.messageId, 'div', father, 'RenderCardRequest');
|
||
div.innerHTML = `<iframe role="presentation" src="${src}"></iframe>`;
|
||
}
|
||
});
|
||
}
|
||
|
||
|
||
/*
|
||
解析generateContentQuery生成内容查询,目前是只有图片
|
||
*/
|
||
function generateContentQuery(message, father) {
|
||
if(message.contentType=="IMAGE"){
|
||
if(father.runed){//防止生成多次
|
||
return;
|
||
}
|
||
father.runed = true;
|
||
generateContentQueryImg(message, father);
|
||
}else{
|
||
console.log('发现一个另类generateContentQuery', JSON.stringify(message));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 解析图片生成目前是只有图片
|
||
*/
|
||
function generateContentQueryImg(message, father){
|
||
getMagicUrl().then(async magicUrl => {
|
||
if (!magicUrl) {
|
||
addError("魔法链接不正确!无法加载图片");
|
||
return;
|
||
}
|
||
if (!expUrl.test(magicUrl)) {
|
||
addError("魔法链接不正确!无法加载图片")
|
||
return;
|
||
}
|
||
let theUrls = new URLSearchParams();
|
||
theUrls.append('re', '1');
|
||
theUrls.append('showselective', '1');
|
||
theUrls.append('sude', '1');
|
||
theUrls.append('kseed', '7500');
|
||
theUrls.append('SFX', '2');
|
||
theUrls.append('q', message.text);
|
||
theUrls.append('iframeid', message.requestId);
|
||
let theUrl = URLTrue(magicUrl,"images/create?") + theUrls.toString();
|
||
|
||
try{
|
||
father.innerHTML = `正在生成${message.text}的图片.`;
|
||
let html = (await (await fetch(theUrl)).text());
|
||
|
||
//如果有错误就输出错误
|
||
let urr = new RegExp('class="gil_err_mt">([^<>]*)</div>').exec(html);
|
||
if(urr && urr[1]){
|
||
father.innerHTML = `<h3>${urr[1]}</h3>`
|
||
urr = new RegExp('class="gil_err_sbt">(([^<>]*<(a|div)[^<>]*>[^<>]*</(a|div)>[^<>]*)*)</div>').exec(html);
|
||
if(urr && urr[1]){
|
||
father.innerHTML = father.innerHTML+`<p>${urr[1]}</p>`;
|
||
}
|
||
return;
|
||
}
|
||
|
||
//如果没错误就匹配链接获取图片
|
||
urr = new RegExp('"/(images/create/async/results/(\\S*))"').exec(html);
|
||
if(!urr || !urr[1]){
|
||
console.log(html);
|
||
addError("请求图片返回不正确的页面,无法加载图片。");
|
||
return;
|
||
}
|
||
let ur = urr[1];
|
||
ur = ur.replaceAll('&','&');
|
||
let imgPageHtmlUrl = URLTrue(magicUrl,ur);
|
||
let count = 0;
|
||
let run = async ()=>{
|
||
father.innerHTML = `正在生成${message.text}的图片.${count}`;
|
||
if(count>20){
|
||
father.innerHTML = "请求图片超时!";
|
||
return;
|
||
}
|
||
count++;
|
||
let imgPageHtml;
|
||
try{
|
||
imgPageHtml = (await (await fetch(imgPageHtmlUrl)).text());
|
||
}catch(e){
|
||
console.error(e);
|
||
}
|
||
if(!imgPageHtml){
|
||
setTimeout(run,3000);
|
||
return;
|
||
}
|
||
|
||
father.innerHTML = '';
|
||
let theUrls = new URLSearchParams();
|
||
theUrls.append('createmessage',message.text);
|
||
let a = document.createElement("a");
|
||
father.appendChild(a);
|
||
//用正则找全部图片
|
||
let allSrc = imgPageHtml.matchAll(/<img[^<>]*src="([^"]*)"[^<>]*>/g);
|
||
let src = undefined;
|
||
let ok = false;
|
||
while(!(src=allSrc.next()).done){
|
||
ok =true;
|
||
theUrls.append('imgs',src.value[1].split('?')[0]);
|
||
let img = document.createElement("img");
|
||
img.src = src.value[1];
|
||
a.appendChild(img);
|
||
}
|
||
if(ok){
|
||
a.target = '_blank';
|
||
a.href = '../GeneratePicture/img.html?'+theUrls.toString();
|
||
}else{
|
||
father.innerHTML = "服务器未正常返回图片!";
|
||
}
|
||
}
|
||
setTimeout(run,3000);
|
||
|
||
}catch(e){
|
||
console.error(e);
|
||
addError("请求图片失败:"+e);
|
||
}
|
||
});
|
||
}
|
||
|
||
/*
|
||
解析adaptiveCards 聊天消息部分
|
||
*/
|
||
function porserAdaptiveCards(adaptiveCards, father) {
|
||
for (let i = 0; i < adaptiveCards.length; i++) {
|
||
let adaptiveCard = adaptiveCards[i];
|
||
if (adaptiveCard.type == 'AdaptiveCard') {
|
||
porserbody(adaptiveCard.body, father);
|
||
} else {
|
||
console.log('发现一个不是AdaptiveCard的adaptiveCard', JSON.stringify(adaptiveCard));
|
||
}
|
||
}
|
||
|
||
}
|
||
/**
|
||
解析body adaptiveCards[].body这个部分
|
||
*/
|
||
function porserbody(bodys, father) {
|
||
for (let i = 0; i < bodys.length; i++) {
|
||
let body = bodys[i];
|
||
if (body.type == 'TextBlock') {
|
||
porserTextBlock(body, father);
|
||
}else {
|
||
console.log('发现一个不是TextBlock的body', JSON.stringify(body));
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
补全代码块,如果文本中有~~~开头却没有~~~结束则在最后补一个~~~,防止内容生成时闪烁
|
||
*/
|
||
function completeCodeBlock(makerdown){
|
||
let to = function(regA,regB,add,makerdown){
|
||
let falst = true;
|
||
let arrs = makerdown.split('\n');
|
||
for(let i=0;i<=arrs.length;i++){
|
||
if(falst){
|
||
if(regA.test(arrs[i])){
|
||
falst = false;
|
||
}
|
||
}else{
|
||
if(regB.test(arrs[i])){
|
||
falst = true;
|
||
}
|
||
}
|
||
}
|
||
if(!falst){
|
||
makerdown = makerdown+add;
|
||
}
|
||
return makerdown;
|
||
}
|
||
let out = to(
|
||
new RegExp('^~~~.*$'),
|
||
new RegExp('^~~~( *)$'),
|
||
'\n~~~',
|
||
to(
|
||
new RegExp('^```.*$'),
|
||
new RegExp('^```( *)$'),
|
||
'\n```',
|
||
makerdown
|
||
)
|
||
);
|
||
// console.log(out);
|
||
return out;
|
||
}
|
||
|
||
renderMathInElementOptions ={
|
||
delimiters: [
|
||
{left: "$$", right: "$$", display: true},
|
||
{left: '$', right: '$', display: false},
|
||
{left: "\\(", right: "\\)", display: false},
|
||
{left: "\\begin{equation}", right: "\\end{equation}", display: true},
|
||
{left: "\\begin{align}", right: "\\end{align}", display: true},
|
||
{left: "\\begin{alignat}", right: "\\end{alignat}", display: true},
|
||
{left: "\\begin{gather}", right: "\\end{gather}", display: true},
|
||
{left: "\\begin{CD}", right: "\\end{CD}", display: true},
|
||
{left: "\\[", right: "\\]", display: true}
|
||
],
|
||
throwOnError: false
|
||
}
|
||
/*
|
||
解析TextBlock body.type==TextBlock
|
||
*/
|
||
function porserTextBlock(body, father) {
|
||
if (!body.size) {
|
||
let div = getByClass('textBlock', 'div', father, 'markdown-body');
|
||
div.innerHTML = marked.marked(completeCodeBlock(body.text));
|
||
renderMathInElement(div,renderMathInElementOptions);
|
||
let aaas = div.getElementsByTagName('a');
|
||
//将超链接在新页面打开
|
||
for(let i=0;i<aaas.length;i++){
|
||
aaas[i].target = '_blank';
|
||
}
|
||
//如果是注释则加上上标样式
|
||
for(let i=0;i<aaas.length;i++){
|
||
let reg = new RegExp('^\\^(\\d+)\\^$');
|
||
if(reg.test(aaas[i].innerHTML)){
|
||
aaas[i].innerHTML = aaas[i].innerHTML.replace(reg,'$1');
|
||
aaas[i].classList.add('superscript');
|
||
}
|
||
}
|
||
|
||
|
||
let nxdiv = getByClass('throttling', 'div', father);
|
||
nxdiv.innerHTML = `${throttling.numUserMessagesInConversation} / ${throttling.maxNumUserMessagesInConversation}`;
|
||
} else if (body.size == 'small') {
|
||
//原本bing官网的small并没有输出
|
||
}
|
||
}
|
||
/*
|
||
添加单行简单文本
|
||
*/
|
||
function porserLineTextBlocks(inline, father) {
|
||
father.innerHTML = `<p>${inline}</p>`;
|
||
}
|
||
|
||
/***
|
||
解析sourceAttributions 聊天消息引用链接部分
|
||
*/
|
||
function porserSourceAttributions(sourceAttributions, father) {
|
||
let html = '';
|
||
for (let i = 0; i < sourceAttributions.length; i++) {
|
||
let sourceAttribution = sourceAttributions[i];
|
||
html = html + `<a target="_blank" href="${sourceAttribution.seeMoreUrl}">${sourceAttribution.providerDisplayName}</a>`;
|
||
}
|
||
father.innerHTML = html;
|
||
}
|
||
/***
|
||
解析suggestedResponses 建议发送的消息,聊天建议
|
||
*/
|
||
function porserSuggestedResponses(suggestedResponses) {
|
||
var searchSuggestions = document.getElementById('SearchSuggestions');
|
||
searchSuggestions.innerHTML = '';
|
||
for (let i = 0; i < suggestedResponses.length; i++) {
|
||
let a = document.createElement('a');
|
||
a.innerHTML = suggestedResponses[i].text;
|
||
a.onclick = (event)=>{send(event.target.innerHTML);}
|
||
searchSuggestions.appendChild(a);
|
||
}
|
||
}
|