Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit d5d9ad1

Browse files
fix($compile): ensure that hidden input values are correct after history.back
Due to the nature of some browser's PageCache/BFCache, returning to an Angular app sometimes causes `input[hidden]` elements to retain the last value that was stored before the page was navigated away from previously. This is particularly problematic if the input has an interpolated value. E.g. `<input type="hidden" value="{{ 1 + 2 }}">` since when the browser returns, instead of the original interpolation template, the HTML contains the previous value `<input type="hidden" value="3">`. This commit instructs the browser not to attempt to reinstate the previous value when navigating back in history by setting `autocomplete="off"` on the hidden input element element.
1 parent d36b5c2 commit d5d9ad1

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

src/ng/compile.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -2085,13 +2085,17 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
20852085
var nodeType = node.nodeType,
20862086
attrsMap = attrs.$attr,
20872087
match,
2088+
nodeName,
20882089
className;
20892090

20902091
switch (nodeType) {
20912092
case NODE_TYPE_ELEMENT: /* Element */
2093+
2094+
nodeName = nodeName_(node);
2095+
20922096
// use the node name: <directive>
20932097
addDirective(directives,
2094-
directiveNormalize(nodeName_(node)), 'E', maxPriority, ignoreDirective);
2098+
directiveNormalize(nodeName), 'E', maxPriority, ignoreDirective);
20952099

20962100
// iterate over the attributes
20972101
for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes,
@@ -2133,6 +2137,12 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
21332137
attrEndName);
21342138
}
21352139

2140+
if (nodeName === 'input' && node.getAttribute('type') === 'hidden') {
2141+
// Hidden input elements can have strange behaviour when navigating back to the page
2142+
// This tells the browser not to try to cache and reinstate previous values
2143+
node.setAttribute('autocomplete', 'off');
2144+
}
2145+
21362146
// use class as directive
21372147
if (!cssClassDirectivesEnabled) break;
21382148
className = node.className;
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html ng-app>
3+
<body>
4+
<form>
5+
<input type="hidden" value="{{value}}" />
6+
<button ng-click="value = '{{ 7 * 6 }}'">Click me</button>
7+
</form>
8+
<script src="angular.js"></script>
9+
</body>
10+
</html>

test/e2e/tests/input-hidden.spec.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
'use strict';
2+
3+
describe('hidden thingy', function() {
4+
it('should pass', function() {
5+
6+
loadFixture('input-hidden');
7+
expect(element(by.css('input')).getAttribute('value')).toEqual('');
8+
9+
element(by.css('button')).click();
10+
expect(element(by.css('input')).getAttribute('value')).toEqual('{{ 7 * 6 }}');
11+
12+
loadFixture('sample');
13+
browser.driver.executeScript('history.back()');
14+
var expectedValue = browser.params.browser === 'safari' ? '{{ 7 * 6 }}' : '';
15+
expect(element(by.css('input')).getAttribute('value')).toEqual(expectedValue);
16+
});
17+
});

0 commit comments

Comments
 (0)