1
0
Fork 0
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:
Gunther Brunner 2014-07-31 16:54:09 +09:00
parent e6465fe8cc
commit 8696f833c2
8 changed files with 254 additions and 190 deletions

View 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.

View file

@ -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')
// }
}
}
}

View file

@ -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');
*/
});
});

View file

@ -0,0 +1,4 @@
module.exports = angular.module('stf.enable-autofill', [
])
.directive('enableAutofill', require('./enable-autofill-directive'))

View file

@ -12,5 +12,6 @@ module.exports = angular.module('stf/common-ui', [
require('./include-cached').name, require('./include-cached').name,
require('./text-focus-select').name, require('./text-focus-select').name,
require('./counter').name, require('./counter').name,
require('./badge-icon').name require('./badge-icon').name,
require('./enable-autofill').name
]) ])

View file

@ -2,49 +2,20 @@ var _ = require('lodash')
module.exports = function NavigationCtrl($scope, $rootScope) { module.exports = function NavigationCtrl($scope, $rootScope) {
$scope.urlHistory = [] function addHttp(textUrl) {
if (textUrl.indexOf(':') === -1 && textUrl.indexOf('.') !== -1) {
function addToHistory() { return 'http://' + textUrl
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
} }
return textUrl
} }
$scope.openURL = function () { $scope.openURL = function () {
addHttp()
addToHistory()
return $scope.control.openBrowser( return $scope.control.openBrowser(
$scope.textURL, addHttp($scope.textURL),
$scope.browser $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) { function setCurrentBrowser(browser) {
if (browser && browser.apps) { if (browser && browser.apps) {
var currentBrowser = {} var currentBrowser = {}

View file

@ -3,7 +3,8 @@
i.fa.fa-globe i.fa.fa-globe
span(translate) Navigation span(translate) Navigation
span 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 i.fa.fa-trash-o
span(translate) Reset span(translate) Reset
//.button-spacer.pull-right //.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-forward.pull-right(ng-click='forward()', title='{{"Go Forward"|translate}}')
//i.fa.fa-step-backward.pull-right(ng-click='back()', title='{{"Go Back"|translate}}') //i.fa.fa-step-backward.pull-right(ng-click='back()', title='{{"Go Back"|translate}}')
.widget-content.padded .widget-content.padded
form form(enable-autofill, action='about:blank')
//form(name='navigationForm', method='post', action='about:blank', target='_autofill')
.input-group .input-group
input.form-control(type='text', placeholder='http://...', autocomplete='off', ng-model='textURL', input.form-control(type='text', name='textURL', placeholder='http://...',
typeahead='url for url in urlHistory | filter:$viewValue', text-focus-select, autocomplete='url', ng-model='textURL', text-focus-select,
accesskey='N', tabindex='10').form-control accesskey='N', tabindex='10').form-control
.input-group-btn .input-group-btn
button(ng-click='openURL()', ng-disabled='!textURL', translate).btn.btn-primary-outline Open 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(ng-if='$root.browser')
.btn-group .btn-group

View file

@ -1,22 +1,22 @@
body { body {
/*font-size: 14px;*/ /*font-size: 14px;*/
/*background: #eee;*/ /*background: #eee;*/
} }
.page-container { .page-container {
padding: 0 30px; padding: 0 30px;
margin: 0 auto; margin: 0 auto;
} }
.stf-container { .stf-container {
margin-right: auto; margin-right: auto;
margin-left: auto; margin-left: auto;
padding-left: 15px; padding-left: 15px;
padding-right: 15px; padding-right: 15px;
} }
.accordion-body.in:hover { .accordion-body.in:hover {
overflow: visible; overflow: visible;
} }
.button-spacer { .button-spacer {
@ -28,11 +28,11 @@ body {
/* Overflow */ /* Overflow */
.overflow-x { .overflow-x {
overflow-x: auto; overflow-x: auto;
} }
.overflow-y { .overflow-y {
overflow-y: auto; overflow-y: auto;
} }
.overflow-auto { .overflow-auto {
@ -41,50 +41,50 @@ body {
/* Fix btn-group */ /* Fix btn-group */
.btn-group.pull-right { .btn-group.pull-right {
margin-right: 10px; margin-right: 10px;
} }
/** /**
Accelerate Accelerate
*/ */
.force-gpu { .force-gpu {
-webkit-transform: translateZ(0); -webkit-transform: translateZ(0);
-moz-transform: translateZ(0); -moz-transform: translateZ(0);
-ms-transform: translateZ(0); -ms-transform: translateZ(0);
-o-transform: translateZ(0); -o-transform: translateZ(0);
transform: translateZ(0); transform: translateZ(0);
-webkit-backface-visibility: hidden; -webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden; -moz-backface-visibility: hidden;
-ms-backface-visibility: hidden; -ms-backface-visibility: hidden;
backface-visibility: hidden; backface-visibility: hidden;
-webkit-perspective: 1000; -webkit-perspective: 1000;
-moz-perspective: 1000; -moz-perspective: 1000;
-ms-perspective: 1000; -ms-perspective: 1000;
perspective: 1000; perspective: 1000;
} }
/** /**
Colors for awesome fonts Colors for awesome fonts
*/ */
.text-status-on { .text-status-on {
color: green; color: green;
text-shadow: 0 0 4px rgba(8, 208, 0, 0.3); text-shadow: 0 0 4px rgba(8, 208, 0, 0.3);
} }
.text-status-off { .text-status-off {
color: lightgrey; color: lightgrey;
} }
.text-status-error { .text-status-error {
color: red; color: red;
} }
.text-status-waiting { .text-status-waiting {
color: #ffcc66; color: #ffcc66;
} }
.text-status-inuse { .text-status-inuse {
color: blue; color: blue;
} }
/** /**
@ -92,208 +92,208 @@ Colors for awesome fonts
*/ */
.stf-ace-editor { .stf-ace-editor {
height: 150px; height: 150px;
} }
.stf-mini-ace-viewer { .stf-mini-ace-viewer {
/*min-height: 10px;*/ /*min-height: 10px;*/
} }
.ace_editor_wrapper { .ace_editor_wrapper {
position: relative; position: relative;
height: 180px; height: 180px;
} }
.ace_editor { .ace_editor {
top: 0; top: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
left: 0; left: 0;
} }
/* Nothing to show */ /* Nothing to show */
.nothing-to-show { .nothing-to-show {
color: #b7b7b7; color: #b7b7b7;
min-height: 130px; min-height: 130px;
text-align: center; text-align: center;
} }
.nothing-to-show p { .nothing-to-show p {
font-size: 20px; font-size: 20px;
} }
/** /**
General styles General styles
*/ */
.vertical-center { .vertical-center {
display: -webkit-box; display: -webkit-box;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
-webkit-box-pack: center; -webkit-box-pack: center;
-webkit-box-align: center; -webkit-box-align: center;
display: -moz-box; display: -moz-box;
-moz-box-orient: vertical; -moz-box-orient: vertical;
-moz-box-pack: center; -moz-box-pack: center;
-moz-box-align: center; -moz-box-align: center;
display: box; display: box;
box-orient: vertical; box-orient: vertical;
box-pack: center; box-pack: center;
box-align: center; box-align: center;
} }
/* Screenshots */ /* Screenshots */
ul.screenshots-icon-view { ul.screenshots-icon-view {
list-style-type: none; list-style-type: none;
font-family: 'HelveticaNeue-UltraLight', Helvetica, Arial, sans-serif; font-family: 'HelveticaNeue-UltraLight', Helvetica, Arial, sans-serif;
} }
ul.screenshots-icon-view li { ul.screenshots-icon-view li {
float: left; float: left;
clear: none; clear: none;
margin: 8px; margin: 8px;
} }
/* Progress */ /* Progress */
.value-next-to-progress { .value-next-to-progress {
float: left; float: left;
margin-right: 10px; margin-right: 10px;
} }
.table-progress { .table-progress {
margin-bottom: 0; margin-bottom: 0;
} }
/* Icons */ /* Icons */
.icon-fixed { .icon-fixed {
width: 150px !important; width: 150px !important;
} }
/* Cookies */ /* Cookies */
ul.cookies-list { ul.cookies-list {
list-style-type: none; list-style-type: none;
} }
/* Login */ /* Login */
.login-bg { .login-bg {
background: #8a6073; background: #8a6073;
background: -moz-linear-gradient(top, #8a6073 0%, #c68779 24%, #637476 57%, #4c7b7d 79%, #658e7d 94%, #6c8c77 97%); background: -moz-linear-gradient(top, #8a6073 0%, #c68779 24%, #637476 57%, #4c7b7d 79%, #658e7d 94%, #6c8c77 97%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #8a6073), color-stop(24%, #c68779), color-stop(57%, #637476), color-stop(79%, #4c7b7d), color-stop(94%, #658e7d), color-stop(97%, #6c8c77)); background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #8a6073), color-stop(24%, #c68779), color-stop(57%, #637476), color-stop(79%, #4c7b7d), color-stop(94%, #658e7d), color-stop(97%, #6c8c77));
background: -webkit-linear-gradient(top, #8a6073 0%, #c68779 24%, #637476 57%, #4c7b7d 79%, #658e7d 94%, #6c8c77 97%); background: -webkit-linear-gradient(top, #8a6073 0%, #c68779 24%, #637476 57%, #4c7b7d 79%, #658e7d 94%, #6c8c77 97%);
background: -o-linear-gradient(top, #8a6073 0%, #c68779 24%, #637476 57%, #4c7b7d 79%, #658e7d 94%, #6c8c77 97%); background: -o-linear-gradient(top, #8a6073 0%, #c68779 24%, #637476 57%, #4c7b7d 79%, #658e7d 94%, #6c8c77 97%);
background: -ms-linear-gradient(top, #8a6073 0%, #c68779 24%, #637476 57%, #4c7b7d 79%, #658e7d 94%, #6c8c77 97%); background: -ms-linear-gradient(top, #8a6073 0%, #c68779 24%, #637476 57%, #4c7b7d 79%, #658e7d 94%, #6c8c77 97%);
background: linear-gradient(to bottom, #8a6073 0%, #c68779 24%, #637476 57%, #4c7b7d 79%, #658e7d 94%, #6c8c77 97%); background: linear-gradient(to bottom, #8a6073 0%, #c68779 24%, #637476 57%, #4c7b7d 79%, #658e7d 94%, #6c8c77 97%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#8a6073', endColorstr='#6c8c77', GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#8a6073', endColorstr='#6c8c77', GradientType=0);
} }
/* d3 lines */ /* d3 lines */
svg { svg {
font: 10px sans-serif; font: 10px sans-serif;
} }
.line { .line {
fill: none; fill: none;
stroke: steelblue; stroke: steelblue;
stroke-width: 1.5px; stroke-width: 1.5px;
} }
.axis path, .axis path,
.axis line { .axis line {
fill: none; fill: none;
stroke: #000; stroke: #000;
shape-rendering: crispEdges; shape-rendering: crispEdges;
} }
/* Interact Control */ /* Interact Control */
.interact-sidebar { .interact-sidebar {
width: 280px; width: 280px;
} }
/* Movement Area */ /* Movement Area */
.movement-area-container { .movement-area-container {
/*background: #555;*/ /*background: #555;*/
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.movement-area-image { .movement-area-image {
width: 100%; width: 100%;
height: 100%; height: 100%;
background-size: contain; background-size: contain;
background-color: #444; background-color: #444;
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: 50% 50%; background-position: 50% 50%;
position: relative; position: relative;
} }
.interact-control .btn-toolbar .btn { .interact-control .btn-toolbar .btn {
min-width: 41px; min-width: 41px;
} }
/* Height */ /* Height */
.as-table { .as-table {
display: table; display: table;
} }
.as-row { .as-row {
display: table-row; display: table-row;
} }
.as-cell { .as-cell {
display: table-cell; display: table-cell;
} }
.fill-height { .fill-height {
height: 100%; height: 100%;
} }
.fill-auto { .fill-auto {
height: auto; height: auto;
} }
.special-keys-buttons button { .special-keys-buttons button {
width: 40px; width: 40px;
} }
.special-keys-buttons .btn-xs button { .special-keys-buttons .btn-xs button {
width: 36px; width: 36px;
} }
.special-keys-dpad-buttons button { .special-keys-dpad-buttons button {
width: 40px; width: 40px;
} }
/* /*
Drawer Drawer
*/ */
.stf-drawer { .stf-drawer {
background: #ddd; background: #ddd;
} }
.stf-drawer-bar { .stf-drawer-bar {
background: #aaa; background: #aaa;
} }
.stf-drawer-docked-down .stf-drawer-bar { .stf-drawer-docked-down .stf-drawer-bar {
width: 100%; width: 100%;
height: 2px; height: 2px;
cursor: ns-resize; cursor: ns-resize;
} }
.stf-drawer-docked-right .stf-drawer-bar { .stf-drawer-docked-right .stf-drawer-bar {
width: 2px; width: 2px;
height: 100%; height: 100%;
cursor: ew-resize; cursor: ew-resize;
} }
.stf-drawer-docked { .stf-drawer-docked {
opacity: 0.9; opacity: 0.9;
z-index: 5000; z-index: 5000;
} }
.stf-drawer-floating { .stf-drawer-floating {
@ -301,91 +301,100 @@ svg {
} }
.stf-drawer-docked-down { .stf-drawer-docked-down {
width: 100%; width: 100%;
height: 300px; height: 300px;
bottom: 0; bottom: 0;
position: absolute; position: absolute;
} }
.stf-drawer-docked-right { .stf-drawer-docked-right {
width: 300px; width: 300px;
height: 100%; height: 100%;
right: 0; right: 0;
position: absolute; position: absolute;
} }
.stf-drawer-buttons { .stf-drawer-buttons {
text-align: right; text-align: right;
} }
/* For se7en bootstrap */ /* For se7en bootstrap */
.btn [class^="fa"], .btn [class^="fa"],
.btn [class*="fa"] { .btn [class*="fa"] {
margin-right: 0 !important; margin-right: 0 !important;
} }
/*.btn [class^="fa"]+span i,*/ /*.btn [class^="fa"]+span i,*/
/*.btn [class*="fa"]+span {*/ /*.btn [class*="fa"]+span {*/
/*margin-right: 15px;*/ /*margin-right: 15px;*/
/*}*/ /*}*/
.interact-control .navbar { .interact-control .navbar {
height: auto !important; height: auto !important;
} }
.interact-control .navbar-brand { .interact-control .navbar-brand {
padding: 8px 15px; padding: 8px 15px;
} }
.interact-control .btn-group { .interact-control .btn-group {
margin: 0; margin: 0;
} }
/* Make text input on tables be 100% */ /* Make text input on tables be 100% */
.table td input[type="number"], .table td input[type="number"],
.table td input[type="text"] { .table td input[type="text"] {
width: 100%; width: 100%;
} }
/* Re-reset the table alignment */ /* Re-reset the table alignment */
.ng-table th { .ng-table th {
text-align: left; text-align: left;
} }
.remote-control { .remote-control {
background: #888; background: #888;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
.stf-feedback > li > a { .stf-feedback > li > a {
font-size: 14px; font-size: 14px;
} }
.stf-nav-web-native-button { .stf-nav-web-native-button {
margin-top: 8px !important; margin-top: 8px !important;
} }
a.active { a.active {
color: #007aff !important; color: #007aff !important;
} }
.weinre-window { .weinre-window {
z-index: 10; z-index: 10;
position: absolute; position: absolute;
top: 31px; top: 31px;
bottom: 3px; bottom: 3px;
left: 0; left: 0;
right: 0; right: 0;
} }
/* Hide datalist for non-supporting browsers */ /* Hide datalist for non-supporting browsers */
datalist { datalist {
display: none; 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;
}