Skip to content
This repository has been archived by the owner on Dec 11, 2019. It is now read-only.

Commit

Permalink
Merge pull request #13563 from AlexRobinson-/arobinson/window-prompt
Browse files Browse the repository at this point in the history
Add feature window.prompt
  • Loading branch information
bsclifton authored May 7, 2018
2 parents d8438b3 + 489b1a5 commit 2a7f9b7
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 11 deletions.
36 changes: 27 additions & 9 deletions app/browser/tabMessageBox.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const appActions = require('../../js/actions/appActions')
const tabMessageBoxState = require('../common/state/tabMessageBoxState')
const {makeImmutable} = require('../common/state/immutableUtil')
const locale = require('../../app/locale')

// callbacks for alert, confirm, etc.
let messageBoxCallbacks = {}
Expand All @@ -13,6 +14,23 @@ const cleanupCallback = (tabId) => {
return false
}

const onWindowPrompt = show => (webContents, extraData, title, message, defaultPromptText,
shouldDisplaySuppressCheckbox, isBeforeUnloadDialog, isReload, muonCb) => {
const tabId = webContents.getId()
const detail = {
message,
title,
buttons: [locale.translation('messageBoxOk'), locale.translation('messageBoxCancel')],
cancelId: 1,
suppress: false,
allowInput: true,
defaultPromptText,
showSuppress: shouldDisplaySuppressCheckbox
}

show(tabId, detail, muonCb)
}

const tabMessageBox = {
init: (state, action) => {
process.on('window-alert', (webContents, extraData, title, message, defaultPromptText,
Expand All @@ -21,7 +39,7 @@ const tabMessageBox = {
const detail = {
message,
title,
buttons: ['ok'],
buttons: [locale.translation('messageBoxOk')],
suppress: false,
showSuppress: shouldDisplaySuppressCheckbox
}
Expand All @@ -35,7 +53,7 @@ const tabMessageBox = {
const detail = {
message,
title,
buttons: ['ok', 'cancel'],
buttons: [locale.translation('messageBoxOk'), locale.translation('messageBoxCancel')],
cancelId: 1,
suppress: false,
showSuppress: shouldDisplaySuppressCheckbox
Expand All @@ -44,12 +62,7 @@ const tabMessageBox = {
tabMessageBox.show(tabId, detail, muonCb)
})

process.on('window-prompt', (webContents, extraData, title, message, defaultPromptText,
shouldDisplaySuppressCheckbox, isBeforeUnloadDialog, isReload, muonCb) => {
console.warn('window.prompt is not supported yet')
let suppress = false
muonCb(null, '', suppress)
})
process.on('window-prompt', onWindowPrompt(tabMessageBox.show))

return state
},
Expand All @@ -70,6 +83,7 @@ const tabMessageBox = {
const muonCb = messageBoxCallbacks[tabId]
let suppress = false
let result = true
let input = ''
state = tabMessageBoxState.removeDetail(state, action)
if (muonCb) {
cleanupCallback(tabId)
Expand All @@ -80,7 +94,10 @@ const tabMessageBox = {
if (detail.has('result')) {
result = detail.get('result')
}
muonCb(result, '', suppress)
if (detail.has('input')) {
input = detail.get('input')
}
muonCb(result, input, suppress)
} else {
muonCb(false, '', false)
}
Expand Down Expand Up @@ -130,3 +147,4 @@ const tabMessageBox = {
}

module.exports = tabMessageBox
module.exports.onWindowPrompt = onWindowPrompt
2 changes: 2 additions & 0 deletions app/extensions/brave/locales/en-US/menu.properties
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ learnSpelling=Learn Spelling
licenseText=This software uses libraries from the FFmpeg project under the LGPLv2.1
lookupSelection=Look Up “{{selectedVariable}}”
mergeAllWindows=Merge All Windows
messageBoxOk=ok
messageBoxCancel=cancel
minimize=Minimize
moveTabToNewWindow=Move to New Window
muteOtherTabs=Mute other Tabs
Expand Down
2 changes: 2 additions & 0 deletions app/locale.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ var rendererIdentifiers = function () {
'dappDismiss',
'dappEnableExtension',
'banSiteConfirmation',
'messageBoxOk',
'messageBoxCancel',
// other
'passwordsManager',
'extensionsManager',
Expand Down
31 changes: 31 additions & 0 deletions app/renderer/components/common/messageBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const Dialog = require('./dialog')
const FlyoutDialog = require('./flyoutDialog')
const BrowserButton = require('../common/browserButton')
const SwitchControl = require('./switchControl')
const {PromptTextBox} = require('./textbox')

// Actions
const appActions = require('../../../../js/actions/appActions')
Expand All @@ -36,12 +37,21 @@ class MessageBox extends React.Component {
super(props)
this.onKeyDown = this.onKeyDown.bind(this)
this.onSuppressChanged = this.onSuppressChanged.bind(this)
this.state = {
textInput: props.defaultPromptText
}
}

componentWillMount () {
document.addEventListener('keydown', this.onKeyDown)
}

componentDidMount () {
if (this.props.allowInput) {
this.inputRef.select()
}
}

componentWillUnmount () {
document.removeEventListener('keydown', this.onKeyDown)
}
Expand Down Expand Up @@ -82,6 +92,10 @@ class MessageBox extends React.Component {
response.result = buttonId !== this.props.cancelId
}

if (this.props.allowInput) {
response.input = this.state.textInput
}

appActions.tabMessageBoxDismissed(tabId, response)
}

Expand Down Expand Up @@ -112,6 +126,8 @@ class MessageBox extends React.Component {
// used in renderer
props.tabId = tabId
props.message = messageBoxDetail.get('message')
props.allowInput = messageBoxDetail.get('allowInput')
props.defaultPromptText = messageBoxDetail.get('defaultPromptText')
props.suppress = tabMessageBoxState.getSuppress(state, tabId)
props.title = tabMessageBoxState.getTitle(state, tabId)
props.showSuppress = tabMessageBoxState.getShowSuppress(state, tabId)
Expand Down Expand Up @@ -151,6 +167,21 @@ class MessageBox extends React.Component {
/>
: null
}
{
this.props.allowInput && (
<PromptTextBox
value={this.state.textInput}
inputRef={ref => {
this.inputRef = ref
}}
onChange={e => {
this.setState({
textInput: e.target.value
})
}}
/>
)
}
<div className={css(styles.buttons)} data-test-id='msgBoxButtons'>
{this.messageBoxButtons}
</div>
Expand Down
16 changes: 15 additions & 1 deletion app/renderer/components/common/textbox.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ class Textbox extends ImmutableComponent {
(this.props.readonly || this.props.readOnly) ? styles.readOnly : styles.outlineable,
this.props['data-isCommonForm'] && commonStyles.isCommonForm,
this.props['data-isSettings'] && styles.isSettings,
this.props['data-isPrompt'] && styles.isPrompt,
this.props.customClass && this.props.customClass
)

const props = Object.assign({}, this.props)
const ref = this.props.inputRef
delete props.customClass
delete props.inputRef

return <input type='text' className={className} {...props} />
return <input type='text' className={className} {...props} ref={ref} />
}
}

Expand Down Expand Up @@ -66,6 +69,12 @@ class SettingTextbox extends ImmutableComponent {
}
}

class PromptTextBox extends ImmutableComponent {
render () {
return <FormTextbox data-isPrompt='true' {...this.props} />
}
}

// TextArea
class TextArea extends ImmutableComponent {
render () {
Expand Down Expand Up @@ -160,6 +169,10 @@ const styles = StyleSheet.create({
isSettings: {
width: '280px'
},
isPrompt: {
width: '100%',
marginBottom: '20px'
},
readOnly: {
background: globalStyles.color.lightGray,
boxShadow: 'none',
Expand Down Expand Up @@ -248,6 +261,7 @@ module.exports = {
FormTextbox,
GroupedFormTextbox,
SettingTextbox,
PromptTextBox,
TextArea,
DefaultTextArea,
WordCountTextArea
Expand Down
48 changes: 48 additions & 0 deletions test/unit/app/browser/tabMessageBoxTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,13 @@ describe('tabMessageBox unit tests', function () {
useCleanCache: true
})

const fakeLocale = {
translation: (token) => { return token }
}

mockery.registerMock('electron', require('../../lib/fakeElectron'))
mockery.registerMock('../common/state/tabMessageBoxState', fakeMessageBoxState)
mockery.registerMock('../../../js/l10n', fakeLocale)
tabMessageBox = require('../../../../app/browser/tabMessageBox')
appActions = require('../../../../js/actions/appActions')

Expand Down Expand Up @@ -224,4 +229,47 @@ describe('tabMessageBox unit tests', function () {
})
})
})

describe('onWindowPrompt', () => {
const tabId = '123'
const webContents = {
getId: () => tabId
}
const extraData = undefined
const title = 'some title'
const message = 'some message'
const defaultPromptText = 'some prompt text'
const shouldDisplaySuppressCheckbox = true
const isBeforeUnloadDialog = undefined
const isReload = undefined
const muonCb = 'muonCb'

it('calls tabMessageBox.show', () => {
const mockShow = sinon.stub()
const expectecDetail = {
message,
title,
buttons: ['MESSAGEBOXOK', 'MESSAGEBOXCANCEL'],
cancelId: 1,
suppress: false,
allowInput: true,
defaultPromptText,
showSuppress: shouldDisplaySuppressCheckbox
}

tabMessageBox.onWindowPrompt(mockShow)(
webContents,
extraData,
title,
message,
defaultPromptText,
shouldDisplaySuppressCheckbox,
isBeforeUnloadDialog,
isReload,
muonCb
)

assert.equal(mockShow.withArgs(tabId, expectecDetail, muonCb).calledOnce, true)
})
})
})
56 changes: 55 additions & 1 deletion test/unit/app/renderer/components/common/messageBoxTest.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,25 @@ let appState = Immutable.fromJS({
}
})

const createAppState = detail => Immutable.fromJS({
windows: [{
windowId: 1,
windowUUID: 'uuid'
}],
tabs: [{
tabId: tabId,
windowId: 1,
windowUUID: 'uuid',
url: 'https://brave.com',
messageBoxDetail: detail
}],
tabsInternal: {
index: {
1: 0
}
}
})

describe('MessageBox component unit tests', function () {
before(function () {
mockery.enable({
Expand All @@ -60,7 +79,7 @@ describe('MessageBox component unit tests', function () {

describe('Rendering', function () {
before(function () {
appStoreRenderer.state = Immutable.fromJS(appState)
appStoreRenderer.state = createAppState(detail1)
})
it('renders itself inside a dialog component', function () {
const wrapper = mount(
Expand Down Expand Up @@ -98,6 +117,19 @@ describe('MessageBox component unit tests', function () {
assert.equal(wrapper.find('button[data-l10n-id="Cancel"][data-test-id="secondaryColor"]').length, 1)
})

it('renders the PromptTextBox when input is allowed', function () {
appStoreRenderer.state = createAppState(Object.assign({}, detail1, {
allowInput: true
}))
const wrapper = mount(
<MessageBox
tabId={tabId}
allowInput
/>
)
assert.equal(wrapper.find('PromptTextBox').length, 1)
})

it('hides the suppress checkbox if showSuppress is false', function () {
const appState2 = appState.setIn(['tabs', 0, 'messageBoxDetail', 'showSuppress'], false)
appStoreRenderer.state = Immutable.fromJS(appState2)
Expand Down Expand Up @@ -158,5 +190,27 @@ describe('MessageBox component unit tests', function () {
assert.equal(spy.withArgs(tabId, response).calledOnce, true)
appActions.tabMessageBoxDismissed.restore()
})

it('calls appActions.tabMessageBoxDismissed with input input is allowed', function () {
const expectedInput = 'some input'
appStoreRenderer.state = createAppState(Object.assign({}, detail1, {
allowInput: true,
defaultPromptText: expectedInput
}))
const spy = sinon.spy(appActions, 'tabMessageBoxDismissed')
const wrapper = mount(
<MessageBox
tabId={tabId}
/>
)
const response = {
suppress: detail1.suppress,
result: false,
input: expectedInput
}
wrapper.find('button[data-l10n-id="Cancel"][data-test-id="secondaryColor"]').simulate('click')
assert.equal(spy.withArgs(tabId, response).calledOnce, true)
appActions.tabMessageBoxDismissed.restore()
})
})
})

0 comments on commit 2a7f9b7

Please sign in to comment.