OSDN Git Service

return文の前に改行を入れるようにした
[kcd/KCD.git] / KCD / ExternalBrowserWindowController.swift
1 //
2 //  ExternalBrowserWindowController.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2016/12/23.
6 //  Copyright © 2016年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10 import WebKit
11
12 final class ExternalBrowserWindowController: NSWindowController {
13         
14     @IBOutlet private var webView: WebView!
15     @IBOutlet private var goSegment: NSSegmentedControl!
16     @IBOutlet private var bookmarkListView: NSView!
17     
18     private var canGoBackObservation: NSKeyValueObservation?
19     private var canGoForwardObservation: NSKeyValueObservation?
20     
21     override var windowNibName: NSNib.Name {
22         
23         return .nibName(instanceOf: self)
24     }
25     
26     @objc dynamic var canResize: Bool = true {
27         
28         willSet {
29             
30             if canResize == newValue {
31                 
32                 return
33             }
34             
35             if newValue {
36                 
37                 window?.styleMask.insert(.resizable)
38                 
39             } else {
40                 
41                 window?.styleMask.remove(.resizable)
42             }
43         }
44     }
45     
46     @objc dynamic var canScroll: Bool = true {
47         
48         willSet {
49             
50             if canScroll == newValue {
51                 
52                 return
53             }
54             
55             webView?.mainFrame.frameView.allowsScrolling = newValue
56         }
57     }
58     @objc dynamic var canMovePage: Bool = true
59     
60     var urlString: String? {
61         
62         return webView.mainFrameURL
63     }
64     
65     var windowContentSize: NSSize {
66         
67         get {
68             
69             guard let window = window else {
70                 
71                 return .zero
72             }
73             
74             return window.contentRect(forFrameRect: window.frame).size
75         }
76         set {
77             guard let window = window else {
78                 
79                 return
80             }
81             
82             var contentRect: NSRect = .zero
83             contentRect.size = newValue
84             var newFrame = window.frameRect(forContentRect: contentRect)
85             let frame = window.frame
86             newFrame.origin.x = frame.minX
87             newFrame.origin.y = frame.maxY - newFrame.height
88             window.setFrame(newFrame, display: true)
89         }
90     }
91     
92     var contentVisibleRect: NSRect {
93         
94         get { return webView.mainFrame.frameView.documentView.visibleRect }
95         set { webView.mainFrame.frameView.documentView.scrollToVisible(newValue) }
96     }
97     
98     private var bookmarkShowing: Bool = false
99     private var waitingBookmarkItem: Bookmark?
100     
101     private lazy var bookmarkListViwController: BookmarkListViewController? = { [weak self] in
102         
103         guard let `self` = self else {
104             
105             return nil
106         }
107         
108         let controller = BookmarkListViewController()
109         self.bookmarkListView = controller.view
110         controller.delegate = self
111         
112         var frame = self.webView.frame
113         frame.size.width = 200
114         frame.origin.x = -200
115         self.bookmarkListView.frame = frame
116         self.webView.superview?.addSubview(self.bookmarkListView, positioned: .below, relativeTo: self.webView)
117         
118         return controller
119     }()
120     
121     override func windowDidLoad() {
122         
123         super.windowDidLoad()
124         
125         canGoBackObservation = webView.observe(\WebView.canGoBack) { [weak self] _, _ in
126             
127             guard let `self` = self else {
128                 
129                 return
130             }
131             
132             self.goSegment.setEnabled(self.webView.canGoBack, forSegment: 0)
133         }
134         canGoForwardObservation = webView.observe(\WebView.canGoForward) { [weak self] _, _ in
135             
136             guard let `self` = self else {
137                 
138                 return
139             }
140             
141             self.goSegment.setEnabled(self.webView.canGoForward, forSegment: 1)
142         }
143         
144         webView.applicationNameForUserAgent = AppDelegate.shared.appNameForUserAgent
145         webView.frameLoadDelegate = self
146     }
147     
148     override func swipe(with event: NSEvent) {
149         
150         if event.deltaX > 0 && showsBookmarkList() {
151             
152             showBookmark(nil)
153         }
154         
155         if event.deltaX < 0 && !showsBookmarkList() {
156             
157             showBookmark(nil)
158         }
159     }
160     
161     private func move(bookmark: Bookmark) {
162         
163         if !canMovePage {
164             
165             AppDelegate.shared.createNewBrowser().move(bookmark: bookmark)
166             
167             return
168         }
169         
170         webView.mainFrameURL = bookmark.urlString
171         windowContentSize = bookmark.windowContentSize
172         canResize = bookmark.canResize
173         canScroll = bookmark.canScroll
174         waitingBookmarkItem = bookmark
175     }
176     
177     private func showsBookmarkList() -> Bool {
178         
179         return webView.frame.origin.x > 0
180     }
181 }
182
183 extension ExternalBrowserWindowController: NSWindowDelegate {
184     
185     func windowWillClose(_ notification: Notification) {
186         
187         webView.policyDelegate = nil
188         webView.uiDelegate = nil
189         webView.downloadDelegate = nil
190         webView.frameLoadDelegate = nil
191     }
192 }
193
194 // MARK: - IBAction
195 extension ExternalBrowserWindowController {
196     
197     override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
198         
199         guard let action = menuItem.action else {
200             
201             return false
202         }
203         
204         switch action {
205             
206         case #selector(ExternalBrowserWindowController.addBookmark(_:)):
207             
208             return webView.mainFrameURL != nil
209             
210         case #selector(ExternalBrowserWindowController.showBookmark(_:)):
211             
212             if showsBookmarkList() {
213                 
214                 menuItem.title = LocalizedStrings.hideBookmark.string
215                 
216             } else {
217                 
218                 menuItem.title = LocalizedStrings.showBookmark.string
219             }
220             
221             return true
222             
223         case #selector(ExternalBrowserWindowController.selectBookmark(_:)):
224             
225             return true
226             
227         case #selector(ExternalBrowserWindowController.reloadContent(_:)):
228             
229             return true
230             
231         default:
232             
233             return false
234             
235         }
236     }
237     
238     @IBAction func selectBookmark(_ sender: AnyObject?) {
239         
240         guard let item = sender?.representedObject as? Bookmark else {
241             
242             return
243         }
244         
245         move(bookmark: item)
246     }
247     
248     @IBAction func reloadContent(_ sender: AnyObject?) {
249         
250         webView.reload(nil)
251     }
252     
253     @IBAction func goHome(_ sender: AnyObject?) {
254         
255         webView.mainFrameURL = "http://www.dmm.com/"
256     }
257     
258     @IBAction func clickGoBackSegment(_ sender: AnyObject?) {
259         
260         guard let cell = goSegment.cell as? NSSegmentedCell else {
261             
262             return
263         }
264         
265         let tag = cell.tag(forSegment: cell.selectedSegment)
266         switch tag {
267             
268         case 0: webView.goBack(nil)
269             
270         case 1: webView.goForward(nil)
271             
272         default: break
273             
274         }
275     }
276     
277     @IBAction func addBookmark(_ sender: AnyObject?) {
278         
279         guard let window = window else {
280             
281             return
282         }
283         _ = BookmarkManager.shared.createNewBookmark { bookmark in
284             
285             bookmark.name = window.title
286             bookmark.urlString = self.webView.mainFrameURL
287             bookmark.windowContentSize = self.windowContentSize
288             bookmark.contentVisibleRect = self.contentVisibleRect
289             bookmark.canResize = self.canResize
290             bookmark.canScroll = self.canScroll
291             bookmark.scrollDelay = 0.5
292             
293             return true
294         }
295     }
296     
297     @IBAction func showBookmark(_ sender: AnyObject?) {
298         
299         guard let window = window else {
300             
301             return
302         }
303         guard let _ = bookmarkListViwController else {
304             
305             return
306         }
307         guard !bookmarkShowing else {
308             
309             return
310         }
311         
312         bookmarkShowing = true
313         
314         var frame = bookmarkListView.frame
315         frame.size.height = webView.frame.size.height
316         bookmarkListView.frame = frame
317         
318         var newFrame = webView.frame
319         
320         if showsBookmarkList() {
321             
322             frame.origin.x = -200
323             newFrame.origin.x = 0
324             newFrame.size.width = window.frame.size.width
325             
326         } else {
327             
328             frame.origin.x = 0
329             newFrame.origin.x = 200
330             newFrame.size.width = window.frame.size.width - 200
331         }
332         
333         let webAnime = ViewAnimationAttributes(target: webView, endFrame: newFrame)
334         let bookmarkAnime = ViewAnimationAttributes(target: bookmarkListView, endFrame: frame)
335
336         let anime = ViewAnimation(viewAnimations: [webAnime, bookmarkAnime])
337         anime.start { [weak self] in
338             
339             self?.bookmarkShowing = false
340         }
341     }
342     
343     @IBAction func scrollLeft(_ sender: AnyObject?) {
344         
345         var rect = contentVisibleRect
346         rect.origin.x += 1
347         contentVisibleRect = rect
348     }
349     
350     @IBAction func scrollRight(_ sender: AnyObject?) {
351         
352         var rect = contentVisibleRect
353         rect.origin.x -= 1
354         contentVisibleRect = rect
355     }
356     
357     @IBAction func scrollUp(_ sender: AnyObject?) {
358         
359         var rect = contentVisibleRect
360         rect.origin.y += 1
361         contentVisibleRect = rect
362     }
363     
364     @IBAction func scrollDown(_ sender: AnyObject?) {
365         
366         var rect = contentVisibleRect
367         rect.origin.y -= 1
368         contentVisibleRect = rect
369     }
370     
371     @IBAction func increaseWidth(_ sender: AnyObject?) {
372         
373         guard let window = window else {
374             
375             return
376         }
377         
378         var frame = window.frame
379         frame.size.width += 1
380         window.setFrame(frame, display: true)
381     }
382     
383     @IBAction func decreaseWidth(_ sender: AnyObject?) {
384         
385         guard let window = window else {
386             
387             return
388         }
389         
390         var frame = window.frame
391         frame.size.width -= 1
392         window.setFrame(frame, display: true)
393     }
394     
395     @IBAction func increaseHeight(_ sender: AnyObject?) {
396         
397         guard let window = window else {
398             
399             return
400         }
401         
402         var frame = window.frame
403         frame.size.height += 1
404         frame.origin.y -= 1
405         window.setFrame(frame, display: true)
406     }
407     
408     @IBAction func decreaseHeight(_ sender: AnyObject?) {
409         
410         guard let window = window else {
411             
412             return
413         }
414         
415         var frame = window.frame
416         frame.size.height -= 1
417         frame.origin.y += 1
418         window.setFrame(frame, display: true)
419     }
420 }
421
422 extension ExternalBrowserWindowController: BookmarkListViewControllerDelegate {
423     
424     func didSelectBookmark(_ bookmark: Bookmark) {
425         
426         move(bookmark: bookmark)
427     }
428 }
429
430 extension ExternalBrowserWindowController: WebFrameLoadDelegate, WebPolicyDelegate {
431     
432     @objc func updateContentVisibleRect(_ timer: Timer) {
433         
434         guard let item = timer.userInfo as? Bookmark else {
435             
436             return
437         }
438         
439         contentVisibleRect = item.contentVisibleRect
440     }
441     
442     func webView(_ sender: WebView!, didFinishLoadFor frame: WebFrame!) {
443         
444         if let waitingBookmarkItem = waitingBookmarkItem {
445             
446             Timer.scheduledTimer(timeInterval: waitingBookmarkItem.scrollDelay,
447                                  target: self,
448                                  selector: #selector(ExternalBrowserWindowController.updateContentVisibleRect(_:)),
449                                  userInfo: waitingBookmarkItem,
450                                  repeats: false)
451         }
452         waitingBookmarkItem = nil
453     }
454     
455     func webView(_ webView: WebView!,
456                  decidePolicyForNavigationAction actionInformation: [AnyHashable: Any]!,
457                  request: URLRequest!,
458                  frame: WebFrame!,
459                  decisionListener listener: WebPolicyDecisionListener!) {
460         
461         if actionInformation?[WebActionNavigationTypeKey] as? WebNavigationType == .linkClicked {
462             
463             if canMovePage {
464                 
465                 listener.use()
466             }
467             
468             return
469         }
470         
471         listener.use()
472     }
473 }