Sanitize notifications from chromium browsers
This commit is contained in:
@@ -30,6 +30,22 @@ Item {
|
|||||||
? hostShell.firstPartyServiceFor("omarchy.notifications")
|
? hostShell.firstPartyServiceFor("omarchy.notifications")
|
||||||
: null
|
: null
|
||||||
|
|
||||||
|
function isChromiumDerived(app, appIcon) {
|
||||||
|
var source = (String(app || "") + "\n" + String(appIcon || "")).toLowerCase()
|
||||||
|
return source.indexOf("chrom") >= 0 || source.indexOf("brave") >= 0 ||
|
||||||
|
source.indexOf("vivaldi") >= 0 || source.indexOf("microsoft-edge") >= 0 ||
|
||||||
|
source.indexOf("opera") >= 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function sanitizeBody(s, app, appIcon) {
|
||||||
|
var text = String(s || "").replace(/<img[^>]*>/gi, "")
|
||||||
|
if (!isChromiumDerived(app, appIcon)) return text
|
||||||
|
|
||||||
|
return text
|
||||||
|
.replace(/^\s*<a\b[^>]*>\s*(?:https?:\/\/|www\.)?(?:[a-z0-9-]+\.)+[a-z]{2,}(?::\d+)?(?:\/[^<\s]*)?\s*<\/a>\s*/i, "")
|
||||||
|
.replace(/^\s*(?:https?:\/\/|www\.)?(?:[a-z0-9-]+\.)+[a-z]{2,}(?::\d+)?(?:\/\S*)?\s+/i, "")
|
||||||
|
}
|
||||||
|
|
||||||
readonly property int pendingCount: notificationService ? notificationService.pendingModel.count : 0
|
readonly property int pendingCount: notificationService ? notificationService.pendingModel.count : 0
|
||||||
readonly property int pastCount: notificationService ? notificationService.pastModel.count : 0
|
readonly property int pastCount: notificationService ? notificationService.pastModel.count : 0
|
||||||
readonly property bool dnd: notificationService ? notificationService.doNotDisturb : false
|
readonly property bool dnd: notificationService ? notificationService.doNotDisturb : false
|
||||||
@@ -272,6 +288,7 @@ Item {
|
|||||||
image.indexOf("image://icon//") === 0 || image.indexOf("file://") === 0)
|
image.indexOf("image://icon//") === 0 || image.indexOf("file://") === 0)
|
||||||
readonly property string smallIconSource: image.length > 0 ? image : appIcon
|
readonly property string smallIconSource: image.length > 0 ? image : appIcon
|
||||||
readonly property bool hasIcon: !hasMedia && smallIconSource.length > 0
|
readonly property bool hasIcon: !hasMedia && smallIconSource.length > 0
|
||||||
|
readonly property string sanitizedBody: root.sanitizeBody(body, app, appIcon)
|
||||||
|
|
||||||
width: listView.width
|
width: listView.width
|
||||||
implicitHeight: rowContent.implicitHeight + 20
|
implicitHeight: rowContent.implicitHeight + 20
|
||||||
@@ -334,10 +351,10 @@ Item {
|
|||||||
|
|
||||||
Text {
|
Text {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
visible: rowCard.body.length > 0
|
visible: rowCard.sanitizedBody.length > 0
|
||||||
text: String(rowCard.body).replace(/<img[^>]*>/gi, "")
|
text: rowCard.sanitizedBody
|
||||||
font.family: root.bar ? root.bar.fontFamily : ""
|
font.family: root.bar ? root.bar.fontFamily : ""
|
||||||
textFormat: Text.PlainText
|
textFormat: Text.PlainText
|
||||||
color: root.colDim
|
color: root.colDim
|
||||||
font.pixelSize: 11
|
font.pixelSize: 11
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
|
|||||||
+18
-8
@@ -66,6 +66,13 @@ Rectangle {
|
|||||||
readonly property bool hasGlyph: glyph.length > 0
|
readonly property bool hasGlyph: glyph.length > 0
|
||||||
readonly property bool inlineGlyph: summary.match(/^[^\s]+\s{2,}/) !== null
|
readonly property bool inlineGlyph: summary.match(/^[^\s]+\s{2,}/) !== null
|
||||||
readonly property bool hasSmallIcon: !mediaMode && !inlineGlyph && (smallIconSource.length > 0 || hasGlyph)
|
readonly property bool hasSmallIcon: !mediaMode && !inlineGlyph && (smallIconSource.length > 0 || hasGlyph)
|
||||||
|
readonly property bool chromiumDerived: {
|
||||||
|
var source = (app + "\n" + appIcon).toLowerCase()
|
||||||
|
return source.indexOf("chrom") >= 0 || source.indexOf("brave") >= 0 ||
|
||||||
|
source.indexOf("vivaldi") >= 0 || source.indexOf("microsoft-edge") >= 0 ||
|
||||||
|
source.indexOf("opera") >= 0
|
||||||
|
}
|
||||||
|
readonly property string sanitizedBody: sanitizeBody(body)
|
||||||
|
|
||||||
readonly property color dimColor: Qt.darker(Color.notifications.text, 1.4)
|
readonly property color dimColor: Qt.darker(Color.notifications.text, 1.4)
|
||||||
readonly property color bodyColor: Qt.darker(Color.notifications.text, 1.15)
|
readonly property color bodyColor: Qt.darker(Color.notifications.text, 1.15)
|
||||||
@@ -73,12 +80,15 @@ Rectangle {
|
|||||||
readonly property color accentColor: urgency === 2 ? Color.urgent : (urgency === 0 ? dimColor : Color.notifications.countdown)
|
readonly property color accentColor: urgency === 2 ? Color.urgent : (urgency === 0 ? dimColor : Color.notifications.countdown)
|
||||||
|
|
||||||
function sanitizeBody(s) {
|
function sanitizeBody(s) {
|
||||||
return String(s)
|
var text = String(s).replace(/<img[^>]*>/gi, "")
|
||||||
.replace(/<img[^>]*>/gi, "")
|
if (!chromiumDerived) return text
|
||||||
// Chromium prepends the site origin to some web-push bodies
|
|
||||||
// (e.g. "web.whatsapp.com Message text"). The app/icon already
|
// Chromium web notifications often prefix the body with the sending
|
||||||
// identifies the sender, so hide that noisy URL/domain prefix.
|
// origin, sometimes as a hyperlink. The browser icon already identifies
|
||||||
.replace(/^(?:https?:\/\/)?(?:[a-z0-9-]+\.)+[a-z]{2,}(?::\d+)?\/?\s+/i, "")
|
// the source, so drop only that leading URL/domain.
|
||||||
|
return text
|
||||||
|
.replace(/^\s*<a\b[^>]*>\s*(?:https?:\/\/|www\.)?(?:[a-z0-9-]+\.)+[a-z]{2,}(?::\d+)?(?:\/[^<\s]*)?\s*<\/a>\s*/i, "")
|
||||||
|
.replace(/^\s*(?:https?:\/\/|www\.)?(?:[a-z0-9-]+\.)+[a-z]{2,}(?::\d+)?(?:\/\S*)?\s+/i, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
implicitWidth: 380
|
implicitWidth: 380
|
||||||
@@ -216,8 +226,8 @@ Rectangle {
|
|||||||
Text {
|
Text {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: 2
|
Layout.topMargin: 2
|
||||||
visible: root.body.length > 0
|
visible: root.sanitizedBody.length > 0
|
||||||
text: root.sanitizeBody(root.body)
|
text: root.sanitizedBody
|
||||||
textFormat: Text.StyledText
|
textFormat: Text.StyledText
|
||||||
font.family: "Liberation Sans"
|
font.family: "Liberation Sans"
|
||||||
color: root.bodyColor
|
color: root.bodyColor
|
||||||
|
|||||||
Reference in New Issue
Block a user