Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add data shim so jQuery's data functions also respect domData. #43

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions can-jquery.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var makeArray = require("can-util/js/make-array/make-array");
var mutate = require("can-util/dom/mutate/mutate");
var setImmediate = require("can-util/js/set-immediate/set-immediate");
var canViewModel = require("can-view-model");
require("./data.js");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.js should probably be removed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we should not include this right now, and document this module so people can add it. That way people can experiment with it? This might be a good way to start.


module.exports = ns.$ = $;

Expand Down
62 changes: 62 additions & 0 deletions can-jquery_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -403,3 +403,65 @@ QUnit.test("extra args to handler can be read using `%arguments`", function () {
var p0 = ta.getElementsByTagName("p")[0];
canEvent.trigger.call(p0, "myevent", ["myarg1", "myarg2"]);
});

QUnit.module("can-jquery/legacy - data functions", {
setup: function() {
enableLegacyMode($);
this.$div = $("<div />").appendTo("#qunit-fixture");
},
teardown: function() {
disableLegacyMode();
}
});

QUnit.test("data() compatibility with can-util/dom/data/", function() {
domData.set.call(this.$div[0], "foo", "bar");
QUnit.equal(this.$div.data("foo"), "bar");

this.$div.data("foo", "baz");
QUnit.equal(domData.get.call(this.$div[0], "foo"), "baz");
});

QUnit.test("data() returns full data object from domData.get() with no arguments", function() {
domData.set.call(this.$div[0], "foo", "bar");
QUnit.deepEqual(this.$div.data(), {"foo" : "bar"});

QUnit.deepEqual($.data(this.$div[0]), {"foo" : "bar"});
});

QUnit.test("data() destructures objects before passing to domData.set", function() {
this.$div.data({"foo": "baz"});
QUnit.equal(domData.get.call(this.$div[0], "foo"), "baz");
});

QUnit.test("hasData() checks both jQuery data and domData", function() {
domData.set.call(this.$div[0], "foo", "bar");
$.data(this.$div[0], "quux", "thud");
QUnit.ok($.hasData(this.$div[0], "foo"));
QUnit.ok($.hasData(this.$div[0], "quux"));
});

QUnit.test("removeData() also calls domData.clean", function() {
domData.set.call(this.$div[0], "foo", "bar");
domData.set.call(this.$div[0], "quux", "thud");

this.$div.removeData("foo");
QUnit.ok(!domData.get.call(this.$div[0], "foo"));
QUnit.equal(domData.get.call(this.$div[0], "quux"), "thud");

this.$div.removeData(); // remove all remaining data;
QUnit.ok(!domData.get.call(this.$div[0], "quux"));

// Repeat for static $.removeData
domData.set.call(this.$div[0], "foo", "bar");
domData.set.call(this.$div[0], "quux", "thud");

$.removeData(this.$div[0], "foo");
QUnit.ok(!domData.get.call(this.$div[0], "foo"));
QUnit.equal(domData.get.call(this.$div[0], "quux"), "thud");

$.removeData(this.$div[0]); // remove all remaining data;
QUnit.ok(!domData.get.call(this.$div[0], "quux"));
});


106 changes: 106 additions & 0 deletions data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/* global module, require */
var $ = require("jquery");
var domData = require("can-util/dom/data/data");
var each = require("can-util/js/each/each");
var assign = require("can-util/js/assign/assign");

module.exports = $;

var oldData = $.data;
var oldFnData = $.fn.data;
$.fn.data = function() {
var args = arguments,
ret = oldFnData.apply(this, arguments);

if(arguments.length < 1) {
// get all (from the first element in the jQ)
assign(ret, domData.get.call(this[0]));
return ret;
} else if(arguments.length === 1 && typeof arguments[0] === "string") {
// get named property
if(ret != null) {
return ret;
} else {
return this.get().reduce(function(val, el) {
return val != null ? val : domData.get.apply(el, args);
}, null);
}
} else {
// set
this.each(function(i, el) {
if(typeof args[0] === "string") {
domData.set.apply(el, args);
} else {
each(args[0], function(val, key) {
domData.set.call(el, key, val);
});
}
});
return ret;
}
};

$.data = function() {
var elem = arguments[0],
args = [].slice.call(arguments, 1),
ret = oldData.apply(this, arguments);

if(arguments.length < 2) {
// get all
assign(ret, domData.get.call(elem));
return ret;
} else if(arguments.length === 2 && typeof arguments[1] === "string") {
// get named property
return ret != null ? ret : domData.get.apply(elem, args);
} else {
if(typeof args[0] === "string") {
domData.set.apply(elem, args);
} else {
each(args[0], function(val, key) {
domData.set.call(elem, key, val);
});
}
return ret;
}
};

var oldHasData = $.hasData;
$.hasData = function() {
var elem = arguments[0],
args = [].slice.call(arguments, 1);
return oldHasData.apply(this, arguments) || domData.get.call(elem).hasOwnProperty(args[0]);
};

var oldRemoveData = $.removeData;
var oldFnRemoveData = $.fn.removeData;

$.fn.removeData = function() {
var args = arguments,
ret = oldFnRemoveData.apply(this, arguments);

this.each(function(i, el) {
if(typeof args[0] === "string") {
domData.clean.apply(el, args);
} else {
each(domData.get.call(el), function(val, key) {
domData.clean.call(el, key);
});
}
});
return ret;
};

$.removeData = function() {
var elem = arguments[0],
args = [].slice.call(arguments, 1),
ret = oldRemoveData.apply(this, arguments);

if(typeof args[0] === "string") {
domData.clean.apply(elem, args);
} else {
each(domData.get.call(elem), function(val, key) {
domData.clean.call(elem, key);
});
}
return ret;
};