Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Setting through el.dataset.x doesn't reflect on the HTML. #1571

Open
MayhemYDG opened this Issue · 14 comments

3 participants

@MayhemYDG
// ==UserScript==
// @name           x
// @version        1
// @namespace      x
// @include        http://*
// ==/UserScript==

(function() {

    d = document;
    a = d.createElement('a');
    a.href = 'http://google.com';
    // doesn't work
    a.dataset.test1 = 'test';
    // works
    a.setAttribute('data-test2', 'test');
    d.head.appendChild(a);

})();

See title and sample code.
Retrieving through el.dataset.x works IF the data-x attribute is set, but setting through el.dataset.x doesn't set the data-x HTML attribute.

@arantius
Collaborator

http://wiki.greasespot.net/Avoid_Common_Pitfalls_in_Greasemonkey
This sounds very much like pitfall #4. "el.dataset" isn't a standard thing is it?

@arantius
Collaborator

Thanks for the info. Perhaps you can use http://wiki.greasespot.net/Content_Scope_Runner ? Or try the 1.0 betas and use "@grant none" which has a similar effect (except of course all users of the script would have to do this -- and the beta really is a beta, it's not necessarily ready for wide use yet).

@MayhemYDG

I'll keep using setAttribute until it's fixed.

@arantius
Collaborator

Ok! I'm leaving this open until it is fixed; but this sounds like the sort of thing that will be very hard, if possible, to fix. The goal for version 1.0 is for user scripts to run in the content scope where everything "just works", rather than in the traditional security-restricted sandbox. For reasons just like this.

@MayhemYDG

I'd like to add that retrieving values through element.dataset.key works, so saving a value through the same means is what I'd like to use.
Conversion between element.dataset.key = ... into an HTML attribute isn't important for me, as I have no use for element.getAttribute('data-key').

tl;dr: el.dataset.key setter itself is more important than conversion into an html attribute.

@arantius
Collaborator

https://gist.github.com/4622821

When I install this script and visit any page (Firefox 19.0, GM 1.7.1), in the console I see:

el_work: test
el_fail: test

And the HTML output looks like (lots of other stuff in the document HEAD and):

<div data-test2="test" id="el_work"></div><div data-test1="test" id="el_fail"></div>

So, this works as expected? It seems to continue to work if I specify @grant none or @grant GM_log.

@MayhemYDG

Nope, doesn't work when I use  @grand GM_log.

Here's the test: https://gist.github.com/4624255

Here's what I get:

[17:22:26.711] work: uno
[17:22:26.712] fail: dos
[17:22:26.714] ["<body data-one=\"uno\">"]
[17:22:28.861] work: uno
[17:22:28.861] fail: undefined
[17:22:28.863] ["<body data-one=\"uno\">"]

The fail test works the first time because the browser didn't do its garbage collection round.
Wait a bit and the fail test will indeed fail.

I'm on GM 1.6 and Fx 18 it that matters.

@MayhemYDG

Same thing happens on GM 1.7.1 + Fx 18.

@MayhemYDG

@arantius

this sounds like the sort of thing that will be very hard, if possible, to fix.

It might be a long shot, but you may be able to fix this using Proxies.
The doc says proxies are non-standard because ES6 hasn't been finalized yet.

It also needs to handle the camelCase -> dashed conversion.
https://developer.mozilla.org/en-US/docs/Web/API/element.dataset

Since datasets aren't in the prototype, you'll have to somehow set this on every elements. I hope it's possible for GM.

Something like

function dataDashing(key) {
  return 'data-' + key.replace(/[A-Z]/g, function(c) {
    return '-' + c.toLowerCase();
  });
}
function setDataset(el) {
  el.dataset = new Proxy({}, {
    get: function(obj, key) {
      return el.getAttribute(dashing(key));
    },
    set: function(obj, key, val) {
      el.setAttribute(dashing(key), val);
      return val;
    },
    'delete': function(obj, key) {
      el.removeAttribute(dashing(key));
      return true;
    }
  });
}
@janekptacijarabaci

Maybe it's been fixed (GM 1.10 + FF 22.0). But maybe I'm wrong...

@MayhemYDG

Looks like it is indeed, thanks.

@MayhemYDG MayhemYDG closed this
@MayhemYDG

Actually it's not entirely fixed,

delete el.dataset.key;

doesn't work from a userscript.

@MayhemYDG MayhemYDG reopened this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.