forked from macvim-dev/macvim
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMMWhatsNewController.m
More file actions
204 lines (167 loc) · 6.62 KB
/
MMWhatsNewController.m
File metadata and controls
204 lines (167 loc) · 6.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
//
// MMWhatsNewWindow.m
//
// Window for displaying a "What's New" page with latest release notes.
//
#import "MMWhatsNewController.h"
#import "MacVim.h"
#import <WebKit/WebKit.h>
@interface MMWhatsNewController () <WKNavigationDelegate>
@property WKWebView* webView;
@property NSURL *whatsNewURL;
- (id)init;
- (void)dealloc;
@end
@implementation MMWhatsNewController
static MMWhatsNewController *singleton = nil;
static NSString *_fromVersion;
static NSString *_latestVersion;
+ (void)openSharedInstance
{
if (![MMWhatsNewController canOpen]) {
return;
}
if (!singleton) {
singleton = [[MMWhatsNewController alloc] init];
}
NSWindow *window = [singleton window];
[window makeKeyAndOrderFront:self];
[window setDelegate:singleton];
return;
}
/// Whether this feature is supported on this OS.
+ (BOOL)canOpen
{
// While macOS 10.10 added WKWebView, 10.10-10.11 have issues with expired
// certs which means they can't easily access macvim.org. Just disable this
// feature to avoid confusing certifate errors when we pop up a blank page.
if (AVAILABLE_MAC_OS(10, 12))
{
return YES;
}
return NO;
}
/// Sets a requested version range for displaying What's New. Useful for when
/// we have updated across multiple versions and we can show a list of them.
+ (void)setRequestVersionRange:(NSString *)fromVersion to:(NSString *)latestVersion
{
// These will leak as we never release, but it's ok. We intentionally remember
// the values so that even if the user dismissed the initial window they can
// open this again and it will be remembered as long as MacVim is open. This
// results in a better UX than only seeing the info once.
_fromVersion = [fromVersion retain];
_latestVersion = [latestVersion retain];
}
- (id)init
{
self = [super initWithWindowNibName:@"WhatsNew"];
[self setWindowFrameAutosaveName:@"WhatsNew"];
NSString *whatsNewURLStr = [[NSBundle mainBundle]
objectForInfoDictionaryKey:@"MMWhatsNewURL"];
if (_fromVersion != nil && _latestVersion != nil) {
// We just updated to a new version. Show a message to user and also
// requests specifically these new versions for the welcome message
whatsNewURLStr = [NSString stringWithFormat:@"%@?from=%@&to=%@",
whatsNewURLStr,
_fromVersion,
_latestVersion];
}
else {
// Just show the current version MacVim has
NSString *currentVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
whatsNewURLStr = [NSString stringWithFormat:@"%@?version=%@",
whatsNewURLStr,
currentVersion];
}
_whatsNewURL = [[NSURL URLWithString:whatsNewURLStr] retain];
return self;
}
- (void)dealloc
{
webViewContainer = nil;
[_webView release]; _webView = nil;
[_whatsNewURL release]; _whatsNewURL = nil;
[super dealloc];
}
- (void)windowDidLoad
{
if (_fromVersion != nil && _latestVersion != nil) {
messageTextField.stringValue = [NSString stringWithFormat:
NSLocalizedString(@"MacVim has been updated to a new version (from r%@ to r%@)! See below for what's new.", @"New version prompt"),
_fromVersion, _latestVersion];
}
else {
// This will pin the web view to the top, on top of the message box
[webViewAlignTopConstraint setPriority:999];
messageTextField.stringValue = @"";
}
WKWebViewConfiguration *config = [[[WKWebViewConfiguration alloc] init] autorelease];
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11
if (AVAILABLE_MAC_OS(10, 11)) {
// Don't leave stale files in user's Library
config.websiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
}
#endif
// Construct a web view at runtime instead of relying on using the xib because this is
// more backwards compatible as we can use runtime checks and compiler defines.
_webView = [[WKWebView alloc] initWithFrame:NSZeroRect
configuration:config];
[webViewContainer addSubview:_webView];
_webView.frame = webViewContainer.bounds;
_webView.autoresizingMask = NSViewWidthSizable | NSViewHeightSizable;
_webView.navigationDelegate = self;
[_webView loadRequest:[NSURLRequest requestWithURL:_whatsNewURL]];
}
// NSWindowDelegate methods
- (void)windowWillClose:(NSNotification *)notification
{
[singleton release]; singleton = nil;
return;
}
// Font size delegates for menu items
#if defined(MAC_OS_VERSION_11_0) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_11_0
- (IBAction)fontSizeUp:(id)sender
{
if (@available(macos 11.0, *)) {
CGFloat pageZoom = _webView.pageZoom + 0.25;
_webView.pageZoom = pageZoom > 3.0 ? 3.0 : pageZoom;
}
}
- (IBAction)fontSizeDown:(id)sender
{
if (@available(macos 11.0, *)) {
CGFloat pageZoom = _webView.pageZoom - 0.25;
_webView.pageZoom = pageZoom < 0.25 ? 0.25 : pageZoom;
}
}
#endif
// WKNavigationDelegate methods
/// Tells web view how to handle links and navigation. Current behavior is
/// anything that is not the release notes will be opened by system web browser.
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{
NSURLRequest *request = navigationAction.request;
NSURL *requestURL = request.URL;
if ([requestURL.scheme isEqual:_whatsNewURL.scheme] &&
[requestURL.host isEqual:_whatsNewURL.host] &&
requestURL.port.integerValue == _whatsNewURL.port.integerValue &&
[requestURL.path isEqual:_whatsNewURL.path] &&
[requestURL.query isEqual:_whatsNewURL.query])
{
// Only allow if everything except for fragment is the same (which
// we allow so that table of contents anchor links would work).
decisionHandler(WKNavigationActionPolicyAllow);
}
else {
// We want to open any links in the release notes with a browser instead.
decisionHandler(WKNavigationActionPolicyCancel);
if ([requestURL.scheme isEqualToString:@"https"]) {
// Just try to be sane and only open https:// urls. There should be
// no reason why the release notes should contain other schemes and it
// would be an indication something is wrong or malicious (e.g. file:
// URLs).
[[NSWorkspace sharedWorkspace] openURL: requestURL];
}
}
}
@end