WebExtensionMiddleware.kt
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package mozilla.components.browser.state.engine.middleware
import mozilla.components.browser.state.action.BrowserAction
import mozilla.components.browser.state.action.EngineAction
import mozilla.components.browser.state.action.TabListAction
import mozilla.components.browser.state.action.WebExtensionAction
import mozilla.components.browser.state.selector.findTab
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.concept.engine.EngineSession
import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.MiddlewareContext
import mozilla.components.support.base.log.logger.Logger
/**
* [Middleware] implementation responsible for calling [EngineSession.markActiveForWebExtensions] on
* [EngineSession] instances.
*/
internal class WebExtensionMiddleware : Middleware<BrowserState, BrowserAction> {
private val logger = Logger("WebExtensionsMiddleware")
override fun invoke(
context: MiddlewareContext<BrowserState, BrowserAction>,
next: (BrowserAction) -> Unit,
action: BrowserAction,
) {
when (action) {
is EngineAction.UnlinkEngineSessionAction -> {
if (context.state.activeWebExtensionTabId == action.tabId) {
val activeTab = context.state.findTab(action.tabId)
activeTab?.engineState?.engineSession?.markActiveForWebExtensions(false)
}
}
else -> {
// no-op
}
}
next(action)
when (action) {
is TabListAction,
is EngineAction.LinkEngineSessionAction,
-> {
switchActiveStateIfNeeded(context)
}
else -> {
// no-op
}
}
}
private fun switchActiveStateIfNeeded(context: MiddlewareContext<BrowserState, BrowserAction>) {
val state = context.state
if (state.activeWebExtensionTabId == state.selectedTabId) {
return
}
val previousActiveTab = state.activeWebExtensionTabId?.let { state.findTab(it) }
previousActiveTab?.engineState?.engineSession?.markActiveForWebExtensions(false)
val nextActiveTab = state.selectedTabId?.let { state.findTab(it) }
val engineSession = nextActiveTab?.engineState?.engineSession
if (engineSession == null) {
logger.debug("No engine session for new active tab (${nextActiveTab?.id})")
context.dispatch(WebExtensionAction.UpdateActiveWebExtensionTabAction(null))
return
} else {
logger.debug("New active tab (${nextActiveTab.id})")
engineSession.markActiveForWebExtensions(true)
context.dispatch(WebExtensionAction.UpdateActiveWebExtensionTabAction(nextActiveTab.id))
}
}
}