Skip to content

Commit

Permalink
Add JS Alert block button (duckduckgo#1039)
Browse files Browse the repository at this point in the history
* POC for suppress dialogs

https://app.asana.com/0/715106103902962/1201481513493461/f

* Modify suppress alert text

https://app.asana.com/0/715106103902962/1201481513493461/f

* PFR Feedback - JSAlerts

Add pixel and change alert button label
https://app.asana.com/0/1175293949586521/1201692089019804/f

* Add translations
  • Loading branch information
Bunn authored Jan 28, 2022
1 parent 203def3 commit 0e8f7c1
Show file tree
Hide file tree
Showing 53 changed files with 211 additions and 29 deletions.
3 changes: 3 additions & 0 deletions Core/Pixel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ public enum PixelName: String {

case textSizeSettingsShown = "m_text_size_settings_shown"
case textSizeSettingsChanged = "m_text_size_settings_changed"

case jsAlertShown = "m_js_alert_shown"
case jsAlertBlocked = "m_js_alert_blocked"

// MARK: SERP pixels

Expand Down
35 changes: 22 additions & 13 deletions DuckDuckGo/TabViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class TabViewController: UIViewController {
private var textSizeUserScript = TextSizeUserScript()
private var autofillUserScript = AutofillUserScript()
private var debugScript = DebugUserScript()
private var shouldBlockJSAlert = false

lazy var emailManager: EmailManager = {
let emailManager = EmailManager()
Expand All @@ -186,7 +187,7 @@ class TabViewController: UIViewController {
private var userScripts: [UserScript] = []

private var canDisplayJavaScriptAlert: Bool {
return presentedViewController == nil && delegate?.tabCheckIfItsBeingCurrentlyPresented(self) ?? false
return !shouldBlockJSAlert && presentedViewController == nil && delegate?.tabCheckIfItsBeingCurrentlyPresented(self) ?? false
}

static func loadFromStoryboard(model: Tab) -> TabViewController {
Expand Down Expand Up @@ -1397,8 +1398,10 @@ extension TabViewController: WKUIDelegate {
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping () -> Void) {
if canDisplayJavaScriptAlert {
let alertController = WebJSAlert(message: message,
alertType: .alert(handler: completionHandler)).createAlertController()
let alertController = WebJSAlert(message: message, alertType: .alert(handler: { [weak self] blockAlerts in
self?.shouldBlockJSAlert = blockAlerts
completionHandler()
})).createAlertController()

self.present(alertController, animated: true, completion: nil)
} else {
Expand All @@ -1413,29 +1416,35 @@ extension TabViewController: WKUIDelegate {

if canDisplayJavaScriptAlert {
let alertController = WebJSAlert(message: message,
alertType: .confirm(handler: completionHandler)).createAlertController()
alertType: .confirm(handler: { [weak self] blockAlerts, confirm in
self?.shouldBlockJSAlert = blockAlerts
completionHandler(confirm)
})).createAlertController()

self.present(alertController, animated: true, completion: nil)
} else {
completionHandler(false)
}
}

func webView(_ webView: WKWebView,
runJavaScriptTextInputPanelWithPrompt prompt: String,
defaultText: String?,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (String?) -> Void) {
func webView(_ webView: WKWebView,
runJavaScriptTextInputPanelWithPrompt prompt: String,
defaultText: String?,
initiatedByFrame frame: WKFrameInfo,
completionHandler: @escaping (String?) -> Void) {
if canDisplayJavaScriptAlert {
let alertController = WebJSAlert(message: prompt,
alertType: .text(handler: completionHandler,
defaultText: defaultText)).createAlertController()
alertType: .text(handler: { [weak self] blockAlerts, text in

self?.shouldBlockJSAlert = blockAlerts
completionHandler(text)
}, defaultText: defaultText)).createAlertController()

self.present(alertController, animated: true, completion: nil)
} else {
completionHandler(nil)
}
}
}
}

extension TabViewController: UIPopoverPresentationControllerDelegate {
Expand Down
2 changes: 2 additions & 0 deletions DuckDuckGo/UserText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -425,4 +425,6 @@ public struct UserText {
let message = NSLocalizedString("textSize.footer", value: "Text Size - %@", comment: "Replacement string is a current percent value e.g. '120%'")
return message.format(arguments: percentage)
}
public static let webJSAlertDisableAlertsButton = NSLocalizedString("webJSAlert.block-alerts.button", value: "Block Alerts", comment: "Block Alerts button for JavaScript alerts")

}
51 changes: 36 additions & 15 deletions DuckDuckGo/WebJSAlert.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
//

import UIKit
import Core

struct WebJSAlert {
enum JSAlertType {
case confirm(handler: (Bool) -> Void)
case text(handler: (String?) -> Void, defaultText: String?)
case alert(handler: () -> Void)
case confirm(handler: (_ blockAlerts: Bool, _ confirm: Bool) -> Void)
case text(handler: (_ blockAlerts: Bool, _ text: String?) -> Void, defaultText: String?)
case alert(handler: (_ blockAlerts: Bool) -> Void)
}

private let message: String
Expand All @@ -35,26 +36,40 @@ struct WebJSAlert {
}

func createAlertController() -> UIAlertController {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)

switch alertType {
// createAlertController is only called right before its presentation
Pixel.fire(pixel: .jsAlertShown)

let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)
switch alertType {

case .confirm(let handler):
alertController.addAction(UIAlertAction(title: UserText.webJSAlertOKButton,
style: .default, handler: { _ in
handler(true)
handler(false, true)
}))

alertController.addAction(UIAlertAction(title: UserText.webJSAlertCancelButton,
style: .cancel, handler: { _ in
handler(false)
style: .default, handler: { _ in
handler(false, false)
}))

alertController.addAction(UIAlertAction(title: UserText.webJSAlertDisableAlertsButton,
style: .destructive, handler: { _ in
Pixel.fire(pixel: .jsAlertBlocked)
handler(true, false)
}))
return alertController

case .alert(let handler):
alertController.addAction(UIAlertAction(title: UserText.webJSAlertOKButton,
style: .default, handler: { _ in
handler()
handler(false)
}))
alertController.addAction(UIAlertAction(title: UserText.webJSAlertDisableAlertsButton,
style: .destructive, handler: { _ in
Pixel.fire(pixel: .jsAlertBlocked)
handler(true)
}))
return alertController

Expand All @@ -65,16 +80,22 @@ struct WebJSAlert {

alertController.addAction(UIAlertAction(title: UserText.webJSAlertOKButton,
style: .default, handler: { [weak alertController] _ in
handler(alertController?.textFields?.first?.text)

handler(false, alertController?.textFields?.first?.text)
}))

alertController.addAction(UIAlertAction(title: UserText.webJSAlertCancelButton,
style: .cancel, handler: { _ in
handler(nil)
style: .default, handler: { _ in
handler(false, nil)
}))

alertController.addAction(UIAlertAction(title: UserText.webJSAlertDisableAlertsButton,
style: .destructive, handler: { _ in
Pixel.fire(pixel: .jsAlertBlocked)
handler(true, nil)
}))

return alertController
}
}
}
}
3 changes: 3 additions & 0 deletions DuckDuckGo/bg.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Позволява запазване на изображения на вашето устройство";

/* Privacy - Speech Recognition Usage Description */
"NSSpeechRecognitionUsageDescription" = "Необходимо е за използване на гласово търсене. DuckDuckGo никога не записва какво казвате.";

/* (No Comment) */
"Paste from clipboard" = "Поставяне от клипборда";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/bg.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,9 @@
/* Confirmation message */
"web.url.save.favorite.done" = "Добавено в любими";

/* Block Alerts button for JavaScript alerts */
"webJSAlert.block-alerts.button" = "Блокиране на предупрежденията";

/* Cancel button for JavaScript alerts */
"webJSAlert.cancel.button" = "Отмени";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/cs.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Umožňuje vám ukládat obrázky do vašeho zařízení";

/* Privacy - Speech Recognition Usage Description */
"NSSpeechRecognitionUsageDescription" = "Je potřeba pro používání hlasového vyhledávání. DuckDuckGo nikdy nenahrává, co říkáš.";

/* (No Comment) */
"Paste from clipboard" = "Vložit ze schránky";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/cs.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,9 @@
/* Confirmation message */
"web.url.save.favorite.done" = "Oblíbené položky uloženy";

/* Block Alerts button for JavaScript alerts */
"webJSAlert.block-alerts.button" = "Blokovat výstrahy";

/* Cancel button for JavaScript alerts */
"webJSAlert.cancel.button" = "Zrušit";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/da.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Gør det muligt at gemme billeder på din enhed";

/* Privacy - Speech Recognition Usage Description */
"NSSpeechRecognitionUsageDescription" = "Dette er nødvendigt for at bruge stemmesøgning. DuckDuckGo optager aldrig det, du siger.";

/* (No Comment) */
"Paste from clipboard" = "Indsæt fra udklipsholder";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/da.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,9 @@
/* Confirmation message */
"web.url.save.favorite.done" = "Favorit tilføjet";

/* Block Alerts button for JavaScript alerts */
"webJSAlert.block-alerts.button" = "Bloker advarsler";

/* Cancel button for JavaScript alerts */
"webJSAlert.cancel.button" = "Annullér";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/de.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Speichere Bilder auf deinem Gerät";

/* Privacy - Speech Recognition Usage Description */
"NSSpeechRecognitionUsageDescription" = "Dies ist für die Nutzung der Sprachsuche erforderlich. DuckDuckGo zeichnet nie auf, was du sagst.";

/* (No Comment) */
"Paste from clipboard" = "Vom Clipboard einfügen";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,9 @@
/* Confirmation message */
"web.url.save.favorite.done" = "Favorit wurde hinzugefügt";

/* Block Alerts button for JavaScript alerts */
"webJSAlert.block-alerts.button" = "Benachrichtigungen blockieren";

/* Cancel button for JavaScript alerts */
"webJSAlert.cancel.button" = "Abbrechen";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/el.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Σας επιτρέπει να αποθηκεύετε φωτογραφίες στη συσκευή σας";

/* Privacy - Speech Recognition Usage Description */
"NSSpeechRecognitionUsageDescription" = "Αυτό είναι απαραίτητο για τη χρήση φωνητικής αναζήτησης. Το DuckDuckGo δεν καταγράφει ποτέ ό,τι λέτε.";

/* (No Comment) */
"Paste from clipboard" = "Επικόλληση από το πρόχειρο";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/el.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,9 @@
/* Confirmation message */
"web.url.save.favorite.done" = "Προστέθηκε αγαπημένο";

/* Block Alerts button for JavaScript alerts */
"webJSAlert.block-alerts.button" = "Αποκλεισμός ειδοποιήσεων";

/* Cancel button for JavaScript alerts */
"webJSAlert.cancel.button" = "Ακύρωση";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,9 @@
/* Confirmation message */
"web.url.save.favorite.done" = "Favorite added";

/* Block Alerts button for JavaScript alerts */
"webJSAlert.block-alerts.button" = "Block Alerts";

/* Cancel button for JavaScript alerts */
"webJSAlert.cancel.button" = "Cancel";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/es.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Te permite guardar imágenes en tu dispositivo";

/* Privacy - Speech Recognition Usage Description */
"NSSpeechRecognitionUsageDescription" = "Esto es necesario para utilizar la búsqueda por voz. DuckDuckGo nunca graba lo que dices.";

/* (No Comment) */
"Paste from clipboard" = "Pegar desde el portapapeles";

Expand Down
5 changes: 4 additions & 1 deletion DuckDuckGo/es.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@
"feedback.positive.header" = "¡Es fantástico oír eso!";

/* No comment provided by engineer. */
"feedback.positive.noThanks" = "No, gracias. He terminado";
"feedback.positive.noThanks" = "No, gracias He terminado";

/* Button encouraging uses to share details aboout their feedback */
"feedback.positive.submit" = "Compartir detalles";
Expand Down Expand Up @@ -1078,6 +1078,9 @@
/* Confirmation message */
"web.url.save.favorite.done" = "Favorito añadido";

/* Block Alerts button for JavaScript alerts */
"webJSAlert.block-alerts.button" = "Bloquear alertas";

/* Cancel button for JavaScript alerts */
"webJSAlert.cancel.button" = "Cancelar";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/et.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Võimaldab salvestada pilte oma seadmesse";

/* Privacy - Speech Recognition Usage Description */
"NSSpeechRecognitionUsageDescription" = "See on vajalik häälotsingu kasutamiseks. DuckDuckGo ei salvesta kunagi seda, mida te ütlete.";

/* (No Comment) */
"Paste from clipboard" = "Kleebi lõikelaualt";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/et.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,9 @@
/* Confirmation message */
"web.url.save.favorite.done" = "Lemmik lisatud";

/* Block Alerts button for JavaScript alerts */
"webJSAlert.block-alerts.button" = "Blokeerige märguanded";

/* Cancel button for JavaScript alerts */
"webJSAlert.cancel.button" = "Tühista";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/fi.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Voit tallentaa kuvia laitteellesi";

/* Privacy - Speech Recognition Usage Description */
"NSSpeechRecognitionUsageDescription" = "Tämä vaaditaan puhehaun käyttämiseen. DuckDuckGo ei koskaan tallenna puhettasi.";

/* (No Comment) */
"Paste from clipboard" = "Liitä leikepöydältä";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/fi.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,9 @@
/* Confirmation message */
"web.url.save.favorite.done" = "Suosikki lisätty";

/* Block Alerts button for JavaScript alerts */
"webJSAlert.block-alerts.button" = "Estä ilmoitukset";

/* Cancel button for JavaScript alerts */
"webJSAlert.cancel.button" = "Peruuta";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/fr.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Vous permet d'enregistrer des images sur votre appareil";

/* Privacy - Speech Recognition Usage Description */
"NSSpeechRecognitionUsageDescription" = "Requis pour utiliser la recherche vocale. DuckDuckGo n'enregistre jamais ce que vous dites.";

/* (No Comment) */
"Paste from clipboard" = "Coller depuis le presse-papier";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/fr.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,9 @@
/* Confirmation message */
"web.url.save.favorite.done" = "Favori ajouté";

/* Block Alerts button for JavaScript alerts */
"webJSAlert.block-alerts.button" = "Bloquer les alertes";

/* Cancel button for JavaScript alerts */
"webJSAlert.cancel.button" = "Annuler";

Expand Down
3 changes: 3 additions & 0 deletions DuckDuckGo/hr.lproj/InfoPlist.strings
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
/* Privacy - Photo Library Additions Usage Description */
"NSPhotoLibraryAddUsageDescription" = "Omogućuje ti spremanje slika na uređaj";

/* Privacy - Speech Recognition Usage Description */
"NSSpeechRecognitionUsageDescription" = "To je potrebno za korištenje glasovnih funkcija. DuckDuckGo nikad ne snima ono što govorite.";

/* (No Comment) */
"Paste from clipboard" = "Zalijepi iz međuspremnika";

Expand Down
Loading

0 comments on commit 0e8f7c1

Please sign in to comment.