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

feat: WebKit message handlers #7

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

buzsh
Copy link
Contributor

@buzsh buzsh commented Jun 2, 2024

TODO

Example Syntax

declare global {
  interface Window {
    webkit: {
      messageHandlers: {
        copilotMessageProcessed: {
          postMessage: (message: string) => void;
        };
        copilotSidebarHidden: {
          postMessage: (message: string) => void;
        };
        copilotPopupHidden: {
          postMessage: (message: string) => void;
        };
      };
    };
    sendMessageToCopilot: (message: string) => void;
    showCopilotSidebar: () => void;
    hideCopilotSidebar: () => void;
    showCopilotPopup: () => void;
    hideCopilotPopup: () => void;
  }
}
  • Parse webkit message handlers
  • Generate separate enum for typesafe ScriptMessageHandlers
  • Generate WebView extensions for typesafe ScriptMessageHandlers
  • Generate view modifiers for typesafe ScriptMessageHandlers

Additional Ideas

  • Pass types through postMessage functions
  • Swift extensions for verifying types

Testing

  • Ensure duplicate postMessage names cannot be created

More Examples

Boolean

declare global {
  interface Window {
    webkit: {
      messageHandlers: {
        copilotSidebarHidden: {
          postMessage: (isHidden: boolean) => void;
        };
      };
    };
  }
}

// Sending a boolean message
window.webkit.messageHandlers.copilotSidebarHidden.postMessage(true);

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  if message.name == "copilotSidebarHidden" {
    if let isHidden = message.body as? Bool, isHidden {
      // Do something when the sidebar is hidden
    }
  }
}

Multiple Parameter Types

interface SidebarStatus {
  isHidden: boolean;
  timestamp: number;
}

declare global {
  interface Window {
    webkit: {
      messageHandlers: {
        copilotSidebarHidden: {
          postMessage: (status: SidebarStatus) => void;
        };
      };
    };
  }
}

// Sending an object message
window.webkit.messageHandlers.copilotSidebarHidden.postMessage({ isHidden: true, timestamp: Date.now() });

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  if message.name == "copilotSidebarHidden" {
    if let status = message.body as? [String: Any],
       let isHidden = status["isHidden"] as? Bool,
       let timestamp = status["timestamp"] as? Double {
      // Do something with isHidden and timestamp
    }
  }
}

Different Method Name

declare global {
  interface Window {
    webkit: {
      messageHandlers: {
        handleSidebarStatus: {
          sendStatus: (status: string) => void;
        };
      };
    };
  }
}

// Sending a string message
window.webkit.messageHandlers.handleSidebarStatus.sendStatus("hidden");

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  if message.name == "handleSidebarStatus" {
    if let status = message.body as? String, status == "hidden" {
      // Do something when the sidebar status is "hidden"
    }
  }
}

Generative: interface

interface SidebarStatus {
  isHidden: boolean;
  progress: number;
}

struct SidebarStatus: Codable {
  let isHidden: Bool
  let progress: Double
}

Usage

let status = SidebarStatus(isHidden: true, progress: 0.75)

Conversion

interface SidebarStatus {
  isHidden: boolean;
  progress: number;
}

declare global {
  interface Window {
    webkit: {
      messageHandlers: {
        copilotSidebarHidden: {
          postMessage: (status: SidebarStatus) => void;
        };
      };
    };
  }
}

// Sending an object message
window.webkit.messageHandlers.copilotSidebarHidden.postMessage({ isHidden: true, progress: 0.75 });

struct SidebarStatus: Codable {
  let isHidden: Bool
  let progress: Double
}

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
  if message.name == "copilotSidebarHidden" {
    if let data = message.body as? [String: Any] {
      do {
        let jsonData = try JSONSerialization.data(withJSONObject: data, options: [])
        let status = try JSONDecoder().decode(SidebarStatus.self, from: jsonData)
        // Use the status struct
        print("Sidebar is hidden: \(status.isHidden), progress: \(status.progress)")
      } catch {
        print("Failed to decode SidebarStatus: \(error)")
      }
    }
  }
}

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.

1 participant