OSDN Git Service

WKWebViewを使用するようにした
[kcd/KCD.git] / KCD / GameViewController.swift
index 2e633a8..a9c1163 100644 (file)
@@ -16,17 +16,22 @@ fileprivate extension Selector {
     static let screenShot = #selector(GameViewController.screenShot(_:))
 }
 
+func viewHierarchy(_ view: NSView) {
+    print(view)
+    view.subviews.forEach { viewHierarchy($0) }
+}
+
 class GameViewController: NSViewController {
     private static let gamePageURL = "http://www.dmm.com/netgame/social/-/gadgets/=/app_id=854854/"
     private static let loginPageURLPrefix = "https://www.dmm.com/my/-/login/=/"
     
-    @IBOutlet var webView: WebView!
+    var webView: WKWebView!
     
     override var nibName: String! {
         return "GameViewController"
     }
     
-    fileprivate var flashTopLeft = NSPoint(x: 2600, y: 1445)
+    fileprivate var flashTopLeft = NSPoint(x: 500, y: 20)
     private var clipView: NSClipView {
         return view as! NSClipView  // swiftlint:disable:this force_cast
     }
@@ -34,31 +39,49 @@ class GameViewController: NSViewController {
     override func viewDidLoad() {
         super.viewDidLoad()
         
+        let pref = WKPreferences()
+        pref.plugInsEnabled = true
+        let config = WKWebViewConfiguration()
+        config.preferences = pref
+        config.applicationNameForUserAgent = AppDelegate.shared.appNameForUserAgent
+        let frame = CGRect(x: 0, y: 0, width: 2000, height: 2_000)
+        webView = WKWebView(frame: frame, configuration: config)
+        webView.navigationDelegate = self
+        
         clipView.documentView = webView
         
         adjustFlash()
         
-        webView.mainFrame.frameView.allowsScrolling = false
+        webView.allowsBackForwardNavigationGestures = false
+        webView.allowsMagnification = false
+        webView.allowsLinkPreview = false
+        
+        loadURLString(urlString: GameViewController.gamePageURL)
+    }
+    
+    func loadURLString(urlString: String) {
+        guard let url = URL(string: urlString) else { return }
+        print("load \(urlString)")
         
-        webView.applicationNameForUserAgent = AppDelegate.shared.appNameForUserAgent
-        webView.mainFrameURL = GameViewController.gamePageURL
+        let req = URLRequest(url: url)
+        webView.load(req)
     }
     func adjustFlash() {
-        webView.superview?.scroll(flashTopLeft)
+        clipView.scroll(flashTopLeft)
     }
     
     @IBAction func reloadContent(_ sender: AnyObject?) {
-        guard let _ = webView.mainFrameURL
+        guard let _ = webView.url
             else {
-                webView.mainFrameURL = GameViewController.gamePageURL
+                loadURLString(urlString: GameViewController.gamePageURL)
                 return
         }
         // ゲームページでない場合はゲームページを表示する
-        if webView.mainFrameURL != GameViewController.gamePageURL {
-            webView.mainFrameURL = GameViewController.gamePageURL
+        if let url = webView?.url, url.absoluteString != GameViewController.gamePageURL {
+            loadURLString(urlString: GameViewController.gamePageURL)
             return
         }
-        if webView.mainFrameURL.hasPrefix(GameViewController.loginPageURLPrefix) {
+        if let url = webView.url, url.absoluteString.hasPrefix(GameViewController.loginPageURLPrefix) {
             webView.reload(sender)
             return
         }
@@ -111,8 +134,7 @@ class GameViewController: NSViewController {
     
     override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
         if menuItem.action == .reloadContent {
-            guard let _ = webView.mainFrame,
-                let frameURL = webView.mainFrameURL
+            guard let frameURL = webView.url?.absoluteString
                 else { return true }
             switch frameURL {
             case GameViewController.gamePageURL:
@@ -134,6 +156,46 @@ class GameViewController: NSViewController {
     }
 }
 
+extension GameViewController: WKNavigationDelegate {
+    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
+        webView.evaluateJavaScript(
+            ["var iframe = document.getElementById('game_frame');",
+             "var validIframe = 0;",
+             "var atop = 0;",
+             "var aleft = 0;",
+             "var aWidfth = 0;",
+             "if(iframe) {",
+             "    validIframe = 1;",
+             "    var rect = iframe.getBoundingClientRect();",
+             "    atop = rect.top;",
+             "    aleft = rect.left;",
+             "    aWidth = rect.width;",
+             "}",
+             "var dict = {valid:validIframe, top:atop, left:aleft, width:aWidth};",
+             "dict;"]
+                .reduce("", +)
+        ) { (dict, error) in
+            error.map { print($0) }
+            
+            guard let param = dict as? [String: Any] else { return }
+            guard let valid = param["valid"] as? Int else { return }
+            guard valid == 1 else { return }
+            guard let top = param["top"] as? Int,
+                let left = param["left"] as? Int,
+                let width = param["width"] as? Int
+                else { return }
+            
+            DispatchQueue.main.async { [weak self] in
+                guard let `self` = self else { return }
+                
+                self.flashTopLeft = NSPoint(x: CGFloat(left + (width - 800) / 2),
+                                            y: CGFloat(top + 16))
+                self.adjustFlash()
+            }
+        }
+    }
+}
+
 extension GameViewController: WebFrameLoadDelegate, WebUIDelegate {
     private static let excludeMenuItemTag = [
         WebMenuItemTagOpenLinkInNewWindow,