2 // GameViewController.swift
5 // Created by Hori,Masaki on 2016/12/31.
6 // Copyright © 2016年 Hori,Masaki. All rights reserved.
13 fileprivate extension Selector {
14 static let reloadContent = #selector(GameViewController.reloadContent(_:))
15 static let deleteCacheAndReload = #selector(GameViewController.deleteCacheAndReload(_:))
16 static let screenShot = #selector(GameViewController.screenShot(_:))
19 class GameViewController: NSViewController {
20 private static let gamePageURL = "http://www.dmm.com/netgame/social/-/gadgets/=/app_id=854854/"
21 private static let loginPageURLPrefix = "https://www.dmm.com/my/-/login/=/"
23 @IBOutlet var webView: WebView!
25 override var nibName: String! {
26 return "GameViewController"
29 fileprivate var flashTopLeft = NSPoint(x: 2600, y: 1445)
30 private var clipView: NSClipView {
31 return view as! NSClipView // swiftlint:disable:this force_cast
34 override func viewDidLoad() {
37 clipView.documentView = webView
41 webView.mainFrame.frameView.allowsScrolling = false
43 webView.applicationNameForUserAgent = AppDelegate.shared.appNameForUserAgent
44 webView.mainFrameURL = GameViewController.gamePageURL
47 webView.superview?.scroll(flashTopLeft)
50 @IBAction func reloadContent(_ sender: AnyObject?) {
51 guard let _ = webView.mainFrameURL
53 webView.mainFrameURL = GameViewController.gamePageURL
56 // ゲームページでない場合はゲームページを表示する
57 if webView.mainFrameURL != GameViewController.gamePageURL {
58 webView.mainFrameURL = GameViewController.gamePageURL
61 if webView.mainFrameURL.hasPrefix(GameViewController.loginPageURLPrefix) {
62 webView.reload(sender)
68 let prevDate = UserDefaults.standard.prevReloadDate
69 if let prevDate = prevDate {
70 let now = Date(timeIntervalSinceNow: 0.0)
71 if now.timeIntervalSince(prevDate) < 1 * 60 {
72 let untilDate = prevDate.addingTimeInterval(1 * 60)
73 let date = DateFormatter.localizedString(from: untilDate, dateStyle: .none, timeStyle: .medium)
75 alert.messageText = NSLocalizedString("Reload interval is too short?", comment: "")
76 let format = NSLocalizedString("Reload interval is too short.\nWait until %@.", comment: "")
77 alert.informativeText = String(format: format, date)
84 webView.reload(sender)
86 UserDefaults.standard.prevReloadDate = Date(timeIntervalSinceNow: 0.0)
88 @IBAction func deleteCacheAndReload(_ sender: AnyObject?) {
89 let panel = ProgressPanel()
90 guard let window = view.window,
91 let panelWindow = panel.window
94 panel.message = NSLocalizedString("Deleting caches...", comment: "Deleting caches...")
97 window.beginSheet(panelWindow) { _ in NSSound(named: "Submarine")?.play() }
99 AppDelegate.shared.clearCache()
101 window.endSheet(panelWindow)
103 @IBAction func screenShot(_ sender: AnyObject?) {
104 let frame = webView.visibleRect
105 let screenshotBorder = UserDefaults.standard.screenShotBorderWidth
106 let f = frame.insetBy(dx: -screenshotBorder, dy: -screenshotBorder)
107 guard let rep = webView.bitmapImageRepForCachingDisplay(in: f) else { return }
108 webView.cacheDisplay(in: frame, to: rep)
109 AppDelegate.shared.screenshotListWindowController.registerScreenshot(rep, fromOnScreen: .zero)
112 override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
113 if menuItem.action == .reloadContent {
114 guard let _ = webView.mainFrame,
115 let frameURL = webView.mainFrameURL
118 case GameViewController.gamePageURL:
119 menuItem.title = NSLocalizedString("Reload", comment: "Reload menu, reload")
120 case let s where s.hasPrefix(GameViewController.loginPageURLPrefix):
121 menuItem.title = NSLocalizedString("Reload", comment: "Reload menu, reload")
123 menuItem.title = NSLocalizedString("Back To Game", comment: "Reload menu, back to game")
127 if menuItem.action == .deleteCacheAndReload {
130 if menuItem.action == .screenShot {
137 extension GameViewController: WebFrameLoadDelegate, WebUIDelegate {
138 private static let excludeMenuItemTag = [
139 WebMenuItemTagOpenLinkInNewWindow,
140 WebMenuItemTagDownloadLinkToDisk,
141 WebMenuItemTagOpenImageInNewWindow,
142 WebMenuItemTagOpenFrameInNewWindow,
143 WebMenuItemTagGoBack,
144 WebMenuItemTagGoForward,
149 func webView(_ sender: WebView!, didFinishLoadFor frame: WebFrame!) {
150 guard let path = frame.dataSource?.initialRequest.url?.path else { return }
152 let handler: (JSContext?, JSValue?) -> Void = { (context, exception) in
153 print("Caught exception in evaluteScript -> \(exception)")
156 if path.hasSuffix("gadgets/ifr") {
157 guard let context = frame.javaScriptContext else { return }
158 context.exceptionHandler = handler
159 context.evaluateScript(
160 ["var emb = document.getElementById('flashWrap');",
161 "var rect = emb.getBoundingClientRect();",
162 "var atop = rect.top;",
163 "var aleft = rect.left;"]
166 let top = context.objectForKeyedSubscript("atop").toDouble()
167 let left = context.objectForKeyedSubscript("aleft").toDouble()
168 flashTopLeft = NSPoint(x: CGFloat(left), y: webView.frame.size.height - CGFloat(top) - 480)
170 if path.hasSuffix("app_id=854854") {
171 guard let context = frame.javaScriptContext else { return }
172 context.exceptionHandler = handler
173 context.evaluateScript(
174 ["var iframe = document.getElementById('game_frame');",
175 "var validIframe = 0;",
178 " var rect = iframe.getBoundingClientRect();",
179 " var atop = rect.top;",
180 " var aleft = rect.left;",
184 let validIframe = context.objectForKeyedSubscript("validIframe").toInt32()
185 guard validIframe != 0 else { return }
186 let top = context.objectForKeyedSubscript("atop").toDouble()
187 let left = context.objectForKeyedSubscript("aleft").toDouble()
188 flashTopLeft = NSPoint(x: flashTopLeft.x + CGFloat(left), y: flashTopLeft.y - CGFloat(top))
193 func webView(_ sender: WebView!,
194 contextMenuItemsForElement element: [AnyHashable: Any]!,
195 defaultMenuItems: [Any]!) -> [Any]! {
196 guard let menuItems = defaultMenuItems as? [NSMenuItem] else { return [] }
197 return menuItems.flatMap {
198 GameViewController.excludeMenuItemTag.contains($0.tag) ? nil : $0