Since there is no way to programatically add context menu items, my idea was instead to add a bunch of placeholder items to Info.plist:
<key>SFSafariContextMenu</key> <array> <dict> <key>Text</key> <string>menu0</string> <key>Command</key> <string>menu0</string> </dict> <dict> <key>Text</key> <string>menu1</string> <key>Command</key> <string>menu1</string> </dict> [...] <dict> <key>Text</key> <string>menu9</string> <key>Command</key> <string>menu9</string> </dict> </array>
and hide them by default, or change their names and display when contextually required in the background Swift code by using
func validateContextMenuItem(withCommand command: String, in page: SFSafariPage, userInfo: [String : Any]? = nil, validationHandler: @escaping (Bool, String?) -> Void)
The problem is that the background app process is often killed by the OS and since the bg app startup takes some time, validateContextMenuItem upon background page restart does not respond adequately quickly, in which case the context menu displays all the placeholder items instead.
Naturally, this is an unacceptable behaviour, so my question is whether there is a way to reliably programatically control the contents of the context menus in Safari?
In the old Safari extension framework we used the popover on the button to display contextual options for users, because the button had two behaviours: one on click, and one on click-and-hold. However in the App Extension system you can only choose one behaviour and we need the single-button click behaviour in our extension to just perform the extension action, so this is not an option for us.