Skip to content

Commit eea52dc

Browse files
author
James Allardice
committed
Merge pull request #40 from jamesallardice/adapters
Adapters to patch jQuery, PrototypeJS and YUI3 methods
2 parents 5165804 + b37d4cc commit eea52dc

File tree

11 files changed

+322
-7
lines changed

11 files changed

+322
-7
lines changed

Gruntfile.js

Lines changed: 61 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ module.exports = function (grunt) {
2828
quotmark: "double"
2929
},
3030
uses_defaults: [
31-
"lib/main.js"
31+
"lib/main.js",
32+
"lib/utils.js"
3233
],
33-
with_overrides: {
34+
override_node: {
3435
options: {
3536
browser: false,
3637
node: true
@@ -41,24 +42,78 @@ module.exports = function (grunt) {
4142
"package.json"
4243
]
4344
}
45+
},
46+
override_jquery: {
47+
options: {
48+
jquery: true
49+
},
50+
files: {
51+
src: ["lib/adapters/placeholders.jquery.js"]
52+
}
53+
},
54+
override_prototype: {
55+
options: {
56+
prototypejs: true,
57+
validthis: true,
58+
"-W020": true // We have to overwrite a prototype built-in method
59+
},
60+
files: {
61+
src: ["lib/adapters/placeholders.prototype.js"]
62+
}
63+
},
64+
override_yui: {
65+
options: {
66+
yui: true
67+
},
68+
files: {
69+
src: ["lib/adapters/placeholders.yui3.js"]
70+
}
4471
}
4572
},
4673
concat: {
47-
dist: {
74+
basic: {
4875
src: [
4976
"lib/utils.js",
5077
"lib/main.js"
5178
],
52-
dest: "build/Placeholders.js"
79+
dest: "build/placeholders.js"
80+
},
81+
jquery: {
82+
src: [
83+
"lib/utils.js",
84+
"lib/main.js",
85+
"lib/adapters/placeholders.jquery.js"
86+
],
87+
dest: "build/placeholders.jquery.js"
88+
},
89+
prototype: {
90+
src: [
91+
"lib/utils.js",
92+
"lib/main.js",
93+
"lib/adapters/placeholders.prototype.js"
94+
],
95+
dest: "build/placeholders.prototype.js"
96+
},
97+
yui3: {
98+
src: [
99+
"lib/utils.js",
100+
"lib/main.js",
101+
"lib/adapters/placeholders.yui3.js"
102+
],
103+
dest: "build/placeholders.yui3.js"
53104
}
54105
},
55106
uglify: {
56107
options: {
57108
banner: "/* Placeholders.js v<%= pkg.version %> */\n"
58109
},
59110
build: {
60-
src: "build/Placeholders.js",
61-
dest: "build/Placeholders.min.js"
111+
files: {
112+
"build/placeholders.min.js": ["build/placeholders.js"],
113+
"build/placeholders.jquery.min.js": ["build/placeholders.jquery.js"],
114+
"build/placeholders.prototype.min.js": ["build/placeholders.prototype.js"],
115+
"build/placeholders.yui3.min.js": ["build/placeholders.yui3.js"]
116+
}
62117
}
63118
}
64119
});

lib/adapters/placeholders.jquery.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
(function ($) {
2+
3+
"use strict";
4+
5+
var originalValFn = $.fn.val,
6+
originalPropFn = $.fn.prop;
7+
8+
if (!Placeholders.nativeSupport) {
9+
$.fn.val = function (val) {
10+
if (val === undefined && this.eq(0).data("placeholder-active")) {
11+
return "";
12+
}
13+
return originalValFn.apply(this, arguments);
14+
};
15+
16+
$.fn.prop = function (name, val) {
17+
if (val === undefined && this.eq(0).data("placeholder-active") && name === "value") {
18+
return "";
19+
}
20+
return originalPropFn.apply(this, arguments);
21+
};
22+
}
23+
24+
}(jQuery));
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
(function (F) {
2+
3+
"use strict";
4+
5+
var originalGetValueMethod = F.Element.Methods.getValue,
6+
originalGetValueStatic = F.Element.getValue,
7+
originalGlobal = $F;
8+
9+
function getValue(originalFn, elem) {
10+
if (elem.getAttribute("data-placeholder-active")) {
11+
return "";
12+
}
13+
return originalFn.call(this, elem);
14+
}
15+
16+
if (!Placeholders.nativeSupport) {
17+
18+
$F = function (elem) {
19+
return getValue.call(this, originalGlobal, elem);
20+
};
21+
22+
F.Element.getValue = function (elem) {
23+
return getValue.call(this, originalGetValueStatic, elem);
24+
};
25+
26+
Element.addMethods([
27+
"INPUT",
28+
"TEXTAREA"
29+
], {
30+
getValue: function (elem) {
31+
return getValue.call(this, originalGetValueMethod, elem);
32+
}
33+
});
34+
}
35+
36+
}(Form));

lib/adapters/placeholders.yui3.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
(function (YUI) {
2+
3+
"use strict";
4+
5+
YUI.add("placeholders", function (Y) {
6+
var originalGetFn = Y.Node.prototype.get;
7+
Y.Node.prototype.get = function (attr) {
8+
if (attr === "value" && this.getAttribute("data-placeholder-active")) {
9+
return "";
10+
}
11+
return originalGetFn.apply(this, arguments);
12+
};
13+
}, "3.0.0", {
14+
requires: [
15+
"node"
16+
]
17+
});
18+
19+
}(YUI));

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "Placeholders.js",
3-
"version": "2.1.1",
3+
"version": "3.0.0",
44
"author": "James Allardice <[email protected]>",
55
"description": "A JavaScript polyfill for the HTML5 placeholder attribute",
66
"private": true,

test/adapters/jquery/tests.html

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Placeholders.js Browser Test</title>
6+
<link rel="stylesheet" href="../../tests.css">
7+
</head>
8+
<body>
9+
10+
<!-- jQuery adapter should cause the val method to return the empty string -->
11+
<input placeholder="Test no type" id="jq1">
12+
13+
<!-- Adapter should handle elements with a placeholder and an initial value -->
14+
<input type="text" placeholder="Test initial value" value="Initial value" id="jq2">
15+
16+
<!-- Adapter should handle placeholder values that change via script (this changes after 1s) -->
17+
<input type="text" placeholder="Test changing value" id="handle1">
18+
19+
<!-- Adapter should handle placeholder values are added via script (this gets one after 1s) -->
20+
<input type="text" id="handle2">
21+
22+
<!-- Adapter should handle input types that change after page load e.g. text->password -->
23+
<input type="text" id="handle3" placeholder="Change to password">
24+
25+
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
26+
<script src="../../../build/placeholders.jquery.js"></script>
27+
<script src="tests.js"></script>
28+
</body>
29+
</html>

test/adapters/jquery/tests.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
setTimeout(function () {
2+
3+
// Test changing placeholder attribute value
4+
document.getElementById("handle1").setAttribute("placeholder", "This value has changed");
5+
6+
// Test created placeholder attribute value
7+
document.getElementById("handle2").setAttribute("placeholder", "This value has been added");
8+
9+
// Test input type changing after page load
10+
try {
11+
document.getElementById("handle3").type = "password";
12+
} catch (e) {
13+
// This will fail in IE < 9
14+
}
15+
16+
setTimeout(function () {
17+
18+
// The behaviour of `val` and `prop` as getters should be patched
19+
alert($("#jq1").val() === "");
20+
alert($("#jq1").prop("value") === "");
21+
22+
alert($("#jq2").val() === "Initial value");
23+
alert($("#jq2").prop("value") === "Initial value");
24+
25+
alert($("#handle1").val() === "");
26+
alert($("#handle1").prop("value") === "");
27+
28+
alert($("#handle2").val() === "");
29+
alert($("#handle2").prop("value") === "");
30+
31+
alert($("#handle3").val() === "");
32+
alert($("#handle3").prop("value") === "");
33+
34+
// The behaviour of `val` and `prop` as setters should not be affected)
35+
alert($("#jq1").val("set new") instanceof $);
36+
alert($("#handle3").prop("value", "another new") instanceof $);
37+
}, 1000);
38+
39+
}, 1000);

test/adapters/prototype/tests.html

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Placeholders.js Browser Test</title>
6+
<link rel="stylesheet" href="../../tests.css">
7+
</head>
8+
<body>
9+
10+
<!-- Prototype adapter should cause the getValue methods to return the empty string -->
11+
<input placeholder="Test no type" id="p1">
12+
13+
<!-- Adapter should handle elements with a placeholder and an initial value -->
14+
<input type="text" placeholder="Test initial value" value="Initial value" id="p2">
15+
16+
<!-- Adapter should handle placeholder values that change via script (this changes after 1s) -->
17+
<input type="text" placeholder="Test changing value" id="handle1">
18+
19+
<!-- Adapter should handle placeholder values are added via script (this gets one after 1s) -->
20+
<input type="text" id="handle2">
21+
22+
<!-- Adapter should handle input types that change after page load e.g. text->password -->
23+
<input type="text" id="handle3" placeholder="Change to password">
24+
25+
<script src="http://ajax.googleapis.com/ajax/libs/prototype/1.7.1.0/prototype.js"></script>
26+
<script src="../../../build/placeholders.prototype.js"></script>
27+
<script src="tests.js"></script>
28+
</body>
29+
</html>

test/adapters/prototype/tests.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
setTimeout(function () {
2+
3+
// Test changing placeholder attribute value
4+
document.getElementById("handle1").setAttribute("placeholder", "This value has changed");
5+
6+
// Test created placeholder attribute value
7+
document.getElementById("handle2").setAttribute("placeholder", "This value has been added");
8+
9+
// Test input type changing after page load
10+
try {
11+
document.getElementById("handle3").type = "password";
12+
} catch (e) {
13+
// This will fail in IE < 9
14+
}
15+
16+
setTimeout(function () {
17+
// The behaviour of `getValue` as an instance method should be patched
18+
alert($("p1").getValue());
19+
alert($("p2").getValue());
20+
alert($("handle1").getValue());
21+
alert($("handle2").getValue());
22+
alert($("handle3").getValue());
23+
24+
// The behaviour of `getValue` as a static method should be patched
25+
alert(Form.Element.getValue($("p1")));
26+
27+
// The behaviour of `$F` as an alias of `getValue` should be patched
28+
alert($F($("p1")));
29+
}, 1000);
30+
31+
}, 1000);

test/adapters/yui3/tests.html

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<!doctype html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Placeholders.js Browser Test</title>
6+
<link rel="stylesheet" href="../../tests.css">
7+
</head>
8+
<body>
9+
10+
<!-- YUI3 adapter should cause the get method to return the empty string -->
11+
<input placeholder="Test no type" id="p1">
12+
13+
<!-- Adapter should handle elements with a placeholder and an initial value -->
14+
<input type="text" placeholder="Test initial value" value="Initial value" id="p2">
15+
16+
<!-- Adapter should handle placeholder values that change via script (this changes after 1s) -->
17+
<input type="text" placeholder="Test changing value" id="handle1">
18+
19+
<!-- Adapter should handle placeholder values are added via script (this gets one after 1s) -->
20+
<input type="text" id="handle2">
21+
22+
<!-- Adapter should handle input types that change after page load e.g. text->password -->
23+
<input type="text" id="handle3" placeholder="Change to password">
24+
25+
<script src="http://cdnjs.cloudflare.com/ajax/libs/yui/3.3.0/yui-min.js"></script>
26+
<script src="../../../build/placeholders.yui3.js"></script>
27+
<script src="tests.js"></script>
28+
</body>
29+
</html>

0 commit comments

Comments
 (0)