Skip to content

Commit 495936c

Browse files
Fix issue downloading Python Script in Safari. (#298)
It also only shows the "safari bug" alert message in versions of Safari lower than v10.
1 parent 6aca519 commit 495936c

File tree

5 files changed

+232
-25
lines changed

5 files changed

+232
-25
lines changed

editor.html

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -409,19 +409,15 @@ <h2 id="modal-msg-title"></h2>
409409
</div>
410410
</div>
411411
</div>
412-
<script src="ace/ace.js" type="application/javascript"
413-
charset="utf-8"></script>
414-
<script src="ace/ext-language_tools.js" type="application/javascript"
415-
charset="utf-8"></script>
416-
<script src="static/js/jquery-2.1.4.min.js"
417-
type="application/javascript"></script>
412+
<script src="ace/ace.js" type="application/javascript" charset="utf-8"></script>
413+
<script src="ace/ext-language_tools.js" type="application/javascript" charset="utf-8"></script>
414+
<script src="static/js/jquery-2.1.4.min.js" type="application/javascript"></script>
415+
<script src="static/js/jquery.browser.min.js" type="application/javascript"></script>
418416
<script src="static/js/forge.min.js" type="application/javascript"></script>
419417
<script src="static/js/FileSaver.min.js" type="application/javascript"></script>
420-
<script src="static/js/vex.combined.min.js"
421-
type="application/javascript"></script>
418+
<script src="static/js/vex.combined.min.js" type="application/javascript"></script>
422419
<script src="static/js/encoding.min.js" type="application/javascript"></script>
423-
<script src="static/js/mustache.min.js"
424-
type="application/javascript"></script>
420+
<script src="static/js/mustache.min.js" type="application/javascript"></script>
425421
<script src="static/js/ResizeSensor.js"></script>
426422
<script src="static/js/ElementQueries.min.js"></script>
427423
<script src="static/js/custom-event-polyfill.js"></script>

python-main.js

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -797,18 +797,20 @@ function web_editor(config) {
797797

798798
// Downloads a file from the filesystem, main.py is renamed to the script name
799799
function downloadFileFromFilesystem(filename) {
800-
var output = micropythonFs.readBytes(filename);
801-
var ua = navigator.userAgent.toLowerCase();
802-
if ((ua.indexOf('safari/') > -1) && (ua.indexOf('chrome') == -1)) {
800+
// Safari before v10 had issues downloading a file blob
801+
if ($.browser.safari && ($.browser.versionNumber < 10)) {
803802
alert(config.translate.alerts.save);
803+
var output = micropythonFs.read(filename);
804804
window.open('data:application/octet;charset=utf-8,' + encodeURIComponent(output), '_newtab');
805-
} else {
806-
var blob = new Blob([output], {type: 'text/plain'});
807-
if (filename === 'main.py'){
808-
filename = getSafeName() + '.py';
809-
}
810-
saveAs(blob, filename);
805+
return;
811806
}
807+
// This works in all other browsers
808+
var output = micropythonFs.readBytes(filename);
809+
var blob = new Blob([output], { 'type': 'text/plain' });
810+
if (filename === 'main.py') {
811+
filename = getSafeName() + '.py';
812+
}
813+
saveAs(blob, filename);
812814
}
813815

814816
// Update the widget that shows how much space is used in the filesystem
@@ -924,15 +926,16 @@ function web_editor(config) {
924926
alert(config.translate.alerts.error + e.message);
925927
return;
926928
}
927-
var ua = navigator.userAgent.toLowerCase();
928-
if((ua.indexOf('safari/') > -1) && (ua.indexOf('chrome') == -1)) {
929+
// Safari before v10 had issues downloading the file blob
930+
if ($.browser.safari && ($.browser.versionNumber < 10)) {
929931
alert(config.translate.alerts.download);
930932
window.open('data:application/octet;charset=utf-8,' + encodeURIComponent(output), '_newtab');
931-
} else {
932-
var filename = getSafeName();
933-
var blob = new Blob([output], {type: "application/octet-stream"});
934-
saveAs(blob, filename + ".hex");
933+
return;
935934
}
935+
// This works in all other browser
936+
var filename = getSafeName();
937+
var blob = new Blob([output], { 'type': 'application/octet-stream' });
938+
saveAs(blob, filename + '.hex');
936939
}
937940

938941
function invalidFileWarning(fileType){

static/js/jquery.browser.js

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/*!
2+
* jQuery Browser Plugin 0.1.0
3+
* https://github.com/gabceb/jquery-browser-plugin
4+
*
5+
* Original jquery-browser code Copyright 2005, 2015 jQuery Foundation, Inc. and other contributors
6+
* http://jquery.org/license
7+
*
8+
* Modifications Copyright 2015 Gabriel Cebrian
9+
* https://github.com/gabceb
10+
*
11+
* Released under the MIT license
12+
*
13+
* Date: 05-07-2015
14+
*/
15+
/*global window: false */
16+
17+
(function (factory) {
18+
if (typeof define === 'function' && define.amd) {
19+
// AMD. Register as an anonymous module.
20+
define(['jquery'], function ($) {
21+
return factory($);
22+
});
23+
} else if (typeof module === 'object' && typeof module.exports === 'object') {
24+
// Node-like environment
25+
module.exports = factory(require('jquery'));
26+
} else {
27+
// Browser globals
28+
factory(window.jQuery);
29+
}
30+
}(function(jQuery) {
31+
"use strict";
32+
33+
function uaMatch( ua ) {
34+
// If an UA is not provided, default to the current browser UA.
35+
if ( ua === undefined ) {
36+
ua = window.navigator.userAgent;
37+
}
38+
ua = ua.toLowerCase();
39+
40+
var match = /(edge)\/([\w.]+)/.exec( ua ) ||
41+
/(opr)[\/]([\w.]+)/.exec( ua ) ||
42+
/(chrome)[ \/]([\w.]+)/.exec( ua ) ||
43+
/(iemobile)[\/]([\w.]+)/.exec( ua ) ||
44+
/(version)(applewebkit)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec( ua ) ||
45+
/(webkit)[ \/]([\w.]+).*(version)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec( ua ) ||
46+
/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
47+
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
48+
/(msie) ([\w.]+)/.exec( ua ) ||
49+
ua.indexOf("trident") >= 0 && /(rv)(?::| )([\w.]+)/.exec( ua ) ||
50+
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
51+
[];
52+
53+
var platform_match = /(ipad)/.exec( ua ) ||
54+
/(ipod)/.exec( ua ) ||
55+
/(windows phone)/.exec( ua ) ||
56+
/(iphone)/.exec( ua ) ||
57+
/(kindle)/.exec( ua ) ||
58+
/(silk)/.exec( ua ) ||
59+
/(android)/.exec( ua ) ||
60+
/(win)/.exec( ua ) ||
61+
/(mac)/.exec( ua ) ||
62+
/(linux)/.exec( ua ) ||
63+
/(cros)/.exec( ua ) ||
64+
/(playbook)/.exec( ua ) ||
65+
/(bb)/.exec( ua ) ||
66+
/(blackberry)/.exec( ua ) ||
67+
[];
68+
69+
var browser = {},
70+
matched = {
71+
browser: match[ 5 ] || match[ 3 ] || match[ 1 ] || "",
72+
version: match[ 2 ] || match[ 4 ] || "0",
73+
versionNumber: match[ 4 ] || match[ 2 ] || "0",
74+
platform: platform_match[ 0 ] || ""
75+
};
76+
77+
if ( matched.browser ) {
78+
browser[ matched.browser ] = true;
79+
browser.version = matched.version;
80+
browser.versionNumber = parseInt(matched.versionNumber, 10);
81+
}
82+
83+
if ( matched.platform ) {
84+
browser[ matched.platform ] = true;
85+
}
86+
87+
// These are all considered mobile platforms, meaning they run a mobile browser
88+
if ( browser.android || browser.bb || browser.blackberry || browser.ipad || browser.iphone ||
89+
browser.ipod || browser.kindle || browser.playbook || browser.silk || browser[ "windows phone" ]) {
90+
browser.mobile = true;
91+
}
92+
93+
// These are all considered desktop platforms, meaning they run a desktop browser
94+
if ( browser.cros || browser.mac || browser.linux || browser.win ) {
95+
browser.desktop = true;
96+
}
97+
98+
// Chrome, Opera 15+ and Safari are webkit based browsers
99+
if ( browser.chrome || browser.opr || browser.safari ) {
100+
browser.webkit = true;
101+
}
102+
103+
// IE11 has a new token so we will assign it msie to avoid breaking changes
104+
if ( browser.rv || browser.iemobile) {
105+
var ie = "msie";
106+
107+
matched.browser = ie;
108+
browser[ie] = true;
109+
}
110+
111+
// Edge is officially known as Microsoft Edge, so rewrite the key to match
112+
if ( browser.edge ) {
113+
delete browser.edge;
114+
var msedge = "msedge";
115+
116+
matched.browser = msedge;
117+
browser[msedge] = true;
118+
}
119+
120+
// Blackberry browsers are marked as Safari on BlackBerry
121+
if ( browser.safari && browser.blackberry ) {
122+
var blackberry = "blackberry";
123+
124+
matched.browser = blackberry;
125+
browser[blackberry] = true;
126+
}
127+
128+
// Playbook browsers are marked as Safari on Playbook
129+
if ( browser.safari && browser.playbook ) {
130+
var playbook = "playbook";
131+
132+
matched.browser = playbook;
133+
browser[playbook] = true;
134+
}
135+
136+
// BB10 is a newer OS version of BlackBerry
137+
if ( browser.bb ) {
138+
var bb = "blackberry";
139+
140+
matched.browser = bb;
141+
browser[bb] = true;
142+
}
143+
144+
// Opera 15+ are identified as opr
145+
if ( browser.opr ) {
146+
var opera = "opera";
147+
148+
matched.browser = opera;
149+
browser[opera] = true;
150+
}
151+
152+
// Stock Android browsers are marked as Safari on Android.
153+
if ( browser.safari && browser.android ) {
154+
var android = "android";
155+
156+
matched.browser = android;
157+
browser[android] = true;
158+
}
159+
160+
// Kindle browsers are marked as Safari on Kindle
161+
if ( browser.safari && browser.kindle ) {
162+
var kindle = "kindle";
163+
164+
matched.browser = kindle;
165+
browser[kindle] = true;
166+
}
167+
168+
// Kindle Silk browsers are marked as Safari on Kindle
169+
if ( browser.safari && browser.silk ) {
170+
var silk = "silk";
171+
172+
matched.browser = silk;
173+
browser[silk] = true;
174+
}
175+
176+
// Assign the name and platform variable
177+
browser.name = matched.browser;
178+
browser.platform = matched.platform;
179+
return browser;
180+
}
181+
182+
// Run the matching process, also assign the function to the returned object
183+
// for manual, jQuery-free use if desired
184+
window.jQBrowser = uaMatch( window.navigator.userAgent );
185+
window.jQBrowser.uaMatch = uaMatch;
186+
187+
// Only assign to jQuery.browser if jQuery is loaded
188+
if ( jQuery ) {
189+
jQuery.browser = window.jQBrowser;
190+
}
191+
192+
return window.jQBrowser;
193+
}));

static/js/jquery.browser.min.js

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<script src="ace/ext-language_tools.js" type="application/javascript"
1515
charset="utf-8"></script>
1616
<script src="static/js/jquery-2.1.4.min.js"></script>
17+
<script src="static/js/jquery.browser.min.js"></script>
1718
<script src="static/js/forge.min.js"></script>
1819
<script src="static/js/microbit-fs.umd.js"></script>
1920
<script src="micropythonapi.js" type="application/javascript"></script>

0 commit comments

Comments
 (0)