summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xdropbox-oauth-receiver.html14
-rwxr-xr-x[-rw-r--r--]index.html6
-rwxr-xr-x[-rw-r--r--]js/wwwsqldesigner.js229
-rwxr-xr-x[-rw-r--r--]locale/en.xml3
4 files changed, 216 insertions, 36 deletions
diff --git a/dropbox-oauth-receiver.html b/dropbox-oauth-receiver.html
new file mode 100755
index 0000000..fd16bad
--- /dev/null
+++ b/dropbox-oauth-receiver.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/dropbox.js/0.10.2/dropbox.min.js"></script>
+ <script type="text/javascript">
+ Dropbox.AuthDriver.Popup.oauthReceiver();
+ </script>
+ </head>
+ <body>
+ <h1>Dropbox sign-in successful</h1>
+
+ <p>Please close this window.</p>
+ </body>
+</html> \ No newline at end of file
diff --git a/index.html b/index.html
index a956b10..55c3401 100644..100755
--- a/index.html
+++ b/index.html
@@ -15,6 +15,7 @@
<link rel="stylesheet" href="styles/print.css" type="text/css" media="print" />
<script type="text/javascript" src="js/oz.js"></script>
<script type="text/javascript" src="js/config.js"></script>
+ <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/dropbox.js/0.10.2/dropbox.min.js"></script>
<script type="text/javascript" src="js/wwwsqldesigner.js"></script>
</head>
@@ -151,6 +152,11 @@
<legend id="client"></legend>
<input type="button" id="clientsave" />
<input type="button" id="clientload" />
+ <br/>
+ <input type="button" id="clientdropboxsave" /><!--should get hidden if 'Dropbox.isBrowserSupported()' is false-->
+ <input type="button" id="clientdropboxload" /><!--should get hidden if 'Dropbox.isBrowserSupported()' is false-->
+ <input type="button" id="clientdropboxlist" /><!--should get hidden if 'Dropbox.isBrowserSupported()' is false-->
+ <br/>
<input type="button" id="clientlocalsave" />
<input type="button" id="clientlocalload" />
<input type="button" id="clientlocallist" />
diff --git a/js/wwwsqldesigner.js b/js/wwwsqldesigner.js
index 7e0394d..b1c61ab 100644..100755
--- a/js/wwwsqldesigner.js
+++ b/js/wwwsqldesigner.js
@@ -1,8 +1,31 @@
+/* -------------------- configuration -------------------- */
+
+/*
+ * The key below needs to be set individually by you if you want to use the Dropbox load/save feature.
+ * To do that, first sign up with Dropbox (may require a specific developer / SDK sign-up), go to
+ * https://www.dropbox.com/developers/apps and use "Create app" to add a new app. Call it, for instance,
+ * "wwwsqldesigner", and give it the "App Folder" permission. Unter "OAuth 2", "Redirect URIs", add
+ * the URL to the "dropbox-oauth-receiver.html" file on your server. E.g, if you install wwwsqldesigner
+ * on your local web server under "http://localhost/sqldesigner/", then add
+ * http://localhost/sqldesigner/dropbox-oauth-receiver.html as a Redirection URI.
+ * Copy the shown "App key" and paste it here below:
+ */
+var dropboxAppKey = null; // "your app key";
+
+
+/* -------------------- globals -------------------- */
+
function _(str) { /* getText */
if (!(str in window.LOCALE)) { return str; }
return window.LOCALE[str];
}
+if (typeof String.prototype.endsWith !== 'function') {
+ String.prototype.endsWith = function(suffix) {
+ return this.indexOf(suffix, this.length - suffix.length) !== -1;
+ };
+}
+
var DATATYPES = false;
var LOCALE = {};
var SQL = {};
@@ -1255,6 +1278,7 @@ SQL.IO.prototype.init = function(owner) {
};
var ids = ["saveload","clientlocalsave", "clientsave", "clientlocalload", "clientlocallist","clientload", "clientsql",
+ "clientdropboxsave", "clientdropboxload", "clientdropboxlist",
"quicksave", "serversave", "serverload",
"serverlist", "serverimport"];
for (var i=0;i<ids.length;i++) {
@@ -1290,6 +1314,9 @@ SQL.IO.prototype.init = function(owner) {
OZ.Event.add(this.dom.clientlocalload, "click", this.bind(this.clientlocalload));
OZ.Event.add(this.dom.clientlocallist, "click", this.bind(this.clientlocallist));
OZ.Event.add(this.dom.clientload, "click", this.bind(this.clientload));
+ OZ.Event.add(this.dom.clientdropboxload, "click", this.bind(this.clientdropboxload));
+ OZ.Event.add(this.dom.clientdropboxsave, "click", this.bind(this.clientdropboxsave));
+ OZ.Event.add(this.dom.clientdropboxlist, "click", this.bind(this.clientdropboxlist));
OZ.Event.add(this.dom.clientsql, "click", this.bind(this.clientsql));
OZ.Event.add(this.dom.quicksave, "click", this.bind(this.quicksave));
OZ.Event.add(this.dom.serversave, "click", this.bind(this.serversave));
@@ -1328,6 +1355,24 @@ SQL.IO.prototype.click = function() { /* open io dialog */
this.owner.window.open(_("saveload"),this.dom.container);
}
+SQL.IO.prototype.fromXMLText = function(xml) {
+ try {
+ if (window.DOMParser) {
+ var parser = new DOMParser();
+ var xmlDoc = parser.parseFromString(xml, "text/xml");
+ } else if (window.ActiveXObject || "ActiveXObject" in window) {
+ var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
+ xmlDoc.loadXML(xml);
+ } else {
+ throw new Error("No XML parser available.");
+ }
+ } catch(e) {
+ alert(_("xmlerror")+': '+e.message);
+ return;
+ }
+ this.fromXML(xmlDoc);
+}
+
SQL.IO.prototype.fromXML = function(xmlDoc) {
if (!xmlDoc || !xmlDoc.documentElement) {
alert(_("xmlerror")+': Null document');
@@ -1349,21 +1394,8 @@ SQL.IO.prototype.clientload = function() {
alert(_("empty"));
return;
}
- try {
- if (window.DOMParser) {
- var parser = new DOMParser();
- var xmlDoc = parser.parseFromString(xml, "text/xml");
- } else if (window.ActiveXObject || "ActiveXObject" in window) {
- var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
- xmlDoc.loadXML(xml);
- } else {
- throw new Error("No XML parser available.");
- }
- } catch(e) {
- alert(_("xmlerror")+': '+e.message);
- return;
- }
- this.fromXML(xmlDoc);
+
+ this.fromXMLText(xml);
}
SQL.IO.prototype.clientlocalsave = function() {
@@ -1379,7 +1411,8 @@ SQL.IO.prototype.clientlocalsave = function() {
}
var key = prompt(_("serversaveprompt"), this._name);
- if (key === null) { return; }
+ if (!key) { return; }
+ this._name = key;
key = "wwwsqldesigner_databases_" + (key || "default");
try {
@@ -1390,8 +1423,6 @@ SQL.IO.prototype.clientlocalsave = function() {
}
}
-
-
SQL.IO.prototype.clientlocalload = function() {
if (!window.localStorage) {
alert("Sorry, your browser does not seem to support localStorage.");
@@ -1399,7 +1430,8 @@ SQL.IO.prototype.clientlocalload = function() {
}
var key = prompt(_("serverloadprompt"), this._name);
- if (key === null) { return; }
+ if (!key) { return; }
+ this._name = key;
key = "wwwsqldesigner_databases_" + (key || "default");
try {
@@ -1410,22 +1442,7 @@ SQL.IO.prototype.clientlocalload = function() {
return;
}
- try {
- if (window.DOMParser) {
- var parser = new DOMParser();
- var xmlDoc = parser.parseFromString(xml, "text/xml");
- } else if (window.ActiveXObject || "ActiveXObject" in window) {
- var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
- xmlDoc.loadXML(xml);
- } else {
- throw new Error("No XML parser available.");
- }
- } catch(e) {
- alert(_("xmlerror")+': '+e.message);
- return;
- }
-
- this.fromXML(xmlDoc);
+ this.fromXMLText(xml);
}
SQL.IO.prototype.clientlocallist = function() {
@@ -1434,7 +1451,7 @@ SQL.IO.prototype.clientlocallist = function() {
return;
}
- /* --- Define some usefull vars --- */
+ /* --- Define some useful vars --- */
var baseKeysName = "wwwsqldesigner_databases_";
var localLen = localStorage.length;
var data = "";
@@ -1461,6 +1478,146 @@ SQL.IO.prototype.clientlocallist = function() {
this.listresponse(data, code);
}
+/* ------------------------- Dropbox start ------------------------ */
+
+/*
+ * The following code uses this lib: https://github.com/dropbox/dropbox-js
+ */
+
+var dropboxClient = null;
+
+if (dropboxAppKey) {
+ dropboxClient = new Dropbox.Client({ key: dropboxAppKey });
+} else {
+ // Here we should remove the Dropbox buttons but I (TT) honestly don't know how to do that without including something like jquery.
+}
+
+var showDropboxError = function(error) {
+ var prefix = _("Dropbox error")+": ";
+ var msg = error.status;
+
+ switch (error.status) {
+ case Dropbox.ApiError.INVALID_TOKEN:
+ // If you're using dropbox.js, the only cause behind this error is that
+ // the user token expired.
+ // Get the user through the authentication flow again.
+ msg = _("Invalid Token (expired)");
+ break;
+
+ case Dropbox.ApiError.NOT_FOUND:
+ // The file or folder you tried to access is not in the user's Dropbox.
+ // Handling this error is specific to your application.
+ msg = _("File not found");
+ break;
+
+ case Dropbox.ApiError.OVER_QUOTA:
+ // The user is over their Dropbox quota.
+ // Tell them their Dropbox is full. Refreshing the page won't help.
+ msg = _("Dropbox is full");
+ break;
+
+ case Dropbox.ApiError.RATE_LIMITED:
+ // Too many API requests. Tell the user to try again later.
+ // Long-term, optimize your code to use fewer API calls.
+ break;
+
+ case Dropbox.ApiError.NETWORK_ERROR:
+ // An error occurred at the XMLHttpRequest layer.
+ // Most likely, the user's network connection is down.
+ // API calls will not succeed until the user gets back online.
+ msg = _("Network error");
+ break;
+
+ case Dropbox.ApiError.INVALID_PARAM:
+ case Dropbox.ApiError.OAUTH_ERROR:
+ case Dropbox.ApiError.INVALID_METHOD:
+ default:
+ // Caused by a bug in dropbox.js, in your application, or in Dropbox.
+ // Tell the user an error occurred, ask them to refresh the page.
+ }
+
+ alert (prefix+msg);
+};
+
+var showDropboxAuthenticate = function() {
+ if (!dropboxClient) return false;
+
+ // We want to use a popup window for authentication as the default redirection won't work for us as it'll make us lose our schema data
+ dropboxClient.authDriver(new Dropbox.AuthDriver.Popup({ receiverUrl: "dropbox-oauth-receiver.html" }));
+
+ // Now let's authenticate us
+ var success = false;
+ dropboxClient.authenticate( function(error, client) {
+ if (error) {
+ showDropboxError(error);
+ return;
+ }
+ success = true;
+ return;
+ });
+ return success;
+}
+
+SQL.IO.prototype.clientdropboxsave = function() {
+ if (!showDropboxAuthenticate()) return;
+
+ var key = prompt(_("serversaveprompt"), this._name);
+ if (!key) { return; }
+ if (key.endsWith(".xml")) {
+ // remove ".xml" from name
+ key = key.substr(0, key.length-4);
+ }
+ this._name = key;
+ var filename = (key || "default") + ".xml";
+
+ var xml = this.owner.toXML();
+ dropboxClient.writeFile(filename, xml, function(error, stat) {
+ if (error) {
+ return showDropboxError(error);
+ }
+ alert(filename+" "+_("was saved to Dropbox"));
+ });
+}
+
+SQL.IO.prototype.clientdropboxload = function() {
+ if (!showDropboxAuthenticate()) return;
+
+ var key = prompt(_("serverloadprompt"), this._name);
+ if (!key) { return; }
+ if (key.endsWith(".xml")) {
+ // remove ".xml" from name
+ key = key.substr(0, key.length-4);
+ }
+ this._name = key;
+ var filename = (key || "default") + ".xml";
+
+ var sql_io = this;
+ dropboxClient.readFile(filename, function(error, data) {
+ if (error) {
+ return showDropboxError(error);
+ }
+ sql_io.fromXMLText(data);
+ });
+}
+
+SQL.IO.prototype.clientdropboxlist = function() {
+ if (!showDropboxAuthenticate()) return;
+
+ var sql_io = this;
+ sql_io.listresponse("Loading...", 200);
+ dropboxClient.readdir("/", function(error, entries) {
+ if (error) {
+ sql_io.listresponse("", 200);
+ return showDropboxError(error);
+ }
+ var data = entries.join("\n")+"\n";
+ sql_io.listresponse(data, 200);
+ });
+}
+
+
+/* ------------------------- Dropbox end ------------------------ */
+
SQL.IO.prototype.clientsql = function() {
var bp = this.owner.getOption("staticpath");
var path = bp + "db/"+window.DATATYPES.getAttribute("db")+"/output.xsl";
diff --git a/locale/en.xml b/locale/en.xml
index f489dac..2faabc3 100644..100755
--- a/locale/en.xml
+++ b/locale/en.xml
@@ -75,6 +75,9 @@
<string name="output">Input / Output</string>
<string name="clientsave">Save XML</string>
<string name="clientload">Load XML</string>
+ <string name="clientdropboxsave">Save to Dropbox</string>
+ <string name="clientdropboxload">Load from Dropbox</string>
+ <string name="clientdropboxlist">List from Dropbox</string>
<string name="clientlocalsave">Save in Browser</string>
<string name="clientlocalload">Load from Browser</string>
<string name="clientlocallist">List from Browser</string>