Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Centralised Messaging for User Scripts #299

Merged
merged 3 commits into from
May 25, 2023
Merged

Centralised Messaging for User Scripts #299

merged 3 commits into from
May 25, 2023

Conversation

shakyShane
Copy link
Collaborator

@shakyShane shakyShane commented Mar 31, 2023

Please review the release process for BrowserServicesKit here.

Required:

Task/Issue URL:
iOS PR:
macOS PR:
What kind of version bump will this require?: Major/Minor/Patch

Optional:

TODO

  • Catalina/encryption support needs to be added to the new messaging broker

tl;dr - multiple features will soon be messaging from single UserScripts

/// An example of how to conform to `SubFeature`
/// It contains 3 examples that are typical of a feature that needs to
/// communicate to a UserScript
struct TestDelegate: Subfeature {
    weak var broker: UserScriptMessageBroker?

    var featureName = "fooBarFeature"

    /// This feature will accept messages from .all - meaning every origin
    ///
    /// Some features may want to restrict the origin's that it accepts messages from
    var messageOriginPolicy: MessageOriginPolicy = .all

    /// An example of how to provide different handlers bad on
    func handler(forMethodNamed methodName: String) -> Subfeature.Handler? {
        switch methodName {
        case "notifyExample": return notifyExample
        case "errorExample": return errorExample
        case "responseExample": return responseExample
        default:
            return nil
        }
    }

    /// An example of a simple Encodable data type that can be used directly in replies
    struct Person: Encodable {
        let name: String
    }

    /// An example that represents handling a [NotificationMessage](https://duckduckgo.github.io/content-scope-scripts/classes/Messaging_Schema.NotificationMessage.html)
    func notifyExample(params: Any, original: WKScriptMessage) async throws -> Encodable? {
        print("not replying...")
        return nil
    }

    /// An example that represents throwing an exception from a handler
    ///
    /// Note: if this happens as part of a 'request', the error string will be forwarded onto the client side JS
    func errorExample(params: Any, original: WKScriptMessage) async throws -> Encodable? {
        let error = NSError(domain: "MyHandler", code: 0, userInfo: [NSLocalizedDescriptionKey: "Some Error"])
        throw error
    }

    /// An example of how a handler can reply with any Encodable data type
    func responseExample(params: Any, original: WKScriptMessage) async throws -> Encodable? {
        let person = Person(name: "Kittie")
        return person
    }
}

contentScopeUserScript.registerSubFeature(delegate: TestDelegate())

Description:

  • Content Scope Scripts is adding features that require messaging - there will be multiple such features in the future.

  • Therefor, on the JS side we've created a standardised system for messaging to and from WebViews that include enough information for the native platforms to distribute the messages as they see fit.

  • CC @jaceklyp

  • We have Specified a number of types that native platforms must implement and understand, such as

    • NotificationMessage (a fire-and-forget message)
    • RequestMessage (a notification that requires a response)
    • MessageResponse (a response to a RequestMessage)
    • SubscriptionEvent (ability to push data to WebViews)
  • Messaging https://duckduckgo.github.io/content-scope-scripts/modules/Messaging.html

  • MessagingSchema https://duckduckgo.github.io/content-scope-scripts/modules/Messaging_Schema.html

image

Steps to test this PR:
1.
1.

OS Testing:

  • iOS 14
  • iOS 15
  • iOS 16
  • macOS 10.15
  • macOS 11
  • macOS 12

Internal references:

Software Engineering Expectations
Technical Design Template

@shakyShane shakyShane force-pushed the shane/POC-css branch 2 times, most recently from c69cdbc to 2685c2a Compare April 5, 2023 18:11
@shakyShane shakyShane force-pushed the shane/POC-css branch 4 times, most recently from fb6c092 to 7965613 Compare April 18, 2023 18:03
@shakyShane shakyShane marked this pull request as ready for review April 18, 2023 18:04
@shakyShane shakyShane changed the title Shane/poc css Centralised Messaging for ContentScopeScripts Apr 18, 2023
@shakyShane
Copy link
Collaborator Author

Current dependencies on/for this PR:

This comment was auto-generated by Graphite.

@shakyShane shakyShane changed the title Centralised Messaging for ContentScopeScripts Centralised Messaging for User Scripts Apr 23, 2023
@shakyShane
Copy link
Collaborator Author

@ayoy @Bunn @jaceklyp this was just my way of making the new standardised messaging platform work with minimal changes to BSK (it just adds a new protocol, it doesn't alter any existing User Scripts)

Let me know if it's the wrong the direction, or if you can suggest any parts to re-write :p - I'm really just interested in supporting the idea of 'multiple features per User Script' and ensuring it follows what we have documented in C-S-S.

Copy link
Contributor

@Bunn Bunn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some comments there, I think it looks good, but I haven't used UserScript before in a level that I feel comfortable knowing some of the impacts here for existing features. @jaceklyp do you mind taking a second look? And @ayoy as well because of the Duck Player messaging.

From what I'm seeing and using it for DBP, LGTM.

Edit: To be clear, I approved the PR but it doesn't mean it can be merged 😅 just approving the direction

Sources/UserScript/UserScriptMessaging.swift Outdated Show resolved Hide resolved
Sources/UserScript/UserScriptMessaging.swift Outdated Show resolved Hide resolved
Sources/UserScript/UserScriptMessaging.swift Outdated Show resolved Hide resolved
Sources/UserScript/UserScriptMessagingSchema.swift Outdated Show resolved Hide resolved
Sources/UserScript/UserScriptMessagingSchema.swift Outdated Show resolved Hide resolved

public func toJSON() -> String? {

// I added this because I couldn't figure out the generic/recursive Encodable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's discuss it over MM

Sources/UserScript/UserScriptMessaging.swift Outdated Show resolved Hide resolved
Sources/UserScript/UserScriptMessaging.swift Outdated Show resolved Hide resolved
@jaceklyp
Copy link
Contributor

Hey Shane, thank you for this! 🙏 Added several comments - if you have any questions let's discuss them. I would like to give another round of review after your fixes.

@shakyShane shakyShane force-pushed the shane/POC-css branch 2 times, most recently from 34c9240 to b80a0a6 Compare May 5, 2023 16:22
@shakyShane
Copy link
Collaborator Author

@jaceklyp - thanks for the feedback, please feel free to check this again.

Because this work deliberately DOES NOT alter how existing User Scripts work, it should be fairly low-risk to merge and then iterate if we need to following further feedback of course :)

@ayoy
Copy link
Contributor

ayoy commented May 24, 2023

@jaceklyp please have another look after @shakyShane has addressed your comments.

public let isIsolated: Bool
public var messageNames: [String] = []

public init(_ privacyConfigManager: PrivacyConfigurationManaging,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it shoud be init(privacyConfigManager, let's not hide the external label in init

Comment on lines 126 to 135
self.broker = UserScriptMessageBroker(context: contextName)

// dont register any handlers at all if we're not in the isolated context
self.messageNames = self.isIsolated ? [contextName] : []

self.source = ContentScopeUserScript.generateSource(
privacyConfigManager,
properties: properties,
isolated: self.isIsolated,
config: self.broker.messagingConfig()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty much all selfs are not needed here

Comment on lines 78 to 80
public func registerSubFeature(delegate: Subfeature) {
delegate.with(broker: broker)
broker.registerSubFeature(delegate: delegate)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Subfeature :) here and above

@jaceklyp
Copy link
Contributor

Great work, sir!

@shakyShane
Copy link
Collaborator Author

@jaceklyp updated! thanks :)

@shakyShane shakyShane merged commit 3474664 into main May 25, 2023
@shakyShane shakyShane deleted the shane/POC-css branch May 25, 2023 15:29
shakyShane added a commit to duckduckgo/macos-browser that referenced this pull request May 25, 2023
Task/Issue URL: https://app.asana.com/0/0/1204657577764249/f
Tech Design URL:
CC:

**Description**:

Update macOS to use latest BSK
https://app.asana.com/0/0/1204544767438474/f

Those changes to BSK are all additions - there are no functional changes
to macOS in this PR, it's just keeping it up to date to allow
ClickToLoad, DataBrokerProtection and DuckPlayer to use them.

BSK PR: duckduckgo/BrowserServicesKit#299

**Steps to test this PR**:
1. No functional changes should be present - so just verifying
everything still works as it did before

<!--
Tagging instructions
If this PR isn't ready to be merged for whatever reason it should be
marked with the `DO NOT MERGE` label (particularly if it's a draft)
If it's pending Product Review/PFR, please add the `Pending Product
Review` label.

If at any point it isn't actively being worked on/ready for
review/otherwise moving forward (besides the above PR/PFR exception)
strongly consider closing it (or not opening it in the first place). If
you decide not to close it, make sure it's labelled to make it clear the
PRs state and comment with more information.
-->

---
###### Internal references:
[Pull Request Review
Checklist](https://app.asana.com/0/1202500774821704/1203764234894239/f)
[Software Engineering
Expectations](https://app.asana.com/0/59792373528535/199064865822552)
[Technical Design
Template](https://app.asana.com/0/59792373528535/184709971311943)
[Pull Request
Documentation](https://app.asana.com/0/1202500774821704/1204012835277482/f)

---------

Co-authored-by: Shane Osbourne <sosbourne@duckduckgo.com>
samsymons added a commit that referenced this pull request Jun 19, 2023
* main: (45 commits)
  SecureVault Keychain updates (#382)
  Reattach orphaned bookmarks to root folder when reordering (#383)
  Allow for asynchronous sync initialization (#381)
  Drop regex support in param stripping (#367)
  mac promo exp2 - add support for share link message (#375)
  Revert accidentally pushed change
  Remove test that was dependant on the keychain
  Add item to keychain in the background (#380)
  macOS in-context signup updates (#359)
  Fixes the format in a log call (#379)
  Add EventMapping to DDGSync dependencies and call it from handleUnauthenticated (#376)
  Autofill hash migration updates + Bitwarden hotfix (#372)
  Autofill password generation support for iOS (#361)
  Update autofill to 7.1.0 (#370)
  Sync Engine with support for syncing bookmarks (#355)
  Centralised Messaging for User Scripts (#299)
  Update TLD accounts query to be more specific (#368)
  Bump Tests/BrowserServicesKitTests/Resources/privacy-reference-tests (#366)
  Adds a different hash Account per each macOS build kind (#363)
  adjust os_log parameter name using disfavoredOverload (#349)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants