Merge pull request #5074 from epixa/5061-import-firefox-bug
Safely window.confirm when importing saved object
This commit is contained in:
commit
95873a07c7
|
@ -55,6 +55,7 @@ exports.reload = function () {
|
||||||
'ui/persisted_log',
|
'ui/persisted_log',
|
||||||
'ui/private',
|
'ui/private',
|
||||||
'ui/promises',
|
'ui/promises',
|
||||||
|
'ui/safe_confirm',
|
||||||
'ui/state_management/app_state',
|
'ui/state_management/app_state',
|
||||||
'ui/state_management/global_state',
|
'ui/state_management/global_state',
|
||||||
'ui/storage',
|
'ui/storage',
|
||||||
|
|
|
@ -4,6 +4,7 @@ define(function (require) {
|
||||||
|
|
||||||
require('ui/es');
|
require('ui/es');
|
||||||
require('ui/promises');
|
require('ui/promises');
|
||||||
|
require('ui/safe_confirm');
|
||||||
require('ui/index_patterns');
|
require('ui/index_patterns');
|
||||||
|
|
||||||
require('ui/modules').get('kibana/courier')
|
require('ui/modules').get('kibana/courier')
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
define(function (require) {
|
define(function (require) {
|
||||||
return function SavedObjectFactory(es, kbnIndex, Promise, Private, Notifier, indexPatterns) {
|
return function SavedObjectFactory(es, kbnIndex, Promise, Private, Notifier, safeConfirm, indexPatterns) {
|
||||||
var angular = require('angular');
|
var angular = require('angular');
|
||||||
var errors = require('ui/errors');
|
var errors = require('ui/errors');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
|
@ -252,12 +252,12 @@ define(function (require) {
|
||||||
if (_.get(err, 'origError.status') === 409) {
|
if (_.get(err, 'origError.status') === 409) {
|
||||||
var confirmMessage = 'Are you sure you want to overwrite ' + self.title + '?';
|
var confirmMessage = 'Are you sure you want to overwrite ' + self.title + '?';
|
||||||
|
|
||||||
if (window.confirm(confirmMessage)) { // eslint-disable-line no-alert
|
return safeConfirm(confirmMessage).then(
|
||||||
return docSource.doIndex(source).then(finish);
|
function () {
|
||||||
}
|
return docSource.doIndex(source).then(finish);
|
||||||
|
},
|
||||||
// if the user doesn't overwrite record, just swallow the error
|
_.noop // if the user doesn't overwrite record, just swallow the error
|
||||||
return;
|
);
|
||||||
}
|
}
|
||||||
return Promise.reject(err);
|
return Promise.reject(err);
|
||||||
});
|
});
|
||||||
|
|
82
src/ui/public/safe_confirm/__tests__/safe_confirm.js
Normal file
82
src/ui/public/safe_confirm/__tests__/safe_confirm.js
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
describe('ui/safe_confirm', function () {
|
||||||
|
var sinon = require('sinon');
|
||||||
|
var expect = require('expect.js');
|
||||||
|
var ngMock = require('ngMock');
|
||||||
|
|
||||||
|
var $rootScope;
|
||||||
|
var $window;
|
||||||
|
var $timeout;
|
||||||
|
var message;
|
||||||
|
var safeConfirm;
|
||||||
|
var promise;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
ngMock.module('kibana', function ($provide) {
|
||||||
|
$provide.value('$window', {
|
||||||
|
confirm: sinon.stub().returns(true)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ngMock.inject(function ($injector) {
|
||||||
|
safeConfirm = $injector.get('safeConfirm');
|
||||||
|
$rootScope = $injector.get('$rootScope');
|
||||||
|
$window = $injector.get('$window');
|
||||||
|
$timeout = $injector.get('$timeout');
|
||||||
|
});
|
||||||
|
|
||||||
|
message = 'woah';
|
||||||
|
|
||||||
|
promise = safeConfirm(message);
|
||||||
|
});
|
||||||
|
|
||||||
|
context('before timeout completes', function () {
|
||||||
|
it('$window.confirm is not invoked', function () {
|
||||||
|
expect($window.confirm.called).to.be(false);
|
||||||
|
});
|
||||||
|
it('returned promise is not resolved', function () {
|
||||||
|
var isResolved = false;
|
||||||
|
function markAsResolved() {
|
||||||
|
isResolved = true;
|
||||||
|
}
|
||||||
|
promise.then(markAsResolved, markAsResolved);
|
||||||
|
$rootScope.$apply(); // attempt to resolve the promise, but this won't flush $timeout promises
|
||||||
|
expect(isResolved).to.be(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('after timeout completes', function () {
|
||||||
|
it('$window.confirm is invoked with message', function () {
|
||||||
|
$timeout.flush();
|
||||||
|
expect($window.confirm.calledWith(message)).to.be(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
context('when confirmed', function () {
|
||||||
|
it('promise is fulfilled with true', function () {
|
||||||
|
$timeout.flush();
|
||||||
|
|
||||||
|
var value;
|
||||||
|
promise.then(function (v) {
|
||||||
|
value = v;
|
||||||
|
});
|
||||||
|
$rootScope.$apply();
|
||||||
|
|
||||||
|
expect(value).to.be(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
context('when canceled', function () {
|
||||||
|
it('promise is rejected with false', function () {
|
||||||
|
$window.confirm.returns(false); // must be set before $timeout.flush()
|
||||||
|
$timeout.flush();
|
||||||
|
|
||||||
|
var value;
|
||||||
|
promise.then(null, function (v) {
|
||||||
|
value = v;
|
||||||
|
});
|
||||||
|
$rootScope.$apply();
|
||||||
|
|
||||||
|
expect(value).to.be(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
31
src/ui/public/safe_confirm/safe_confirm.js
Normal file
31
src/ui/public/safe_confirm/safe_confirm.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
define(function (require) {
|
||||||
|
require('ui/modules').get('kibana')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Angular doesn't play well with thread blocking calls such as
|
||||||
|
* window.confirm() unless those calls are specifically handled inside a call
|
||||||
|
* to $timeout(). Rather than litter the code with that implementation
|
||||||
|
* detail, safeConfirm() can be used.
|
||||||
|
*
|
||||||
|
* WARNING: safeConfirm differs from a native call to window.confirm in that
|
||||||
|
* it only blocks the thread beginning on the next tick. For that reason, a
|
||||||
|
* promise is returned so consumers can handle the control flow.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* safeConfirm('This message will be passed to window.confirm()').then(
|
||||||
|
* function () {
|
||||||
|
* // user clicked confirm
|
||||||
|
* },
|
||||||
|
* function () {
|
||||||
|
* // user canceled the confirmation
|
||||||
|
* }
|
||||||
|
* );
|
||||||
|
*/
|
||||||
|
.factory('safeConfirm', function ($window, $timeout, $q) {
|
||||||
|
return function safeConfirm(message) {
|
||||||
|
return $timeout(function () {
|
||||||
|
return $window.confirm(message) || $q.reject(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue