diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index db1bc88e..61dbac1a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,9 +9,9 @@ Compiler default is C++11 (eventually C99 for C parts) Here's the software you'll need before you start building (mandatory in bold) - **Standard C++ Library** (>= C++11) -- **Qt5** (>= 5.5) -- **Boost** (>= 1.79) -- CMake (>= 3.1.0) or QMake (>= 5.5) +- **Qt6** (>= 6.0) +- **Boost** (>= 1.77) +- CMake (>= 3.1.0) - GNU C++ Compiler (gcc/g++ >= 5.3.0) or Microsoft Visual Studio (>= 2017) @@ -35,47 +35,34 @@ Follow official instructions of each tool. sudo apt install git sudo apt install git-gui -#### Install Qt5 - - sudo apt install qt5-default - whereis qt5 - $ qt5: /usr/lib/x86_64-linux-gnu/qt5 /usr/lib/qt5 /usr/share/qt5 - -#### Install Qt5 IDE (QtCreator) and SDK - - sudo apt install qtcreator - -Or follow [instructions](https://wiki.qt.io/Install_Qt_5_on_Ubuntu -"https://wiki.qt.io/Install_Qt_5_on_Ubuntu"). +#### Install Qt and QtCreator sudo apt install libfontconfig1 sudo apt install mesa-common-dev sudo apt install libglu1-mesa-dev - wget https://download.qt.io/official_releases/qt/5.14/5.14.2/qt-opensource-linux-x64-5.14.2.run + wget https://download.qt.io/official_releases/qt/6.0/6.0.0/qt-opensource-linux-x64-6.0.0.run - chmod +x qt-opensource-linux-x64-5.14.2.run - sudo ./qt-opensource-linux-x64-5.14.2.run + chmod +x qt-opensource-linux-x64-6.0.0.run + sudo ./qt-opensource-linux-x64-6.0.0.run -Select a dummy proxy, to skip the login page. - -It install the tools (QtCreator 4.11.1) and SDK on `/opt/Qt5.14.2/`. +It install the tools (QtCreator) and SDK on `/opt/Qt/`. Run it: - /opt/Qt5.14.2/Tools/QtCreator/bin/qtcreator + /opt/Qt/Tools/QtCreator/bin/qtcreator Create a shortcut (Ubuntu, KDE...): mkdir ~/.local/share/applications - cp /opt/Qt5.14.2/Tools/QtCreator/share/applications/org.qt-project.qtcreator.desktop ~/.local/share/applications + cp /opt/Qt/Tools/QtCreator/share/applications/org.qt-project.qtcreator.desktop ~/.local/share/applications #### Install Boost C++ Library - wget https://boostorg.jfrog.io/artifactory/main/release/1.79.0/source/boost_1_79_0.tar.bz2 - tar -zxvf boost_1_79_0.tar.gz + wget https://boostorg.jfrog.io/artifactory/main/release/1.77.0/source/boost_1_77_0.tar.bz2 + tar -zxvf boost_1_77_0.tar.gz Or download and unzip manually an older version of [Boost](https://www.boost.org/users/history/). @@ -96,13 +83,6 @@ Setup the *Boost* library: - For CMake: Add variable `BOOST_ROOT_DIR` (type: PATH) with the path to Boost PS: or configure `Boost_INCLUDE_DIR` - -- For QMake: - Open `./3rd/boost/boost.pri` - and add path manually to variable `BOOST_ROOT_DIR`, - that gives the following line: - `BOOST_ROOT_DIR = /Boost/boost_1_79_0` - Build the application: diff --git a/README.md b/README.md index 2b5aa147..e1812a44 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ ![GitHub All Releases](https://img.shields.io/github/downloads/setvisible/ArrowDL/total?style=for-the-badge) ![Chrome Web Store Users](https://img.shields.io/chrome-web-store/users/modofbhnhlagjmejdbalnijgncppjeio?style=for-the-badge&label=users&logo=google&logoColor=white) -[![Mozilla Add-on](https://img.shields.io/amo/users/down-right-now?style=for-the-badge&label=users&logo=mozilla&logoColor=white)](https://addons.mozilla.org/firefox/addon/down-right-now/ "Mozilla Firefox Add-on") -[![Chocolatey](https://img.shields.io/chocolatey/dt/downzemall?style=for-the-badge&label=chocolatey%20package)](https://community.chocolatey.org/packages/downzemall) +[![Mozilla Add-on](https://img.shields.io/amo/users/arrow-dl?style=for-the-badge&label=users&logo=mozilla&logoColor=white)](https://addons.mozilla.org/firefox/addon/arrow-dl/ "Mozilla Firefox Add-on") +[![Chocolatey](https://img.shields.io/chocolatey/dt/arrowdl?style=for-the-badge&label=chocolatey%20package)](https://community.chocolatey.org/packages/arrowdl) ![X (formerly Twitter) Follow](https://img.shields.io/twitter/follow/ArrowDLApp?style=for-the-badge&logo=x&label=Follow&logoColor=white) @@ -66,7 +66,7 @@ More screenshots on the [Gallery](https://www.arrow-dl.com/ArrowDL/category/scre Go to [Download](https://www.arrow-dl.com/ArrowDL/category/download.html) page to install the application for your operating system. -Rem: *Native-Client* is an alternative to *DownRightNow*. Click [here](NativeClient.md "NativeClient.md") for more information. +Rem: *Native-Client* is an alternative to *ArrowDL*. Click [here](NativeClient.md "NativeClient.md") for more information. On Windows, you can also use the [Chocolatey package](https://community.chocolatey.org/packages/arrowdl) to handle the installation/updates: ```powershell @@ -147,6 +147,6 @@ Click [here](CONTRIBUTING.md "CONTRIBUTING.md") for build instructions and tips. The code is released under the GNU [Lesser General Public License (LGPL)](LICENSE "LICENSE"). -Use it at your own risk. None of the authors, contributors, or anyone else connected with this ArrowDL software and the DownRightNow web-extension, in any way whatsoever, can be responsible for your use of the application. +Use it at your own risk. None of the authors, contributors, or anyone else connected with this ArrowDL software and the ArrowDL add-ons, in any way whatsoever, can be responsible for your use of the application. Please be aware that this site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. diff --git a/TRANSLATORS.md b/TRANSLATORS.md index 4b9ec7f3..c5843449 100644 --- a/TRANSLATORS.md +++ b/TRANSLATORS.md @@ -104,7 +104,7 @@ Note that unfinished translations may also be deployed from time to time. ### Offline Translation This method requires: -- [Qt Framework](https://www.qt.io/) (Qt5.14 at the time of writing these lines) +- [Qt Framework](https://www.qt.io/) - local clone of the repository These files are the translations source (*.ts): @@ -189,7 +189,7 @@ It generates *.qm (compiled translation files) to be deployed with the applicati ## References -- [Internationalization with Qt](https://doc.qt.io/qt-5/internationalization.html) -- [Qt Linguist Manual](https://doc.qt.io/qt-5/qtlinguist-index.html) +- [Internationalization with Qt](https://doc.qt.io/qt-6/internationalization.html) +- [Qt Linguist Manual](https://doc.qt.io/qt-6/qtlinguist-index.html) - [Transifex Documentation](https://docs.transifex.com/formats/qt-ts) - [Transifex TX Client](https://docs.transifex.com/transifex-github-integrations/github-tx-client) diff --git a/TROUBLESHOOTING.md b/TROUBLESHOOTING.md index cb7d19b3..36f30405 100644 --- a/TROUBLESHOOTING.md +++ b/TROUBLESHOOTING.md @@ -1,5 +1,7 @@ # Troubleshooting +**This page is frozen. Please use Github > Issues instead.** + ## Security Restriction ### Binary signature diff --git a/docs/_posts/2019-11-16-introducing-arrowdl.md b/docs/_posts/2019-11-16-introducing-arrowdl.md index c142d230..632c98b5 100644 --- a/docs/_posts/2019-11-16-introducing-arrowdl.md +++ b/docs/_posts/2019-11-16-introducing-arrowdl.md @@ -14,7 +14,7 @@ excerpt_separator: It aims to work with latest versions of Mozilla Firefox (powered by *WebExtensions*), and other web browsers (Chrome, Edge, Safari...). -*ArrowDL* is written in C++ and based on the [Qt5](https://www.qt.io/ "https://www.qt.io/") framework. +*ArrowDL* is written in C++ and based on the [Qt](https://www.qt.io/ "https://www.qt.io/") framework. ## Goals diff --git a/docs/_posts/2019-12-05-web-extension.md b/docs/_posts/2019-12-05-web-extension.md index 547b297a..105236be 100644 --- a/docs/_posts/2019-12-05-web-extension.md +++ b/docs/_posts/2019-12-05-web-extension.md @@ -17,20 +17,18 @@ excerpt_separator: *ArrowDL* is now compatible with Chrome and Firefox! -The add-on *DownRightNow* sends data from your web browser to the standalone application *ArrowDL*. +The *ArrowDL* add-on sends data from your web browser to the *ArrowDL* application. -### Install the Web Browser Add-on (WebExtensions) +### Install the Add-on | ![logo](/ArrowDL/assets/images/firefox.png) | ![logo](/ArrowDL/assets/images/chrome.png) | |-----------------------------------|----------------------------------| -| Click here to intall [DownRightNow for Mozilla Firefox](https://addons.mozilla.org/en-US/firefox/addon/down-right-now/ "https://addons.mozilla.org/en-US/firefox/addon/down-right-now/") | Click here to intall [DownRightNow for Google Chrome](https://chrome.google.com/webstore/detail/down-right-now/modofbhnhlagjmejdbalnijgncppjeio "https://chrome.google.com/webstore/detail/down-right-now/modofbhnhlagjmejdbalnijgncppjeio") | +| Click here to intall [ArrowDL for Mozilla Firefox](https://addons.mozilla.org/en-US/firefox/addon/arrow-dl/ "https://addons.mozilla.org/en-US/firefox/addon/arrow-dl/") | Click here to intall [ArrowDL for Google Chrome](https://chrome.google.com/webstore/detail/arrow-dl/modofbhnhlagjmejdbalnijgncppjeio "https://chrome.google.com/webstore/detail/arrow-dl/modofbhnhlagjmejdbalnijgncppjeio") | -1. Install **DownRightNow** add-on - -2. Go to the install directory of the Application (*ArrowDL*), and follow the instructions in `ReadMe.txt` - -3. Then, go to "*Options*" in the WebExtension interface in your Web Browser. It should tell you if it's correctly connected with the Application. +1. Install **ArrowDL** add-on +2. Go to the install directory of the application (*ArrowDL*), and follow the instructions in `ReadMe.txt` +3. Then, go to "*Options*" in the WebExtensions interface in your web browser. It should tell you if it's correctly connected with the application. diff --git a/docs/_posts/2020-08-12-proxy-settings.md b/docs/_posts/2020-08-12-proxy-settings.md index c55997cd..c97d9b32 100644 --- a/docs/_posts/2020-08-12-proxy-settings.md +++ b/docs/_posts/2020-08-12-proxy-settings.md @@ -62,7 +62,7 @@ LibTorrent uses a separate settings storage, then to enable proxying with torren ### Further reading - [Proxy server](https://en.wikipedia.org/wiki/Proxy_server) definition on Wikipedia -- Qt5 [Proxy Documentation](https://doc.qt.io/qt-5/qnetworkproxy.html) +- Qt6 [Proxy Documentation](https://doc.qt.io/qt-6/qnetworkproxy.html) - LibTorrent [Proxy Documentation](https://www.libtorrent.org/features.html) diff --git a/docs/category/download-advanced.md b/docs/category/download-advanced.md index 4f3c807f..c7a45ce1 100644 --- a/docs/category/download-advanced.md +++ b/docs/category/download-advanced.md @@ -30,7 +30,7 @@ Table of Content: 2. Then, install the web extension: - 1. Install **DownRightNow** add-on on the [web browser](#install-webextension) + 1. Install **ArrowDL** add-on on the [web browser](#install-webextension) 2. Go to the install directory of the Application (*ArrowDL*), and follow the instructions in `ReadMe.txt` @@ -44,7 +44,7 @@ Choose the browser: | ![logo](/ArrowDL/assets/images/firefox.png) | ![logo](/ArrowDL/assets/images/chrome.png) | ![logo](/ArrowDL/assets/images/iexplorer.png) | |-----------------------------------|----------------------------------|----------------------------------| -| Click here to intall [DownRightNow for Mozilla Firefox](https://addons.mozilla.org/en-US/firefox/addon/down-right-now/ ) | Click here to intall [DownRightNow for Google Chrome](https://chrome.google.com/webstore/detail/down-right-now/modofbhnhlagjmejdbalnijgncppjeio "https://chrome.google.com/webstore/detail/down-right-now/modofbhnhlagjmejdbalnijgncppjeio") | Click here to intall... Just kidding | +| Click here to intall [ArrowDL for Mozilla Firefox](https://addons.mozilla.org/en-US/firefox/addon/arrow-dl/ ) | Click here to intall [ArrowDL for Google Chrome](https://chrome.google.com/webstore/detail/arrow-dl/modofbhnhlagjmejdbalnijgncppjeio "https://chrome.google.com/webstore/detail/arrow-dl/modofbhnhlagjmejdbalnijgncppjeio") | Click here to intall... Just kidding | #### Portable Archives @@ -153,8 +153,8 @@ Footnotes: /* A-Z sorted Urls */ const artifact_id_to_filenames = { - 'id_chromium': "DownRightNow_chromium_" + tag_name + ".zip", - 'id_firefox': "DownRightNow_firefox_" + tag_name + ".xpi", + 'id_chromium': "ArrowDL_chromium_" + tag_name + ".zip", + 'id_firefox': "ArrowDL_firefox_" + tag_name + ".xpi", 'id_linux_x64_app': "ArrowDL_" + tag_name + "_x86_64_no_launcher.AppImage", 'id_linux_x64_zip': "ArrowDL_" + tag_name + "_x86_64.tar.gz", 'id_mac_x64_dmg': "ArrowDL_" + tag_name + "_x86_64.dmg", diff --git a/docs/category/download.md b/docs/category/download.md index 71da9ff1..c47f682b 100644 --- a/docs/category/download.md +++ b/docs/category/download.md @@ -43,12 +43,12 @@ title: Download - + firefox logo - + chrome logo @@ -59,14 +59,14 @@ title: Download Click here to intall - - DownRightNow for Mozilla Firefox + + ArrowDL for Mozilla Firefox Click here to intall - - DownRightNow for Google Chrome + + ArrowDL for Google Chrome @@ -213,13 +213,13 @@ CPU architecture, browser, or release version, have a look at if (browserType === "Chrome") { webExtensionBrowserName = "Google Chrome"; - webExtensionUrl="https://chrome.google.com/webstore/detail/down-right-now/modofbhnhlagjmejdbalnijgncppjeio"; + webExtensionUrl="https://chrome.google.com/webstore/detail/arrow-dl/modofbhnhlagjmejdbalnijgncppjeio"; webExtensionImageSrc = "/ArrowDL/assets/images/chrome.png"; showSpecificInstructions(true); } else if (browserType === "Firefox") { webExtensionBrowserName = "Mozilla Firefox"; - webExtensionUrl="https://addons.mozilla.org/en-US/firefox/addon/down-right-now/"; + webExtensionUrl="https://addons.mozilla.org/en-US/firefox/addon/arrow-dl/"; webExtensionImageSrc = "/ArrowDL/assets/images/firefox.png"; showSpecificInstructions(true); diff --git a/docs/category/tutorial.md b/docs/category/tutorial.md index 5d70f1c8..24b97f61 100644 --- a/docs/category/tutorial.md +++ b/docs/category/tutorial.md @@ -10,11 +10,11 @@ It contains some dummy data to run the application. 1. Open *ArrowDL* - *Start Menu* > *ArrowDL* - > Or alternatively, open *DownRightNow* from your web browser (-> toolbar menu, or right-click context menu) + > Or alternatively, open *ArrowDL* add-on from your web browser (-> toolbar menu, or right-click context menu) 2. Open the wizard - copy-paste the URL - > Or alternatively, click 'immediate download' from *DownRightNow* + > Or alternatively, click 'immediate download' from *ArrowDL* add-on ![](../assets/images/tutorial/01-wizard.png) diff --git a/docs/index.md b/docs/index.md index 72f9f949..9ab24d91 100644 --- a/docs/index.md +++ b/docs/index.md @@ -5,9 +5,9 @@ title: What is ArrowDL **ArrowDL is a mass download manager** for Windows, Mac OS X and Linux. It helps you to select, organize, prioritize and run your downloads in parallel. -Based on the [Qt5](https://www.qt.io/ "https://www.qt.io/") framework, ArrowDL is written in C/C++. It's a free (as in "*free speech*" and also as in "*free beer*") software. Its use is governed by [LGPL](/ArrowDL/LICENSE.txt "LICENSE") License. +Based on the [Qt](https://www.qt.io/ "https://www.qt.io/") framework, ArrowDL is written in C/C++. It's a free (as in "*free speech*" and also as in "*free beer*") software. Its use is governed by [LGPL](/ArrowDL/LICENSE.txt "LICENSE") License. -**DownRightNow is an add-on for Chrome/Firefox**. It connects *ArrowDL* with your web browser. This extension helps you to download all the links and media you can find on the Web. When you visit a page, click to DownRightNow to see the content of the page. The content are links, references, images, videos... and other media present on the page. +**ArrowDL add-on for Chrome/Firefox**. It connects *ArrowDL* with your web browser. This WebExtensions add-on helps you to download all the links and media you can find on the Web. When you visit a page, click to ArrowDL to see the content of the page. The content are links, references, images, videos... and other media present on the page. ![Screenshot](/ArrowDL/assets/images/screenshot_1280x800.png) diff --git a/src/core/torrentcontext_p.cpp b/src/core/torrentcontext_p.cpp index e94feb19..7ff9f844 100644 --- a/src/core/torrentcontext_p.cpp +++ b/src/core/torrentcontext_p.cpp @@ -1311,53 +1311,41 @@ void WorkerThread::signalizeAlert(lt::alert* a) if (auto s = lt::alert_cast(a)) { //QString hash = toString(s->info_hashes.get_best()); // emit torrentRemoved(hash); - log(s); } else if (auto s = lt::alert_cast(a)) { // lt::torrent_status::state_t oldStatus = s->prev_state; // lt::torrent_status::state_t newStatus = s->state; // emit torrentStateChanged(oldState, newState); // rem quel torrent ? - log(s); } else if (auto s = lt::alert_cast(a)) { // int piece_index = (int)s->piece_index; // emit pieceHashCheckFailed(piece_index); - log(s); } else if (auto s = lt::alert_cast(a)) { // emit torrentFinished(); - log(s); } else if (auto s = lt::alert_cast(a)) { // emit torrentPaused(); - log(s); } else if (auto s = lt::alert_cast(a)) { // emit torrentResumed(); - log(s); } else if (auto s = lt::alert_cast(a)) { // emit torrentChecked(); - log(s); } else if (auto s = lt::alert_cast(a)) { // emit torrentFastResumeFailed(); - log(s); } else if (auto s = lt::alert_cast(a)) { // emit trackeridReceived(); - log(s); } else if (auto s = lt::alert_cast(a)) { // emit torrentError(); - log(s); } else if (auto s = lt::alert_cast(a)) { // emit torrentSSLError(); - log(s); } else if (auto s = lt::alert_cast(a)) { - log(s); onTorrentAdded(s->handle, s->params, s->error); } else if (auto s = lt::alert_cast(a)) { @@ -1369,10 +1357,9 @@ void WorkerThread::signalizeAlert(lt::alert* a) // magnet extension else if (auto s = lt::alert_cast(a)) { // emit metadataFailed(); - log(s); + qWarning() << "metadata that was received was corrupt"; } else if (auto s = lt::alert_cast(a)) { - log(s); onMetadataReceived(s->handle); } @@ -1489,9 +1476,33 @@ void WorkerThread::signalizeAlert(lt::alert* a) /* storage_notification */ - // else if (auto s = lt::alert_cast(a)) { - // emit fileCompleted(index); - // } + else if (auto s = lt::alert_cast(a)) { + Q_UNUSED(s) // emit fileCompleted(index); + } + else if (auto s = lt::alert_cast(a)) { + Q_UNUSED(s) + } + else if (auto s = lt::alert_cast(a)) { + Q_UNUSED(s) + } + else if (auto s = lt::alert_cast(a)) { + Q_UNUSED(s) + } + else if (auto s = lt::alert_cast(a)) { + Q_UNUSED(s) + } + else if (auto s = lt::alert_cast(a)) { + Q_UNUSED(s) + } + else if (auto s = lt::alert_cast(a)) { + Q_UNUSED(s) + } + else if (auto s = lt::alert_cast(a)) { + Q_UNUSED(s) + } + else if (auto s = lt::alert_cast(a)) { + Q_UNUSED(s) + } else if (auto s = lt::alert_cast(a)) { // int index = (int)s->index; @@ -1653,6 +1664,7 @@ void WorkerThread::signalizeAlert(lt::alert* a) /* block_progress_notification */ else if (auto s = lt::alert_cast(a)) { Q_UNUSED(s) // emit alerts_dropped_alert(); + qWarning() << "Alert queue grew too big."; } else if (auto s = lt::alert_cast(a)) { Q_UNUSED(s) // emit socks5_alert(); diff --git a/src/ipc/interprocesscommunication.cpp b/src/ipc/interprocesscommunication.cpp index bb01999c..d7ab66f7 100644 --- a/src/ipc/interprocesscommunication.cpp +++ b/src/ipc/interprocesscommunication.cpp @@ -95,7 +95,7 @@ QString InterProcessCommunication::getCurrentUrl(const QString &message) auto resources = message.split(QChar::Space, Qt::SkipEmptyParts); for (auto i = 0; i < resources.count() - 1; ++i) { if (resources.at(i).trimmed() == C_KEYWORD_OPEN_URL) { - return resources.at(i+1).trimmed(); + return resources.at(i + 1).trimmed(); } } return {}; @@ -111,7 +111,7 @@ QString InterProcessCommunication::getDownloadLink(const QString &message) const QStringList resources = message.split(QChar::Space, Qt::SkipEmptyParts); for (int i = 0; i < resources.count() - 1; ++i) { if (resources.at(i).trimmed() == C_KEYWORD_DOWNLOAD_LINK) { - return resources.at(i+1).trimmed(); + return resources.at(i + 1).trimmed(); } } return {}; diff --git a/src/locale/arrowdl_it_IT.ts b/src/locale/arrowdl_it_IT.ts index d1000e88..222421df 100644 --- a/src/locale/arrowdl_it_IT.ts +++ b/src/locale/arrowdl_it_IT.ts @@ -2875,12 +2875,12 @@ Per proteggere la privacy, inserisci un indirizzo Riferimento vuoto o falso. Bootstrap Icons (default) - + Icone bootstrap (predefinite) FontAwesome Flat Design - + Design piatto FontAwesome diff --git a/src/locale/arrowdl_nl_NL.ts b/src/locale/arrowdl_nl_NL.ts index fbea4b9e..69ca5d8f 100644 --- a/src/locale/arrowdl_nl_NL.ts +++ b/src/locale/arrowdl_nl_NL.ts @@ -2861,12 +2861,12 @@ Hieronder volgen enkele voorbeelden. Klik om het voorbeeld te plakken. Bootstrap Icons (default) - + Pictogrammen extraheren (standaard) FontAwesome Flat Design - + FontAwesome - Plat ontwerp diff --git a/src/locale/arrowdl_zh_CN.ts b/src/locale/arrowdl_zh_CN.ts index d993d0a4..f7a4343d 100644 --- a/src/locale/arrowdl_zh_CN.ts +++ b/src/locale/arrowdl_zh_CN.ts @@ -2251,12 +2251,12 @@ Some examples are given below. Click to paste the example. Concurrent fragments: - + 并发片段: 20 - + 20 @@ -2723,7 +2723,7 @@ Some examples are given below. Click to paste the example. Servers might split large files into multiple fragments, to optimize downloads. This option enables multi-threaded fragment downloads: Select the number of fragments that should be downloaded concurrently. Note that the concurrency makes download faster (when available), but the progress status and estimated time could be inaccurate (by design). Choose between precision and speed. Recommended value depends on your connection and machine. 20 is a good start. To disable it, set it to 1. - + 服务器可能会将大文件分割成多个片段,以优化下载。 此选项启用多线程片段下载:选择应同时下载的片段数量。 请注意,并发性使下载速度更快(如果可用),但进度状态和估计时间可能不准确(根据设计)。 在精度和速度之间进行选择。 建议值取决于您的连接和机器。 20 是一个好的开始。 要禁用它,请将其设置为 1。 @@ -2861,12 +2861,12 @@ Some examples are given below. Click to paste the example. Bootstrap Icons (default) - + Bootstrap 图标(默认) FontAwesome Flat Design - + FontAwesome 平面设计 diff --git a/src/widgets/textedit.cpp b/src/widgets/textedit.cpp index dc0b25da..31d8c3ea 100644 --- a/src/widgets/textedit.cpp +++ b/src/widgets/textedit.cpp @@ -633,9 +633,9 @@ void TextEdit::removeBlockSelection(const QString &text) cursor.setPosition( block.position() + endPos, QTextCursor::KeepAnchor); cursor.removeSelectedText(); } else { - cursor.setPosition( block.position()+block.length()-1, QTextCursor::MoveAnchor); + cursor.setPosition( block.position()+block.length() - 1, QTextCursor::MoveAnchor); QString str = ""; - str.fill(' ', leftColumn-block.length()+1 ); // str == " " + str.fill(' ', leftColumn-block.length() + 1 ); // str == " " cursor.insertText( str ); } if (!text.isEmpty()) { diff --git a/version b/version index fcdb2e10..1454f6ed 100644 --- a/version +++ b/version @@ -1 +1 @@ -4.0.0 +4.0.1 diff --git a/web-extension/extension/README.md b/web-extension/extension/README.md index 44039a16..dd8c54e3 100644 --- a/web-extension/extension/README.md +++ b/web-extension/extension/README.md @@ -23,4 +23,4 @@ eq. to: .\make.bat --output-directory . -See `.appveyor` script for packaging to .ZIP and .XPI files. +See the Github Workflows script for packaging to .ZIP and .XPI files. diff --git a/web-extension/extension/make.py b/web-extension/extension/make.py index 4b92c2e7..6d91b01e 100644 --- a/web-extension/extension/make.py +++ b/web-extension/extension/make.py @@ -65,11 +65,11 @@ def make_addons(current_path, output_path): apply_version(application_version, os.path.join(output_path, "firefox", "manifest.json")) print("Archiving...") - base_name = f"DownRightNow_chromium_v{application_version}" + base_name = f"ArrowDL_chromium_v{application_version}" chromium_full_name = make_archive(base_name=base_name, format="zip", root_dir=os.path.join(output_path, "chromium"), base_dir=".") print(f"Created archive: {chromium_full_name}") - base_name = f"DownRightNow_firefox_v{application_version}" + base_name = f"ArrowDL_firefox_v{application_version}" name = make_archive(base_name=base_name, format="zip", root_dir=os.path.join(output_path, "firefox"), base_dir=".") firefox_full_name = name.replace(".zip", ".xpi") if os.path.exists(firefox_full_name): diff --git a/web-extension/extension/src/base/_locales/ar/messages.json b/web-extension/extension/src/base/_locales/ar/messages.json index a3827e9d..2ea6d075 100644 --- a/web-extension/extension/src/base/_locales/ar/messages.json +++ b/web-extension/extension/src/base/_locales/ar/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/de/messages.json b/web-extension/extension/src/base/_locales/de/messages.json index a3827e9d..2ea6d075 100644 --- a/web-extension/extension/src/base/_locales/de/messages.json +++ b/web-extension/extension/src/base/_locales/de/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/en/messages.json b/web-extension/extension/src/base/_locales/en/messages.json index a3827e9d..2ea6d075 100644 --- a/web-extension/extension/src/base/_locales/en/messages.json +++ b/web-extension/extension/src/base/_locales/en/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/es/messages.json b/web-extension/extension/src/base/_locales/es/messages.json index e8753e60..1e2656e0 100644 --- a/web-extension/extension/src/base/_locales/es/messages.json +++ b/web-extension/extension/src/base/_locales/es/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/fr/messages.json b/web-extension/extension/src/base/_locales/fr/messages.json index 8f4f8d82..f7396aeb 100644 --- a/web-extension/extension/src/base/_locales/fr/messages.json +++ b/web-extension/extension/src/base/_locales/fr/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/hu/messages.json b/web-extension/extension/src/base/_locales/hu/messages.json index eac0db4a..aa52d006 100644 --- a/web-extension/extension/src/base/_locales/hu/messages.json +++ b/web-extension/extension/src/base/_locales/hu/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/it/messages.json b/web-extension/extension/src/base/_locales/it/messages.json index ae95fddd..722c2bb7 100644 --- a/web-extension/extension/src/base/_locales/it/messages.json +++ b/web-extension/extension/src/base/_locales/it/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/ja/messages.json b/web-extension/extension/src/base/_locales/ja/messages.json index a3827e9d..2ea6d075 100644 --- a/web-extension/extension/src/base/_locales/ja/messages.json +++ b/web-extension/extension/src/base/_locales/ja/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/ko/messages.json b/web-extension/extension/src/base/_locales/ko/messages.json index a3827e9d..2ea6d075 100644 --- a/web-extension/extension/src/base/_locales/ko/messages.json +++ b/web-extension/extension/src/base/_locales/ko/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/nl/messages.json b/web-extension/extension/src/base/_locales/nl/messages.json index a37ea11f..6df4964a 100644 --- a/web-extension/extension/src/base/_locales/nl/messages.json +++ b/web-extension/extension/src/base/_locales/nl/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/pl/messages.json b/web-extension/extension/src/base/_locales/pl/messages.json index a3827e9d..2ea6d075 100644 --- a/web-extension/extension/src/base/_locales/pl/messages.json +++ b/web-extension/extension/src/base/_locales/pl/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/pt_BR/messages.json b/web-extension/extension/src/base/_locales/pt_BR/messages.json index 4c7ddef9..5a026143 100644 --- a/web-extension/extension/src/base/_locales/pt_BR/messages.json +++ b/web-extension/extension/src/base/_locales/pt_BR/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/pt_PT/messages.json b/web-extension/extension/src/base/_locales/pt_PT/messages.json index a3827e9d..2ea6d075 100644 --- a/web-extension/extension/src/base/_locales/pt_PT/messages.json +++ b/web-extension/extension/src/base/_locales/pt_PT/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/ru/messages.json b/web-extension/extension/src/base/_locales/ru/messages.json index a3827e9d..2ea6d075 100644 --- a/web-extension/extension/src/base/_locales/ru/messages.json +++ b/web-extension/extension/src/base/_locales/ru/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/base/_locales/vi/messages.json b/web-extension/extension/src/base/_locales/vi/messages.json index a3827e9d..2ea6d075 100644 --- a/web-extension/extension/src/base/_locales/vi/messages.json +++ b/web-extension/extension/src/base/_locales/vi/messages.json @@ -1,6 +1,6 @@ { "extensionName": { - "message": "Down Right Now", + "message": "ArrowDL", "description": "Name of the extension, displayed in the web store. Should not exceed 45 characters." }, "extensionDescription": { diff --git a/web-extension/extension/src/chromium/background.js b/web-extension/extension/src/chromium/background.js index c3f5fa41..0cf1c93f 100644 --- a/web-extension/extension/src/chromium/background.js +++ b/web-extension/extension/src/chromium/background.js @@ -1,6 +1,9 @@ "use strict"; -const application = "com.setvisible.downrightnow"; +const application = "com.arrowdl.extension"; + +// let us know we're running +console.log("Background service worker has loaded via Manifest V3."); /* ***************************** */ /* Context Menu */ @@ -28,7 +31,6 @@ chrome.contextMenus.removeAll( addAction("save-image", chrome.i18n.getMessage("contextMenuSaveImage"), "image"); addAction("save-video", chrome.i18n.getMessage("contextMenuSaveVideo"), "video"); addAction("save-audio", chrome.i18n.getMessage("contextMenuSaveAudio"), "audio"); - addAction("save-launcher", chrome.i18n.getMessage("contextMenuSaveLauncher"), "launcher"); } ); @@ -38,7 +40,6 @@ chrome.contextMenus.onClicked.addListener( } else if (info.menuItemId === "save-frame" ) { save_page(info, tab); } else if (info.menuItemId === "save-image" ) { save_image(info, tab); } else if (info.menuItemId === "save-audio" ) { save_image(info, tab); - } else if (info.menuItemId === "save-launcher" ) { save_page(info, tab); } else if (info.menuItemId === "save-link" ) { save_link(info, tab); } else if (info.menuItemId === "save-selection" ) { save_page(info, tab); } else if (info.menuItemId === "save-video" ) { save_image(info, tab); @@ -48,196 +49,187 @@ chrome.contextMenus.onClicked.addListener( ); function save_page(info, tab) { - collectDOMandSendData(); + chrome.storage.local.get((userSettings) => { + collectDOMandSendData(userSettings); + }); } function save_link(info, tab) { - const safeUrl = escapeHTML(info.linkUrl); - sendData("[DOWNLOAD_LINK] " + safeUrl); + let safeUrl = escapeHTML(info.linkUrl); + sendDataToArrowDL("[DOWNLOAD_LINK] " + safeUrl); } function save_image(info, tab) { const safeUrl = escapeHTML(info.srcUrl); - sendData("[DOWNLOAD_LINK] " + safeUrl); + sendDataToArrowDL("[DOWNLOAD_LINK] " + safeUrl); } + /* ***************************** */ -/* Options */ +/* Collect links and media */ /* ***************************** */ -var mySettings = undefined; - -function getDownloadActionChoice() { - function onOptionResponse(response) { - if (chrome.runtime.lastError) { - console.log(chrome.runtime.lastError.message); - onOptionError(response); - } - if (response === undefined) { - onOptionError(response); - } else { - mySettings = response; - // console.log("Settings changed: " + JSON.stringify(mySettings)); - } - } - function onOptionError(error) { - console.log(`Error: ${error}`); - } - chrome.storage.local.get(onOptionResponse); -} - -getDownloadActionChoice(); - -function isSettingAskEnabled() { - return mySettings === undefined || mySettings.radioApplicationId === undefined || mySettings.radioApplicationId === 1; -} - -function getSettingMediaId() { - if (mySettings === undefined) { - return -1; - } - return mySettings.radioMediaId; -} - -function isSettingStartPaused() { - if (mySettings === undefined) { - return false; - } - return mySettings.startPaused; +function collectDOMandSendData(userSettings) { + + chrome.tabs.query({"active": true, "lastFocusedWindow": true}, (tabs) => { + + const tab = tabs[0]; + const tabId = tab.id; + const tabUrl = tab.url; + + if (tabUrl.startsWith("chrome")) { + console.log("Nothing to download from 'chrome://' or 'chrome-extension://'"); + console.log("ArrowDL is disabled when the current tab is Chrome settings tab."); + return; + } + + function injectableScriptFunction(args) { + const restoredSettings = JSON.parse(args); + let hasLinks = true; + let hasMedia = true; + let array = ""; + + console.log(restoredSettings); + + // Options + if (restoredSettings.radioApplicationId === 1) { + array += ""; + + } else if (restoredSettings.radioApplicationId === 2) { + + if (restoredSettings.radioMediaId === 1) { + hasMedia = false; + array += "[QUICK_LINKS]"; + array += " "; + + } else if (restoredSettings.radioMediaId === 2) { + hasLinks = false; + array += "[QUICK_MEDIA]"; + array += " "; + } + + if (restoredSettings.startPaused === true) { + array += "[STARTED_PAUSED]"; + array += " "; + } + } + + // Get the current URL + const url = document.URL; + array += "[CURRENT_URL] "; + array += url; + array += " "; + + if (hasLinks) { + // Get all elements of type + array += "[LINKS] "; + const links = document.getElementsByTagName("a"); + for (let i = 0; i < links.length; i++) { + array += links[i].href; + array += " "; + } + } + + if (hasMedia) { + // Get all elements of type + array += "[MEDIA] "; + const pictures = document.getElementsByTagName("img"); + for (let i = 0; i < pictures.length; i++) { + array += pictures[i].src; + array += " "; + } + } + + return array; + } + + /* Remark: + * code: "" + * The value of "" is actually the function's code of myFunction. + * myFunction is interpreted as a string. + * Indeed, "(" + myFunction + ")()" is a string, because function.toString() returns function's code. + */ + // const codeToExecute = "(" + myFunction + ")(" + myArgument + ");"; + const injectableScriptFunctionArgumentList = [ JSON.stringify(userSettings) ]; + + chrome.scripting.executeScript({ + "target": {"tabId": tabId, "allFrames": true}, + "func": injectableScriptFunction, + "args": injectableScriptFunctionArgumentList + }).then(results => { + if (chrome.runtime.lastError) { + console.log(chrome.runtime.lastError.message); + } + if (results.length > 0 && results[0] !== undefined) { + const data = results[0].result; + sendDataToArrowDL(data); + } + }); + }); } /* ***************************** */ -/* Collect links and media */ +/* Worker Message */ /* ***************************** */ -function collectDOMandSendData() { +chrome.runtime.onMessage.addListener((message , sender, sendResponse) => { + console.log("Message received!", message); - function myFunction(myArgument) { - var restoredSettings = myArgument; // not necessary: JSON.parse(myArgument); - var hasLinks = true; - var hasMedia = true; - var array = ""; + if (message === 'get-user-settings') { - // Options - if (restoredSettings.radioApplicationId === 1) { - array += ""; + chrome.storage.local.get((userSettings) => { + if (chrome.runtime.lastError) { + console.log(chrome.runtime.lastError.message); + console.log(`Error: ${userSettings}`); + } - } else if (restoredSettings.radioApplicationId === 2) { + if (userSettings === undefined) { + console.log(`Error: ${userSettings}`); + } else { + sendResponse(userSettings); + // console.log("Settings changed: " + JSON.stringify(userSettings)); + } + }); - if (restoredSettings.radioMediaId === 1) { - hasMedia = false; - array += "[QUICK_LINKS]"; - array += " "; + } else if (message === 'collect-dom-and-send-to-native-app') { - } else if (restoredSettings.radioMediaId === 2) { - hasLinks = false; - array += "[QUICK_MEDIA]"; - array += " "; - } + chrome.storage.local.get((userSettings) => { + collectDOMandSendData(userSettings); + }); - if (restoredSettings.startPaused === true) { - array += "[STARTED_PAUSED]"; - array += " "; - } - } + } else if (message === 'collect-dom-and-send-to-native-app-with-wizard') { - // Get the current URL - const url = document.URL; - array += "[CURRENT_URL] "; - array += url; - array += " "; - - if (hasLinks) { - // Get all elements of type - array += "[LINKS] "; - var links = document.getElementsByTagName("a"); - var max = links.length; - var i = 0; - for (; i < max; i++) { - array += links[i].href; - array += " "; - } - } + chrome.storage.local.get((userSettings) => { + userSettings.radioApplicationId = 1; // Force the Wizard to appear + collectDOMandSendData(userSettings); + }); - if (hasMedia) { - // Get all elements of type - array += "[MEDIA] "; - var pictures = document.getElementsByTagName("img"); - var max = pictures.length; - var i = 0; - for (; i < max; i++) { - array += pictures[i].src; - array += " "; - } - } - - return array; - } - - var myArgument = JSON.stringify(mySettings); + } else if ('send-to-native-app' in message) { - // We have permission to access the activeTab, so we can call chrome.tabs.executeScript. - /* Remark: - * code: "" - * The value of "" is actually the function's code of myFunction. - * myFunction is interpreted as a string. - * Indeed, "(" + myFunction + ")()" is a string, because function.toString() returns function's code. - */ - var codeToExecute = "(" + myFunction + ")(" + myArgument + ");"; + const data = message['send-to-native-app']; + console.log("Sending message to native app: " + data); + sendDataToArrowDL(data); - chrome.tabs.executeScript({ - "code": codeToExecute - }, function(results) { - if (chrome.runtime.lastError) { - console.log(chrome.runtime.lastError.message); - } - sendData(results[0]); } - ); -} - -function collectDOMandSendDataWithWizard() { - // We *hack* the settings - var previous = mySettings.radioApplicationId; - mySettings.radioApplicationId = 1; - - collectDOMandSendData(); - - mySettings.radioApplicationId = previous; -} - -/* ***************************** */ -/* Message */ -/* ***************************** */ -function handleMessage(request, sender, sendResponse) { - console.log("Message from the options.js: " + JSON.stringify(request)); - mySettings = request; - sendResponse({response: "ok"}); -} -chrome.runtime.onMessage.addListener(handleMessage); + sendResponse(true); +}); /* ***************************** */ /* Native Message */ /* ***************************** */ -function sendData(links) { - function onResponse(response) { - if (chrome.runtime.lastError) { - console.log(chrome.runtime.lastError.message); - onError(response); - } - if (response === undefined) { - onError(response); - } else { - console.log("Message from the launcher: " + response.text); - } - } - - function onError(error) { - console.log(`Error: ${error}`); - } +function sendDataToArrowDL(data) { + const message = {"text": "launch " + data}; + chrome.runtime.sendNativeMessage(application, message, (response) => { + if (chrome.runtime.lastError) { + console.log(chrome.runtime.lastError.message); + console.log(`Error: ${response}`); + } - var data = "launch " + links; - console.log("Sending message to launcher: " + data); - chrome.runtime.sendNativeMessage(application, { "text": data }, onResponse); + if (response === undefined) { + console.log(`Error: ${response}`); + } else { + console.log("Received response from native app: " + response.text); + } + }); } /* ***************************** */ diff --git a/web-extension/extension/src/chromium/manifest.json b/web-extension/extension/src/chromium/manifest.json index 85c2c2dc..41217971 100644 --- a/web-extension/extension/src/chromium/manifest.json +++ b/web-extension/extension/src/chromium/manifest.json @@ -1,9 +1,9 @@ { "author": "SetVisible(0!=1)", "background": { - "scripts": ["background.js"] + "service_worker": "background.js" }, - "browser_action": { + "action": { "default_icon": { "16": "icons/icon16.png", "24": "icons/icon24.png", @@ -17,7 +17,7 @@ }, "default_locale": "en", "description": "__MSG_extensionDescription__", - "homepage_url": "https://www.arrow-dl.com/ArrowDL", + "homepage_url": "https://www.arrow-dl.com/", "icons": { "16": "icons/icon16.png", "24": "icons/icon24.png", @@ -26,19 +26,20 @@ "64": "icons/icon64.png", "128": "icons/icon128.png" }, - "manifest_version": 2, + "manifest_version": 3, "name": "__MSG_extensionName__", "options_ui": { "page": "options.html", - "chrome_style": false + "browser_style": false }, "permissions": [ "activeTab", "contextMenus", "nativeMessaging", + "scripting", "storage", "tabs" ], - "short_name": "DRN!", + "short_name": "ArrowDL", "version": "0.0.65536" } diff --git a/web-extension/extension/src/chromium/options.js b/web-extension/extension/src/chromium/options.js index fed94cff..80c63bec 100644 --- a/web-extension/extension/src/chromium/options.js +++ b/web-extension/extension/src/chromium/options.js @@ -1,7 +1,7 @@ "use strict"; -const application = "com.setvisible.downrightnow"; -const website_download_link = "https://www.arrow-dl.com/ArrowDL/category/download.html"; +const application = "com.arrowdl.extension"; +const website_download_link = "https://www.arrow-dl.com/"; /* ***************************** */ /* Options */ @@ -29,12 +29,12 @@ function restoreOptions() { } function saveOptions() { - var options = getOptions(); + const options = getOptions(); chrome.storage.local.set(options); } function getOptions() { - var options = {}; + let options = {}; options["radioApplicationId"] = getApplicationRadio(); options["radioMediaId"] = getMediaRadio(); options["startPaused"] = isStartPaused(); @@ -98,7 +98,7 @@ function setStartPaused(value) { } function refreshButtons(){ - var isChecked = document.getElementById("download_immediately").checked; + const isChecked = document.getElementById("download_immediately").checked; setDivEnabled("full_menu_label", isChecked); setButtonEnabled("get_links", isChecked); setButtonEnabled("get_content", isChecked); @@ -115,10 +115,10 @@ function setDivEnabled(name, enabled) { } function setButtonEnabled(name, enabled) { - var inputButton = document.getElementById(name); + const inputButton = document.getElementById(name); inputButton.disabled = !enabled; - for (var i = 0; i < inputButton.labels.length; i++) { - var label = inputButton.labels[i]; + for (let i = 0; i < inputButton.labels.length; i++) { + const label = inputButton.labels[i]; if (enabled) { label.classList.remove("disabled"); } else { @@ -128,12 +128,12 @@ function setButtonEnabled(name, enabled) { } function showOptions(visible) { - var instructions = document.getElementsByClassName("show-instruction"); - for (var i = 0; i < instructions.length; i ++) { + const instructions = document.getElementsByClassName("show-instruction"); + for (let i = 0; i < instructions.length; i ++) { instructions[i].style.display = visible ? "none" : "block"; } - var options = document.getElementsByClassName("options"); - for (var i = 0; i < options.length; i ++) { + const options = document.getElementsByClassName("options"); + for (let i = 0; i < options.length; i ++) { options[i].style.display = visible ? "block" : "none"; } } @@ -151,10 +151,10 @@ function checkConnection() { onHelloError(response); } else { console.log(`Message from the launcher: ${response.text}`); - var messageOk = chrome.i18n.getMessage("optionsOk"); - var messageDetectedPath = chrome.i18n.getMessage("optionsDetectedPath"); - var connectionStatus = "✓ " + messageOk; - var details = "

" + messageDetectedPath + "
" + response.text + ""; + const messageOk = chrome.i18n.getMessage("optionsOk"); + const messageDetectedPath = chrome.i18n.getMessage("optionsDetectedPath"); + const connectionStatus = "✓ " + messageOk; + const details = "

" + messageDetectedPath + "
" + response.text + ""; setConnectionStatus(connectionStatus, details, "MediumSeaGreen"); showOptions(true); } @@ -162,20 +162,20 @@ function checkConnection() { function onHelloError(error) { console.log(`Launcher didn't send any message. ${error}.`); - var messageError = chrome.i18n.getMessage("optionsError"); - var messageInstructions = chrome.i18n.getMessage("optionsInstructions"); - var connectionStatus = "⚠ " + messageError; - var details = "

" + messageInstructions; + const messageError = chrome.i18n.getMessage("optionsError"); + const messageInstructions = chrome.i18n.getMessage("optionsInstructions"); + const connectionStatus = "⚠ " + messageError; + const details = "

" + messageInstructions; setConnectionStatus(connectionStatus, details, "Tomato"); showOptions(false); } - var data = "areyouthere"; + const data = "areyouthere"; chrome.runtime.sendNativeMessage(application, { "text": data }, onHelloResponse); } function setConnectionStatus(connectionStatus, details, color) { - var messageStatus = chrome.i18n.getMessage("optionsStatus"); + const messageStatus = chrome.i18n.getMessage("optionsStatus"); const statusTag = `${messageStatus}  ${connectionStatus}    ${details}`; safeInnerHtmlAssignment2("status-message", statusTag); @@ -223,7 +223,7 @@ function notifyBackgroundPage() { function onError(error) { console.log(`Error: ${error}`); } - var options = getOptions(); + const options = getOptions(); chrome.runtime.sendMessage(options, onResponse); } @@ -234,8 +234,8 @@ function loadPage() { restoreOptions(); checkInstallation(); - var input = document.querySelectorAll("input"); - for(var i = 0; i < input.length; i++) { + const input = document.querySelectorAll("input"); + for (let i = 0; i < input.length; i++) { input[i].addEventListener("change", onInputChanged); } } diff --git a/web-extension/extension/src/chromium/popup.js b/web-extension/extension/src/chromium/popup.js index ac5f3190..0f013d92 100644 --- a/web-extension/extension/src/chromium/popup.js +++ b/web-extension/extension/src/chromium/popup.js @@ -1,30 +1,27 @@ "use strict"; -const application = "com.setvisible.downrightnow"; +const application = "com.arrowdl.extension"; /* ***************************** */ /* Native Message */ /* ***************************** */ function checkConnection() { - function onResponse(response) { + // todo chrome.runtime.sendMessage({'send-to-native-app': "areyouthere"}); + const message = {"text": "areyouthere"}; + chrome.runtime.sendNativeMessage(application, message, (response) => { if (chrome.runtime.lastError) { console.log(chrome.runtime.lastError.message); - onError(response); + console.log(`Error: ${response}`); + showWarningMessage(true); } + if (response === undefined) { - onError(response); + console.log(`Error: ${response}`); + showWarningMessage(true); } else { showWarningMessage(false); } - } - - function onError(error) { - console.log(`Error: ${error}`); - showWarningMessage(true); - } - - var data = "areyouthere"; - chrome.runtime.sendNativeMessage(application, { "text": data }, onResponse); + }); } @@ -32,7 +29,7 @@ function checkConnection() { /* Core */ /* ***************************** */ function showWarningMessage(hasError) { - var x = document.getElementById("warning-area"); + const x = document.getElementById("warning-area"); if (hasError) { x.style.display = "block"; } else { @@ -62,9 +59,9 @@ function setVisible(name, visible) { } } -function immediateButtonLabel() { - var mediaId = getBackgroundPage().getSettingMediaId(); - var startPaused = getBackgroundPage().isSettingStartPaused(); +function immediateButtonLabel(userSettings) { + const mediaId = getSettingMediaId(userSettings); + const startPaused = isSettingStartPaused(userSettings); if (mediaId === 1) { if (startPaused) { return chrome.i18n.getMessage("popupDownloadLinksPaused") @@ -92,127 +89,46 @@ function safeInnerHtmlAssignment(elementId, label) { } /* ***************************** */ -/* FIREFOX BUG #1329304 */ +/* Events */ /* ***************************** */ -function checkIncognitoMode() { - showIncognitoWarningMessage(hasIncognitoModeBug()); -} - -function hasIncognitoModeBug() { - // Remark: - // https://developer.mozilla.org/en/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getBackgroundPage - // method 'getBackgroundPage()' cannot be used in a private window in Firefox - // it always returns null. - // For more info see related bug at bugzilla. - // https://bugzilla.mozilla.org/show_bug.cgi?id=1329304 - return (chrome.extension.getBackgroundPage() === null); -} - -function showIncognitoWarningMessage(hasError) { - var x = document.getElementById("warning-area-incognito"); - if (hasError) { - x.style.display = "block"; - } else { - x.style.display = "none"; - } - if (hasError) { - setDisabled("button-start", true); - } -} - -// This function is a work-around to the Firefox Incognito Context mode Bug. -function getBackgroundPage() { - if (hasIncognitoModeBug()) { - return new DummyChromeExtensionForIncognitoMode(); - } - return chrome.extension.getBackgroundPage(); -} - -class DummyChromeExtensionForIncognitoMode { - constructor() { - } - - isSettingAskEnabled() { - return true; - } - getSettingMediaId() { - return -1; - } - isSettingStartPaused() { - return false; - } - collectDOMandSendDataWithWizard() { - // Nothing - } - collectDOMandSendData() { - // Nothing - } - - sendData(links) { - function onResponse(response) { - if (chrome.runtime.lastError) { - console.log(chrome.runtime.lastError.message); - onError(response); - } - if (response === undefined) { - onError(response); - } else { - console.log("Message from the launcher: " + response.text); - } - } +document.addEventListener('DOMContentLoaded', () => { + checkConnection(); - function onError(error) { - console.log(`Error: ${error}`); - } + // send a message to the background + chrome.runtime.sendMessage('get-user-settings', (userSettings) => { + const enabled = isSettingAskEnabled(userSettings); + setVisible("button-immediate-download", !enabled); - var data = "launch " + links; - console.log("Sending message to launcher: " + data); - chrome.runtime.sendNativeMessage(application, { "text": data }, onResponse); - } -} - -/* ***************************** */ -/* Events */ -/* ***************************** */ -function onLoaded() { - checkConnection(); - checkIncognitoMode(); - - var enabled = getBackgroundPage().isSettingAskEnabled(); - setVisible("button-immediate-download", !enabled); - - if (!enabled) { - var label = immediateButtonLabel(); - safeInnerHtmlAssignment("button-immediate-download-label", label); - } -} + if (!enabled) { + const label = immediateButtonLabel(userSettings); + safeInnerHtmlAssignment("button-immediate-download-label", label); + } + }); +}); -document.addEventListener('DOMContentLoaded', onLoaded); document.getElementById("button-start").addEventListener('click', () => { - getBackgroundPage().collectDOMandSendDataWithWizard(); + chrome.runtime.sendMessage('collect-dom-and-send-to-native-app-with-wizard'); window.close(); }); document.getElementById("button-immediate-download").addEventListener('click', () => { - getBackgroundPage().collectDOMandSendData(); + chrome.runtime.sendMessage('collect-dom-and-send-to-native-app'); window.close(); }); -document.getElementById("button-manager").addEventListener('click', () => { - var command = "[MANAGER]"; - getBackgroundPage().sendData(command); +document.getElementById("button-manager").addEventListener('click', () => { + chrome.runtime.sendMessage({'send-to-native-app': "[MANAGER]"}); window.close(); }); -document.getElementById("button-preference").addEventListener('click', () => { - var command = "[PREFS]"; - getBackgroundPage().sendData(command); +document.getElementById("button-preference").addEventListener('click', () => { + chrome.runtime.sendMessage({'send-to-native-app': "[PREFS]"}); window.close(); }); document.getElementById("button-options-page").addEventListener('click', () => { - var openingPage = chrome.runtime.openOptionsPage(); + const openingPage = chrome.runtime.openOptionsPage(); window.close(); }); @@ -221,6 +137,27 @@ document.getElementById("button-website").addEventListener('click', () => { window.close(); }); +/* ***************************** */ +/* Options */ +/* ***************************** */ +function isSettingAskEnabled(userSettings) { + return userSettings === undefined || userSettings.radioApplicationId === undefined || userSettings.radioApplicationId === 1; +} + +function getSettingMediaId(userSettings) { + if (userSettings === undefined) { + return -1; + } + return userSettings.radioMediaId; +} + +function isSettingStartPaused(userSettings) { + if (userSettings === undefined) { + return false; + } + return userSettings.startPaused; +} + /* ***************************** */ /* Internationalization */ /* ***************************** */ diff --git a/web-extension/extension/src/firefox/background.js b/web-extension/extension/src/firefox/background.js index bda1b7df..184a19be 100644 --- a/web-extension/extension/src/firefox/background.js +++ b/web-extension/extension/src/firefox/background.js @@ -1,22 +1,27 @@ "use strict"; -const application = "DownRightNow"; +const application = "com.arrowdl.extension"; + +// let us know we're running +console.log("Background service worker has loaded via Manifest V3."); /* ***************************** */ /* Context Menu */ /* ***************************** */ +function contextMenusCreateCallback() { + if (browser.runtime.lastError) { + console.log(browser.runtime.lastError.message); + } +}; + browser.contextMenus.removeAll( function() { function addAction(actionId, actionTitle, actionContext) { browser.contextMenus.create({ id: actionId, title: actionTitle, - icons: { - "16": "icons/icon16.png", - "32": "icons/icon32.png" - }, contexts: [actionContext] - }); + }, contextMenusCreateCallback); } addAction("save-page", browser.i18n.getMessage("contextMenuSavePage"), "page"); addAction("save-frame", browser.i18n.getMessage("contextMenuSaveFrame"), "frame"); @@ -26,7 +31,6 @@ browser.contextMenus.removeAll( addAction("save-image", browser.i18n.getMessage("contextMenuSaveImage"), "image"); addAction("save-video", browser.i18n.getMessage("contextMenuSaveVideo"), "video"); addAction("save-audio", browser.i18n.getMessage("contextMenuSaveAudio"), "audio"); - addAction("save-launcher", browser.i18n.getMessage("contextMenuSaveLauncher"), "launcher"); } ); @@ -36,7 +40,6 @@ browser.contextMenus.onClicked.addListener( } else if (info.menuItemId === "save-frame" ) { save_page(info, tab); } else if (info.menuItemId === "save-image" ) { save_image(info, tab); } else if (info.menuItemId === "save-audio" ) { save_image(info, tab); - } else if (info.menuItemId === "save-launcher" ) { save_page(info, tab); } else if (info.menuItemId === "save-link" ) { save_link(info, tab); } else if (info.menuItemId === "save-selection" ) { save_page(info, tab); } else if (info.menuItemId === "save-video" ) { save_image(info, tab); @@ -46,179 +49,187 @@ browser.contextMenus.onClicked.addListener( ); function save_page(info, tab) { - collectDOMandSendData(); + browser.storage.local.get((userSettings) => { + collectDOMandSendData(userSettings); + }); } function save_link(info, tab) { - const safeUrl = escapeHTML(info.linkUrl); - sendData("[DOWNLOAD_LINK] " + safeUrl); + let safeUrl = escapeHTML(info.linkUrl); + sendDataToArrowDL("[DOWNLOAD_LINK] " + safeUrl); } function save_image(info, tab) { const safeUrl = escapeHTML(info.srcUrl); - sendData("[DOWNLOAD_LINK] " + safeUrl); + sendDataToArrowDL("[DOWNLOAD_LINK] " + safeUrl); } + /* ***************************** */ -/* Options */ +/* Collect links and media */ /* ***************************** */ -var mySettings = undefined; - -function getDownloadActionChoice() { - function onOptionResponse(response) { - mySettings = response; - // console.log("Settings changed: " + JSON.stringify(mySettings)); - } - function onOptionError(error) { - console.log(`Error: ${error}`); - } - var getting = browser.storage.local.get(); - getting.then(onOptionResponse, onOptionError); -} - -getDownloadActionChoice(); - -function isSettingAskEnabled() { - return mySettings === undefined || mySettings.radioApplicationId === undefined || mySettings.radioApplicationId === 1; -} - -function getSettingMediaId() { - if (mySettings === undefined) { - return -1; - } - return mySettings.radioMediaId; -} - -function isSettingStartPaused() { - if (mySettings === undefined) { - return false; - } - return mySettings.startPaused; +function collectDOMandSendData(userSettings) { + + browser.tabs.query({"active": true, "lastFocusedWindow": true}, (tabs) => { + + const tab = tabs[0]; + const tabId = tab.id; + const tabUrl = tab.url; + + if (tabUrl.startsWith("browser")) { + console.log("Nothing to download from 'browser://' or 'browser-extension://'"); + console.log("ArrowDL is disabled when the current tab is browser settings tab."); + return; + } + + function injectableScriptFunction(args) { + const restoredSettings = JSON.parse(args); + let hasLinks = true; + let hasMedia = true; + let array = ""; + + console.log(restoredSettings); + + // Options + if (restoredSettings.radioApplicationId === 1) { + array += ""; + + } else if (restoredSettings.radioApplicationId === 2) { + + if (restoredSettings.radioMediaId === 1) { + hasMedia = false; + array += "[QUICK_LINKS]"; + array += " "; + + } else if (restoredSettings.radioMediaId === 2) { + hasLinks = false; + array += "[QUICK_MEDIA]"; + array += " "; + } + + if (restoredSettings.startPaused === true) { + array += "[STARTED_PAUSED]"; + array += " "; + } + } + + // Get the current URL + const url = document.URL; + array += "[CURRENT_URL] "; + array += url; + array += " "; + + if (hasLinks) { + // Get all elements of type + array += "[LINKS] "; + const links = document.getElementsByTagName("a"); + for (let i = 0; i < links.length; i++) { + array += links[i].href; + array += " "; + } + } + + if (hasMedia) { + // Get all elements of type + array += "[MEDIA] "; + const pictures = document.getElementsByTagName("img"); + for (let i = 0; i < pictures.length; i++) { + array += pictures[i].src; + array += " "; + } + } + + return array; + } + + /* Remark: + * code: "" + * The value of "" is actually the function's code of myFunction. + * myFunction is interpreted as a string. + * Indeed, "(" + myFunction + ")()" is a string, because function.toString() returns function's code. + */ + // const codeToExecute = "(" + myFunction + ")(" + myArgument + ");"; + const injectableScriptFunctionArgumentList = [ JSON.stringify(userSettings) ]; + + browser.scripting.executeScript({ + "target": {"tabId": tabId, "allFrames": true}, + "func": injectableScriptFunction, + "args": injectableScriptFunctionArgumentList + }).then(results => { + if (browser.runtime.lastError) { + console.log(browser.runtime.lastError.message); + } + if (results.length > 0 && results[0] !== undefined) { + const data = results[0].result; + sendDataToArrowDL(data); + } + }); + }); } /* ***************************** */ -/* Collect links and media */ +/* Worker Message */ /* ***************************** */ -function collectDOMandSendData() { +browser.runtime.onMessage.addListener((message , sender, sendResponse) => { + console.log("Message received!", message); - function myFunction(myArgument) { - var restoredSettings = myArgument; // not necessary: JSON.parse(myArgument); - var hasLinks = true; - var hasMedia = true; - var array = ""; + if (message === 'get-user-settings') { - // Options - if (restoredSettings.radioApplicationId === 1) { - array += ""; + browser.storage.local.get((userSettings) => { + if (browser.runtime.lastError) { + console.log(browser.runtime.lastError.message); + console.log(`Error: ${userSettings}`); + } - } else if (restoredSettings.radioApplicationId === 2) { + if (userSettings === undefined) { + console.log(`Error: ${userSettings}`); + } else { + sendResponse(userSettings); + // console.log("Settings changed: " + JSON.stringify(userSettings)); + } + }); - if (restoredSettings.radioMediaId === 1) { - hasMedia = false; - array += "[QUICK_LINKS]"; - array += " "; + } else if (message === 'collect-dom-and-send-to-native-app') { - } else if (restoredSettings.radioMediaId === 2) { - hasLinks = false; - array += "[QUICK_MEDIA]"; - array += " "; - } + browser.storage.local.get((userSettings) => { + collectDOMandSendData(userSettings); + }); - if (restoredSettings.startPaused === true) { - array += "[STARTED_PAUSED]"; - array += " "; - } - } + } else if (message === 'collect-dom-and-send-to-native-app-with-wizard') { - // Get the current URL - const url = document.URL; - array += "[CURRENT_URL] "; - array += url; - array += " "; - - if (hasLinks) { - // Get all elements of type - array += "[LINKS] "; - var links = document.getElementsByTagName("a"); - var max = links.length; - var i = 0; - for (; i < max; i++) { - array += links[i].href; - array += " "; - } - } + browser.storage.local.get((userSettings) => { + userSettings.radioApplicationId = 1; // Force the Wizard to appear + collectDOMandSendData(userSettings); + }); - if (hasMedia) { - // Get all elements of type - array += "[MEDIA] "; - var pictures = document.getElementsByTagName("img"); - var max = pictures.length; - var i = 0; - for (; i < max; i++) { - array += pictures[i].src; - array += " "; - } - } + } else if ('send-to-native-app' in message) { - return array; - } + const data = message['send-to-native-app']; + console.log("Sending message to native app: " + data); + sendDataToArrowDL(data); - var myArgument = JSON.stringify(mySettings); - - // We have permission to access the activeTab, so we can call browser.tabs.executeScript. - /* Remark: - * code: "" - * The value of "" is actually the function's code of myFunction. - * myFunction is interpreted as a string. - * Indeed, "(" + myFunction + ")()" is a string, because function.toString() returns function's code. - */ - var codeToExecute = "(" + myFunction + ")(" + myArgument + ");"; - - browser.tabs.executeScript({ - "code": codeToExecute - }, function(results) { - sendData(results[0]); } - ); -} - -function collectDOMandSendDataWithWizard() { - // We *hack* the settings - var previous = mySettings.radioApplicationId; - mySettings.radioApplicationId = 1; - collectDOMandSendData(); - - mySettings.radioApplicationId = previous; -} - -/* ***************************** */ -/* Message */ -/* ***************************** */ -function handleMessage(request, sender, sendResponse) { - console.log("Message from the options.js: " + JSON.stringify(request)); - mySettings = request; - sendResponse({response: "ok"}); -} - -browser.runtime.onMessage.addListener(handleMessage); + sendResponse(true); +}); /* ***************************** */ /* Native Message */ /* ***************************** */ -function sendData(links) { - function onResponse(message) { - console.log(`Message from the launcher: ${message.text}`); - } - - function onError(error) { - console.log(`Error: ${error}`); - } +function sendDataToArrowDL(data) { + const message = {"text": "launch " + data}; + browser.runtime.sendNativeMessage(application, message, (response) => { + if (browser.runtime.lastError) { + console.log(browser.runtime.lastError.message); + console.log(`Error: ${response}`); + } - var data = "launch " + links; - console.log("Sending message to launcher: " + data); - var sending = browser.runtime.sendNativeMessage(application, data); - sending.then(onResponse, onError); + if (response === undefined) { + console.log(`Error: ${response}`); + } else { + console.log("Received response from native app: " + response.text); + } + }); } /* ***************************** */ diff --git a/web-extension/extension/src/firefox/manifest.json b/web-extension/extension/src/firefox/manifest.json index 0e966507..769104cb 100644 --- a/web-extension/extension/src/firefox/manifest.json +++ b/web-extension/extension/src/firefox/manifest.json @@ -3,7 +3,7 @@ "background": { "scripts": ["background.js"] }, - "browser_action": { + "action": { "default_icon": { "16": "icons/icon16.png", "24": "icons/icon24.png", @@ -23,7 +23,7 @@ }, "default_locale": "en", "description": "__MSG_extensionDescription__", - "homepage_url": "https://www.arrow-dl.com/ArrowDL", + "homepage_url": "https://www.arrow-dl.com/", "icons": { "16": "icons/icon16.png", "24": "icons/icon24.png", @@ -32,21 +32,21 @@ "64": "icons/icon64.png", "128": "icons/icon128.png" }, - "manifest_version": 2, + "manifest_version": 3, "name": "__MSG_extensionName__", "options_ui": { "page": "options.html", "browser_style": false }, "permissions": [ - "", "activeTab", "contextMenus", "menus", "nativeMessaging", + "scripting", "storage", "tabs" ], - "short_name": "DRN!", + "short_name": "ArrowDL", "version": "0.0.65536" } diff --git a/web-extension/extension/src/firefox/options.js b/web-extension/extension/src/firefox/options.js index 93e431ae..7cd7bbb6 100644 --- a/web-extension/extension/src/firefox/options.js +++ b/web-extension/extension/src/firefox/options.js @@ -1,33 +1,40 @@ "use strict"; -const application = "DownRightNow"; -const website_download_link = "https://www.arrow-dl.com/ArrowDL/category/download.html"; +const application = "com.arrowdl.extension"; +const website_download_link = "https://www.arrow-dl.com/"; /* ***************************** */ /* Options */ /* ***************************** */ function restoreOptions() { function onOptionResponse(response) { - setApplicationRadio( response.radioApplicationId ); - setMediaRadio( response.radioMediaId ); - setStartPaused( response.startPaused ); + if (browser.runtime.lastError) { + console.log(browser.runtime.lastError.message); + onOptionError(response); + } + if (response === undefined) { + onOptionError(response); + } else { + setApplicationRadio( response.radioApplicationId ); + setMediaRadio( response.radioMediaId ); + setStartPaused( response.startPaused ); + } } function onOptionError(error) { console.log(`Error: ${error}`); } - var getting = browser.storage.local.get(); - getting.then(onOptionResponse, onOptionError); + browser.storage.local.get(onOptionResponse); } function saveOptions() { - var options = getOptions(); + const options = getOptions(); browser.storage.local.set(options); } function getOptions() { - var options = {}; + let options = {}; options["radioApplicationId"] = getApplicationRadio(); options["radioMediaId"] = getMediaRadio(); options["startPaused"] = isStartPaused(); @@ -91,7 +98,7 @@ function setStartPaused(value) { } function refreshButtons(){ - var isChecked = document.getElementById("download_immediately").checked; + const isChecked = document.getElementById("download_immediately").checked; setDivEnabled("full_menu_label", isChecked); setButtonEnabled("get_links", isChecked); setButtonEnabled("get_content", isChecked); @@ -108,10 +115,10 @@ function setDivEnabled(name, enabled) { } function setButtonEnabled(name, enabled) { - var inputButton = document.getElementById(name); + const inputButton = document.getElementById(name); inputButton.disabled = !enabled; - for (var i = 0; i < inputButton.labels.length; i++) { - var label = inputButton.labels[i]; + for (let i = 0; i < inputButton.labels.length; i++) { + const label = inputButton.labels[i]; if (enabled) { label.classList.remove("disabled"); } else { @@ -121,12 +128,12 @@ function setButtonEnabled(name, enabled) { } function showOptions(visible) { - var instructions = document.getElementsByClassName("show-instruction"); - for (var i = 0; i < instructions.length; i ++) { + const instructions = document.getElementsByClassName("show-instruction"); + for (let i = 0; i < instructions.length; i ++) { instructions[i].style.display = visible ? "none" : "block"; } - var options = document.getElementsByClassName("options"); - for (var i = 0; i < options.length; i ++) { + const options = document.getElementsByClassName("options"); + for (let i = 0; i < options.length; i ++) { options[i].style.display = visible ? "block" : "none"; } } @@ -136,32 +143,39 @@ function showOptions(visible) { /* ***************************** */ function checkConnection() { function onHelloResponse(response) { - console.log(`Message from the launcher: ${response.text}`); - var messageOk = browser.i18n.getMessage("optionsOk"); - var messageDetectedPath = browser.i18n.getMessage("optionsDetectedPath"); - var connectionStatus = "✓ " + messageOk; - var details = "

" + messageDetectedPath + "
" + response.text + ""; - setConnectionStatus(connectionStatus, details, "MediumSeaGreen"); - showOptions(true); + if (browser.runtime.lastError) { + console.log(browser.runtime.lastError.message); + onHelloError(response); + } + if (response === undefined) { + onHelloError(response); + } else { + console.log(`Message from the launcher: ${response.text}`); + const messageOk = browser.i18n.getMessage("optionsOk"); + const messageDetectedPath = browser.i18n.getMessage("optionsDetectedPath"); + const connectionStatus = "✓ " + messageOk; + const details = "

" + messageDetectedPath + "
" + response.text + ""; + setConnectionStatus(connectionStatus, details, "MediumSeaGreen"); + showOptions(true); + } } function onHelloError(error) { console.log(`Launcher didn't send any message. ${error}.`); - var messageError = browser.i18n.getMessage("optionsError"); - var messageInstructions = browser.i18n.getMessage("optionsInstructions"); - var connectionStatus = "⚠ " + messageError; - var details = "

" + messageInstructions; + const messageError = browser.i18n.getMessage("optionsError"); + const messageInstructions = browser.i18n.getMessage("optionsInstructions"); + const connectionStatus = "⚠ " + messageError; + const details = "

" + messageInstructions; setConnectionStatus(connectionStatus, details, "Tomato"); showOptions(false); } - var data = "areyouthere"; - var sending = browser.runtime.sendNativeMessage(application, data); - sending.then(onHelloResponse, onHelloError); + const data = "areyouthere"; + browser.runtime.sendNativeMessage(application, { "text": data }, onHelloResponse); } function setConnectionStatus(connectionStatus, details, color) { - var messageStatus = browser.i18n.getMessage("optionsStatus"); + const messageStatus = browser.i18n.getMessage("optionsStatus"); const statusTag = `${messageStatus}  ${connectionStatus}    ${details}`; safeInnerHtmlAssignment2("status-message", statusTag); @@ -196,14 +210,21 @@ function notifyBackgroundPage() { * that the options have been updated. */ function onResponse(message) { - // console.log(`Message from the background.js: ${message.response}`); + if (browser.runtime.lastError) { + console.log(browser.runtime.lastError.message); + onError(message); + } + if (message === undefined) { + onError(message); + } else { + // console.log(`Message from the background.js: ${message.response}`); + } } function onError(error) { console.log(`Error: ${error}`); } - var options = getOptions(); - var sending = browser.runtime.sendMessage(options); - sending.then(onResponse, onError); + const options = getOptions(); + browser.runtime.sendMessage(options, onResponse); } /* ***************************** */ @@ -213,8 +234,8 @@ function loadPage() { restoreOptions(); checkInstallation(); - var input = document.querySelectorAll("input"); - for(var i = 0; i < input.length; i++) { + const input = document.querySelectorAll("input"); + for (let i = 0; i < input.length; i++) { input[i].addEventListener("change", onInputChanged); } } diff --git a/web-extension/extension/src/firefox/popup.js b/web-extension/extension/src/firefox/popup.js index 8b91e9c6..74455071 100644 --- a/web-extension/extension/src/firefox/popup.js +++ b/web-extension/extension/src/firefox/popup.js @@ -1,21 +1,27 @@ "use strict"; -const application = "DownRightNow"; +const application = "com.arrowdl.extension"; /* ***************************** */ /* Native Message */ /* ***************************** */ function checkConnection() { - function onResponse(response) { - showWarningMessage(false); - } - - function onError(error) { - showWarningMessage(true); - } - var data = "areyouthere"; - var sending = browser.runtime.sendNativeMessage(application, data); - sending.then(onResponse, onError); + // todo browser.runtime.sendMessage({'send-to-native-app': "areyouthere"}); + const message = {"text": "areyouthere"}; + browser.runtime.sendNativeMessage(application, message, (response) => { + if (browser.runtime.lastError) { + console.log(browser.runtime.lastError.message); + console.log(`Error: ${response}`); + showWarningMessage(true); + } + + if (response === undefined) { + console.log(`Error: ${response}`); + showWarningMessage(true); + } else { + showWarningMessage(false); + } + }); } @@ -23,7 +29,7 @@ function checkConnection() { /* Core */ /* ***************************** */ function showWarningMessage(hasError) { - var x = document.getElementById("warning-area"); + const x = document.getElementById("warning-area"); if (hasError) { x.style.display = "block"; } else { @@ -53,9 +59,9 @@ function setVisible(name, visible) { } } -function immediateButtonLabel() { - var mediaId = getBackgroundPage().getSettingMediaId(); - var startPaused = getBackgroundPage().isSettingStartPaused(); +function immediateButtonLabel(userSettings) { + const mediaId = getSettingMediaId(userSettings); + const startPaused = isSettingStartPaused(userSettings); if (mediaId === 1) { if (startPaused) { return browser.i18n.getMessage("popupDownloadLinksPaused") @@ -82,119 +88,47 @@ function safeInnerHtmlAssignment(elementId, label) { } } -/* ***************************** */ -/* FIREFOX BUG #1329304 */ -/* ***************************** */ -function checkIncognitoMode() { - showIncognitoWarningMessage(hasIncognitoModeBug()); -} - -function hasIncognitoModeBug() { - // Remark: - // https://developer.mozilla.org/en/docs/Mozilla/Add-ons/WebExtensions/API/runtime/getBackgroundPage - // method 'getBackgroundPage()' cannot be used in a private window in Firefox - // it always returns null. - // For more info see related bug at bugzilla. - // https://bugzilla.mozilla.org/show_bug.cgi?id=1329304 - return (chrome.extension.getBackgroundPage() === null); -} - -function showIncognitoWarningMessage(hasError) { - var x = document.getElementById("warning-area-incognito"); - if (hasError) { - x.style.display = "block"; - } else { - x.style.display = "none"; - } - if (hasError) { - setDisabled("button-start", true); - } -} - -// This function is a work-around to the Firefox Incognito Context mode Bug. -function getBackgroundPage() { - if (hasIncognitoModeBug()) { - return new DummyChromeExtensionForIncognitoMode(); - } - return chrome.extension.getBackgroundPage(); -} - -class DummyChromeExtensionForIncognitoMode { - constructor() { - } - - isSettingAskEnabled() { - return true; - } - getSettingMediaId() { - return -1; - } - isSettingStartPaused() { - return false; - } - collectDOMandSendDataWithWizard() { - // Nothing - } - collectDOMandSendData() { - // Nothing - } - - sendData(links) { - function onResponse(message) { - console.log(`Message from the launcher: ${message.text}`); - } - function onError(error) { - console.log(`Error: ${error}`); - } - var data = "launch " + links; - console.log("Sending message to launcher: " + data); - var sending = browser.runtime.sendNativeMessage(application, data); - sending.then(onResponse, onError); - } -} - /* ***************************** */ /* Events */ /* ***************************** */ -function onLoaded() { - checkConnection(); - checkIncognitoMode(); - - var enabled = getBackgroundPage().isSettingAskEnabled(); - setVisible("button-immediate-download", !enabled); - - if (!enabled) { - var label = immediateButtonLabel(); - safeInnerHtmlAssignment("button-immediate-download-label", label); - } -} +document.addEventListener('DOMContentLoaded', () => { + checkConnection(); + + // send a message to the background + browser.runtime.sendMessage('get-user-settings', (userSettings) => { + const enabled = isSettingAskEnabled(userSettings); + setVisible("button-immediate-download", !enabled); + + if (!enabled) { + const label = immediateButtonLabel(userSettings); + safeInnerHtmlAssignment("button-immediate-download-label", label); + } + }); +}); -document.addEventListener('DOMContentLoaded', onLoaded); document.getElementById("button-start").addEventListener('click', () => { - getBackgroundPage().collectDOMandSendDataWithWizard(); + browser.runtime.sendMessage('collect-dom-and-send-to-native-app-with-wizard'); window.close(); }); document.getElementById("button-immediate-download").addEventListener('click', () => { - getBackgroundPage().collectDOMandSendData(); + browser.runtime.sendMessage('collect-dom-and-send-to-native-app'); window.close(); }); -document.getElementById("button-manager").addEventListener('click', () => { - var command = "[MANAGER]"; - getBackgroundPage().sendData(command); +document.getElementById("button-manager").addEventListener('click', () => { + browser.runtime.sendMessage({'send-to-native-app': "[MANAGER]"}); window.close(); }); -document.getElementById("button-preference").addEventListener('click', () => { - var command = "[PREFS]"; - getBackgroundPage().sendData(command); +document.getElementById("button-preference").addEventListener('click', () => { + browser.runtime.sendMessage({'send-to-native-app': "[PREFS]"}); window.close(); }); document.getElementById("button-options-page").addEventListener('click', () => { - var openingPage = browser.runtime.openOptionsPage(); + const openingPage = browser.runtime.openOptionsPage(); window.close(); }); @@ -203,10 +137,26 @@ document.getElementById("button-website").addEventListener('click', () => { window.close(); }); -document.getElementById("bug-link").addEventListener('click', () => { - window.open(document.getElementById("bug-link").getAttribute("href"), "_blank"); - window.close(); -}); +/* ***************************** */ +/* Options */ +/* ***************************** */ +function isSettingAskEnabled(userSettings) { + return userSettings === undefined || userSettings.radioApplicationId === undefined || userSettings.radioApplicationId === 1; +} + +function getSettingMediaId(userSettings) { + if (userSettings === undefined) { + return -1; + } + return userSettings.radioMediaId; +} + +function isSettingStartPaused(userSettings) { + if (userSettings === undefined) { + return false; + } + return userSettings.startPaused; +} /* ***************************** */ /* Internationalization */ diff --git a/web-extension/launcher/macx/launcher-manifest-chrome.json b/web-extension/launcher/macx/launcher-manifest-chrome.json index 82d288ed..4b419971 100644 --- a/web-extension/launcher/macx/launcher-manifest-chrome.json +++ b/web-extension/launcher/macx/launcher-manifest-chrome.json @@ -1,6 +1,6 @@ { - "name": "com.setvisible.downrightnow", - "description": "DownRightNow Launcher Host for Native Messaging", + "name": "com.setvisible.arrowdl", + "description": "ArrowDL Launcher Host for Native Messaging", "path": "/ABSOLUTE/PATH/TO/APP/DIRECTORY/launcher", "type": "stdio", "allowed_origins": [ "chrome-extension://modofbhnhlagjmejdbalnijgncppjeio/" ] diff --git a/web-extension/launcher/macx/launcher-manifest-firefox.json b/web-extension/launcher/macx/launcher-manifest-firefox.json index 3221fb2a..31e3d3b4 100644 --- a/web-extension/launcher/macx/launcher-manifest-firefox.json +++ b/web-extension/launcher/macx/launcher-manifest-firefox.json @@ -1,6 +1,6 @@ { - "name": "DownRightNow", - "description": "DownRightNow Launcher Host for Native Messaging", + "name": "ArrowDL", + "description": "ArrowDL Launcher Host for Native Messaging", "path": "/ABSOLUTE/PATH/TO/APP/DIRECTORY/launcher", "type": "stdio", "allowed_extensions": [ "DownRightNow@example.org" ] diff --git a/web-extension/launcher/unix/launcher-manifest-chrome.json b/web-extension/launcher/unix/launcher-manifest-chrome.json index 82d288ed..4b419971 100644 --- a/web-extension/launcher/unix/launcher-manifest-chrome.json +++ b/web-extension/launcher/unix/launcher-manifest-chrome.json @@ -1,6 +1,6 @@ { - "name": "com.setvisible.downrightnow", - "description": "DownRightNow Launcher Host for Native Messaging", + "name": "com.setvisible.arrowdl", + "description": "ArrowDL Launcher Host for Native Messaging", "path": "/ABSOLUTE/PATH/TO/APP/DIRECTORY/launcher", "type": "stdio", "allowed_origins": [ "chrome-extension://modofbhnhlagjmejdbalnijgncppjeio/" ] diff --git a/web-extension/launcher/unix/launcher-manifest-firefox.json b/web-extension/launcher/unix/launcher-manifest-firefox.json index 3221fb2a..31e3d3b4 100644 --- a/web-extension/launcher/unix/launcher-manifest-firefox.json +++ b/web-extension/launcher/unix/launcher-manifest-firefox.json @@ -1,6 +1,6 @@ { - "name": "DownRightNow", - "description": "DownRightNow Launcher Host for Native Messaging", + "name": "ArrowDL", + "description": "ArrowDL Launcher Host for Native Messaging", "path": "/ABSOLUTE/PATH/TO/APP/DIRECTORY/launcher", "type": "stdio", "allowed_extensions": [ "DownRightNow@example.org" ] diff --git a/web-extension/launcher/windows/launcher-manifest-chrome.json b/web-extension/launcher/windows/launcher-manifest-chrome.json index 4b9820df..a033eccb 100644 --- a/web-extension/launcher/windows/launcher-manifest-chrome.json +++ b/web-extension/launcher/windows/launcher-manifest-chrome.json @@ -1,6 +1,6 @@ { - "name": "com.setvisible.downrightnow", - "description": "DownRightNow Launcher Host for Native Messaging", + "name": "com.arrow-dl.extension", + "description": "ArrowDL Launcher Host for Native Messaging", "path": "launcher.exe", "type": "stdio", "allowed_origins": [ "chrome-extension://modofbhnhlagjmejdbalnijgncppjeio/" ] diff --git a/web-extension/launcher/windows/launcher-manifest-firefox.json b/web-extension/launcher/windows/launcher-manifest-firefox.json index d467a10c..aeca856e 100644 --- a/web-extension/launcher/windows/launcher-manifest-firefox.json +++ b/web-extension/launcher/windows/launcher-manifest-firefox.json @@ -1,6 +1,6 @@ { - "name": "DownRightNow", - "description": "DownRightNow Launcher Host for Native Messaging", + "name": "com.arrow-dl.extension", + "description": "ArrowDL Launcher Host for Native Messaging", "path": "launcher.exe", "type": "stdio", "allowed_extensions": [ "DownRightNow@example.org" ] diff --git a/web-extension/setup/macx/TODO b/web-extension/setup/macx/TODO index e79f8548..902b7eb3 100644 --- a/web-extension/setup/macx/TODO +++ b/web-extension/setup/macx/TODO @@ -1,5 +1,5 @@ TODO copy to -~/Library/Application Support/Mozilla/NativeMessagingHosts/DownRightNow.json +~/Library/Application Support/Mozilla/NativeMessagingHosts/ArrowDL.json diff --git a/web-extension/setup/unix/install.sh b/web-extension/setup/unix/install.sh index 719d2f40..bf0b3bbc 100644 --- a/web-extension/setup/unix/install.sh +++ b/web-extension/setup/unix/install.sh @@ -30,12 +30,12 @@ install_manifest () { TITLE='Mozilla' SOURCE=./launcher-manifest-firefox.json DESTINATION=~/.mozilla/native-messaging-hosts -TARGET_NAME="DownRightNow" +TARGET_NAME="com.arrow-dl.extension" install_manifest $TITLE $SOURCE $DESTINATION $TARGET_NAME TITLE='Chromium' SOURCE=./launcher-manifest-chrome.json DESTINATION=~/.config/chromium/NativeMessagingHosts/ -TARGET_NAME="com.setvisible.downrightnow" +TARGET_NAME="com.setvisible.arrowdl" install_manifest $TITLE $SOURCE $DESTINATION $TARGET_NAME diff --git a/web-extension/setup/unix/uninstall.sh b/web-extension/setup/unix/uninstall.sh index b73f7c24..ad444a0d 100644 --- a/web-extension/setup/unix/uninstall.sh +++ b/web-extension/setup/unix/uninstall.sh @@ -20,12 +20,12 @@ uninstall_manifest () { TITLE='Mozilla' SOURCE=./launcher-manifest-firefox.json DESTINATION=~/.mozilla/native-messaging-hosts -TARGET_NAME="DownRightNow" +TARGET_NAME="com.arrow-dl.extension" uninstall_manifest $TITLE $SOURCE $DESTINATION $TARGET_NAME TITLE='Chromium' SOURCE=./launcher-manifest-chrome.json DESTINATION=~/.config/chromium/NativeMessagingHosts/ -TARGET_NAME="com.setvisible.downrightnow" +TARGET_NAME="com.setvisible.arrowdl" uninstall_manifest $TITLE $SOURCE $DESTINATION $TARGET_NAME diff --git a/web-extension/setup/windows/install.bat b/web-extension/setup/windows/install.bat index 47d1bb52..aeaf00dd 100644 --- a/web-extension/setup/windows/install.bat +++ b/web-extension/setup/windows/install.bat @@ -22,7 +22,7 @@ IF NOT "%1"=="" ( ) ECHO ************************************************* -ECHO Down Right Now +ECHO ArrowDL ECHO ************************************************* ECHO. ECHO Install to: %INSTALL_PATH% @@ -31,26 +31,26 @@ ECHO. ECHO. ECHO Writting to Chrome Registry... ECHO --------------------------------- -ECHO Key: HKCU\Software\Google\Chrome\NativeMessagingHosts\com.setvisible.downrightnow -REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.setvisible.downrightnow" /ve /t REG_SZ /d "%INSTALL_PATH%\launcher-manifest-chrome.json" /f +ECHO Key: HKCU\Software\Google\Chrome\NativeMessagingHosts\com.arrow-dl.extension +REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.arrow-dl.extension" /ve /t REG_SZ /d "%INSTALL_PATH%\launcher-manifest-chrome.json" /f ECHO. ECHO Writting to Firefox Registry... ECHO --------------------------------- -ECHO Key: HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\DownRightNow -REG ADD "HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\DownRightNow" /ve /t REG_SZ /d "%INSTALL_PATH%\launcher-manifest-firefox.json" /f +ECHO Key: HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\com.arrow-dl.extension +REG ADD "HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\com.arrow-dl.extension" /ve /t REG_SZ /d "%INSTALL_PATH%\launcher-manifest-firefox.json" /f ECHO. ECHO Writting to Waterfox Registry... ECHO --------------------------------- -ECHO Key: HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\DownRightNow -REG ADD "HKCU\SOFTWARE\Waterfox\NativeMessagingHosts\DownRightNow" /ve /t REG_SZ /d "%INSTALL_PATH%\launcher-manifest-firefox.json" /f +ECHO Key: HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\com.arrow-dl.extension +REG ADD "HKCU\SOFTWARE\Waterfox\NativeMessagingHosts\com.arrow-dl.extension" /ve /t REG_SZ /d "%INSTALL_PATH%\launcher-manifest-firefox.json" /f ECHO. ECHO Writting to Thunderbird Registry... ECHO --------------------------------- -ECHO Key: HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\DownRightNow -REG ADD "HKCU\SOFTWARE\Thunderbird\NativeMessagingHosts\DownRightNow" /ve /t REG_SZ /d "%INSTALL_PATH%\launcher-manifest-firefox.json" /f +ECHO Key: HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\com.arrow-dl.extension +REG ADD "HKCU\SOFTWARE\Thunderbird\NativeMessagingHosts\com.arrow-dl.extension" /ve /t REG_SZ /d "%INSTALL_PATH%\launcher-manifest-firefox.json" /f ECHO. ECHO ^>^>^> Done! ^<^<^< diff --git a/web-extension/setup/windows/uninstall.bat b/web-extension/setup/windows/uninstall.bat index e35d536d..8ad76244 100644 --- a/web-extension/setup/windows/uninstall.bat +++ b/web-extension/setup/windows/uninstall.bat @@ -15,29 +15,29 @@ IF NOT "%1"=="" ( ) ECHO ************************************************* -ECHO Down Right Now +ECHO ArrowDL ECHO ************************************************* ECHO. ECHO. ECHO Deleting Chrome Registry... ECHO --------------------------------- -REG DELETE "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.setvisible.downrightnow" /f +REG DELETE "HKCU\Software\Google\Chrome\NativeMessagingHosts\com.arrow-dl.extension" /f ECHO. ECHO Deleting Firefox Registry... ECHO --------------------------------- -REG DELETE "HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\DownRightNow" /f +REG DELETE "HKCU\SOFTWARE\Mozilla\NativeMessagingHosts\com.arrow-dl.extension" /f ECHO. ECHO Deleting Waterfox Registry... ECHO --------------------------------- -REG DELETE "HKCU\SOFTWARE\Waterfox\NativeMessagingHosts\DownRightNow" /f +REG DELETE "HKCU\SOFTWARE\Waterfox\NativeMessagingHosts\com.arrow-dl.extension" /f ECHO. ECHO Deleting Thunderbird Registry... ECHO --------------------------------- -REG DELETE "HKCU\SOFTWARE\Thunderbird\NativeMessagingHosts\DownRightNow" /f +REG DELETE "HKCU\SOFTWARE\Thunderbird\NativeMessagingHosts\com.arrow-dl.extension" /f ECHO. ECHO ^>^>^> Done! ^<^<^<