Permalink
Comparing changes
Open a pull request
- 2 commits
- 5 files changed
- 0 commit comments
- 2 contributors
Commits on Oct 10, 2016
….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.
Protractor's by.binding selector selects the whole element in which the binding is contained as otherwise it can't know which bit of text has been interpolated. It's safer to wrap the binding in a span so that we're sure what the e2e tests are exactly testing.
Unified
Split
Showing
with
38 additions
and 8 deletions.
- +9 −6 src/ng/directive/input.js
- +10 −0 test/e2e/fixtures/input-hidden/index.html
- +1 −1 test/e2e/fixtures/ng-jq-jquery/index.html
- +1 −1 test/e2e/fixtures/ng-jq/index.html
- +17 −0 test/e2e/tests/input-hidden.spec.js
| @@ -1992,17 +1992,20 @@ var inputDirective = ['$browser', '$sniffer', '$filter', '$parse', | ||
| return { | ||
| restrict: 'E', | ||
| require: ['?ngModel'], | ||
| link: { | ||
| pre: function(scope, element, attr, ctrls) { | ||
| if (ctrls[0]) { | ||
| compile: function(tElement, tAttr) { | ||
| if (lowercase(tAttr.type) === 'hidden') tAttr.$set('autocomplete', 'off'); | ||
| return { | ||
| pre: function(scope, element, attr, ctrls) { | ||
| if (ctrls[0]) { | ||
| var type = lowercase(attr.type); | ||
| if ((type === 'range') && !attr.hasOwnProperty('ngInputRange')) { | ||
| type = 'text'; | ||
| } | ||
| (inputType[type] || inputType.text)(scope, element, attr, ctrls[0], $sniffer, | ||
| $browser, $filter, $parse); | ||
| (inputType[type] || inputType.text)(scope, element, attr, ctrls[0], $sniffer, | ||
| $browser, $filter, $parse); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| }; | ||
| }]; | ||
| @@ -0,0 +1,10 @@ | ||
| <!DOCTYPE html> | ||
| <html ng-app> | ||
| <body> | ||
| <form> | ||
| <input type="hidden" value="{{value}}" /> | ||
| <button ng-click="value = '{{ 7 * 6 }}'">Click me</button> | ||
| </form> | ||
| <script src="angular.js"></script> | ||
| </body> | ||
| </html> |
| @@ -1,7 +1,7 @@ | ||
| <!DOCTYPE html> | ||
| <html ng-app="test" ng-jq="jQuery_2_1_0"> | ||
| <body> | ||
| {{jqueryVersion}} | ||
| <span>{{jqueryVersion}}</span> | ||
|
|
||
| <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script> | ||
| <script> | ||
| @@ -1,7 +1,7 @@ | ||
| <!DOCTYPE html> | ||
| <html ng-app="test" ng-jq> | ||
| <body> | ||
| {{jqueryVersion}} | ||
| <span>{{jqueryVersion}}</span> | ||
|
|
||
| <script src="../../../../bower_components/jquery/dist/jquery.js"></script> | ||
| <script type="text/javascript"> | ||
| @@ -0,0 +1,17 @@ | ||
| 'use strict'; | ||
|
|
||
| describe('hidden thingy', function() { | ||
| it('should pass', function() { | ||
|
|
||
| loadFixture('input-hidden'); | ||
| expect(element(by.css('input')).getAttribute('value')).toEqual(''); | ||
|
|
||
| element(by.css('button')).click(); | ||
| expect(element(by.css('input')).getAttribute('value')).toEqual('{{ 7 * 6 }}'); | ||
|
|
||
| loadFixture('sample'); | ||
| browser.driver.executeScript('history.back()'); | ||
| var expectedValue = browser.params.browser === 'safari' ? '{{ 7 * 6 }}' : ''; | ||
| expect(element(by.css('input')).getAttribute('value')).toEqual(expectedValue); | ||
| }); | ||
| }); |