File indexing completed on 2024-05-05 05:00:08

0001 /*
0002     SPDX-FileCopyrightText: 1996 Martin R. Jones
0003     SPDX-FileCopyrightText: 1998 Bernd Wuebben
0004 
0005     SPDX-FileCopyrightText: 1998 Torben Weis
0006     KControl port & modifications
0007 
0008     SPDX-FileCopyrightText: 1998 David Faure
0009     End of the KControl port, added 'kfmclient configure' call.
0010 
0011     SPDX-FileCopyrightText: 2000 Kalle Dalheimer
0012     New configuration scheme for JavaScript
0013 
0014     SPDX-FileCopyrightText: 2000 Daniel Molkentin
0015     Major cleanup & Java/JS settings split
0016 
0017     SPDX-FileCopyrightText: 2002-2003 Leo Savernik
0018     Big changes to accommodate per-domain settings
0019 
0020 */
0021 
0022 // Own
0023 #include "jsopts.h"
0024 
0025 // Qt
0026 #include <QTreeWidget>
0027 #include <QHBoxLayout>
0028 #include <QVBoxLayout>
0029 // KDE
0030 #include <kconfig.h>
0031 #include <kconfiggroup.h>
0032 #include <kurlrequester.h>
0033 #include <KLocalizedString>
0034 
0035 // Local
0036 #include "htmlopts.h"
0037 #include "policydlg.h"
0038 #include <htmlextension.h>
0039 
0040 // == class KJavaScriptOptions =====
0041 KJavaScriptOptions::KJavaScriptOptions(KSharedConfig::Ptr config, const QString &group, QWidget *parent) :
0042     KCModule(parent),
0043     _removeJavaScriptDomainAdvice(false),
0044     m_pConfig(config), m_groupname(group),
0045     js_global_policies(config, group, true, QString()),
0046     _removeECMADomainSettings(false)
0047 {
0048     QVBoxLayout *toplevel = new QVBoxLayout(widget());
0049 
0050     enableJavaScriptGloballyCB = new QCheckBox(i18n("Ena&ble JavaScript globally"));
0051     enableJavaScriptGloballyCB->setToolTip(i18n("Enables the execution of scripts written in ECMA-Script "
0052             "(also known as JavaScript) that can be contained in HTML pages. "
0053             "Note that, as with any browser, enabling scripting languages can be a security problem."));
0054     connect(enableJavaScriptGloballyCB, &QAbstractButton::clicked, this, &KJavaScriptOptions::markAsChanged);
0055     connect(enableJavaScriptGloballyCB, &QAbstractButton::clicked, this, &KJavaScriptOptions::slotChangeJSEnabled);
0056     toplevel->addWidget(enableJavaScriptGloballyCB);
0057 
0058     // the global checkbox
0059     QGroupBox *globalGB = new QGroupBox(i18n("Debugging"));
0060     QHBoxLayout *hbox = new QHBoxLayout(globalGB);
0061     toplevel->addWidget(globalGB);
0062 
0063     jsDebugWindow = new QCheckBox(i18n("Enable debu&gger"));
0064     jsDebugWindow->setToolTip(i18n("Enables builtin JavaScript debugger."));
0065     connect(jsDebugWindow, &QAbstractButton::clicked, this, &KJavaScriptOptions::markAsChanged);
0066     hbox->addWidget(jsDebugWindow);
0067 
0068     reportErrorsCB = new QCheckBox(i18n("Report &errors"));
0069     reportErrorsCB->setToolTip(i18n("Enables the reporting of errors that occur when JavaScript "
0070                                       "code is executed."));
0071     connect(reportErrorsCB, &QAbstractButton::clicked, this, &KJavaScriptOptions::markAsChanged);
0072     hbox->addWidget(reportErrorsCB);
0073 
0074     // the domain-specific listview
0075     domainSpecific = new JSDomainListView(m_pConfig, m_groupname, this, widget());
0076 #if QT_VERSION_MAJOR < 6
0077     connect(domainSpecific, &DomainListView::changed, this, &KJavaScriptOptions::markAsChanged);
0078 #else
0079     connect(domainSpecific, &DomainListView::changed, this, [this](bool changed){setNeedsSave(changed);});
0080 #endif
0081     toplevel->addWidget(domainSpecific, 2);
0082 
0083     domainSpecific->setToolTip(i18n("Here you can set specific JavaScript policies for any particular "
0084                                       "host or domain. To add a new policy, simply click the <i>New...</i> "
0085                                       "button and supply the necessary information requested by the "
0086                                       "dialog box. To change an existing policy, click on the <i>Change...</i> "
0087                                       "button and choose the new policy from the policy dialog box. Clicking "
0088                                       "on the <i>Delete</i> button will remove the selected policy causing the default "
0089                                       "policy setting to be used for that domain. The <i>Import</i> and <i>Export</i> "
0090                                       "button allows you to easily share your policies with other people by allowing "
0091                                       "you to save and retrieve them from a zipped file."));
0092 
0093     QString wtstr = i18n("<p>This box contains the domains and hosts you have set "
0094                          "a specific JavaScript policy for. This policy will be used "
0095                          "instead of the default policy for enabling or disabling JavaScript on pages sent by these "
0096                          "domains or hosts.</p><p>Select a policy and use the controls on "
0097                          "the right to modify it.</p>");
0098     domainSpecific->listView()->setToolTip(wtstr);
0099 
0100     domainSpecific->importButton()->setToolTip(i18n("Click this button to choose the file that contains "
0101             "the JavaScript policies. These policies will be merged "
0102             "with the existing ones. Duplicate entries are ignored."));
0103     domainSpecific->exportButton()->setToolTip(i18n("Click this button to save the JavaScript policy to a zipped "
0104             "file. The file, named <b>javascript_policy.tgz</b>, will be "
0105             "saved to a location of your choice."));
0106 
0107     // the frame containing the JavaScript policies settings
0108     js_policies_frame = new JSPoliciesFrame(&js_global_policies,
0109                                             i18n("Global JavaScript Policies"), widget());
0110     toplevel->addWidget(js_policies_frame);
0111 #if QT_VERSION_MAJOR < 6
0112     connect(js_policies_frame, &JSPoliciesFrame::changed, this, &KJavaScriptOptions::markAsChanged);
0113 #else
0114     connect(js_policies_frame, &JSPoliciesFrame::changed, this, [this](){setNeedsSave(true);});
0115 #endif
0116 
0117 }
0118 
0119 void KJavaScriptOptions::load()
0120 {
0121     // *** load ***
0122     KConfigGroup cg(m_pConfig, m_groupname);
0123     if (cg.hasKey("ECMADomains")) {
0124         domainSpecific->initialize(cg.readEntry("ECMADomains", QStringList()));
0125     } else if (cg.hasKey("ECMADomainSettings")) {
0126         domainSpecific->updateDomainListLegacy(cg.readEntry("ECMADomainSettings", QStringList()));
0127         _removeECMADomainSettings = true;
0128     } else {
0129         domainSpecific->updateDomainListLegacy(cg.readEntry("JavaScriptDomainAdvice", QStringList()));
0130         _removeJavaScriptDomainAdvice = true;
0131     }
0132 
0133     // *** apply to GUI ***
0134     js_policies_frame->load();
0135     enableJavaScriptGloballyCB->setChecked(
0136         js_global_policies.isFeatureEnabled());
0137     reportErrorsCB->setChecked(cg.readEntry("ReportJavaScriptErrors", false));
0138     jsDebugWindow->setChecked(cg.readEntry("EnableJavaScriptDebug", false));
0139 //    js_popup->setButton( m_pConfig->readUnsignedNumEntry("WindowOpenPolicy", 0) );
0140     KCModule::load();
0141 }
0142 
0143 void KJavaScriptOptions::defaults()
0144 {
0145     js_policies_frame->defaults();
0146     enableJavaScriptGloballyCB->setChecked(
0147         js_global_policies.isFeatureEnabled());
0148     reportErrorsCB->setChecked(false);
0149     jsDebugWindow->setChecked(false);
0150     setNeedsSave(true);
0151 
0152 #if QT_VERSION_MAJOR > 5
0153     setRepresentsDefaults(true);
0154 #endif
0155 }
0156 
0157 void KJavaScriptOptions::save()
0158 {
0159     KConfigGroup cg(m_pConfig, m_groupname);
0160     cg.writeEntry("ReportJavaScriptErrors", reportErrorsCB->isChecked());
0161     cg.writeEntry("EnableJavaScriptDebug", jsDebugWindow->isChecked());
0162 
0163     domainSpecific->save(m_groupname, QStringLiteral("ECMADomains"));
0164     js_policies_frame->save();
0165 
0166     if (_removeECMADomainSettings) {
0167         cg.deleteEntry("ECMADomainSettings");
0168         _removeECMADomainSettings = false;
0169     }
0170 
0171     KCModule::save();
0172 }
0173 
0174 void KJavaScriptOptions::slotChangeJSEnabled()
0175 {
0176     js_global_policies.setFeatureEnabled(enableJavaScriptGloballyCB->isChecked());
0177 }
0178 
0179 // == class JSDomainListView =====
0180 
0181 JSDomainListView::JSDomainListView(KSharedConfig::Ptr config, const QString &group,
0182                                    KJavaScriptOptions *options, QWidget *parent)
0183     : DomainListView(config, i18nc("@title:group", "Do&main-Specific"), parent),
0184       group(group), options(options)
0185 {
0186 }
0187 
0188 JSDomainListView::~JSDomainListView()
0189 {
0190 }
0191 
0192 void JSDomainListView::updateDomainListLegacy(const QStringList &domainConfig)
0193 {
0194     domainSpecificLV->clear();
0195     JSPolicies pol(config, group, false);
0196     pol.defaults();
0197     for (QStringList::ConstIterator it = domainConfig.begin();
0198             it != domainConfig.end(); ++it) {
0199         QString domain;
0200         HtmlSettingsInterface::JavaScriptAdvice javaAdvice;
0201         HtmlSettingsInterface::JavaScriptAdvice javaScriptAdvice;
0202         HtmlSettingsInterface::splitDomainAdvice(*it, domain, javaAdvice, javaScriptAdvice);
0203         if (javaScriptAdvice != HtmlSettingsInterface::JavaScriptDunno) {
0204             QTreeWidgetItem *index =
0205                 new QTreeWidgetItem(domainSpecificLV, QStringList() << domain <<
0206                                     i18n(HtmlSettingsInterface::javascriptAdviceToText(javaScriptAdvice)));
0207 
0208             pol.setDomain(domain);
0209             pol.setFeatureEnabled(javaScriptAdvice != HtmlSettingsInterface::JavaScriptReject);
0210             domainPolicies[index] = new JSPolicies(pol);
0211         }
0212     }
0213 }
0214 
0215 void JSDomainListView::setupPolicyDlg(PushButton trigger, PolicyDialog &pDlg,
0216                                       Policies *pol)
0217 {
0218     JSPolicies *jspol = static_cast<JSPolicies *>(pol);
0219     QString caption;
0220     switch (trigger) {
0221     case AddButton:
0222         caption = i18nc("@title:window", "New JavaScript Policy");
0223         jspol->setFeatureEnabled(!options->enableJavaScriptGloballyCB->isChecked());
0224         break;
0225     case ChangeButton: caption = i18nc("@title:window", "Change JavaScript Policy"); break;
0226     default:; // inhibit gcc warning
0227     }/*end switch*/
0228     pDlg.setWindowTitle(caption);
0229     pDlg.setFeatureEnabledLabel(i18n("JavaScript policy:"));
0230     pDlg.setFeatureEnabledWhatsThis(i18n("Select a JavaScript policy for "
0231                                          "the above host or domain."));
0232     JSPoliciesFrame *panel = new JSPoliciesFrame(jspol, i18n("Domain-Specific "
0233             "JavaScript Policies"), &pDlg);
0234     panel->refresh();
0235     pDlg.addPolicyPanel(panel);
0236     pDlg.refresh();
0237 }
0238 
0239 JSPolicies *JSDomainListView::createPolicies()
0240 {
0241     return new JSPolicies(config, group, false);
0242 }
0243 
0244 JSPolicies *JSDomainListView::copyPolicies(Policies *pol)
0245 {
0246     return new JSPolicies(*static_cast<JSPolicies *>(pol));
0247 }
0248