File: iframeschemehandler.cpp

package info (click to toggle)
goldendict-webengine 23.02.05-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 19,148 kB
  • sloc: cpp: 58,537; javascript: 9,942; ansic: 9,242; xml: 41; makefile: 15; sh: 9
file content (106 lines) | stat: -rw-r--r-- 3,861 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#include "iframeschemehandler.h"

#include <QTextCodec>

IframeSchemeHandler::IframeSchemeHandler(QObject * parent):QWebEngineUrlSchemeHandler(parent){

}
void IframeSchemeHandler::requestStarted(QWebEngineUrlRequestJob *requestJob)
{
  QUrl url = requestJob->requestUrl();

  // website dictionary iframe url
  url = QUrl( Utils::Url::queryItemValue( url, "url" ) );
  QNetworkRequest request;
  request.setUrl( url );
  request.setAttribute(QNetworkRequest::RedirectPolicyAttribute,QNetworkRequest::RedirectPolicy::NoLessSafeRedirectPolicy);

  QNetworkReply * reply = mgr.get( request );

  auto finishAction     = [ = ]() -> void
  {
    QByteArray contentType = "text/html";

    QBuffer * buffer = new QBuffer( requestJob );

    QByteArray replyData = reply->readAll();
    QString articleString;

    QString codecName;
    auto contentTypeV = reply->header(QNetworkRequest::ContentTypeHeader);
    if(contentTypeV.isValid())
    {
      auto _ct = contentTypeV.toString();
      auto index = _ct.indexOf("charset=");
      if(index>-1){
        codecName=_ct.mid(index+QString("charset=").size());
        qDebug()<<codecName;
      }
    }

    QTextCodec * codec = QTextCodec::codecForUtfText( replyData, QTextCodec::codecForName( codecName.toUtf8() ) );
    if(codec)
      articleString      = codec->toUnicode( replyData );
    else
      articleString = QString::fromUtf8(replyData);
    // Handle reply data
    // 404 response may have response body.
    if( reply->error() != QNetworkReply::NoError && articleString.isEmpty())
    {
      if(reply->error()==QNetworkReply::ContentNotFoundError){
        buffer->deleteLater();
        //work around to fix QTBUG-106573
        requestJob->redirect(url);
        return;
      }
      QString emptyHtml = QString( "<html><body>%1</body></html>" ).arg( reply->errorString() );
      buffer->setData( emptyHtml.toUtf8() );
      requestJob->reply( contentType, buffer );
      return;
    }

    // Change links from relative to absolute

    QString root = reply->url().scheme() + "://" + reply->url().host();
    QString base = root + reply->url().path();

    QRegularExpression baseTag( "<base\\s+.*?>",
                             QRegularExpression::CaseInsensitiveOption | QRegularExpression::DotMatchesEverythingOption );
    
    QString baseTagHtml = "<base href=\"" + base + "\">";

    QString depressionFocus ="<script type=\"application/javascript\"> HTMLElement.prototype.focus=function(){console.log(\"focus() has been disabled.\");}</script>"
                      "<script type=\"text/javascript\" src=\"qrc:///scripts/iframeResizer.contentWindow.min.js\"></script>"
                      "<script type=\"text/javascript\" src=\"qrc:///scripts/iframe-defer.js\"></script>";
    
    // remove existed base tag
    articleString.remove( baseTag ) ;

    QRegularExpression headTag( "<head\\b.*?>",
                                QRegularExpression::CaseInsensitiveOption
                                  | QRegularExpression::DotMatchesEverythingOption );
    auto match = headTag.match( articleString, 0 );
    if( match.hasMatch() )
    {
      articleString.insert( match.capturedEnd(), baseTagHtml );
      articleString.insert( match.capturedEnd(), depressionFocus );
    }
    else
    {
      // the html contain no head element
      // just insert at the beginning of the html ,and leave it at the mercy of browser(chrome webengine)
      articleString.insert( 0, baseTagHtml );
      articleString.insert( 0, depressionFocus );
    }

    if(codec)
      buffer->setData(codec->fromUnicode(articleString));
    else
      buffer->setData(articleString.toUtf8());

    requestJob->reply(contentType , buffer );
  };
  connect( reply, &QNetworkReply::finished, requestJob, finishAction );

  connect( requestJob, &QObject::destroyed, reply, &QObject::deleteLater );
}