@@ -9,10 +9,11 @@ | |||
* { | |||
font-weight: bold; | |||
font-family: sans-serif; | |||
font-size: 0.95em; | |||
} | |||
#draw-tools, #file-tools, #edit-tools { | |||
#draw-tools, #file-tools, #edit-tools, #drive-tools { | |||
display: inline-block; | |||
position: relative; | |||
float: left; | |||
@@ -93,6 +94,10 @@ button { | |||
border-bottom: 1px solid #444; | |||
} | |||
#drive-textarea { | |||
margin: 9px; | |||
} | |||
#logo pre { | |||
margin: 0px; | |||
display: none; | |||
@@ -135,11 +140,15 @@ textarea { | |||
<button id="export-button" class="tool">Export</button> | |||
<button id="import-button" class="tool">Import</button> | |||
<button id="save-button" class="tool">Save</button> | |||
<button id="save-button" class="tool">Open</button> | |||
</div> | |||
<div id="edit-tools"> | |||
<button id="clear-button" class="tool">Clear</button> | |||
<button id="undo-button" class="tool">Undo</button> | |||
</div> | |||
<div id="drive-tools"> | |||
<div id="drive-filename" class="edit"></div> | |||
</div> | |||
<div id="export-button-dialog" class="dialog"> | |||
<textarea id="export-area"></textarea> | |||
@@ -150,13 +159,11 @@ textarea { | |||
<button class="close-dialog-button">Close</button> | |||
<button id="import-submit-button">Submit</button> | |||
</div> | |||
<div id="authorize-dialog" class="dialog"> | |||
<button id="authorize-button">Authorize</button> | |||
<button class="close-dialog-button">Close</button> | |||
</div> | |||
<canvas id="ascii-canvas"></canvas> | |||
<script src="https://apis.google.com/js/api.js"></script> | |||
<script src="https://apis.google.com/js/client.js"></script> | |||
<script src="jquery-1.9.1.min.js"></script> | |||
<script src="jquery.jeditable.min.js"></script> | |||
<script src="js-compiled.js"></script> | |||
</body> | |||
</html> |
@@ -0,0 +1,38 @@ | |||
(function($){$.fn.editable=function(target,options){if('disable'==target){$(this).data('disabled.editable',true);return;} | |||
if('enable'==target){$(this).data('disabled.editable',false);return;} | |||
if('destroy'==target){$(this).unbind($(this).data('event.editable')).removeData('disabled.editable').removeData('event.editable');return;} | |||
var settings=$.extend({},$.fn.editable.defaults,{target:target},options);var plugin=$.editable.types[settings.type].plugin||function(){};var submit=$.editable.types[settings.type].submit||function(){};var buttons=$.editable.types[settings.type].buttons||$.editable.types['defaults'].buttons;var content=$.editable.types[settings.type].content||$.editable.types['defaults'].content;var element=$.editable.types[settings.type].element||$.editable.types['defaults'].element;var reset=$.editable.types[settings.type].reset||$.editable.types['defaults'].reset;var callback=settings.callback||function(){};var onedit=settings.onedit||function(){};var onsubmit=settings.onsubmit||function(){};var onreset=settings.onreset||function(){};var onerror=settings.onerror||reset;if(settings.tooltip){$(this).attr('title',settings.tooltip);} | |||
settings.autowidth='auto'==settings.width;settings.autoheight='auto'==settings.height;return this.each(function(){var self=this;var savedwidth=$(self).width();var savedheight=$(self).height();$(this).data('event.editable',settings.event);if(!$.trim($(this).html())){$(this).html(settings.placeholder);} | |||
$(this).bind(settings.event,function(e){if(true===$(this).data('disabled.editable')){return;} | |||
if(self.editing){return;} | |||
if(false===onedit.apply(this,[settings,self])){return;} | |||
e.preventDefault();e.stopPropagation();if(settings.tooltip){$(self).removeAttr('title');} | |||
if(0==$(self).width()){settings.width=savedwidth;settings.height=savedheight;}else{if(settings.width!='none'){settings.width=settings.autowidth?$(self).width():settings.width;} | |||
if(settings.height!='none'){settings.height=settings.autoheight?$(self).height():settings.height;}} | |||
if($(this).html().toLowerCase().replace(/(;|")/g,'')==settings.placeholder.toLowerCase().replace(/(;|")/g,'')){$(this).html('');} | |||
self.editing=true;self.revert=$(self).html();$(self).html('');var form=$('<form />');if(settings.cssclass){if('inherit'==settings.cssclass){form.attr('class',$(self).attr('class'));}else{form.attr('class',settings.cssclass);}} | |||
if(settings.style){if('inherit'==settings.style){form.attr('style',$(self).attr('style'));form.css('display',$(self).css('display'));}else{form.attr('style',settings.style);}} | |||
var input=element.apply(form,[settings,self]);var input_content;if(settings.loadurl){var t=setTimeout(function(){input.disabled=true;content.apply(form,[settings.loadtext,settings,self]);},100);var loaddata={};loaddata[settings.id]=self.id;if($.isFunction(settings.loaddata)){$.extend(loaddata,settings.loaddata.apply(self,[self.revert,settings]));}else{$.extend(loaddata,settings.loaddata);} | |||
$.ajax({type:settings.loadtype,url:settings.loadurl,data:loaddata,async:false,success:function(result){window.clearTimeout(t);input_content=result;input.disabled=false;}});}else if(settings.data){input_content=settings.data;if($.isFunction(settings.data)){input_content=settings.data.apply(self,[self.revert,settings]);}}else{input_content=self.revert;} | |||
content.apply(form,[input_content,settings,self]);input.attr('name',settings.name);buttons.apply(form,[settings,self]);$(self).append(form);plugin.apply(form,[settings,self]);$(':input:visible:enabled:first',form).focus();if(settings.select){input.select();} | |||
input.keydown(function(e){if(e.keyCode==27){e.preventDefault();reset.apply(form,[settings,self]);}});var t;if('cancel'==settings.onblur){input.blur(function(e){t=setTimeout(function(){reset.apply(form,[settings,self]);},500);});}else if('submit'==settings.onblur){input.blur(function(e){t=setTimeout(function(){form.submit();},200);});}else if($.isFunction(settings.onblur)){input.blur(function(e){settings.onblur.apply(self,[input.val(),settings]);});}else{input.blur(function(e){});} | |||
form.submit(function(e){if(t){clearTimeout(t);} | |||
e.preventDefault();if(false!==onsubmit.apply(form,[settings,self])){if(false!==submit.apply(form,[settings,self])){if($.isFunction(settings.target)){var str=settings.target.apply(self,[input.val(),settings]);$(self).html(str);self.editing=false;callback.apply(self,[self.innerHTML,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder);}}else{var submitdata={};submitdata[settings.name]=input.val();submitdata[settings.id]=self.id;if($.isFunction(settings.submitdata)){$.extend(submitdata,settings.submitdata.apply(self,[self.revert,settings]));}else{$.extend(submitdata,settings.submitdata);} | |||
if('PUT'==settings.method){submitdata['_method']='put';} | |||
$(self).html(settings.indicator);var ajaxoptions={type:'POST',data:submitdata,dataType:'html',url:settings.target,success:function(result,status){if(ajaxoptions.dataType=='html'){$(self).html(result);} | |||
self.editing=false;callback.apply(self,[result,settings]);if(!$.trim($(self).html())){$(self).html(settings.placeholder);}},error:function(xhr,status,error){onerror.apply(form,[settings,self,xhr]);}};$.extend(ajaxoptions,settings.ajaxoptions);$.ajax(ajaxoptions);}}} | |||
$(self).attr('title',settings.tooltip);return false;});});this.reset=function(form){if(this.editing){if(false!==onreset.apply(form,[settings,self])){$(self).html(self.revert);self.editing=false;if(!$.trim($(self).html())){$(self).html(settings.placeholder);} | |||
if(settings.tooltip){$(self).attr('title',settings.tooltip);}}}};});};$.editable={types:{defaults:{element:function(settings,original){var input=$('<input type="hidden"></input>');$(this).append(input);return(input);},content:function(string,settings,original){$(':input:first',this).val(string);},reset:function(settings,original){original.reset(this);},buttons:function(settings,original){var form=this;if(settings.submit){if(settings.submit.match(/>$/)){var submit=$(settings.submit).click(function(){if(submit.attr("type")!="submit"){form.submit();}});}else{var submit=$('<button type="submit" />');submit.html(settings.submit);} | |||
$(this).append(submit);} | |||
if(settings.cancel){if(settings.cancel.match(/>$/)){var cancel=$(settings.cancel);}else{var cancel=$('<button type="cancel" />');cancel.html(settings.cancel);} | |||
$(this).append(cancel);$(cancel).click(function(event){if($.isFunction($.editable.types[settings.type].reset)){var reset=$.editable.types[settings.type].reset;}else{var reset=$.editable.types['defaults'].reset;} | |||
reset.apply(form,[settings,original]);return false;});}}},text:{element:function(settings,original){var input=$('<input />');if(settings.width!='none'){input.width(settings.width);} | |||
if(settings.height!='none'){input.height(settings.height);} | |||
input.attr('autocomplete','off');$(this).append(input);return(input);}},textarea:{element:function(settings,original){var textarea=$('<textarea />');if(settings.rows){textarea.attr('rows',settings.rows);}else if(settings.height!="none"){textarea.height(settings.height);} | |||
if(settings.cols){textarea.attr('cols',settings.cols);}else if(settings.width!="none"){textarea.width(settings.width);} | |||
$(this).append(textarea);return(textarea);}},select:{element:function(settings,original){var select=$('<select />');$(this).append(select);return(select);},content:function(data,settings,original){if(String==data.constructor){eval('var json = '+data);}else{var json=data;} | |||
for(var key in json){if(!json.hasOwnProperty(key)){continue;} | |||
if('selected'==key){continue;} | |||
var option=$('<option />').val(key).append(json[key]);$('select',this).append(option);} | |||
$('select',this).children().each(function(){if($(this).val()==json['selected']||$(this).text()==$.trim(original.revert)){$(this).attr('selected','selected');}});}}},addInputType:function(name,input){$.editable.types[name]=input;}};$.fn.editable.defaults={name:'value',id:'id',type:'text',width:'auto',height:'auto',event:'click.editable',onblur:'cancel',loadtype:'GET',loadtext:'Loading...',placeholder:'Click to edit',loaddata:{},submitdata:{},ajaxoptions:{}};})(jQuery); |
@@ -492,29 +492,40 @@ function X(a) { | |||
}.bind(this)); | |||
} | |||
function ha(a) { | |||
window.gapi.auth.authorize({client_id:"125643747010-9s9n1ne2fnnuh5v967licfkt83r4vba5.apps.googleusercontent.com", scope:"https://www.googleapis.com/auth/drive", immediate:!1}, function(b) { | |||
b && !b.error ? a(!0) : (window.alert(b.error), a(!1)); | |||
window.gapi.auth.authorize({client_id:"125643747010-9s9n1ne2fnnuh5v967licfkt83r4vba5.apps.googleusercontent.com", scope:"https://www.googleapis.com/auth/drive", immediate:!0}, function(b) { | |||
b && !b.error ? a(!0) : window.gapi.auth.authorize({client_id:"125643747010-9s9n1ne2fnnuh5v967licfkt83r4vba5.apps.googleusercontent.com", scope:"https://www.googleapis.com/auth/drive", immediate:!1}, function(b) { | |||
a(b && !b.error); | |||
}); | |||
}); | |||
} | |||
function ia(a, b) { | |||
a.file = b; | |||
$("#drive-filename").text(b.title); | |||
$("#drive-filename").editable(function(a) { | |||
this.file.title = a; | |||
this.save(); | |||
$("#drive-filename").off(); | |||
return a; | |||
}.bind(a), {type:"text", submit:"OK"}); | |||
} | |||
X.prototype.save = function() { | |||
window.gapi.client.load("drive", "v2", function() { | |||
ha(function(a) { | |||
a && ia(this).execute(function(a) { | |||
window.console.log(a); | |||
}); | |||
a && ja(this).execute(function(a) { | |||
ia(this, a); | |||
}.bind(this)); | |||
}.bind(this)); | |||
}.bind(this)); | |||
}; | |||
function ia(a) { | |||
a = U(a.state); | |||
a = "\r\n---------314159265358979323846\r\nContent-Type: application/json\r\n\r\n" + JSON.stringify({title:"Untitled ASCII Diagram", mimeType:"text/plain"}) + "\r\n---------314159265358979323846\r\nContent-Type: text/plain\r\n\r\n" + a + "\r\n---------314159265358979323846--"; | |||
return window.gapi.client.request({path:"/upload/drive/v2/files", method:"POST", params:{uploadType:"multipart"}, headers:{"Content-Type":'multipart/mixed; boundary="-------314159265358979323846"'}, body:a}); | |||
function ja(a) { | |||
var b = U(a.state), b = "\r\n---------314159265358979323846\r\nContent-Type: application/json\r\n\r\n" + JSON.stringify({title:null == a.file ? "Untitled ASCII Diagram" : a.file.title, mimeType:"text/plain"}) + "\r\n---------314159265358979323846\r\nContent-Type: text/plain\r\n\r\n" + b + "\r\n---------314159265358979323846--"; | |||
return window.gapi.client.request({path:"/upload/drive/v2/files" + (null == a.file ? "" : "/" + a.file.id), method:null == a.file ? "POST" : "PUT", params:{uploadType:"multipart"}, headers:{"Content-Type":'multipart/mixed; boundary="-------314159265358979323846"'}, body:b}); | |||
} | |||
;function ja(a) { | |||
;function ka(a) { | |||
this.b = a; | |||
this.o(); | |||
} | |||
ja.prototype.o = function() { | |||
ka.prototype.o = function() { | |||
var a = this.b.view.canvas; | |||
$(a).bind("mousewheel", function(a) { | |||
a = this.b.view.zoom * (0 < a.originalEvent.wheelDelta ? 1.1 : 0.9); | |||
@@ -549,7 +560,7 @@ function Y(a) { | |||
this.s = this.k = !1; | |||
this.o(); | |||
} | |||
function ka(a, b) { | |||
function la(a, b) { | |||
a.A = b; | |||
a.D = $.now(); | |||
a.k = !1; | |||
@@ -580,7 +591,7 @@ Y.prototype.o = function() { | |||
$(a).bind("touchstart", function(a) { | |||
a.preventDefault(); | |||
if (1 == a.originalEvent.touches.length) { | |||
ka(this, new f(a.originalEvent.touches[0].pageX, a.originalEvent.touches[0].pageY)); | |||
la(this, new f(a.originalEvent.touches[0].pageX, a.originalEvent.touches[0].pageY)); | |||
} else { | |||
if (1 < a.originalEvent.touches.length) { | |||
var c = new f(a.originalEvent.touches[0].pageX, a.originalEvent.touches[0].pageY); | |||
@@ -611,9 +622,9 @@ Y.prototype.o = function() { | |||
W(this.b); | |||
}.bind(this)); | |||
}; | |||
var Z = new S, la = new x(Z), ma = new V(la, Z); | |||
new Y(ma); | |||
new ja(ma); | |||
var Z = new S, ma = new x(Z), na = new V(ma, Z); | |||
new Y(na); | |||
new ka(na); | |||
new X(Z); | |||
la.animate(); | |||
ma.animate(); | |||
@@ -2,6 +2,8 @@ | |||
var CLIENT_ID = '125643747010-9s9n1ne2fnnuh5v967licfkt83r4vba5.apps.googleusercontent.com'; | |||
/** @const */ | |||
var SCOPES = 'https://www.googleapis.com/auth/drive'; | |||
/** @const */ | |||
var DEVELOPER_KEY = 'AIzaSyBbKO_v9p-G9StQjYmtUYLP6Px4MkGions'; | |||
/** | |||
* | |||
@@ -10,9 +12,10 @@ var SCOPES = 'https://www.googleapis.com/auth/drive'; | |||
ascii.DriveController = function(state) { | |||
/** @type {ascii.State} */ | |||
this.state = state; | |||
// This is a file resource, as defined by the Drive API. | |||
/** @type {Object} */ | |||
this.file = null; | |||
// Let's just hope this happens before anyone clicks save/open. | |||
$('#save-button').click(function(e) { | |||
this.save(); | |||
}.bind(this)); | |||
@@ -25,17 +28,61 @@ ascii.DriveController.prototype.checkAuth = function(callback) { | |||
window['gapi']['auth']['authorize']({ | |||
'client_id': CLIENT_ID, | |||
'scope': SCOPES, | |||
'immediate': false}, | |||
'immediate': true}, | |||
function(result) { | |||
if (result && !result.error) { | |||
callback(true); | |||
} else { | |||
window.alert(result.error); | |||
callback(false); | |||
window['gapi']['auth']['authorize']({ | |||
'client_id': CLIENT_ID, | |||
'scope': SCOPES, | |||
'immediate': false}, | |||
function(result) { | |||
callback(result && !result.error); | |||
}); | |||
} | |||
}); | |||
}; | |||
/** | |||
* Handles a file resource being returned from Drive. | |||
*/ | |||
ascii.DriveController.prototype.handleFile = function(file) { | |||
this.file = file; | |||
$('#drive-filename').text(file['title']); | |||
$('#drive-filename')['editable'](function(value, settings) { | |||
this.file['title'] = value; | |||
this.save(); | |||
// Remove the event handler. | |||
$('#drive-filename').off(); | |||
return value; | |||
}.bind(this), | |||
{ | |||
type : 'text', | |||
submit : 'OK', | |||
}); | |||
}; | |||
/** | |||
* Loads the picker. | |||
* TODO: Implement this... | |||
*/ | |||
ascii.DriveController.prototype.load = function() { | |||
/* | |||
window['gapi']['client']['load']('picker', | |||
{'callback': function() { | |||
var picker = new window['google']['picker']['PickerBuilder'](). | |||
addView(google.picker.ViewId.PHOTOS). | |||
setOAuthToken(oauthToken). | |||
setDeveloperKey(developerKey). | |||
setCallback(pickerCallback). | |||
build(); | |||
picker.setVisible(true); | |||
}}); | |||
*/ | |||
}; | |||
/** | |||
* Saves the current diagram to drive. | |||
*/ | |||
@@ -44,8 +91,8 @@ ascii.DriveController.prototype.save = function() { | |||
this.checkAuth(function(authed) { | |||
if (authed) { | |||
this.getSaveRequest().execute(function(result) { | |||
window.console.log(result); | |||
}); | |||
this.handleFile(result); | |||
}.bind(this)); | |||
} | |||
}.bind(this)) | |||
}.bind(this)); | |||
@@ -58,8 +105,10 @@ ascii.DriveController.prototype.getSaveRequest = function() { | |||
var delimiter = "\r\n--" + boundary + "\r\n"; | |||
var close_delim = "\r\n--" + boundary + "--"; | |||
var title = this.file == null ? 'Untitled ASCII Diagram' : this.file['title']; | |||
var metadata = { | |||
'title': 'Untitled ASCII Diagram', | |||
'title': title, | |||
'mimeType': 'text/plain' | |||
}; | |||
@@ -73,9 +122,13 @@ ascii.DriveController.prototype.getSaveRequest = function() { | |||
text + | |||
close_delim; | |||
// Choose upload path and method depending on whether we have create a file already. | |||
var fileId = this.file == null ? '' : '/' + this.file['id']; | |||
var method = this.file == null ? 'POST' : 'PUT'; | |||
return window['gapi']['client']['request']({ | |||
'path': '/upload/drive/v2/files', | |||
'method': 'POST', | |||
'path': '/upload/drive/v2/files' + fileId, | |||
'method': method, | |||
'params': {'uploadType': 'multipart'}, | |||
'headers': { | |||
'Content-Type': 'multipart/mixed; boundary="' + boundary + '"' | |||