Selaa lähdekoodia

6.1.1.0 release

Gaudenz Alder 8 vuotta sitten
vanhempi
commit
03a75a4dac

+ 9 - 0
ChangeLog

@@ -1,3 +1,12 @@
+16-FEB-2017: 6.1.1.0
+
+- Uses mxGraph 3.7.0.2 beta 4
+- Adds import for SVG and JPG images from backends
+- Adds VSDX/Gliffy/PNG+XML import/open from backends
+- Adds border option for image export
+- Adds timeout handlers for Atlassian cloud
+- Fixes ignored crop in JPEG export
+
 15-FEB-2017: 6.1.0.3
 
 - Fixes possible NPE in OneDriveClient

+ 1 - 1
VERSION

@@ -1 +1 @@
-6.1.0.3
+6.1.1.0

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 3 - 3
etc/mxgraph/mxClient.js


+ 1 - 1
war/WEB-INF/appengine-web.xml

@@ -2,7 +2,7 @@
 <appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
 	<application>drawdotio</application>
 	<!-- IMPORTANT! DO NOT CHANGE THIS VALUE IN SOURCE CONTROL! -->
-	<version>6-1-0-3</version>
+	<version>test</version>
 	
 	<!-- Configure java.util.logging -->
 	<system-properties>

+ 395 - 395
war/cache.manifest

@@ -1,406 +1,406 @@
 CACHE MANIFEST
 
 # THIS FILE WAS GENERATED. DO NOT MODIFY!
-# 02/15/2017 08:38 AM
+# 02/16/2017 06:04 PM
 
-/app.html
-/index.html?offline=1
-/offline.html
-/open.html
-/js/app.min.js
-/js/shapes.min.js
-/styles/grapheditor.css
-/styles/atlas.css
-/stencils.xml
-/search.xml
-/favicon.ico
-/mxgraph/css/common.css
-/js/jscolor/jscolor.js
-/mxgraph/images/maximize.gif
-/mxgraph/images/minimize.gif
-/mxgraph/images/close.gif
-/mxgraph/images/resize.gif
-/mxgraph/images/separator.gif
-/mxgraph/images/window.gif
-/mxgraph/images/window-title.gif
-/mxgraph/images/button.gif
-/mxgraph/images/point.gif
-/mxgraph/images/transparent.gif
-/resources/dia.txt
-/styles/default.xml
-/styles/default-old.xml
-/img/clipart/Gear_128x128.png
-/images/delete.png
-/images/droptarget.png
-/images/edit.gif
-/images/download.png
-/images/logo-flat.png
-/images/osa_drive-harddisk.png
-/images/osa_database.png
-/images/glyphicons_star.png
-/images/logo-confluence.png
-/images/logo-jira.png
-/images/checkmark.gif
-/images/favicon-32x32.png
-/images/favicon-194x194.png
-/images/favicon-96x96.png
-/images/android-chrome-192x192.png
-/images/favicon-16x16.png
-/images/glyphicons_google.png
-/images/glyphicons_facebook.png
-/images/glyphicons_twitter.png
-/images/glyphicons_github.png
-/js/jscolor/arrow.gif
-/js/jscolor/hs.png
-/js/jscolor/cross.gif
-/img/clipart/Battery_0_128x128.png
-/img/clipart/Battery_100_128x128.png
-/img/clipart/Battery_50_128x128.png
-/img/clipart/Battery_75_128x128.png
-/img/clipart/Battery_allstates_128x128.png
-/img/clipart/Bluetooth_128x128.png
-/img/clipart/Earth_globe_128x128.png
-/img/clipart/Empty_Folder_128x128.png
-/img/clipart/Full_Folder_128x128.png
-/img/clipart/Gear_128x128.png
-/img/clipart/Keys_128x128.png
-/img/clipart/Lock_128x128.png
-/img/clipart/Mouse_Pointer_128x128.png
-/img/clipart/Plug_128x128.png
-/img/clipart/Ships_Wheel_128x128.png
-/img/clipart/Star_128x128.png
-/img/clipart/Tire_128x128.png
-/img/computers/Antivirus_128x128.png
-/img/computers/Data_Filtering_128x128.png
-/img/computers/Database_128x128.png
-/img/computers/Database_Add_128x128.png
-/img/computers/Database_Minus_128x128.png
-/img/computers/Database_Move_Stack_128x128.png
-/img/computers/Database_Remove_128x128.png
-/img/computers/Fujitsu_Tablet_128x128.png
-/img/computers/Harddrive_128x128.png
-/img/computers/IBM_Tablet_128x128.png
-/img/computers/iMac_128x128.png
-/img/computers/iPad_128x128.png
-/img/computers/Laptop_128x128.png
-/img/computers/MacBook_128x128.png
-/img/computers/Mainframe_128x128.png
-/img/computers/Monitor_128x128.png
-/img/computers/Monitor_Tower_128x128.png
-/img/computers/Monitor_Tower_Behind_128x128.png
-/img/computers/Netbook_128x128.png
-/img/computers/Network_128x128.png
-/img/computers/Network_2_128x128.png
-/img/computers/Printer_128x128.png
-/img/computers/Printer_Commercial_128x128.png
-/img/computers/Secure_System_128x128.png
-/img/computers/Server_128x128.png
-/img/computers/Server_Rack_128x128.png
-/img/computers/Server_Rack_Empty_128x128.png
-/img/computers/Server_Rack_Partial_128x128.png
-/img/computers/Server_Tower_128x128.png
-/img/computers/Software_128x128.png
-/img/computers/Stylus_128x128.png
-/img/computers/Touch_128x128.png
-/img/computers/USB_Hub_128x128.png
-/img/computers/Virtual_Application_128x128.png
-/img/computers/Virtual_Machine_128x128.png
-/img/computers/Virus_128x128.png
-/img/computers/Workstation_128x128.png
-/img/finance/Arrow_Down_128x128.png
-/img/finance/Arrow_Up_128x128.png
-/img/finance/Coins_128x128.png
-/img/finance/Credit_Card_128x128.png
-/img/finance/Dollar_128x128.png
-/img/finance/Graph_128x128.png
-/img/finance/Pie_Chart_128x128.png
-/img/finance/Piggy_Bank_128x128.png
-/img/finance/Safe_128x128.png
-/img/finance/Shopping_Cart_128x128.png
-/img/finance/Stock_Down_128x128.png
-/img/finance/Stock_Up_128x128.png
-/img/lib/clip_art/computers/Antivirus_128x128.png
-/img/lib/clip_art/computers/Data_Filtering_128x128.png
-/img/lib/clip_art/computers/Database_128x128.png
-/img/lib/clip_art/computers/Database_Add_128x128.png
-/img/lib/clip_art/computers/Database_Minus_128x128.png
-/img/lib/clip_art/computers/Database_Move_Stack_128x128.png
-/img/lib/clip_art/computers/Database_Remove_128x128.png
-/img/lib/clip_art/computers/Fujitsu_Tablet_128x128.png
-/img/lib/clip_art/computers/Harddrive_128x128.png
-/img/lib/clip_art/computers/IBM_Tablet_128x128.png
-/img/lib/clip_art/computers/iMac_128x128.png
-/img/lib/clip_art/computers/iPad_128x128.png
-/img/lib/clip_art/computers/Laptop_128x128.png
-/img/lib/clip_art/computers/MacBook_128x128.png
-/img/lib/clip_art/computers/Mainframe_128x128.png
-/img/lib/clip_art/computers/Monitor_128x128.png
-/img/lib/clip_art/computers/Monitor_Tower_128x128.png
-/img/lib/clip_art/computers/Monitor_Tower_Behind_128x128.png
-/img/lib/clip_art/computers/Netbook_128x128.png
-/img/lib/clip_art/computers/Network_128x128.png
-/img/lib/clip_art/computers/Network_2_128x128.png
-/img/lib/clip_art/computers/Printer_128x128.png
-/img/lib/clip_art/computers/Printer_Commercial_128x128.png
-/img/lib/clip_art/computers/Secure_System_128x128.png
-/img/lib/clip_art/computers/Server_128x128.png
-/img/lib/clip_art/computers/Server_Rack_128x128.png
-/img/lib/clip_art/computers/Server_Rack_Empty_128x128.png
-/img/lib/clip_art/computers/Server_Rack_Partial_128x128.png
-/img/lib/clip_art/computers/Server_Tower_128x128.png
-/img/lib/clip_art/computers/Software_128x128.png
-/img/lib/clip_art/computers/Stylus_128x128.png
-/img/lib/clip_art/computers/Touch_128x128.png
-/img/lib/clip_art/computers/USB_Hub_128x128.png
-/img/lib/clip_art/computers/Virtual_Application_128x128.png
-/img/lib/clip_art/computers/Virtual_Machine_128x128.png
-/img/lib/clip_art/computers/Virus_128x128.png
-/img/lib/clip_art/computers/Workstation_128x128.png
-/img/lib/clip_art/finance/Arrow_Down_128x128.png
-/img/lib/clip_art/finance/Arrow_Up_128x128.png
-/img/lib/clip_art/finance/Coins_128x128.png
-/img/lib/clip_art/finance/Credit_Card_128x128.png
-/img/lib/clip_art/finance/Dollar_128x128.png
-/img/lib/clip_art/finance/Graph_128x128.png
-/img/lib/clip_art/finance/Pie_Chart_128x128.png
-/img/lib/clip_art/finance/Piggy_Bank_128x128.png
-/img/lib/clip_art/finance/Safe_128x128.png
-/img/lib/clip_art/finance/Shopping_Cart_128x128.png
-/img/lib/clip_art/finance/Stock_Down_128x128.png
-/img/lib/clip_art/finance/Stock_Up_128x128.png
-/img/lib/clip_art/general/Battery_0_128x128.png
-/img/lib/clip_art/general/Battery_100_128x128.png
-/img/lib/clip_art/general/Battery_50_128x128.png
-/img/lib/clip_art/general/Battery_75_128x128.png
-/img/lib/clip_art/general/Battery_allstates_128x128.png
-/img/lib/clip_art/general/Bluetooth_128x128.png
-/img/lib/clip_art/general/Earth_globe_128x128.png
-/img/lib/clip_art/general/Empty_Folder_128x128.png
-/img/lib/clip_art/general/Full_Folder_128x128.png
-/img/lib/clip_art/general/Gear_128x128.png
-/img/lib/clip_art/general/Keys_128x128.png
-/img/lib/clip_art/general/Lock_128x128.png
-/img/lib/clip_art/general/Mouse_Pointer_128x128.png
-/img/lib/clip_art/general/Plug_128x128.png
-/img/lib/clip_art/general/Ships_Wheel_128x128.png
-/img/lib/clip_art/general/Star_128x128.png
-/img/lib/clip_art/general/Tire_128x128.png
-/img/lib/clip_art/networking/Bridge_128x128.png
-/img/lib/clip_art/networking/Certificate_128x128.png
-/img/lib/clip_art/networking/Certificate_Off_128x128.png
-/img/lib/clip_art/networking/Cloud_128x128.png
-/img/lib/clip_art/networking/Cloud_Computer_128x128.png
-/img/lib/clip_art/networking/Cloud_Computer_Private_128x128.png
-/img/lib/clip_art/networking/Cloud_Rack_128x128.png
-/img/lib/clip_art/networking/Cloud_Rack_Private_128x128.png
-/img/lib/clip_art/networking/Cloud_Server_128x128.png
-/img/lib/clip_art/networking/Cloud_Server_Private_128x128.png
-/img/lib/clip_art/networking/Cloud_Storage_128x128.png
-/img/lib/clip_art/networking/Concentrator_128x128.png
-/img/lib/clip_art/networking/Email_128x128.png
-/img/lib/clip_art/networking/Firewall-page1_128x128.png
-/img/lib/clip_art/networking/Firewall_02_128x128.png
-/img/lib/clip_art/networking/Firewall_128x128.png
-/img/lib/clip_art/networking/Ip_Camera_128x128.png
-/img/lib/clip_art/networking/Modem_128x128.png
-/img/lib/clip_art/networking/power_distribution_unit_128x128.png
-/img/lib/clip_art/networking/Print_Server_128x128.png
-/img/lib/clip_art/networking/Print_Server_Wireless_128x128.png
-/img/lib/clip_art/networking/Repeater_128x128.png
-/img/lib/clip_art/networking/Router_128x128.png
-/img/lib/clip_art/networking/Router_Icon_128x128.png
-/img/lib/clip_art/networking/Switch_128x128.png
-/img/lib/clip_art/networking/UPS_128x128.png
-/img/lib/clip_art/networking/Wireless_Router_128x128.png
-/img/lib/clip_art/networking/Wireless_Router_N_128x128.png
-/img/lib/clip_art/people/Construction_Worker_Man_128x128.png
-/img/lib/clip_art/people/Construction_Worker_Man_Black_128x128.png
-/img/lib/clip_art/people/Construction_Worker_Woman_128x128.png
-/img/lib/clip_art/people/Construction_Worker_Woman_Black_128x128.png
-/img/lib/clip_art/people/Doctor_Man_128x128.png
-/img/lib/clip_art/people/Doctor_Man_Black_128x128.png
-/img/lib/clip_art/people/Doctor_Woman_128x128.png
-/img/lib/clip_art/people/Doctor_Woman_Black_128x128.png
-/img/lib/clip_art/people/Farmer_Man_128x128.png
-/img/lib/clip_art/people/Farmer_Man_Black_128x128.png
-/img/lib/clip_art/people/Farmer_Woman_128x128.png
-/img/lib/clip_art/people/Farmer_Woman_Black_128x128.png
-/img/lib/clip_art/people/Military_Officer_128x128.png
-/img/lib/clip_art/people/Military_Officer_Black_128x128.png
-/img/lib/clip_art/people/Military_Officer_Woman_128x128.png
-/img/lib/clip_art/people/Military_Officer_Woman_Black_128x128.png
-/img/lib/clip_art/people/Nurse_Man_128x128.png
-/img/lib/clip_art/people/Nurse_Man_Black_128x128.png
-/img/lib/clip_art/people/Nurse_Man_Green_128x128.png
-/img/lib/clip_art/people/Nurse_Man_Red_128x128.png
-/img/lib/clip_art/people/Nurse_Woman_128x128.png
-/img/lib/clip_art/people/Nurse_Woman_Black_128x128.png
-/img/lib/clip_art/people/Nurse_Woman_Green_128x128.png
-/img/lib/clip_art/people/Nurse_Woman_Red_128x128.png
-/img/lib/clip_art/people/Pilot_Man_128x128.png
-/img/lib/clip_art/people/Pilot_Man_Black_128x128.png
-/img/lib/clip_art/people/Pilot_Woman_128x128.png
-/img/lib/clip_art/people/Pilot_Woman_Black_128x128.png
-/img/lib/clip_art/people/Scientist_Man_128x128.png
-/img/lib/clip_art/people/Scientist_Man_Black_128x128.png
-/img/lib/clip_art/people/Scientist_Woman_128x128.png
-/img/lib/clip_art/people/Scientist_Woman_Black_128x128.png
-/img/lib/clip_art/people/Security_Man_128x128.png
-/img/lib/clip_art/people/Security_Man_Black_128x128.png
-/img/lib/clip_art/people/Security_Woman_128x128.png
-/img/lib/clip_art/people/Security_Woman_Black_128x128.png
-/img/lib/clip_art/people/Soldier_128x128.png
-/img/lib/clip_art/people/Soldier_Black_128x128.png
-/img/lib/clip_art/people/Suit_Man_128x128.png
-/img/lib/clip_art/people/Suit_Man_Black_128x128.png
-/img/lib/clip_art/people/Suit_Man_Blue_128x128.png
-/img/lib/clip_art/people/Suit_Man_Green_128x128.png
-/img/lib/clip_art/people/Suit_Man_Green_Black_128x128.png
-/img/lib/clip_art/people/Suit_Woman_128x128.png
-/img/lib/clip_art/people/Suit_Woman_Black_128x128.png
-/img/lib/clip_art/people/Suit_Woman_Blue_128x128.png
-/img/lib/clip_art/people/Suit_Woman_Green_128x128.png
-/img/lib/clip_art/people/Suit_Woman_Green_Black_128x128.png
-/img/lib/clip_art/people/Tech_Man_128x128.png
-/img/lib/clip_art/people/Tech_Man_Black_128x128.png
-/img/lib/clip_art/people/Telesales_Man_128x128.png
-/img/lib/clip_art/people/Telesales_Man_Black_128x128.png
-/img/lib/clip_art/people/Telesales_Woman_128x128.png
-/img/lib/clip_art/people/Telesales_Woman_Black_128x128.png
-/img/lib/clip_art/people/Waiter_128x128.png
-/img/lib/clip_art/people/Waiter_Black_128x128.png
-/img/lib/clip_art/people/Waiter_Woman_128x128.png
-/img/lib/clip_art/people/Waiter_Woman_Black_128x128.png
-/img/lib/clip_art/people/Worker_Black_128x128.png
-/img/lib/clip_art/people/Worker_Man_128x128.png
-/img/lib/clip_art/people/Worker_Woman_128x128.png
-/img/lib/clip_art/people/Worker_Woman_Black_128x128.png
-/img/lib/clip_art/telecommunication/BlackBerry_128x128.png
-/img/lib/clip_art/telecommunication/Cellphone_128x128.png
-/img/lib/clip_art/telecommunication/HTC_smartphone_128x128.png
-/img/lib/clip_art/telecommunication/iPhone_128x128.png
-/img/lib/clip_art/telecommunication/Palm_Treo_128x128.png
-/img/lib/clip_art/telecommunication/Signal_tower_off_128x128.png
-/img/lib/clip_art/telecommunication/Signal_tower_on_128x128.png
-/img/lib/clip_art/telecommunication/Telephone_128x128.png
-/img/networking/Bridge_128x128.png
-/img/networking/Certificate_128x128.png
-/img/networking/Certificate_Off_128x128.png
-/img/networking/Cloud_128x128.png
-/img/networking/Cloud_Computer_128x128.png
-/img/networking/Cloud_Computer_Private_128x128.png
-/img/networking/Cloud_Rack_128x128.png
-/img/networking/Cloud_Rack_Private_128x128.png
-/img/networking/Cloud_Server_128x128.png
-/img/networking/Cloud_Server_Private_128x128.png
-/img/networking/Cloud_Storage_128x128.png
-/img/networking/Concentrator_128x128.png
-/img/networking/Data_Filtering_128x128.png
-/img/networking/Database_128x128.png
-/img/networking/Database_Add_128x128.png
-/img/networking/Database_Minus_128x128.png
-/img/networking/Database_Move_Stack_128x128.png
-/img/networking/Database_Remove_128x128.png
-/img/networking/Email_128x128.png
-/img/networking/Firewall-page1_128x128.png
-/img/networking/Firewall_02_128x128.png
-/img/networking/Firewall_128x128.png
-/img/networking/Ip_Camera_128x128.png
-/img/networking/Mainframe_128x128.png
-/img/networking/Modem_128x128.png
-/img/networking/power_distribution_unit_128x128.png
-/img/networking/Print_Server_128x128.png
-/img/networking/Print_Server_Wireless_128x128.png
-/img/networking/Repeater_128x128.png
-/img/networking/Router_128x128.png
-/img/networking/Router_Icon_128x128.png
-/img/networking/Server_128x128.png
-/img/networking/Server_Rack_128x128.png
-/img/networking/Server_Rack_Empty_128x128.png
-/img/networking/Server_Rack_Partial_128x128.png
-/img/networking/Switch_128x128.png
-/img/networking/UPS_128x128.png
-/img/networking/Wireless_Router_128x128.png
-/img/networking/Wireless_Router_N_128x128.png
-/img/people/Construction_Worker_Man_128x128.png
-/img/people/Construction_Worker_Man_Black_128x128.png
-/img/people/Construction_Worker_Woman_128x128.png
-/img/people/Construction_Worker_Woman_Black_128x128.png
-/img/people/Doctor_Man_128x128.png
-/img/people/Doctor_Man_Black_128x128.png
-/img/people/Doctor_Woman_128x128.png
-/img/people/Doctor_Woman_Black_128x128.png
-/img/people/Farmer_Man_128x128.png
-/img/people/Farmer_Man_Black_128x128.png
-/img/people/Farmer_Woman_128x128.png
-/img/people/Farmer_Woman_Black_128x128.png
-/img/people/Military_Officer_128x128.png
-/img/people/Military_Officer_Black_128x128.png
-/img/people/Military_Officer_Woman_128x128.png
-/img/people/Military_Officer_Woman_Black_128x128.png
-/img/people/Nurse_Man_128x128.png
-/img/people/Nurse_Man_Black_128x128.png
-/img/people/Nurse_Man_Green_128x128.png
-/img/people/Nurse_Man_Red_128x128.png
-/img/people/Nurse_Woman_128x128.png
-/img/people/Nurse_Woman_Black_128x128.png
-/img/people/Nurse_Woman_Green_128x128.png
-/img/people/Nurse_Woman_Red_128x128.png
-/img/people/Pilot_Man_128x128.png
-/img/people/Pilot_Man_Black_128x128.png
-/img/people/Pilot_Woman_128x128.png
-/img/people/Pilot_Woman_Black_128x128.png
-/img/people/Scientist_Man_128x128.png
-/img/people/Scientist_Man_Black_128x128.png
-/img/people/Scientist_Woman_128x128.png
-/img/people/Scientist_Woman_Black_128x128.png
-/img/people/Security_Man_128x128.png
-/img/people/Security_Man_Black_128x128.png
-/img/people/Security_Woman_128x128.png
-/img/people/Security_Woman_Black_128x128.png
-/img/people/Soldier_128x128.png
-/img/people/Soldier_Black_128x128.png
-/img/people/Suit_Man_128x128.png
-/img/people/Suit_Man_Black_128x128.png
-/img/people/Suit_Man_Blue_128x128.png
-/img/people/Suit_Man_Green_128x128.png
-/img/people/Suit_Man_Green_Black_128x128.png
-/img/people/Suit_Woman_128x128.png
-/img/people/Suit_Woman_Black_128x128.png
-/img/people/Suit_Woman_Blue_128x128.png
-/img/people/Suit_Woman_Green_128x128.png
-/img/people/Suit_Woman_Green_Black_128x128.png
-/img/people/Tech_Man_128x128.png
-/img/people/Tech_Man_Black_128x128.png
-/img/people/Telesales_Man_128x128.png
-/img/people/Telesales_Man_Black_128x128.png
-/img/people/Telesales_Woman_128x128.png
-/img/people/Telesales_Woman_Black_128x128.png
-/img/people/Waiter_128x128.png
-/img/people/Waiter_Black_128x128.png
-/img/people/Waiter_Woman_128x128.png
-/img/people/Waiter_Woman_Black_128x128.png
-/img/people/Worker_Black_128x128.png
-/img/people/Worker_Man_128x128.png
-/img/people/Worker_Woman_128x128.png
-/img/people/Worker_Woman_Black_128x128.png
-/img/telecommunication/Battery_0_128x128.png
-/img/telecommunication/Battery_100_128x128.png
-/img/telecommunication/Battery_50_128x128.png
-/img/telecommunication/Battery_75_128x128.png
-/img/telecommunication/Battery_allstates_128x128.png
-/img/telecommunication/BlackBerry_128x128.png
-/img/telecommunication/Cellphone_128x128.png
-/img/telecommunication/HTC_smartphone_128x128.png
-/img/telecommunication/iPhone_128x128.png
-/img/telecommunication/Palm_Treo_128x128.png
-/img/telecommunication/Signal_tower_off_128x128.png
-/img/telecommunication/Signal_tower_on_128x128.png
+app.html
+index.html?offline=1
+offline.html
+open.html
+js/app.min.js
+js/shapes.min.js
+styles/grapheditor.css
+styles/atlas.css
+stencils.xml
+search.xml
+favicon.ico
+mxgraph/css/common.css
+js/jscolor/jscolor.js
+mxgraph/images/maximize.gif
+mxgraph/images/minimize.gif
+mxgraph/images/close.gif
+mxgraph/images/resize.gif
+mxgraph/images/separator.gif
+mxgraph/images/window.gif
+mxgraph/images/window-title.gif
+mxgraph/images/button.gif
+mxgraph/images/point.gif
+mxgraph/images/transparent.gif
+resources/dia.txt
+styles/default.xml
+styles/default-old.xml
+img/clipart/Gear_128x128.png
+images/delete.png
+images/droptarget.png
+images/edit.gif
+images/download.png
+images/logo-flat.png
+images/osa_drive-harddisk.png
+images/osa_database.png
+images/glyphicons_star.png
+images/logo-confluence.png
+images/logo-jira.png
+images/checkmark.gif
+images/favicon-32x32.png
+images/favicon-194x194.png
+images/favicon-96x96.png
+images/android-chrome-192x192.png
+images/favicon-16x16.png
+images/glyphicons_google.png
+images/glyphicons_facebook.png
+images/glyphicons_twitter.png
+images/glyphicons_github.png
+js/jscolor/arrow.gif
+js/jscolor/hs.png
+js/jscolor/cross.gif
+img/clipart/Battery_0_128x128.png
+img/clipart/Battery_100_128x128.png
+img/clipart/Battery_50_128x128.png
+img/clipart/Battery_75_128x128.png
+img/clipart/Battery_allstates_128x128.png
+img/clipart/Bluetooth_128x128.png
+img/clipart/Earth_globe_128x128.png
+img/clipart/Empty_Folder_128x128.png
+img/clipart/Full_Folder_128x128.png
+img/clipart/Gear_128x128.png
+img/clipart/Keys_128x128.png
+img/clipart/Lock_128x128.png
+img/clipart/Mouse_Pointer_128x128.png
+img/clipart/Plug_128x128.png
+img/clipart/Ships_Wheel_128x128.png
+img/clipart/Star_128x128.png
+img/clipart/Tire_128x128.png
+img/computers/Antivirus_128x128.png
+img/computers/Data_Filtering_128x128.png
+img/computers/Database_128x128.png
+img/computers/Database_Add_128x128.png
+img/computers/Database_Minus_128x128.png
+img/computers/Database_Move_Stack_128x128.png
+img/computers/Database_Remove_128x128.png
+img/computers/Fujitsu_Tablet_128x128.png
+img/computers/Harddrive_128x128.png
+img/computers/IBM_Tablet_128x128.png
+img/computers/iMac_128x128.png
+img/computers/iPad_128x128.png
+img/computers/Laptop_128x128.png
+img/computers/MacBook_128x128.png
+img/computers/Mainframe_128x128.png
+img/computers/Monitor_128x128.png
+img/computers/Monitor_Tower_128x128.png
+img/computers/Monitor_Tower_Behind_128x128.png
+img/computers/Netbook_128x128.png
+img/computers/Network_128x128.png
+img/computers/Network_2_128x128.png
+img/computers/Printer_128x128.png
+img/computers/Printer_Commercial_128x128.png
+img/computers/Secure_System_128x128.png
+img/computers/Server_128x128.png
+img/computers/Server_Rack_128x128.png
+img/computers/Server_Rack_Empty_128x128.png
+img/computers/Server_Rack_Partial_128x128.png
+img/computers/Server_Tower_128x128.png
+img/computers/Software_128x128.png
+img/computers/Stylus_128x128.png
+img/computers/Touch_128x128.png
+img/computers/USB_Hub_128x128.png
+img/computers/Virtual_Application_128x128.png
+img/computers/Virtual_Machine_128x128.png
+img/computers/Virus_128x128.png
+img/computers/Workstation_128x128.png
+img/finance/Arrow_Down_128x128.png
+img/finance/Arrow_Up_128x128.png
+img/finance/Coins_128x128.png
+img/finance/Credit_Card_128x128.png
+img/finance/Dollar_128x128.png
+img/finance/Graph_128x128.png
+img/finance/Pie_Chart_128x128.png
+img/finance/Piggy_Bank_128x128.png
+img/finance/Safe_128x128.png
+img/finance/Shopping_Cart_128x128.png
+img/finance/Stock_Down_128x128.png
+img/finance/Stock_Up_128x128.png
+img/lib/clip_art/computers/Antivirus_128x128.png
+img/lib/clip_art/computers/Data_Filtering_128x128.png
+img/lib/clip_art/computers/Database_128x128.png
+img/lib/clip_art/computers/Database_Add_128x128.png
+img/lib/clip_art/computers/Database_Minus_128x128.png
+img/lib/clip_art/computers/Database_Move_Stack_128x128.png
+img/lib/clip_art/computers/Database_Remove_128x128.png
+img/lib/clip_art/computers/Fujitsu_Tablet_128x128.png
+img/lib/clip_art/computers/Harddrive_128x128.png
+img/lib/clip_art/computers/IBM_Tablet_128x128.png
+img/lib/clip_art/computers/iMac_128x128.png
+img/lib/clip_art/computers/iPad_128x128.png
+img/lib/clip_art/computers/Laptop_128x128.png
+img/lib/clip_art/computers/MacBook_128x128.png
+img/lib/clip_art/computers/Mainframe_128x128.png
+img/lib/clip_art/computers/Monitor_128x128.png
+img/lib/clip_art/computers/Monitor_Tower_128x128.png
+img/lib/clip_art/computers/Monitor_Tower_Behind_128x128.png
+img/lib/clip_art/computers/Netbook_128x128.png
+img/lib/clip_art/computers/Network_128x128.png
+img/lib/clip_art/computers/Network_2_128x128.png
+img/lib/clip_art/computers/Printer_128x128.png
+img/lib/clip_art/computers/Printer_Commercial_128x128.png
+img/lib/clip_art/computers/Secure_System_128x128.png
+img/lib/clip_art/computers/Server_128x128.png
+img/lib/clip_art/computers/Server_Rack_128x128.png
+img/lib/clip_art/computers/Server_Rack_Empty_128x128.png
+img/lib/clip_art/computers/Server_Rack_Partial_128x128.png
+img/lib/clip_art/computers/Server_Tower_128x128.png
+img/lib/clip_art/computers/Software_128x128.png
+img/lib/clip_art/computers/Stylus_128x128.png
+img/lib/clip_art/computers/Touch_128x128.png
+img/lib/clip_art/computers/USB_Hub_128x128.png
+img/lib/clip_art/computers/Virtual_Application_128x128.png
+img/lib/clip_art/computers/Virtual_Machine_128x128.png
+img/lib/clip_art/computers/Virus_128x128.png
+img/lib/clip_art/computers/Workstation_128x128.png
+img/lib/clip_art/finance/Arrow_Down_128x128.png
+img/lib/clip_art/finance/Arrow_Up_128x128.png
+img/lib/clip_art/finance/Coins_128x128.png
+img/lib/clip_art/finance/Credit_Card_128x128.png
+img/lib/clip_art/finance/Dollar_128x128.png
+img/lib/clip_art/finance/Graph_128x128.png
+img/lib/clip_art/finance/Pie_Chart_128x128.png
+img/lib/clip_art/finance/Piggy_Bank_128x128.png
+img/lib/clip_art/finance/Safe_128x128.png
+img/lib/clip_art/finance/Shopping_Cart_128x128.png
+img/lib/clip_art/finance/Stock_Down_128x128.png
+img/lib/clip_art/finance/Stock_Up_128x128.png
+img/lib/clip_art/general/Battery_0_128x128.png
+img/lib/clip_art/general/Battery_100_128x128.png
+img/lib/clip_art/general/Battery_50_128x128.png
+img/lib/clip_art/general/Battery_75_128x128.png
+img/lib/clip_art/general/Battery_allstates_128x128.png
+img/lib/clip_art/general/Bluetooth_128x128.png
+img/lib/clip_art/general/Earth_globe_128x128.png
+img/lib/clip_art/general/Empty_Folder_128x128.png
+img/lib/clip_art/general/Full_Folder_128x128.png
+img/lib/clip_art/general/Gear_128x128.png
+img/lib/clip_art/general/Keys_128x128.png
+img/lib/clip_art/general/Lock_128x128.png
+img/lib/clip_art/general/Mouse_Pointer_128x128.png
+img/lib/clip_art/general/Plug_128x128.png
+img/lib/clip_art/general/Ships_Wheel_128x128.png
+img/lib/clip_art/general/Star_128x128.png
+img/lib/clip_art/general/Tire_128x128.png
+img/lib/clip_art/networking/Bridge_128x128.png
+img/lib/clip_art/networking/Certificate_128x128.png
+img/lib/clip_art/networking/Certificate_Off_128x128.png
+img/lib/clip_art/networking/Cloud_128x128.png
+img/lib/clip_art/networking/Cloud_Computer_128x128.png
+img/lib/clip_art/networking/Cloud_Computer_Private_128x128.png
+img/lib/clip_art/networking/Cloud_Rack_128x128.png
+img/lib/clip_art/networking/Cloud_Rack_Private_128x128.png
+img/lib/clip_art/networking/Cloud_Server_128x128.png
+img/lib/clip_art/networking/Cloud_Server_Private_128x128.png
+img/lib/clip_art/networking/Cloud_Storage_128x128.png
+img/lib/clip_art/networking/Concentrator_128x128.png
+img/lib/clip_art/networking/Email_128x128.png
+img/lib/clip_art/networking/Firewall-page1_128x128.png
+img/lib/clip_art/networking/Firewall_02_128x128.png
+img/lib/clip_art/networking/Firewall_128x128.png
+img/lib/clip_art/networking/Ip_Camera_128x128.png
+img/lib/clip_art/networking/Modem_128x128.png
+img/lib/clip_art/networking/power_distribution_unit_128x128.png
+img/lib/clip_art/networking/Print_Server_128x128.png
+img/lib/clip_art/networking/Print_Server_Wireless_128x128.png
+img/lib/clip_art/networking/Repeater_128x128.png
+img/lib/clip_art/networking/Router_128x128.png
+img/lib/clip_art/networking/Router_Icon_128x128.png
+img/lib/clip_art/networking/Switch_128x128.png
+img/lib/clip_art/networking/UPS_128x128.png
+img/lib/clip_art/networking/Wireless_Router_128x128.png
+img/lib/clip_art/networking/Wireless_Router_N_128x128.png
+img/lib/clip_art/people/Construction_Worker_Man_128x128.png
+img/lib/clip_art/people/Construction_Worker_Man_Black_128x128.png
+img/lib/clip_art/people/Construction_Worker_Woman_128x128.png
+img/lib/clip_art/people/Construction_Worker_Woman_Black_128x128.png
+img/lib/clip_art/people/Doctor_Man_128x128.png
+img/lib/clip_art/people/Doctor_Man_Black_128x128.png
+img/lib/clip_art/people/Doctor_Woman_128x128.png
+img/lib/clip_art/people/Doctor_Woman_Black_128x128.png
+img/lib/clip_art/people/Farmer_Man_128x128.png
+img/lib/clip_art/people/Farmer_Man_Black_128x128.png
+img/lib/clip_art/people/Farmer_Woman_128x128.png
+img/lib/clip_art/people/Farmer_Woman_Black_128x128.png
+img/lib/clip_art/people/Military_Officer_128x128.png
+img/lib/clip_art/people/Military_Officer_Black_128x128.png
+img/lib/clip_art/people/Military_Officer_Woman_128x128.png
+img/lib/clip_art/people/Military_Officer_Woman_Black_128x128.png
+img/lib/clip_art/people/Nurse_Man_128x128.png
+img/lib/clip_art/people/Nurse_Man_Black_128x128.png
+img/lib/clip_art/people/Nurse_Man_Green_128x128.png
+img/lib/clip_art/people/Nurse_Man_Red_128x128.png
+img/lib/clip_art/people/Nurse_Woman_128x128.png
+img/lib/clip_art/people/Nurse_Woman_Black_128x128.png
+img/lib/clip_art/people/Nurse_Woman_Green_128x128.png
+img/lib/clip_art/people/Nurse_Woman_Red_128x128.png
+img/lib/clip_art/people/Pilot_Man_128x128.png
+img/lib/clip_art/people/Pilot_Man_Black_128x128.png
+img/lib/clip_art/people/Pilot_Woman_128x128.png
+img/lib/clip_art/people/Pilot_Woman_Black_128x128.png
+img/lib/clip_art/people/Scientist_Man_128x128.png
+img/lib/clip_art/people/Scientist_Man_Black_128x128.png
+img/lib/clip_art/people/Scientist_Woman_128x128.png
+img/lib/clip_art/people/Scientist_Woman_Black_128x128.png
+img/lib/clip_art/people/Security_Man_128x128.png
+img/lib/clip_art/people/Security_Man_Black_128x128.png
+img/lib/clip_art/people/Security_Woman_128x128.png
+img/lib/clip_art/people/Security_Woman_Black_128x128.png
+img/lib/clip_art/people/Soldier_128x128.png
+img/lib/clip_art/people/Soldier_Black_128x128.png
+img/lib/clip_art/people/Suit_Man_128x128.png
+img/lib/clip_art/people/Suit_Man_Black_128x128.png
+img/lib/clip_art/people/Suit_Man_Blue_128x128.png
+img/lib/clip_art/people/Suit_Man_Green_128x128.png
+img/lib/clip_art/people/Suit_Man_Green_Black_128x128.png
+img/lib/clip_art/people/Suit_Woman_128x128.png
+img/lib/clip_art/people/Suit_Woman_Black_128x128.png
+img/lib/clip_art/people/Suit_Woman_Blue_128x128.png
+img/lib/clip_art/people/Suit_Woman_Green_128x128.png
+img/lib/clip_art/people/Suit_Woman_Green_Black_128x128.png
+img/lib/clip_art/people/Tech_Man_128x128.png
+img/lib/clip_art/people/Tech_Man_Black_128x128.png
+img/lib/clip_art/people/Telesales_Man_128x128.png
+img/lib/clip_art/people/Telesales_Man_Black_128x128.png
+img/lib/clip_art/people/Telesales_Woman_128x128.png
+img/lib/clip_art/people/Telesales_Woman_Black_128x128.png
+img/lib/clip_art/people/Waiter_128x128.png
+img/lib/clip_art/people/Waiter_Black_128x128.png
+img/lib/clip_art/people/Waiter_Woman_128x128.png
+img/lib/clip_art/people/Waiter_Woman_Black_128x128.png
+img/lib/clip_art/people/Worker_Black_128x128.png
+img/lib/clip_art/people/Worker_Man_128x128.png
+img/lib/clip_art/people/Worker_Woman_128x128.png
+img/lib/clip_art/people/Worker_Woman_Black_128x128.png
+img/lib/clip_art/telecommunication/BlackBerry_128x128.png
+img/lib/clip_art/telecommunication/Cellphone_128x128.png
+img/lib/clip_art/telecommunication/HTC_smartphone_128x128.png
+img/lib/clip_art/telecommunication/iPhone_128x128.png
+img/lib/clip_art/telecommunication/Palm_Treo_128x128.png
+img/lib/clip_art/telecommunication/Signal_tower_off_128x128.png
+img/lib/clip_art/telecommunication/Signal_tower_on_128x128.png
+img/lib/clip_art/telecommunication/Telephone_128x128.png
+img/networking/Bridge_128x128.png
+img/networking/Certificate_128x128.png
+img/networking/Certificate_Off_128x128.png
+img/networking/Cloud_128x128.png
+img/networking/Cloud_Computer_128x128.png
+img/networking/Cloud_Computer_Private_128x128.png
+img/networking/Cloud_Rack_128x128.png
+img/networking/Cloud_Rack_Private_128x128.png
+img/networking/Cloud_Server_128x128.png
+img/networking/Cloud_Server_Private_128x128.png
+img/networking/Cloud_Storage_128x128.png
+img/networking/Concentrator_128x128.png
+img/networking/Data_Filtering_128x128.png
+img/networking/Database_128x128.png
+img/networking/Database_Add_128x128.png
+img/networking/Database_Minus_128x128.png
+img/networking/Database_Move_Stack_128x128.png
+img/networking/Database_Remove_128x128.png
+img/networking/Email_128x128.png
+img/networking/Firewall-page1_128x128.png
+img/networking/Firewall_02_128x128.png
+img/networking/Firewall_128x128.png
+img/networking/Ip_Camera_128x128.png
+img/networking/Mainframe_128x128.png
+img/networking/Modem_128x128.png
+img/networking/power_distribution_unit_128x128.png
+img/networking/Print_Server_128x128.png
+img/networking/Print_Server_Wireless_128x128.png
+img/networking/Repeater_128x128.png
+img/networking/Router_128x128.png
+img/networking/Router_Icon_128x128.png
+img/networking/Server_128x128.png
+img/networking/Server_Rack_128x128.png
+img/networking/Server_Rack_Empty_128x128.png
+img/networking/Server_Rack_Partial_128x128.png
+img/networking/Switch_128x128.png
+img/networking/UPS_128x128.png
+img/networking/Wireless_Router_128x128.png
+img/networking/Wireless_Router_N_128x128.png
+img/people/Construction_Worker_Man_128x128.png
+img/people/Construction_Worker_Man_Black_128x128.png
+img/people/Construction_Worker_Woman_128x128.png
+img/people/Construction_Worker_Woman_Black_128x128.png
+img/people/Doctor_Man_128x128.png
+img/people/Doctor_Man_Black_128x128.png
+img/people/Doctor_Woman_128x128.png
+img/people/Doctor_Woman_Black_128x128.png
+img/people/Farmer_Man_128x128.png
+img/people/Farmer_Man_Black_128x128.png
+img/people/Farmer_Woman_128x128.png
+img/people/Farmer_Woman_Black_128x128.png
+img/people/Military_Officer_128x128.png
+img/people/Military_Officer_Black_128x128.png
+img/people/Military_Officer_Woman_128x128.png
+img/people/Military_Officer_Woman_Black_128x128.png
+img/people/Nurse_Man_128x128.png
+img/people/Nurse_Man_Black_128x128.png
+img/people/Nurse_Man_Green_128x128.png
+img/people/Nurse_Man_Red_128x128.png
+img/people/Nurse_Woman_128x128.png
+img/people/Nurse_Woman_Black_128x128.png
+img/people/Nurse_Woman_Green_128x128.png
+img/people/Nurse_Woman_Red_128x128.png
+img/people/Pilot_Man_128x128.png
+img/people/Pilot_Man_Black_128x128.png
+img/people/Pilot_Woman_128x128.png
+img/people/Pilot_Woman_Black_128x128.png
+img/people/Scientist_Man_128x128.png
+img/people/Scientist_Man_Black_128x128.png
+img/people/Scientist_Woman_128x128.png
+img/people/Scientist_Woman_Black_128x128.png
+img/people/Security_Man_128x128.png
+img/people/Security_Man_Black_128x128.png
+img/people/Security_Woman_128x128.png
+img/people/Security_Woman_Black_128x128.png
+img/people/Soldier_128x128.png
+img/people/Soldier_Black_128x128.png
+img/people/Suit_Man_128x128.png
+img/people/Suit_Man_Black_128x128.png
+img/people/Suit_Man_Blue_128x128.png
+img/people/Suit_Man_Green_128x128.png
+img/people/Suit_Man_Green_Black_128x128.png
+img/people/Suit_Woman_128x128.png
+img/people/Suit_Woman_Black_128x128.png
+img/people/Suit_Woman_Blue_128x128.png
+img/people/Suit_Woman_Green_128x128.png
+img/people/Suit_Woman_Green_Black_128x128.png
+img/people/Tech_Man_128x128.png
+img/people/Tech_Man_Black_128x128.png
+img/people/Telesales_Man_128x128.png
+img/people/Telesales_Man_Black_128x128.png
+img/people/Telesales_Woman_128x128.png
+img/people/Telesales_Woman_Black_128x128.png
+img/people/Waiter_128x128.png
+img/people/Waiter_Black_128x128.png
+img/people/Waiter_Woman_128x128.png
+img/people/Waiter_Woman_Black_128x128.png
+img/people/Worker_Black_128x128.png
+img/people/Worker_Man_128x128.png
+img/people/Worker_Woman_128x128.png
+img/people/Worker_Woman_Black_128x128.png
+img/telecommunication/Battery_0_128x128.png
+img/telecommunication/Battery_100_128x128.png
+img/telecommunication/Battery_50_128x128.png
+img/telecommunication/Battery_75_128x128.png
+img/telecommunication/Battery_allstates_128x128.png
+img/telecommunication/BlackBerry_128x128.png
+img/telecommunication/Cellphone_128x128.png
+img/telecommunication/HTC_smartphone_128x128.png
+img/telecommunication/iPhone_128x128.png
+img/telecommunication/Palm_Treo_128x128.png
+img/telecommunication/Signal_tower_off_128x128.png
+img/telecommunication/Signal_tower_on_128x128.png
 
 # Redirect app to app.html which redirects to index.html?offline=1
 # this is required to get the URL parameters into the index page.
 FALLBACK:
-/app /app.html
+app app.html
 
 NETWORK:
 *

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 486 - 480
war/js/app.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 422 - 419
war/js/atlas-viewer.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 416 - 409
war/js/atlas.min.js


+ 277 - 92
war/js/diagramly/App.js

@@ -1804,8 +1804,7 @@ App.prototype.open = function()
 							title = this.defaultFilename;
 						}
 						
-						this.fileLoaded(new LocalFile(this, xml, title));
-						this.setMode(null);
+						this.fileLoaded(new LocalFile(this, xml, title, true));
 					}
 					else
 					{
@@ -2060,9 +2059,8 @@ App.prototype.start = function()
 									title = this.defaultFilename;
 								}
 								
-								this.fileLoaded(new LocalFile(this, xml, title));
+								this.fileLoaded(new LocalFile(this, xml, title, true));
 								this.getCurrentFile().setModified(!this.editor.chromeless);
-								this.setMode(null);
 							}
 						}));
 					}
@@ -2073,8 +2071,7 @@ App.prototype.start = function()
 					if (urlParams['demo'] == '1')
 					{
 						var prev = Editor.useLocalStorage;
-						this.createFile(this.defaultFilename, null, null, App.MODE_DEVICE);
-						this.setMode(null);
+						this.createFile(this.defaultFilename, null, null, null, null, null, null, true);
 						Editor.useLocalStorage = prev;
 					}
 					else
@@ -2107,8 +2104,7 @@ App.prototype.start = function()
 								var draft = this.getDraft();
 								var fileData = (draft != null) ? draft.data : this.getFileData();
 								var prev = Editor.useLocalStorage;
-								this.createFile(this.defaultFilename, fileData, null, App.MODE_DEVICE);
-								this.setMode(null);
+								this.createFile(this.defaultFilename, fileData, null, null, null, null, null, true);
 								Editor.useLocalStorage = prev;
 								
 								// Draft was used so the user should save the file
@@ -2180,8 +2176,7 @@ App.prototype.start = function()
 								this.hideDialog();
 								var prev = Editor.useLocalStorage;
 								this.createFile((filename.length > 0) ? filename : this.defaultFilename,
-									this.getFileData(), null, App.MODE_DEVICE);
-								this.setMode(null);
+									this.getFileData(), null, null, null, null, null, true);
 								Editor.useLocalStorage = prev;
 							}
 							else
@@ -2287,8 +2282,7 @@ App.prototype.showSplash = function(force)
 				if (cancel && !mxClient.IS_CHROMEAPP)
 				{
 					var prev = Editor.useLocalStorage;
-					this.createFile(this.defaultFilename, null, null, App.MODE_DEVICE);
-					this.setMode(null);
+					this.createFile(this.defaultFilename, null, null, null, null, null, null, true);
 					Editor.useLocalStorage = prev;
 				}
 			}));
@@ -2420,28 +2414,7 @@ App.prototype.pickFile = function(mode)
 {
 	mode = (mode != null) ? mode : this.mode;
 	
-	if (mode == App.MODE_DROPBOX)
-	{
-		if (this.dropbox != null)
-		{
-			this.dropbox.pickFile();
-		}
-	}
-	else if (mode == App.MODE_GITHUB)
-	{
-		if (this.gitHub != null)
-		{
-			this.gitHub.pickFile();
-		}
-	}
-	else if (mode == App.MODE_ONEDRIVE)
-	{
-		if (this.oneDrive != null)
-		{
-			this.oneDrive.pickFile();
-		}
-	}
-	else if (mode == App.MODE_GOOGLE)
+	if (mode == App.MODE_GOOGLE)
 	{
 		if (this.drive != null && typeof(google) != 'undefined' && typeof(google.picker) != 'undefined')
 		{
@@ -2452,61 +2425,70 @@ App.prototype.pickFile = function(mode)
 			window.open('https://drive.google.com');
 		}
 	}
-	else if (mode == App.MODE_DEVICE && Graph.fileSupport && !mxClient.IS_IE && !mxClient.IS_IE11)
+	else
 	{
-		var input = document.createElement('input');
-		input.setAttribute('type', 'file');
+		var peer = this.getPeerForMode(mode);
 		
-		mxEvent.addListener(input, 'change', mxUtils.bind(this, function()
+		if (peer != null)
 		{
-			if (input.files != null)
+			peer.pickFile();
+		}
+		else if (mode == App.MODE_DEVICE && Graph.fileSupport && !mxClient.IS_IE && !mxClient.IS_IE11)
+		{
+			var input = document.createElement('input');
+			input.setAttribute('type', 'file');
+			
+			mxEvent.addListener(input, 'change', mxUtils.bind(this, function()
 			{
-				this.openFiles(input.files);
-			}
-		}));
-
-		input.click();
-	}
-	else
-	{
-		this.hideDialog();
-		window.openNew = this.getCurrentFile() != null && !this.isDiagramEmpty();
-		window.baseUrl = this.getUrl();
-		window.openKey = 'open';
-		var prevValue = Editor.useLocalStorage;
-		Editor.useLocalStorage = (mode == App.MODE_BROWSER);
-		this.openFile();
-		
-		// Installs local handler for opened files in same window
-		window.openFile.setConsumer(mxUtils.bind(this, function(xml, filename)
+				if (input.files != null)
+				{
+					this.openFiles(input.files);
+				}
+			}));
+	
+			input.click();
+		}
+		else
 		{
-			// Replaces PNG with XML extension
-			var dot = filename.substring(filename.length - 4) == '.png';
+			this.hideDialog();
+			window.openNew = this.getCurrentFile() != null && !this.isDiagramEmpty();
+			window.baseUrl = this.getUrl();
+			window.openKey = 'open';
+			var prevValue = Editor.useLocalStorage;
+			Editor.useLocalStorage = (mode == App.MODE_BROWSER);
+			this.openFile();
 			
-			if (dot > 0)
+			// Installs local handler for opened files in same window
+			window.openFile.setConsumer(mxUtils.bind(this, function(xml, filename)
 			{
-				filename = filename.substring(0, filename.length - 4) + '.xml';
-			}
+				// Replaces PNG with XML extension
+				var dot = filename.substring(filename.length - 4) == '.png';
+				
+				if (dot > 0)
+				{
+					filename = filename.substring(0, filename.length - 4) + '.xml';
+				}
+				
+				this.fileLoaded((mode == App.MODE_BROWSER) ?
+						new StorageFile(this, xml, filename) :
+						new LocalFile(this, xml, filename));
+			}));
 			
-			this.fileLoaded((mode == App.MODE_BROWSER) ?
-					new StorageFile(this, xml, filename) :
-					new LocalFile(this, xml, filename));
-		}));
-		
-		// Extends dialog close to show splash screen
-		var dlg = this.dialog;
-		var dlgClose = dlg.close;
-		
-		this.dialog.close = mxUtils.bind(this, function(cancel)
-		{
-			Editor.useLocalStorage = prevValue;
-			dlgClose.apply(dlg, arguments);
-
-			if (this.getCurrentFile() == null)
+			// Extends dialog close to show splash screen
+			var dlg = this.dialog;
+			var dlgClose = dlg.close;
+			
+			this.dialog.close = mxUtils.bind(this, function(cancel)
 			{
-				this.showSplash();
-			}
-		});
+				Editor.useLocalStorage = prevValue;
+				dlgClose.apply(dlg, arguments);
+	
+				if (this.getCurrentFile() == null)
+				{
+					this.showSplash();
+				}
+			});
+		}
 	}
 };
 
@@ -2919,9 +2901,39 @@ EditorUi.prototype.loadTemplate = function(url, onload, onerror)
  * @param {number} dx X-coordinate of the translation.
  * @param {number} dy Y-coordinate of the translation.
  */
-App.prototype.createFile = function(title, data, libs, mode, done, replace, folderId)
+App.prototype.getPeerForMode = function(mode)
 {
-	mode = (mode != null) ? mode : this.mode;
+	if (mode == App.MODE_GOOGLE)
+	{
+		return this.drive;
+	}
+	else if (mode == App.MODE_GITHUB)
+	{
+		return this.gitHub;
+	}
+	else if (mode == App.MODE_DROPBOX)
+	{
+		return this.dropbox;
+	}
+	else if (mode == App.MODE_ONEDRIVE)
+	{
+		return this.oneDrive;
+	}
+	else
+	{
+		return null;
+	}
+};
+
+/**
+ * Translates this point by the given vector.
+ * 
+ * @param {number} dx X-coordinate of the translation.
+ * @param {number} dy Y-coordinate of the translation.
+ */
+App.prototype.createFile = function(title, data, libs, mode, done, replace, folderId, tempFile)
+{
+	mode = (tempFile) ? null : ((mode != null) ? mode : this.mode);
 
 	if (title != null && this.spinner.spin(document.body, mxResources.get('inserting')))
 	{
@@ -3016,7 +3028,7 @@ App.prototype.createFile = function(title, data, libs, mode, done, replace, fold
 		else
 		{
 			complete();
-			this.fileCreated(new LocalFile(this, data, title), libs, replace, done);
+			this.fileCreated(new LocalFile(this, data, title, mode == null), libs, replace, done);
 		}
 	}
 };
@@ -3197,13 +3209,12 @@ App.prototype.loadFile = function(id, sameWindow, file)
 				}
 				
 				var file = new LocalFile(this, data, (urlParams['title'] != null) ?
-					decodeURIComponent(urlParams['title']) : this.defaultFilename);
+					decodeURIComponent(urlParams['title']) : this.defaultFilename, true);
 				file.getHash = function()
 				{
 					return id;
 				};
 				this.fileLoaded(file);
-				this.setMode(null);
 			}
 			else if (id.charAt(0) == 'U')
 			{
@@ -3242,17 +3253,13 @@ App.prototype.loadFile = function(id, sameWindow, file)
 						}
 						
 						var file = new LocalFile(this, text, (urlParams['title'] != null) ?
-							decodeURIComponent(urlParams['title']) : filename);
+							decodeURIComponent(urlParams['title']) : filename, true);
 						file.getHash = function()
 						{
 							return id;
 						};
 						
-						if (this.fileLoaded(file))
-						{
-							this.setMode(null);	
-						}
-						else
+						if (!this.fileLoaded(file))
 						{
 							// Fallback for non-public Google Drive diagrams
 							if (url.substring(0, 31) == 'https://drive.google.com/uc?id=' &&
@@ -3961,6 +3968,183 @@ App.prototype.showAuthDialog = function(peer, showRememberOption, fn)
 	}));
 };
 
+/**
+ * Checks if the client is authorized and calls the next step. The optional
+ * readXml argument is used for import. Default is false. The optional
+ * readLibrary argument is used for reading libraries. Default is false.
+ */
+App.prototype.convertFile = function(url, filename, mimeType, extension, success, error)
+{
+	var name = filename;
+	
+	// SVG file extensions are valid and needed for image import
+	if (!/\.svg$/i.test(name))
+	{
+		name = name.substring(0, filename.lastIndexOf('.')) + extension;
+	}
+	
+	var gitHubUrl = false;
+	
+	if (this.gitHub != null && url.substring(0, this.gitHub.baseUrl.length) == this.gitHub.baseUrl)
+	{
+		gitHubUrl = true;
+	}
+	
+	// Workaround for wrong binary response with VSDX files
+	if (/\.vsdx$/i.test(filename) && Graph.fileSupport && new XMLHttpRequest().upload &&
+		typeof new XMLHttpRequest().responseType === 'string')
+	{
+		var req = new XMLHttpRequest();
+		req.open('GET', url, true);
+		
+		if (!gitHubUrl)
+		{
+			req.responseType = 'blob';
+		}
+
+		req.onload = mxUtils.bind(this, function()
+		{
+			var blob = null;
+			
+			if (gitHubUrl)
+			{
+				var file = JSON.parse(req.responseText);
+				blob = this.base64ToBlob(file.content, 'application/octet-stream');
+			}
+			else
+			{
+				blob = new Blob([req.response], {type: 'application/octet-stream'});
+			}
+
+			this.parseFile(blob, mxUtils.bind(this, function(xhr)
+			{
+				if (xhr.readyState == 4)
+				{
+					if (xhr.status >= 200 && xhr.status <= 299)
+					{
+						success(new LocalFile(this, xhr.responseText, name, true));
+					}
+					else if (error != null)
+					{
+						error({message: mxResources.get('errorLoadingFile')});
+					}
+				}
+			}), filename);
+		});
+
+		req.send();
+	}
+	else
+	{
+		var handleData = mxUtils.bind(this, function(data)
+		{
+			try
+			{
+				if (/\.png$/i.test(filename))
+				{
+					temp = this.extractGraphModelFromPng(data);
+					
+					if (temp != null)
+					{
+						success(new LocalFile(this, temp, name, true));
+					}
+					else
+					{
+						success(new LocalFile(this, data, filename, true));
+					}
+				}
+				else if (Graph.fileSupport && new XMLHttpRequest().upload)
+				{
+					this.parseFile(new Blob([data], {type: 'application/octet-stream'}), mxUtils.bind(this, function(xhr)
+					{
+						if (xhr.readyState == 4)
+						{
+							if (xhr.status >= 200 && xhr.status <= 299)
+							{
+								success(new LocalFile(this, xhr.responseText, name, true));
+							}
+							else if (error != null)
+							{
+								error({message: mxResources.get('errorLoadingFile')});
+							}
+						}
+					}), filename);
+				}
+				else if (error != null)
+				{
+					error({message: mxResources.get('errorLoadingFile')});
+				}
+			}
+			catch (e)
+			{
+				if (error != null)
+				{
+					error(e);
+				}
+			}
+		});
+
+		var binary = /\.png$/i.test(filename) || /\.jpe?g$/i.test(filename) || (mimeType != null &&
+			mimeType.substring(0, 6) == 'image/');
+		
+		// NOTE: Cannot force non-binary request via loadUrl so needs separate
+		// code as decoding twice on content with binary data did not work
+		if (gitHubUrl)
+		{
+			mxUtils.get(url, mxUtils.bind(this, function(req)
+			{
+				if (req.getStatus() >= 200 && req.getStatus() <= 299)
+				{
+			    	if (success != null)
+			    	{
+				    	var file = JSON.parse(req.getText());
+				    	var data = file.content;
+				    	
+				    	if (file.encoding === 'base64')
+				    	{
+				    		if (/\.png$/i.test(filename))
+					    	{
+					    		data = 'data:image/png;base64,' + data;	
+					    	}
+					    	else if (/\.jpe?g$/i.test(filename))
+					    	{
+					    		data = 'data:image/jpeg;base64,' + data;	
+					    	}
+					    	else
+					    	{
+					    		// Workaround for character encoding issues in IE10/11
+					    		data = (window.atob && !mxClient.IS_IE && !mxClient.IS_IE11) ? atob(data) : Base64.decode(data);
+					    	}
+				    	}
+				    	
+				    	handleData(data);
+			    	}
+				}
+				else if (error != null)
+		    	{
+		    		error({code: App.ERROR_UNKNOWN});
+		    	}
+			}), function()
+			{
+		    	if (error != null)
+		    	{
+		    		error({code: App.ERROR_UNKNOWN});
+		    	}
+			}, false, this.timeout, function()
+		    {
+		    	if (error != null)
+				{
+					error({code: App.ERROR_TIMEOUT, retry: fn});
+				}
+		    });
+		}
+		else
+		{
+			this.loadUrl(url, handleData, error, binary);
+		}
+	}
+};
+
 /**
  * Checks if the client is authorized and calls the next step.
  */
@@ -3968,7 +4152,7 @@ App.prototype.loadUrl = function(url, success, error, forceBinary, retry)
 {
 	try
 	{
-		var binary = (forceBinary || /(\.png)($|\?)/i.test(url));
+		var binary = (forceBinary || /(\.png)($|\?)/i.test(url) || /(\.jpe?g)($|\?)/i.test(url));
 		retry = (retry != null) ? retry : true;
 		
 		var fn = mxUtils.bind(this, function()
@@ -3999,6 +4183,7 @@ App.prototype.loadUrl = function(url, success, error, forceBinary, retry)
 								data = tmp.join('');
 							}
 							
+							// LATER: Could be JPG but modern browser ignore the mime type
 							data = 'data:image/png;base64,' + this.base64Encode(data);
 						}
 			    		

+ 2 - 2
war/js/diagramly/Dialogs.js

@@ -68,8 +68,7 @@ var StorageDialog = function(editorUi, fn, rowLimit)
 	{
 		editorUi.hideDialog();
 		var prev = Editor.useLocalStorage;
-		editorUi.createFile(editorUi.defaultFilename, null, null, App.MODE_DEVICE);
-		editorUi.setMode(null);
+		editorUi.createFile(editorUi.defaultFilename, null, null, null, null, null, null, true);
 		Editor.useLocalStorage = prev;
 	});
 	
@@ -486,6 +485,7 @@ var SplashDialog = function(editorUi)
 		mxEvent.addListener(link, 'click', function()
 		{
 			editorUi.hideDialog(false);
+			editorUi.setMode(null);
 			editorUi.clearMode();
 			editorUi.showSplash(true);
 		});

+ 9 - 40
war/js/diagramly/DriveClient.js

@@ -597,40 +597,6 @@ DriveClient.prototype.getLibrary = function(id, success, error)
 	return this.getFile(id, success, error, true, true);
 };
 
-/**
- * Checks if the client is authorized and calls the next step. The optional
- * readXml argument is used for import. Default is false. The optional
- * readLibrary argument is used for reading libraries. Default is false.
- */
-DriveClient.prototype.convertFile = function(resp, success, error)
-{
-	var name = resp.title;
-	name = name.substring(0, name.lastIndexOf('.')) + this.extension;
-	
-	// Gets file data
-	var token = gapi.auth.getToken().access_token;
-	var url = resp.downloadUrl + '&access_token=' + token;
-	
-	this.ui.loadUrl(url, mxUtils.bind(this, function(data)
-	{
-		this.ui.parseFile(new Blob([data], {type: 'application/octet-stream'}), mxUtils.bind(this, function(xhr)
-		{
-			if (xhr.readyState == 4)
-			{
-				if (xhr.status >= 200 && xhr.status <= 299 && xhr.responseText.substring(0, 13) == '<mxGraphModel')
-				{
-					this.insertFile(name, xhr.responseText, (resp.parents != null && resp.parents.length > 0) ?
-						resp.parents[0].id : null, success, error);
-				}
-				else if (error != null)
-				{
-					error({message: mxResources.get('errorLoadingFile')});
-				}
-			}
-		}), resp.title);
-	}));
-};
-
 /**
  * Checks if the client is authorized and calls the next step. The optional
  * readXml argument is used for import. Default is false. The optional
@@ -654,11 +620,11 @@ DriveClient.prototype.getFile = function(id, success, error, readXml, readLibrar
 		{
 			if (this.user != null)
 			{
-				// Handles .vsdx and Gliffy files by creating a new file
-				if (!readLibrary && !readXml && Graph.fileSupport && new XMLHttpRequest().upload &&
-					(/(\.vsdx)$/i.test(resp.title) || /(\.gliffy)$/i.test(resp.title)))
+				// Handles .vsdx, Gliffy and PNG+XML files by creating a temporary file
+				if ((/\.vsdx$/i.test(resp.title) || /\.gliffy$/i.test(resp.title) || /\.png$/i.test(resp.title)))
 				{
-					this.convertFile(resp, success, error);
+					var url = resp.downloadUrl + '&access_token=' + gapi.auth.getToken().access_token;
+					this.ui.convertFile(url, resp.title, resp.mimeType, this.extension, success, error);
 				}
 				else
 				{
@@ -707,7 +673,9 @@ DriveClient.prototype.getFile = function(id, success, error, readXml, readLibrar
 DriveClient.prototype.loadRealtime = function(resp, success, error)
 {
 	// Redirects to new app because the realtime models of different apps are not visible
-	if (urlParams['ignoremime'] != '1' && this.appId == '420247213240' && (resp.mimeType == 'application/mxr' || resp.mimeType == 'application/vnd.jgraph.mxfile.realtime'))
+	if (urlParams['ignoremime'] != '1' && this.appId == '420247213240' &&
+		(resp.mimeType == 'application/vnd.jgraph.mxfile.realtime' ||
+		resp.mimeType == 'application/mxr'))
 	{
 		this.redirectToNewApp(error, resp.id);
 	}
@@ -793,7 +761,8 @@ DriveClient.prototype.getXmlFile = function(resp, doc, success, error, ignoreMim
 				success(file);
 			}
 		}
-	}), error, resp.mimeType.substring(0, 6) == 'image/');
+	}), error, (resp.mimeType.substring(0, 6) == 'image/' && resp.mimeType.substring(0, 9) != 'image/svg') ||
+		/\.png$/i.test(resp.title) || /\.jpe?g$/i.test(resp.title));
 };
 
 /**

+ 98 - 122
war/js/diagramly/DropboxClient.js

@@ -190,13 +190,13 @@ DropboxClient.prototype.authorize = function(interactive, fn)
  */
 DropboxClient.prototype.getLibrary = function(path, success, error)
 {
-	this.getFile(path, success, error, false, true);
+	this.getFile(path, success, error, true);
 };
 
 /**
  * DenyConvert is ignored in this client, just added for API compatibility.
  */
-DropboxClient.prototype.getFile = function(path, success, error, denyConvert, asLibrary)
+DropboxClient.prototype.getFile = function(path, success, error, asLibrary)
 {
 	asLibrary = (asLibrary != null) ? asLibrary : false;
 	
@@ -204,51 +204,61 @@ DropboxClient.prototype.getFile = function(path, success, error, denyConvert, as
 	{
 		this.execute(mxUtils.bind(this, function()
 		{
-			var acceptResponse = true;
-			
-			var timeoutThread = window.setTimeout(mxUtils.bind(this, function()
-			{
-				acceptResponse = false;
-				error({code: App.ERROR_TIMEOUT, retry: fn});
-			}), this.ui.timeout);
-			
-			var options = null;
-			
-			if (urlParams['rev'] != null)
+			if (/^https:\/\//i.test(path) || /\.vsdx$/i.test(path) || /\.gliffy$/i.test(path) || /\.png$/i.test(path))
 			{
-				options = {versionTag: urlParams['rev']};
+				var tokens = path.split('/');
+				var name = (tokens.length > 0) ? tokens[tokens.length - 1] : path;
+		
+				this.ui.convertFile(path, name, null, this.extension, success, error);
 			}
-			
-			this.client.readFile('/' + path, options, mxUtils.bind(this, function(err, data, stat)
+			else
 			{
-				try
+				var acceptResponse = true;
+				
+				var timeoutThread = window.setTimeout(mxUtils.bind(this, function()
 				{
-			    	window.clearTimeout(timeoutThread);
-			    	
-			    	if (acceptResponse)
-			    	{
-						if (err != null)
-						{
-							error(err)
-						}
-						else
-						{
-							if (asLibrary)
+					acceptResponse = false;
+					error({code: App.ERROR_TIMEOUT, retry: fn});
+				}), this.ui.timeout);
+				
+				var options = null;
+				
+				if (urlParams['rev'] != null)
+				{
+					options = {versionTag: urlParams['rev']};
+				}
+				
+				this.client.readFile('/' + path, options, mxUtils.bind(this, function(err, data, stat)
+				{
+					try
+					{
+				    	window.clearTimeout(timeoutThread);
+				    	
+				    	if (acceptResponse)
+				    	{
+							if (err != null)
 							{
-								success(new DropboxLibrary(this.ui, data, stat));
+								error(err)
 							}
 							else
 							{
-								success(new DropboxFile(this.ui, data, stat));
+								if (asLibrary)
+								{
+									success(new DropboxLibrary(this.ui, data, stat));
+								}
+								else
+								{
+									success(new DropboxFile(this.ui, data, stat));
+								}
 							}
-						}
-			    	}
-				}
-				catch (e)
-				{
-					error(e);
-				}
-			}));
+				    	}
+					}
+					catch (e)
+					{
+						error(e);
+					}
+				}));
+			}
 		}));
 	});
 	
@@ -587,7 +597,7 @@ DropboxClient.prototype.pickFile = function(fn, readOnly)
 	{
 		fn = (fn != null) ? fn : mxUtils.bind(this, function(path, file)
 		{
-			this.ui.loadFile('D' + encodeURIComponent(path), null, file);
+			this.ui.loadFile((path != null) ? 'D' + encodeURIComponent(path) : file.getHash(), null, file);
 		});
 		
 		// Authentication will be carried out on open to make sure the
@@ -623,39 +633,47 @@ DropboxClient.prototype.pickFile = function(fn, readOnly)
 							this.ui.spinner.stop();
 							fn(path, file);
 						});
-				
-						var tmp = files[0].link.indexOf(this.appPath);
-	
-						if (tmp > 0 && !/(\.png)$/i.test(files[0].name) && !/(\.vs?dx)$/i.test(files[0].name) && !/(\.gliffy)$/i.test(files[0].name))
+						
+						if ((/\.vsdx$/i.test(files[0].name) || /\.gliffy$/i.test(files[0].name) ||
+							/\.png$/i.test(files[0].name)))
 						{
-							// Checks if file is in app folder by loading file from there and comparing relative path and size
-							// KNOWN: This check fails if a file is inside a drawio directory with same relative path and size
-							this.execute(mxUtils.bind(this, function()
-							{		
-								var rel = decodeURIComponent(files[0].link.substring(tmp + this.appPath.length - 1));
-								
-								this.client.readFile(rel, null, mxUtils.bind(this, function(err, data, stat)
-								{
-									if (stat != null && parseInt(files[0].bytes) === parseInt(stat.size) && rel === stat.path)
-									{
-										this.ui.spinner.stop();
-										
-										// No need to load file a second time
-										fn(rel.substring(1), new DropboxFile(this.ui, data, stat));
-									}
-									else
-									{
-										this.createFile(files[0], success, error);
-									}
-								}));
-							}));
+							success(files[0].link);
 						}
 						else
 						{
-							this.execute(mxUtils.bind(this, function()
+							var tmp = files[0].link.indexOf(this.appPath);
+							
+							if (tmp > 0)
 							{
-								this.createFile(files[0], success, error);
-							}));
+								// Checks if file is in app folder by loading file from there and comparing relative path and size
+								// KNOWN: This check fails if a file is inside a drawio directory with same relative path and size
+								this.execute(mxUtils.bind(this, function()
+								{		
+									var rel = decodeURIComponent(files[0].link.substring(tmp + this.appPath.length - 1));
+									
+									this.client.readFile(rel, null, mxUtils.bind(this, function(err, data, stat)
+									{
+										if (stat != null && parseInt(files[0].bytes) === parseInt(stat.size) && rel === stat.path)
+										{
+											this.ui.spinner.stop();
+											
+											// No need to load file a second time
+											fn(rel.substring(1), new DropboxFile(this.ui, data, stat));
+										}
+										else
+										{
+											this.createFile(files[0], success, error);
+										}
+									}));
+								}));
+							}
+							else
+							{
+								this.execute(mxUtils.bind(this, function()
+								{
+									this.createFile(files[0], success, error);
+								}));
+							}
 						}
 					}
 				}
@@ -676,70 +694,28 @@ DropboxClient.prototype.pickFile = function(fn, readOnly)
  */
 DropboxClient.prototype.createFile = function(file, success, error)
 {
-	var name = file.name;
-	
-	if (/(\.png)$/i.test(name) || /(\.vs?dx)$/i.test(name) || /(\.gliffy)$/i.test(name))
-	{
-		name = name.substring(0, name.lastIndexOf('.')) + this.extension;
-	}
-	
-	var doInsert = mxUtils.bind(this, function(filename, data)
-	{
-		this.ui.confirm(mxResources.get('note') + ': ' + mxResources.get('fileWillBeSavedInAppFolder', [filename]), mxUtils.bind(this, function()
-		{
-			this.insertFile(filename, data, mxUtils.bind(this, function(newFile)
-	    	{
-				success(filename, newFile);
-	    	}), error);
-		}), mxUtils.bind(this, function()
-		{
-    		this.ui.spinner.stop();
-		}));
-	});
-	
 	this.ui.loadUrl(file.link, mxUtils.bind(this, function(data)
     {
-		if (/(\.vs?dx)$/i.test(file.name) || /(\.gliffy)$/i.test(file.name))
+		if (data != null && data.length > 0)
 		{
-			this.ui.parseFile(new Blob([data], {type: 'application/octet-stream'}), mxUtils.bind(this, function(xhr)
+			this.ui.confirm(mxResources.get('note') + ': ' + mxResources.get('fileWillBeSavedInAppFolder', [file.name]), mxUtils.bind(this, function()
 			{
-				if (xhr.readyState == 4)
-				{
-					if (xhr.status >= 200 && xhr.status <= 299 && xhr.responseText.substring(0, 13) == '<mxGraphModel')
-					{
-						doInsert(name, xhr.responseText);
-					}
-					else
-					{
-			    		this.ui.spinner.stop();
-			    		
-			    		if (error != null)
-			    		{
-			    			error({message: mxResources.get('errorLoadingFile')});
-			    		}
-					}
-				}
-			}), file.name);
+				this.insertFile(file.name, data, mxUtils.bind(this, function(newFile)
+		    	{
+					success(file.name, newFile);
+		    	}), error);
+			}), mxUtils.bind(this, function()
+			{
+	    		this.ui.spinner.stop();
+			}));
 		}
 		else
 		{
-			if (/(\.png)$/i.test(file.name))
-			{
-				data = this.ui.extractGraphModelFromPng(data);
-			}
+			this.ui.spinner.stop();
 			
-			if (data != null && data.length > 0)
-			{
-				doInsert(name, data);
-			}
-			else
+			if (error != null)
 			{
-				this.ui.spinner.stop();
-				
-				if (error != null)
-				{
-					error({message: mxResources.get('errorLoadingFile')});
-				}
+				error({message: mxResources.get('errorLoadingFile')});
 			}
 		}
     }), error, /(\.png)$/i.test(file.name));

+ 39 - 0
war/js/diagramly/Editor.js

@@ -230,6 +230,45 @@
 		return node;
 	};
 	
+	/**
+	 * Helper function to extract the graph model XML node.
+	 */
+	Editor.prototype.isDataSvg = function(svg)
+	{
+		try
+		{
+			var svgRoot = mxUtils.parseXml(svg).documentElement;
+			var tmp = svgRoot.getAttribute('content');
+			
+			if (tmp != null)
+			{
+				if (tmp != null && tmp.charAt(0) != '<' && tmp.charAt(0) != '%')
+				{
+					tmp = unescape((window.atob) ? atob(tmp) : Base64.decode(cont, tmp));
+				}
+				
+				if (tmp != null && tmp.charAt(0) == '%')
+				{
+					tmp = decodeURIComponent(tmp);
+				}
+				
+				if (tmp != null && tmp.length > 0)
+				{
+					var node = mxUtils.parseXml(tmp).documentElement;
+					
+					
+					return node.nodeName == 'mxfile' || node.nodeName == 'mxGraphModel';
+				}
+			}
+		}
+		catch (e)
+		{
+			// ignore
+		}
+		
+		return false;
+	};
+	
 	/**
 	 * Helper function to extract the graph model XML node.
 	 */

+ 27 - 13
war/js/diagramly/EditorUi.js

@@ -1238,15 +1238,15 @@
 				this.setCurrentFile(file);
 				file.addListener('descriptorChanged', this.descriptorChangedListener);
 				file.addListener('contentChanged', this.descriptorChangedListener);
-				this.setMode(file.getMode());
 				this.descriptorChanged();
 				file.open();
-	
+				
 				this.diagramContainer.style.visibility = '';
 				this.formatContainer.style.visibility = '';
 				this.hsplit.style.display = '';
 				this.sidebarContainer.style.display = '';
 				this.sidebarFooterContainer.style.display = '';
+				this.setMode(file.getMode());
 				this.editor.undoManager.clear();
 				this.updateUi();
 				
@@ -1306,7 +1306,7 @@
 	//	        	}
 	//			}
 				
-				if (this.mode == file.getMode() && file.getMode() != App.MODE_DEVICE)
+				if (this.mode == file.getMode() && file.getMode() != App.MODE_DEVICE && file.getMode() != null)
 				{
 					try
 					{
@@ -2798,7 +2798,7 @@
 	/**
 	 *
 	 */
-	EditorUi.prototype.exportSvg = function(scale, transparentBackground, ignoreSelection, addShadow, editable, embedImages, noCrop, currentPage)
+	EditorUi.prototype.exportSvg = function(scale, transparentBackground, ignoreSelection, addShadow, editable, embedImages, border, noCrop, currentPage)
 	{
 		if (this.spinner.spin(document.body, mxResources.get('export')))
 		{
@@ -2819,7 +2819,7 @@
 			
 			// Sets or disables alternate text for foreignObjects. Disabling is needed
 			// because PhantomJS seems to ignore switch statements and paint all text.
-			var svgRoot = this.editor.graph.getSvg(bg, scale, null, noCrop, null, ignoreSelection);
+			var svgRoot = this.editor.graph.getSvg(bg, scale, border, noCrop, null, ignoreSelection);
 			
 			if (addShadow)
 			{
@@ -3490,7 +3490,6 @@
 		div.appendChild(hd);
 		
 		mxUtils.write(div, mxResources.get('zoom') + ':');
-		
 		var zoomInput = document.createElement('input');
 		zoomInput.setAttribute('type', 'text');
 		zoomInput.style.marginRight = '16px';
@@ -3498,8 +3497,16 @@
 		zoomInput.style.marginLeft = '4px';
 		zoomInput.style.marginRight = '12px';
 		zoomInput.value = '100%';
-		
 		div.appendChild(zoomInput);
+		
+		mxUtils.write(div, mxResources.get('borderWidth') + ':');
+		var borderInput = document.createElement('input');
+		borderInput.setAttribute('type', 'text');
+		borderInput.style.marginRight = '16px';
+		borderInput.style.width = '60px';
+		borderInput.style.marginLeft = '4px';
+		borderInput.value = '0';
+		div.appendChild(borderInput);
 		mxUtils.br(div);
 		
 		var transparent = this.addCheckbox(div, mxResources.get('transparentBackground'),
@@ -3573,7 +3580,7 @@
 		var dlg = new CustomDialog(this, div, mxUtils.bind(this, function()
 		{
 			callback(zoomInput.value, transparent.checked, !selection.checked, shadow.checked,
-				include.checked, cb5.checked, cb6.checked, !allPages.checked);
+				include.checked, cb5.checked, borderInput.value, cb6.checked, !allPages.checked);
 		}), null, btnLabel, helpLink);
 		this.showDialog(dlg.container, 320, height, true, true);
 		zoomInput.focus();
@@ -3603,7 +3610,6 @@
 		div.appendChild(hd);
 		
 		mxUtils.write(div, mxResources.get('zoom') + ':');
-		
 		var zoomInput = document.createElement('input');
 		zoomInput.setAttribute('type', 'text');
 		zoomInput.style.marginRight = '16px';
@@ -3611,8 +3617,16 @@
 		zoomInput.style.marginLeft = '4px';
 		zoomInput.style.marginBottom = '4px';
 		zoomInput.value = '100%';
-		
 		div.appendChild(zoomInput);
+		
+		mxUtils.write(div, mxResources.get('borderWidth') + ':');
+		var borderInput = document.createElement('input');
+		borderInput.setAttribute('type', 'text');
+		borderInput.style.marginRight = '16px';
+		borderInput.style.width = '60px';
+		borderInput.style.marginLeft = '4px';
+		borderInput.value = '0';
+		div.appendChild(borderInput);
 		mxUtils.br(div);
 		
 		var selection = this.addCheckbox(div, mxResources.get('selectionOnly'),
@@ -3651,7 +3665,7 @@
 				
 		var dlg = new CustomDialog(this, div, mxUtils.bind(this, function()
 		{
-			callback(zoomInput.value, !selection.checked, shadow.checked, cb5.checked, cb6.checked);
+			callback(zoomInput.value, !selection.checked, shadow.checked, borderInput.value, cb6.checked);
 		}), null, mxResources.get('export'), helpLink);
 		this.showDialog(dlg.container, 320, 190, true, true);
 		zoomInput.focus();
@@ -4102,7 +4116,7 @@
 	/**
 	 *
 	 */
-	EditorUi.prototype.exportImage = function(scale, transparentBackground, ignoreSelection, addShadow, editable, noCrop, currentPage, format)
+	EditorUi.prototype.exportImage = function(scale, transparentBackground, ignoreSelection, addShadow, editable, border, noCrop, currentPage, format)
 	{
 		format = (format != null) ? format : 'png';
 		
@@ -4145,7 +4159,7 @@
 			   		this.spinner.stop();
 			   		this.handleError(e);
 			   	}), null, ignoreSelection, scale || 1, transparentBackground,
-			   		addShadow, null, null, null, noCrop);
+			   		addShadow, null, null, border, noCrop);
 			}
 			catch (e)
 			{

+ 1 - 3
war/js/diagramly/ElectronApp.js

@@ -610,6 +610,4 @@ FeedbackDialog.feedbackUrl = 'https://log.draw.io/email';
         	}));
 		}
 	};
-	
-	EditorUi.prototype.addBeforeUnloadListener = function() {};
-})();
+})();

+ 66 - 43
war/js/diagramly/GitHubClient.js

@@ -318,20 +318,45 @@ GitHubClient.prototype.getFile = function(path, success, error, asLibrary)
 	var ref = tokens[2];
 	var path = tokens.slice(3, tokens.length).join('/');
 	
-	var req = new mxXmlRequest(this.baseUrl + '/repos/' + org + '/' + repo +
-		'/contents/' + path + '?ref=' + encodeURIComponent(ref), null, 'GET');
-	
-	this.executeRequest(req, mxUtils.bind(this, function(req)
+	// Handles .vsdx, Gliffy and PNG+XML files by creating a temporary file
+	if (/\.vsdx$/i.test(path) || /\.gliffy$/i.test(path) || /\.png$/i.test(path))
 	{
-		try
+		// Should never be null
+		if (this.token != null)
 		{
-			success(this.createGitHubFile(org, repo, ref, req, asLibrary));
+			var url = this.baseUrl + '/repos/' + org + '/' + repo +
+				'/contents/' + path + '?ref=' + encodeURIComponent(ref) +
+				'&token=' + this.token;
+			var tokens = path.split('/');
+			var name = (tokens.length > 0) ? tokens[tokens.length - 1] : path;
+	
+			this.ui.convertFile(url, name, null, this.extension, success, error);
 		}
-		catch (e)
+		else if (error != null)
 		{
-			error(e);
+			error();
 		}
-	}), error);
+	}
+	else
+	{
+		var req = new mxXmlRequest(this.baseUrl + '/repos/' + org + '/' + repo +
+			'/contents/' + path + '?ref=' + encodeURIComponent(ref), null, 'GET');
+		
+		this.executeRequest(req, mxUtils.bind(this, function(req)
+		{
+			try
+			{
+				success(this.createGitHubFile(org, repo, ref, req, asLibrary));
+			}
+			catch (e)
+			{
+				if (error != null)
+				{
+					error(e);
+				}
+			}
+		}), error);
+	}
 };
 
 /**
@@ -350,19 +375,8 @@ GitHubClient.prototype.createGitHubFile = function(org, repo, ref, req, asLibrar
 	
 	if (data.encoding === 'base64')
 	{
-		if ((/(\.jpe?g)$/i.test(data.name)))
-		{
-			content = 'data:image/jpg;base64,' + content;
-		}
-		else if ((/(\.png)$/i.test(data.name)))
-		{
-			content = 'data:image/png;base64,' + content;
-		}
-		else
-		{
-			// Workaround for character encoding issues in IE10/11
-			content = (window.atob && !mxClient.IS_IE && !mxClient.IS_IE11) ? atob(content) : Base64.decode(content);
-		}
+		// Workaround for character encoding issues in IE10/11
+		content = (window.atob && !mxClient.IS_IE && !mxClient.IS_IE11) ? atob(content) : Base64.decode(content);
 	}
 	
 	return (asLibrary) ? new GitHubLibrary(this.ui, content, meta) : new GitHubFile(this.ui, content, meta);
@@ -728,29 +742,26 @@ GitHubClient.prototype.showGitHubDialog = function(showFiles, fn)
 			this.ui.spinner.stop();
 			var files = JSON.parse(req.getText());
 			
-			if (path != null && path.length > 0)
+			var link = document.createElement('a');
+			link.setAttribute('href', 'javascript:void(0);');
+			mxUtils.write(link, '../ [Up]');
+			div.appendChild(link);
+			mxUtils.br(div);
+			
+			mxEvent.addListener(link, 'click', mxUtils.bind(this, function()
 			{
-				var link = document.createElement('a');
-				link.setAttribute('href', 'javascript:void(0);');
-				mxUtils.write(link, '../ [Up]');
-				div.appendChild(link);
-				mxUtils.br(div);
-				
-				mxEvent.addListener(link, 'click', mxUtils.bind(this, function()
+				if (path == '')
 				{
-					if (path == '')
-					{
-						path = null;
-						selectRepo();
-					}
-					else
-					{
-						var tokens = path.split('/');
-						path = tokens.slice(0, tokens.length - 1).join('/');
-						selectFile();
-					}
-				}));
-			}
+					path = null;
+					selectRepo();
+				}
+				else
+				{
+					var tokens = path.split('/');
+					path = tokens.slice(0, tokens.length - 1).join('/');
+					selectFile();
+				}
+			}));
 
 			if (files == null || files.length == 0)
 			{
@@ -818,6 +829,18 @@ GitHubClient.prototype.showGitHubDialog = function(showFiles, fn)
 			updatePathInfo(true);
 			var branches = JSON.parse(req.getText());
 			
+			var link = document.createElement('a');
+			link.setAttribute('href', 'javascript:void(0);');
+			mxUtils.write(link, '../ [Up]');
+			div.appendChild(link);
+			mxUtils.br(div);
+			
+			mxEvent.addListener(link, 'click', mxUtils.bind(this, function()
+			{
+				path = null;
+				selectRepo();
+			}));
+			
 			if (branches == null || branches.length == 0)
 			{
 				mxUtils.write(div, mxResources.get('noFiles'));

+ 1 - 0
war/js/diagramly/Init.js

@@ -231,6 +231,7 @@ if (urlParams['offline'] == '1' || urlParams['demo'] == '1' || urlParams['stealt
 	urlParams['gapi'] = '0';
 	urlParams['db'] = '0';
 	urlParams['od'] = '0';
+	urlParams['gh'] = '0';
 }
 
 // Disables math in offline mode

+ 3 - 2
war/js/diagramly/LocalFile.js

@@ -8,11 +8,12 @@
  * @param {number} x X-coordinate of the point.
  * @param {number} y Y-coordinate of the point.
  */
-LocalFile = function(ui, data, title)
+LocalFile = function(ui, data, title, temp)
 {
 	DrawioFile.call(this, ui, data);
 	
 	this.title = title;
+	this.mode = (temp) ? null : App.MODE_DEVICE;
 };
 
 //Extends mxEventSource
@@ -37,7 +38,7 @@ LocalFile.prototype.isAutosave = function()
  */
 LocalFile.prototype.getMode = function()
 {
-	return App.MODE_DEVICE;
+	return this.mode;
 };
 
 /**

+ 23 - 32
war/js/diagramly/Menus.js

@@ -963,7 +963,6 @@
 					editorUi.createEmbedImage(fit, shadow, retina, lightbox, edit, layers, function(result)
 					{
 						editorUi.spinner.stop();
-						
 						var dlg = new EmbedDialog(editorUi, result);
 						editorUi.showDialog(dlg.container, 440, 240, true, true);
 						dlg.init();
@@ -1164,14 +1163,14 @@
 					editorUi.showExportDialog(mxResources.get('image'), false, mxResources.get('export'),
 						'https://support.draw.io/display/DO/Exporting+Files',
 						mxUtils.bind(this, function(scale, transparentBackground, ignoreSelection,
-							addShadow, editable, embedImages, cropImage, currentPage)
+							addShadow, editable, embedImages, border, cropImage, currentPage)
 						{
 							var val = parseInt(scale);
 							
 							if (!isNaN(val) && val > 0)
 							{
 							   	this.editorUi.exportImage(val / 100, transparentBackground, ignoreSelection,
-							   		addShadow, editable, !cropImage, currentPage);
+							   		addShadow, editable, border, !cropImage, currentPage);
 							}
 						}), true);
 				}), parent);
@@ -1181,14 +1180,14 @@
 					menu.addItem(mxResources.get('formatJpg') + '...', null, mxUtils.bind(this, function()
 					{
 						editorUi.showExportJpgDialog('https://support.draw.io/display/DO/Exporting+Files',
-							mxUtils.bind(this, function(scale, ignoreSelection, addShadow, cropImage)
+							mxUtils.bind(this, function(scale, ignoreSelection, addShadow, border, cropImage)
 							{
 								var val = parseInt(scale);
 								
 								if (!isNaN(val) && val > 0)
 								{
 								   	this.editorUi.exportImage(val / 100, false, ignoreSelection,
-								   		addShadow, false, !cropImage, false, 'jpeg');
+								   		addShadow, false, border, !cropImage, false, 'jpeg');
 								}
 							}), true);
 					}), parent);
@@ -1212,14 +1211,14 @@
 				editorUi.showExportDialog(mxResources.get('formatSvg'), true, mxResources.get('export'),
 					'https://support.draw.io/display/DO/Exporting+Files',
 					mxUtils.bind(this, function(scale, transparentBackground, ignoreSelection,
-						addShadow, editable, embedImages, cropImage, currentPage)
+						addShadow, editable, embedImages, border, cropImage, currentPage)
 					{
 						var val = parseInt(scale);
 						
 						if (!isNaN(val) && val > 0)
 						{
 						   	this.editorUi.exportSvg(val / 100, transparentBackground, ignoreSelection,
-						   		addShadow, editable, embedImages, !cropImage, currentPage);
+						   		addShadow, editable, embedImages, border, !cropImage, currentPage);
 						}
 					}), true);
 			}), parent);
@@ -1413,7 +1412,7 @@
 				var bds = graph.getGraphBounds();
 				var x = graph.snap(Math.ceil(Math.max(0, bds.x / view.scale - view.translate.x) + 4 * graph.gridSize));
 				var y = graph.snap(Math.ceil(Math.max(0, (bds.y + bds.height) / view.scale - view.translate.y) + 4 * graph.gridSize));
-				
+
 				if (mime.substring(0, 6) == 'image/')
 				{
 					editorUi.loadImage(data, mxUtils.bind(this, function(img)
@@ -1468,34 +1467,26 @@
 				{
 					if (editorUi.spinner.spin(document.body, mxResources.get('loading')))
 					{
-						if (service == editorUi.dropbox)
+						// NOTE The third argument in getFile says denyConvert to match
+						// the existing signature in the original DriveClient which has
+						// as slightly different semantic, but works the same way.
+						service.getFile(id, function(file)
 						{
-							var mime = getMimeType(id);
+							var mime = getMimeType(file.getTitle());
 							
-							editorUi.loadUrl(id, function(data)
+							// Imports SVG as images
+							if (/\.svg$/i.test(file.getTitle()) && !editorUi.editor.isDataSvg(file.getData()))
 							{
-								doImportFile(data, mime, id);
-							},
-							function(resp)
-							{
-								editorUi.handleError(resp, (resp != null) ? mxResources.get('errorLoadingFile') : null);
-							}, mime.substring(0, 6) == 'image/');
-						}
-						else
+								file.setData(editorUi.createSvgDataUri(file.getData()));
+								mime = 'image/svg+xml';
+							}
+							
+							doImportFile(file.getData(), mime, file.getTitle());
+						},
+						function(resp)
 						{
-							// NOTE The third argument in getFile says denyConvert to match
-							// the existing signature in the original DriveClient which has
-							// as slightly different semantic, but works the same way.
-							service.getFile(id, function(file)
-							{
-								var mime = getMimeType(file.getTitle());
-								doImportFile(file.getData(), mime, file.getTitle());
-							},
-							function(resp)
-							{
-								editorUi.handleError(resp, (resp != null) ? mxResources.get('errorLoadingFile') : null);
-							}, true);
-						}
+							editorUi.handleError(resp, (resp != null) ? mxResources.get('errorLoadingFile') : null);
+						}, service == editorUi.drive);
 					}
 				}, true);
 			};

+ 6 - 5
war/js/diagramly/OneDriveClient.js

@@ -273,11 +273,12 @@ OneDriveClient.prototype.getFile = function(id, success, error, denyConvert, asL
 			    		{
 							var meta = JSON.parse(req.getText());
 							
-							if (!denyConvert && Graph.fileSupport && new XMLHttpRequest().upload &&
-								(/(\.png)$/i.test(meta.name) || /(\.vs?dx)$/i.test(meta.name) ||
-								/(\.gliffy)$/i.test(meta.name)))
+							// Handles .vsdx, Gliffy and PNG+XML files by creating a temporary file
+							if ((/\.vsdx$/i.test(meta.name) || /\.gliffy$/i.test(meta.name) || /\.png$/i.test(meta.name)))
 							{
-								this.convertFile(meta, success, error);
+								var mimeType = (meta.file != null) ? meta.file.mimeType : null;
+								this.ui.convertFile(meta['@content.downloadUrl'], meta.name, mimeType,
+									this.extension, success, error);
 							}
 							else
 							{
@@ -291,7 +292,7 @@ OneDriveClient.prototype.getFile = function(id, success, error, denyConvert, asL
 									{
 										success(new OneDriveFile(this.ui, data, meta));
 									}
-					    		}), err, meta != null && meta.file != null && meta.file.mimeType != null &&
+					    		}), err, meta.file != null && meta.file.mimeType != null &&
 					    			meta.file.mimeType.substring(0, 6) == 'image/');
 							}
 			    		}

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 4 - 4
war/js/embed-static.min.js


+ 7 - 1
war/js/mxgraph/Dialogs.js

@@ -1877,7 +1877,7 @@ var ExportDialog = function(editorUi)
 	
 	var borderInput = document.createElement('input');
 	borderInput.setAttribute('type', 'number');
-	borderInput.setAttribute('value', '0');
+	borderInput.setAttribute('value', ExportDialog.lastBorderValue);
 	borderInput.style.width = '180px';
 
 	td = document.createElement('td');
@@ -2038,6 +2038,7 @@ var ExportDialog = function(editorUi)
 				bg = '#ffffff';
 			}
 			
+			ExportDialog.lastBorderValue = b;
 			ExportDialog.exportFile(editorUi, name, format, bg, s, b);
 		}
 	}));
@@ -2066,6 +2067,11 @@ var ExportDialog = function(editorUi)
 	this.container = table;
 };
 
+/**
+ * Remembers last value for border.
+ */
+ExportDialog.lastBorderValue = 0;
+
 /**
  * Global switches for the export dialog.
  */

+ 35 - 21
war/js/mxgraph/Format.js

@@ -1420,7 +1420,7 @@ ArrangePanel.prototype.init = function()
 	this.addEdgeGeometry(this.container);
 	this.container.appendChild(this.addAngle(this.createPanel()));
 
-	if (!ss.containsLabel)
+	if (!ss.containsLabel && ss.edges.length == 0)
 	{
 		this.container.appendChild(this.addFlip(this.createPanel()));
 	}
@@ -1717,14 +1717,20 @@ ArrangePanel.prototype.addAngle = function(div)
 	span.style.width = '70px';
 	span.style.marginTop = '0px';
 	span.style.fontWeight = 'bold';
-	mxUtils.write(span, mxResources.get('angle'));
-	div.appendChild(span);
 	
+	var input = null;
 	var update = null;
-	var input = this.addUnitInput(div, '°', 84, 44, function()
+	
+	if (ss.edges.length == 0)
 	{
-		update.apply(this, arguments);
-	});
+		mxUtils.write(span, mxResources.get('angle'));
+		div.appendChild(span);
+		
+		input = this.addUnitInput(div, '°', 84, 44, function()
+		{
+			update.apply(this, arguments);
+		});
+	}
 
 	if (!ss.containsLabel)
 	{
@@ -1740,23 +1746,31 @@ ArrangePanel.prototype.addAngle = function(div)
 		btn.style.width = '61px';
 		div.appendChild(btn);
 	}
-
-	var listener = mxUtils.bind(this, function(sender, evt, force)
+	
+	if (input == null)
 	{
-		if (force || document.activeElement != input)
+		btn.style.right = '';
+		btn.style.width = '202px';
+	}
+	else
+	{
+		var listener = mxUtils.bind(this, function(sender, evt, force)
 		{
-			ss = this.format.getSelectionState();
-			var tmp = parseFloat(mxUtils.getValue(ss.style, mxConstants.STYLE_ROTATION, 0));
-			input.value = (isNaN(tmp)) ? '' : tmp  + '°';
-		}
-	});
-
-	update = this.installInputHandler(input, mxConstants.STYLE_ROTATION, 0, 0, 360, '°', null, true);
-	this.addKeyHandler(input, listener);
-
-	graph.getModel().addListener(mxEvent.CHANGE, listener);
-	this.listeners.push({destroy: function() { graph.getModel().removeListener(listener); }});
-	listener();
+			if (force || document.activeElement != input)
+			{
+				ss = this.format.getSelectionState();
+				var tmp = parseFloat(mxUtils.getValue(ss.style, mxConstants.STYLE_ROTATION, 0));
+				input.value = (isNaN(tmp)) ? '' : tmp  + '°';
+			}
+		});
+	
+		update = this.installInputHandler(input, mxConstants.STYLE_ROTATION, 0, 0, 360, '°', null, true);
+		this.addKeyHandler(input, listener);
+	
+		graph.getModel().addListener(mxEvent.CHANGE, listener);
+		this.listeners.push({destroy: function() { graph.getModel().removeListener(listener); }});
+		listener();
+	}
 
 	return div;
 };

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 4 - 4
war/js/reader.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 422 - 420
war/js/viewer.min.js