mirror of
https://github.com/openstf/stf
synced 2025-10-06 03:50:04 +02:00
Added native auto-fill support for URL input in Chrome.
This commit is contained in:
parent
e6465fe8cc
commit
8696f833c2
8 changed files with 254 additions and 190 deletions
28
res/app/components/stf/common-ui/enable-autofill/README.md
Normal file
28
res/app/components/stf/common-ui/enable-autofill/README.md
Normal file
|
@ -0,0 +1,28 @@
|
|||
# enable-autofill
|
||||
|
||||
This directive enables autofill (HTML5 autocomplete) on the selected form.
|
||||
|
||||
Currently this is only needed in `Chrome` because `autofill` only works on form `POST` method.
|
||||
|
||||
Based on [this](http://stackoverflow.com/questions/16445463/how-to-get-chrome-to-autofill-with-asynchronous-post/22191041#22191041).
|
||||
|
||||
## Usage
|
||||
|
||||
```html
|
||||
<form enable-autofill action="about:blank">
|
||||
<input type="text" autocomplete="on">
|
||||
</form>
|
||||
```
|
||||
|
||||
This will create the following DOM:
|
||||
|
||||
```html
|
||||
<iframe src="about:blank" name="_autofill" style="display:none">
|
||||
<form method="post" action="about:blank" target="_autofill">
|
||||
<input type="text" autocomplete="on">
|
||||
</form>
|
||||
```
|
||||
|
||||
Yes, it is a bit ugly but it is currently the only way.
|
||||
|
||||
It will create only one `iframe` which will be reused.
|
|
@ -0,0 +1,34 @@
|
|||
module.exports = function enableAutofillDirective($rootElement) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
compile: function compile(tElement, tAttrs) {
|
||||
|
||||
// Creates hidden iFrame for auto-fill forms if there isn't one already
|
||||
if ($rootElement.find('iframe').attr('name') !== '_autofill') {
|
||||
$rootElement.append(angular.element(
|
||||
'<iframe src="about:blank" name="_autofill" style="display:none">'
|
||||
))
|
||||
}
|
||||
|
||||
// Add attribute method POST to the current form
|
||||
if (!tAttrs.method) {
|
||||
tElement.attr('method', 'post')
|
||||
} else {
|
||||
if (!tAttrs.method.match(/post/i)) {
|
||||
console.error('Auto-fill only works with form POST method')
|
||||
}
|
||||
}
|
||||
|
||||
// Add attribute target to the current form
|
||||
if (!tAttrs.target) {
|
||||
tElement.attr('target', '_autofill')
|
||||
}
|
||||
|
||||
// Add attribute action to the current form
|
||||
// NOTE: This doesn't work so it has to be added manually
|
||||
// if (!tAttrs.action) {
|
||||
// tElement.attr('action', 'about:blank')
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
describe('enableAutofill', function () {
|
||||
|
||||
beforeEach(module('stf.enable-autofill'));
|
||||
|
||||
var scope, compile;
|
||||
|
||||
beforeEach(inject(function ($rootScope, $compile) {
|
||||
scope = $rootScope.$new();
|
||||
compile = $compile;
|
||||
}));
|
||||
|
||||
it('should ...', function () {
|
||||
|
||||
/*
|
||||
To test your directive, you need to create some html that would use your directive,
|
||||
send that through compile() then compare the results.
|
||||
|
||||
var element = compile('<div enable-autofill name="name">hi</div>')(scope);
|
||||
expect(element.text()).toBe('hello, world');
|
||||
*/
|
||||
|
||||
});
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
module.exports = angular.module('stf.enable-autofill', [
|
||||
|
||||
])
|
||||
.directive('enableAutofill', require('./enable-autofill-directive'))
|
|
@ -12,5 +12,6 @@ module.exports = angular.module('stf/common-ui', [
|
|||
require('./include-cached').name,
|
||||
require('./text-focus-select').name,
|
||||
require('./counter').name,
|
||||
require('./badge-icon').name
|
||||
require('./badge-icon').name,
|
||||
require('./enable-autofill').name
|
||||
])
|
||||
|
|
|
@ -2,49 +2,20 @@ var _ = require('lodash')
|
|||
|
||||
module.exports = function NavigationCtrl($scope, $rootScope) {
|
||||
|
||||
$scope.urlHistory = []
|
||||
|
||||
function addToHistory() {
|
||||
var HISTORY_LIMIT = 20
|
||||
|
||||
var history = $scope.urlHistory
|
||||
history.unshift($scope.textURL)
|
||||
if (history.length > HISTORY_LIMIT) {
|
||||
history.pop()
|
||||
}
|
||||
$scope.urlHistory = _.uniq(history)
|
||||
}
|
||||
|
||||
function addHttp() {
|
||||
if ($scope.textURL.indexOf(':') === -1) {
|
||||
$scope.textURL = 'http://' + $scope.textURL
|
||||
function addHttp(textUrl) {
|
||||
if (textUrl.indexOf(':') === -1 && textUrl.indexOf('.') !== -1) {
|
||||
return 'http://' + textUrl
|
||||
}
|
||||
return textUrl
|
||||
}
|
||||
|
||||
$scope.openURL = function () {
|
||||
addHttp()
|
||||
addToHistory()
|
||||
|
||||
return $scope.control.openBrowser(
|
||||
$scope.textURL,
|
||||
addHttp($scope.textURL),
|
||||
$scope.browser
|
||||
)
|
||||
}
|
||||
|
||||
$scope.clearHistory = function () {
|
||||
$scope.urlHistory = []
|
||||
}
|
||||
|
||||
$scope.hasHistory = function () {
|
||||
return $scope.urlHistory.length > 0
|
||||
}
|
||||
|
||||
$scope.insertURL = function ($url) {
|
||||
$scope.textURL = $url
|
||||
$scope.openURL()
|
||||
}
|
||||
|
||||
|
||||
function setCurrentBrowser(browser) {
|
||||
if (browser && browser.apps) {
|
||||
var currentBrowser = {}
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
i.fa.fa-globe
|
||||
span(translate) Navigation
|
||||
span
|
||||
button.btn.btn-xs.btn-danger-outline.pull-right(ng-click='clearSettings()', tooltip='{{ "Reset all browser settings" | translate }}')
|
||||
button.btn.btn-xs.btn-danger-outline.pull-right(ng-click='clearSettings()',
|
||||
tooltip='{{ "Reset all browser settings" | translate }}')
|
||||
i.fa.fa-trash-o
|
||||
span(translate) Reset
|
||||
//.button-spacer.pull-right
|
||||
|
@ -11,22 +12,15 @@
|
|||
//i.fa.fa-step-forward.pull-right(ng-click='forward()', title='{{"Go Forward"|translate}}')
|
||||
//i.fa.fa-step-backward.pull-right(ng-click='back()', title='{{"Go Back"|translate}}')
|
||||
.widget-content.padded
|
||||
form
|
||||
form(enable-autofill, action='about:blank')
|
||||
//form(name='navigationForm', method='post', action='about:blank', target='_autofill')
|
||||
.input-group
|
||||
input.form-control(type='text', placeholder='http://...', autocomplete='off', ng-model='textURL',
|
||||
typeahead='url for url in urlHistory | filter:$viewValue', text-focus-select,
|
||||
input.form-control(type='text', name='textURL', placeholder='http://...',
|
||||
autocomplete='url', ng-model='textURL', text-focus-select,
|
||||
accesskey='N', tabindex='10').form-control
|
||||
|
||||
.input-group-btn
|
||||
button(ng-click='openURL()', ng-disabled='!textURL', translate).btn.btn-primary-outline Open
|
||||
//button(type='button', ng-disabled='!hasHistory()').btn.btn-primary-outline.dropdown-toggle
|
||||
span.caret
|
||||
//ul.dropdown-menu
|
||||
li(ng-repeat='url in urlHistory')
|
||||
a(ng-click='insertURL(url)').btn-link {{url}}
|
||||
li.divider
|
||||
li
|
||||
a(ng-click='clearHistory()', type='button', translate).btn-link Clear
|
||||
|
||||
.btn-group(ng-if='$root.browser')
|
||||
.btn-group
|
||||
|
|
|
@ -342,8 +342,6 @@ svg {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Make text input on tables be 100% */
|
||||
.table td input[type="number"],
|
||||
.table td input[type="text"] {
|
||||
|
@ -355,7 +353,6 @@ svg {
|
|||
text-align: left;
|
||||
}
|
||||
|
||||
|
||||
.remote-control {
|
||||
background: #888;
|
||||
width: 100%;
|
||||
|
@ -370,8 +367,6 @@ svg {
|
|||
margin-top: 8px !important;
|
||||
}
|
||||
|
||||
|
||||
|
||||
a.active {
|
||||
color: #007aff !important;
|
||||
}
|
||||
|
@ -389,3 +384,17 @@ a.active {
|
|||
datalist {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Make auto-fill controls white instead of the default yellow */
|
||||
input:-webkit-autofill,
|
||||
textarea:-webkit-autofill,
|
||||
select:-webkit-autofill {
|
||||
-webkit-box-shadow: 0 0 0 200px white inset !important;
|
||||
box-shadow: 0 0 0 200px white inset !important;
|
||||
}
|
||||
|
||||
/* Remove transition for input text */
|
||||
input {
|
||||
-webkit-transition: none !important;
|
||||
transition: none !important;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue