Skip to content
This repository has been archived by the owner on Mar 25, 2023. It is now read-only.

GNotifier must process the message body #24

Closed
ssokolow opened this issue May 5, 2014 · 5 comments
Closed

GNotifier must process the message body #24

ssokolow opened this issue May 5, 2014 · 5 comments
Milestone

Comments

@ssokolow
Copy link

ssokolow commented May 5, 2014

My tests show that GNotifier is passing through the message body verbatim. Unfortunately, notification daemons don't expect HTML and many react poorly.

(This is a common mistake people make since Pango markup borrows certain common tag names like <b> from HTML but is not actually HTML.)

For example:

  • The notification-daemon reference implementation which Lubuntu 12.04 uses applies XML-style strict parsing rules and, if there's markup it doesn't recognize, it displays a blank message.
  • GNOME Shell apparently displays anything but <b>, <i>, and <u> as literal plaintext.

According to the Web Notifications spec, "The user agent must process any markup in this string so that it appears as plain text when used as a string in the underlying notification platform."

On Bug 858519 in Bugzilla, I've gone into detail on what the restrictions are and proposed an approach to performing said transformations.

@mkiol
Copy link
Owner

mkiol commented May 5, 2014

Thanks for this discover.

So as you suggested in Bug 858519, text should be filter out before passing data to libnotify. I would be very appreciated if you could propose javascript function that can do such filtering.

@mkiol mkiol added the bug label May 5, 2014
@ssokolow
Copy link
Author

ssokolow commented May 6, 2014

I have no experience with Firefox internals but I'll do what I can. (almost a decade ago, I tried to write extensions and found the API documentation and tooling discouragingly awful. Since the Jetpack SDK came out, I haven't needed to write an extension.)

I ran out of time today, but here's the partly-pseudo code I was able to come up with in the time given. (eg. No HTML sanitization yet and it just assumes that the notification daemon has the IMAGE_SVG capability when the site provides an SVG icon rather than rasterizing it)

The more you can clarify what you need me to do, the more I can focus my efforts.

// --== Stuff you'll probably want to call once on init ==--

var capabilities = notify_get_server_caps();
var server_info = notify_get_server_info();

var clean_markup = function(dom_node) {
    // TODO: Maybe tomorrow.
};

// --== Stuff to call each time ==--

var title = title_as_provided_by_the_api;
var body_dom = dom_firefox_generates_for_internal_notification_renderer;
var icon = icon_as_provided_by_the_api;

if (capabilities.index_of('body-markup') === -1) {
  // I'm too used to jQuery to write this on my own but here's the relevant bit of jQuery().text()
  // http://stackoverflow.com/a/5023626
  var notification = new NotifyNotification(
      title,
      jQuery(body_dom).text(),
      icon);
} else {
  var notification = new NotifyNotification(
      title,
      clean_markup(body_dom),
      icon);
}

if (capabilities.index_of('actions') !== -1 and server_info.name !== 'notify-osd') {
  // This name-matching is really how Unity's notify-osd expects you to manage its dysfunctional 
  // "if there are actions, show an old-style dialog" behaviour.

    var actions = body_dom.querySelectorAll(
        'input[type="submit"], input[type="button"], button');
    for (var i = 0; i < actions.length; ++i) {
        var dom_node = actions[i];
        var action_id = /* Whatever code you use to reconcile DOM and GTK+ events */
        var action_callback = /* Whatever code you use to reconcile DOM and GTK+ events */

        notification.add_action(
            action_id,
            jQuery(dom_node).text(),
            action_callback);
    }
}

Since I ran out of time before implementing it, here's what render_markup must do:

  1. Replace <img> tags with the contents of their alt attributes unless body-images is present in the capabilities.
  2. Subject to the effects of other rules like body-images, remove any elements which are neither text nor <b>, <big>, <i>, <sub>, <sup>, <small>, <span>, <tt>, <u>, or <s> and hoist their children to become children of their parent node.
  3. Remove all attributes except <img src=""> (assuming body-images) and <a href=""> (assuming body-hyperlinks).
  4. Use a regex like sub('\s+', ' ') to perform HTML-like normalization on text nodes since Pango renders as if white-space: pre is in effect.
  5. Replace <br> and <p> with \n since that's how Pango insists newlines be represented.
  6. If the host is GNOME Shell (I'm not sure what the exact server_info.name value is), filter markup further to only <b>, <i>, and <u> or it'll treat other tags as stuff like &lt;big&gt;.

@ssokolow
Copy link
Author

ssokolow commented May 8, 2014

As my not commenting yesterday implied, I'm a bit busy. Do you want me to wait until I can give code for clean_markup that will actually run or will pseudocode do?

(All my DOM manipulation experience is using either jQuery or the Python LXML DOM library so familiarizing myself with the W3C DOM API is a very non-trivial portion of the time it'll take.)

@mkiol
Copy link
Owner

mkiol commented May 8, 2014

I think I have enough information (from you) and can do this dirty work by myself :-) Many thanks for your involvement!

@mkiol
Copy link
Owner

mkiol commented Mar 4, 2018

Finally, the issue has been fixed in the latest dev xpi. It took me only 4 years! ;-)

@mkiol mkiol closed this as completed Mar 4, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants