fix: emit focus/blur events for webview (#14344)

* fix: emit focus/blur events for webview

* test: webview can emit focus event
This commit is contained in:
Cheng Zhao 2018-08-29 03:35:44 +09:00 committed by Charles Kerr
parent edd5c4b9bb
commit 459a2304b4
5 changed files with 53 additions and 21 deletions

View file

@ -30,6 +30,7 @@ class WebViewImpl {
v8Util.setHiddenValue(this.webviewNode, 'internal', this)
this.elementAttached = false
this.beforeFirstNavigation = true
this.hasFocus = false
// Check for removed attributes.
for (const attributeName of removedAttributes) {
@ -41,13 +42,21 @@ class WebViewImpl {
// on* Event handlers.
this.on = {}
// Create internal iframe element.
this.internalElement = this.createInternalElement()
const shadowRoot = this.webviewNode.attachShadow({mode: 'open'})
shadowRoot.innerHTML = '<!DOCTYPE html><style type="text/css">:host { display: flex; }</style>'
this.setupWebViewAttributes()
this.setupFocusPropagation()
this.viewInstanceId = getNextId()
shadowRoot.appendChild(this.internalElement)
// Provide access to contentWindow.
Object.defineProperty(this.webviewNode, 'contentWindow', {
get: () => {
return this.internalElement.contentWindow
},
enumerable: true
})
}
createInternalElement () {
@ -91,26 +100,6 @@ class WebViewImpl {
})
}
setupFocusPropagation () {
if (!this.webviewNode.hasAttribute('tabIndex')) {
// <webview> needs a tabIndex in order to be focusable.
// TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute
// to allow <webview> to be focusable.
// See http://crbug.com/231664.
this.webviewNode.setAttribute('tabIndex', -1)
}
// Focus the BrowserPlugin when the <webview> takes focus.
this.webviewNode.addEventListener('focus', () => {
this.internalElement.focus()
})
// Blur the BrowserPlugin when the <webview> loses focus.
this.webviewNode.addEventListener('blur', () => {
this.internalElement.blur()
})
}
// This observer monitors mutations to attributes of the <webview> and
// updates the BrowserPlugin properties accordingly. In turn, updating
// a BrowserPlugin property will update the corresponding BrowserPlugin
@ -185,6 +174,15 @@ class WebViewImpl {
}
}
// Emits focus/blur events.
onFocusChange () {
const hasFocus = document.activeElement === this.webviewNode
if (hasFocus !== this.hasFocus) {
this.hasFocus = hasFocus
this.dispatchEvent(new Event(hasFocus ? 'focus' : 'blur'))
}
}
onAttach (storagePartitionId) {
return this.attributes[webViewConstants.ATTRIBUTE_PARTITION].setValue(storagePartitionId)
}