From 2a68fb254940d88036ad481ff5c1cbd017d50147 Mon Sep 17 00:00:00 2001 From: starnutoditopo Date: Mon, 12 Feb 2018 19:59:07 +0100 Subject: [PATCH] 1st commit --- .gitignore | 2 + .hgignore | 25 + all.build.js | 5 + all.build.map.js | 1 + app.build.css | 1 + css/app.css | 894 +++++++++++++++++++++++++++++ favicon.ico | Bin 0 -> 99678 bytes html/app.html | 444 +++++++++++++++ icon-128.png | Bin 0 -> 980 bytes icon-128b.png | Bin 0 -> 980 bytes icon-256.png | Bin 0 -> 14872 bytes icon-ico.ico | Bin 0 -> 99678 bytes index.html | 1 + js/ad_data.jsonp | 86 +++ js/app.js | 1058 +++++++++++++++++++++++++++++++++++ js/banner_ads.js | 94 ++++ js/clipboard.js | 117 ++++ js/drag_drop.js | 55 ++ js/drop_down.js | 121 ++++ js/file_model.js | 282 ++++++++++ js/file_pane.js | 382 +++++++++++++ js/find_pane.js | 644 +++++++++++++++++++++ js/help_pane.js | 111 ++++ js/history_tool.js | 366 ++++++++++++ js/history_tool_worker.js | 643 +++++++++++++++++++++ js/info.js | 200 +++++++ js/keyboard.js | 55 ++ js/offline_simple.js | 86 +++ js/open_pane.js | 56 ++ js/patch_ace.js | 42 ++ js/patch_ace_history.js | 329 +++++++++++ js/print.js | 43 ++ js/save.js | 213 +++++++ js/settings_pane.js | 202 +++++++ js/using_apis.js | 327 +++++++++++ js/utils.js | 157 ++++++ package-lock.json | 617 ++++++++++++++++++++ package.json | 24 + polyfill/es6-promise.min.js | 9 + readme.md | 108 ++++ 40 files changed, 7800 insertions(+) create mode 100644 .gitignore create mode 100644 .hgignore create mode 100644 all.build.js create mode 100644 all.build.map.js create mode 100644 app.build.css create mode 100644 css/app.css create mode 100644 favicon.ico create mode 100644 html/app.html create mode 100644 icon-128.png create mode 100644 icon-128b.png create mode 100644 icon-256.png create mode 100644 icon-ico.ico create mode 100644 index.html create mode 100644 js/ad_data.jsonp create mode 100644 js/app.js create mode 100644 js/banner_ads.js create mode 100644 js/clipboard.js create mode 100644 js/drag_drop.js create mode 100644 js/drop_down.js create mode 100644 js/file_model.js create mode 100644 js/file_pane.js create mode 100644 js/find_pane.js create mode 100644 js/help_pane.js create mode 100644 js/history_tool.js create mode 100644 js/history_tool_worker.js create mode 100644 js/info.js create mode 100644 js/keyboard.js create mode 100644 js/offline_simple.js create mode 100644 js/open_pane.js create mode 100644 js/patch_ace.js create mode 100644 js/patch_ace_history.js create mode 100644 js/print.js create mode 100644 js/save.js create mode 100644 js/settings_pane.js create mode 100644 js/using_apis.js create mode 100644 js/utils.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 polyfill/es6-promise.min.js create mode 100644 readme.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..804efef --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +node_modules* +js/__tmp.js \ No newline at end of file diff --git a/.hgignore b/.hgignore new file mode 100644 index 0000000..12351c0 --- /dev/null +++ b/.hgignore @@ -0,0 +1,25 @@ +# use regexp syntax +#------------------- +syntax: regexp + +# use glob syntax +#---------------- +syntax: glob + +# Ignore Thumbs.db files +Thumbs.db + + +# Ignore log, backup and temporary files +*.log +*.tmp +*.bak + +# Ignore node modules and builds +node_modules/ +build/ + +# Ignore original and rejected files +*.rej +*.orig + diff --git a/all.build.js b/all.build.js new file mode 100644 index 0000000..0534076 --- /dev/null +++ b/all.build.js @@ -0,0 +1,5 @@ +(function(global){var k,_handlers={},_mods={16:false,18:false,17:false,91:false},_scope="all",_MODIFIERS={"⇧":16,shift:16,"⌥":18,alt:18,option:18,"⌃":17,ctrl:17,control:17,"⌘":91,command:91},_MAP={backspace:8,tab:9,clear:12,enter:13,return:13,esc:27,escape:27,space:32,left:37,up:38,right:39,down:40,del:46,delete:46,home:36,end:35,pageup:33,pagedown:34,",":188,".":190,"/":191,"`":192,"-":189,"=":187,";":186,"'":222,"[":219,"]":221,"\\":220},code=function(x){return _MAP[x]||x.toUpperCase().charCodeAt(0)},_downKeys=[];for(k=1;k<20;k++)_MAP["f"+k]=111+k;function index(array,item){var i=array.length;while(i--)if(array[i]===item)return i;return-1}function compareArray(a1,a2){if(a1.length!=a2.length)return false;for(var i=0;i0;for(k in _mods)if(!_mods[k]&&index(handler.mods,+k)>-1||_mods[k]&&index(handler.mods,+k)==-1)modifiersMatch=false;if(handler.mods.length==0&&!_mods[16]&&!_mods[18]&&!_mods[17]&&!_mods[91]||modifiersMatch){if(handler.method(event,handler)===false){if(event.preventDefault)event.preventDefault();else event.returnValue=false;if(event.stopPropagation)event.stopPropagation();if(event.cancelBubble)event.cancelBubble=true}}}}}function clearModifier(event){var key=event.keyCode,k,i=index(_downKeys,key);if(i>=0){_downKeys.splice(i,1)}if(key==93||key==224)key=91;if(key in _mods){_mods[key]=false;for(k in _MODIFIERS)if(_MODIFIERS[k]==key)assignKey[k]=false}}function resetModifiers(){for(k in _mods)_mods[k]=false;for(k in _MODIFIERS)assignKey[k]=false}function assignKey(key,scope,method){var keys,mods;keys=getKeys(key);if(method===undefined){method=scope;scope="all"}for(var i=0;i1){mods=getMods(key);key=[key[key.length-1]]}key=key[0];key=code(key);if(!(key in _handlers))_handlers[key]=[];_handlers[key].push({shortcut:keys[i],scope:scope,method:method,key:keys[i],mods:mods})}}function unbindKey(key,scope){var multipleKeys,keys,mods=[],i,j,obj;multipleKeys=getKeys(key);for(j=0;j1){mods=getMods(keys);key=keys[keys.length-1]}key=code(key);if(scope===undefined){scope=getScope()}if(!_handlers[key]){return}for(i=0;i<_handlers[key].length;i++){obj=_handlers[key][i];if(obj.scope===scope&&compareArray(obj.mods,mods)){_handlers[key][i]={}}}}}function isPressed(keyCode){if(typeof keyCode=="string"){keyCode=code(keyCode)}return index(_downKeys,keyCode)!=-1}function getPressedKeyCodes(){return _downKeys.slice(0)}function filter(event){var tagName=(event.target||event.srcElement).tagName;return!(tagName=="INPUT"||tagName=="SELECT"||tagName=="TEXTAREA")}for(k in _MODIFIERS)assignKey[k]=false;function setScope(scope){_scope=scope||"all"}function getScope(){return _scope||"all"}function deleteScope(scope){var key,handlers,i;for(key in _handlers){handlers=_handlers[key];for(i=0;i").replace(/\t/g,"    ")};var escape_str=function(str){str=str||"";return str.replace(/[\u00A0-\u9999<>\&]/g,function(i){return"&#"+i.charCodeAt(0)+";"})};var hex_print_string=function(str){var c=[];for(var ii=0;ii"+escape_str(val)+""}).join("");this.val_array=val_array.slice(0);this.el_list=document.createElement("div");this.el_list.className="dropdown_item_list";this.el_list.tabindex=-1;this.el_list.style.display="none";this.el_list.innerHTML=str;this.el_collapsed=document.createElement("div");this.el_collapsed.className="dropdown_collapsed";this.el=document.createElement("div");this.el.className="dropdown";this.el.appendChild(this.el_list);this.el.appendChild(this.el_collapsed);this.ind=0;this.el_collapsed.textContent=val_array[0];this.event_callbacks={};this.open=false;this.enabled=true;var dd=this;this.document_mousedown=function(e){dd.el_list.style.display="none";dd.open=false;dd.trigger("blur");document.removeEventListener("mousedown",dd.document_mousedown)};this.el_collapsed.addEventListener("mousedown",function(){if(!dd.enabled)return;if(!dd.trigger("click"))return;dd.el.parentNode.classList.add("selected");dd.el_list.style.display="";this.open=true;setTimeout(function(){dd.el_list.focus();dd.el_list.scrollTop=dd.el_list.children[dd.ind].offsetTop;document.addEventListener("mousedown",dd.document_mousedown)},1)});var on_click=function(e){dd.SetInd(this.getAttribute("data-ind"));dd.el_list.style.display="none";dd.open=false;e.stopPropagation();document.removeEventListener("mousedown",dd.document_mousedown)};for(var ii=0;ii-1)return"Windows";else if(navigator.platform.indexOf("Linux")>-1)return"Linux";else if(navigator.platform.indexOf("Mac")>-1)return"Mac";return null}();"use strict";dn.FileModel=function(){this.is_loaded=false;this.file_id=null;this.folder_id=null;this.title=null;this.description="";this.ext="";this.loaded_body="";this.loaded_mime_type=undefined;this.chosen_mime_type="text/plain";this.is_read_only=false;this.is_shared=false;this.properties_chosen={},this.properties={},this.properties_detected_info={};this.change_callbacks=[];return this};dn.FileModel.prototype.addEventListener=function(kind,c){if(kind!=="change")throw"only change listeners please!";this.change_callbacks.push(c)};dn.FileModel.prototype.trigger=function(kind,ob){if(kind!=="change")throw"only change events please!";for(var ii=0;ii=dn.const_.min_soft_tab_n&&prop.n<=dn.const_.max_soft_tab_n))prop.n=undefined;if(prop.val==="spaces"&&prop.n===undefined)throw 0}catch(e){prop={val:"detect"}}this.properties.tabs=prop;if(prop.val==="tab")this.properties_chosen.tabs=prop;else if(prop.val==="spaces")this.properties_chosen.tabs=prop;else this.properties_chosen.tabs=undefined;var indents=str.match(this.re_whitepace)||[];var n_only_tabs=0;var n_only_space;var space_hist=[];var n_with_mixture=0;var n_samp=Math.min(indents.length,1e3);for(var ii=0;ii=dn.const_.detect_tabs_tabs_frac){this.properties_detected_info.tabs="hard tab indentation detected";if(this.properties_chosen.tabs===undefined)this.properties_chosen.tabs={val:"tabs"};if(this.properties_chosen.tabs.n===undefined)this.properties_chosen.tabs.n=dn.g_settings.get("softTabN")}else if(n_samp===0||n_only_space/n_samp=dn.const_.min_soft_tab_n;ss--)if(space_mod_hist[ss]/n_only_space>dn.const_.detect_tabs_n_spaces_frac){this.properties_detected_info.tabs="detected soft-tabs of "+ss+" spaces";break}if(ssdn.const_.detect_tabs_n_spaces_frac_for_default)this.properties_detected_info.tabs="detected close match to default of "+ss+" spaces";else this.properties_detected_info.tabs="detected soft-tabs, assuming default "+ss+" spaces"}if(this.properties_chosen.tabs===undefined)this.properties_chosen.tabs={val:"spaces"};if(this.properties_chosen.tabs.n===undefined)this.properties_chosen.tabs.n=ss}this.trigger("change",{property:"tabs"})};"use strict";dn.settings_pane=function(){var el={};var theme_drop_down;var on_document_ready=function(){el.theme_chooser=document.getElementById("theme_chooser");el.button_clear_clipboard=document.getElementById("button_clear_clipboard");el.button_clear_find_replace=document.getElementById("button_clear_find_replace");el.gutter_history_show=document.getElementById("gutter_history_show");el.gutter_history_hide=document.getElementById("gutter_history_hide");el.word_wrap_off=document.getElementById("word_wrap_off");el.word_wrap_at=document.getElementById("word_wrap_at");el.word_wrap_edge=document.getElementById("word_wrap_edge");el.font_size_dec=document.getElementById("font_size_dec");el.font_size_inc=document.getElementById("font_size_inc");el.font_size_text=document.getElementById("font_size_text");el.tab_hard=document.getElementById("tab_hard");el.tab_soft=document.getElementById("tab_soft");el.newline_windows=document.getElementById("newline_menu_windows");el.newline_unix=document.getElementById("newline_menu_unix");el.tab_soft_text=document.getElementById("tab_soft_text");el.tab_soft_dec=document.getElementById("tab_soft_dec");el.tab_soft_inc=document.getElementById("tab_soft_inc");el.word_wrap_at_text=document.getElementById("word_wrap_at_text");el.word_wrap_at_dec=document.getElementById("word_wrap_at_dec");el.word_wrap_at_inc=document.getElementById("word_wrap_at_inc");dn.g_settings.addEventListener("VALUE_CHANGED",on_change);var themes=require("ace/ext/themelist");theme_drop_down=new DropDown(Object.keys(themes.themesByName));theme_drop_down.addEventListener("change",function(){dn.g_settings.set("theme",theme_drop_down.GetVal())});theme_drop_down.addEventListener("blur",function(){dn.focus_editor()});el.theme_chooser.appendChild(theme_drop_down.el);el.newline_windows.addEventListener("click",function(){dn.g_settings.set("newLineDefault","windows")});el.newline_unix.addEventListener("click",function(){dn.g_settings.set("newLineDefault","unix")});el.tab_hard.addEventListener("click",function(){dn.g_settings.set("tabIsHard",1)});el.tab_soft.addEventListener("click",function(){dn.g_settings.set("tabIsHard",0)});el.tab_soft_dec.addEventListener("click",function(){var at=dn.g_settings.get("softTabN")-1;at=atdn.const_.max_soft_tab_n?dn.const_.max_soft_tab_n:at;dn.g_settings.set("softTabN",at)});el.font_size_dec.addEventListener("click",font_size_dec_click);el.font_size_inc.addEventListener("click",font_size_inc_click);el.word_wrap_off.addEventListener("click",function(){dn.g_settings.set("wordWrap",[0,0,0])});el.word_wrap_at.addEventListener("click",function(){var at=dn.g_settings.get("wordWrapAt");dn.g_settings.set("wordWrap",[1,at,at])});el.word_wrap_at_dec.addEventListener("click",function(){var at=dn.g_settings.get("wordWrapAt")-dn.const_.wrap_at_increment;at=atdn.const_.max_wrap_at?dn.const_.max_wrap_at:at;dn.g_settings.set("wordWrapAt",at)});el.word_wrap_edge.addEventListener("click",function(){dn.g_settings.set("wordWrap",[1,null,null])});el.gutter_history_show.addEventListener("click",function(){dn.g_settings.set("showGutterHistory",1)});el.gutter_history_hide.addEventListener("click",function(){dn.g_settings.set("showGutterHistory",0)});el.button_clear_clipboard.addEventListener("click",function(){dn.g_clipboard.clear()});el.button_clear_find_replace.addEventListener("click",function(){dn.g_find_history.clear()})};var font_size_dec_click=function(){var font_size=dn.g_settings.get("fontSize");font_size-=dn.const_.font_size_increment;font_size=font_sizedn.const_.max_font_size?dn.const_.max_font_size:font_size;dn.g_settings.set("fontSize",font_size)};var on_change=function(e){var new_value=e.newValue;switch(e.property){case"showGutterHistory":var s=dn.editor.getSession();if(new_value){el.gutter_history_show.classList.add("selected");el.gutter_history_hide.classList.remove("selected")}else{el.gutter_history_hide.classList.add("selected");el.gutter_history_show.classList.remove("selected")}break;case"wordWrapAt":el.word_wrap_at_text.textContent=new_value;break;case"wordWrap":if(!new_value[0])el.word_wrap_off.classList.add("selected");else el.word_wrap_off.classList.remove("selected");if(new_value[0]&&!new_value[1])el.word_wrap_edge.classList.add("selected");else el.word_wrap_edge.classList.remove("selected");if(new_value[0]&&new_value[1])el.word_wrap_at.classList.add("selected");else el.word_wrap_at.classList.remove("selected");break;case"softTabN":el.tab_soft_text.textContent=new_value;break;case"tabIsHard":if(new_value){el.tab_soft.classList.remove("selected");el.tab_hard.classList.add("selected")}else{el.tab_soft.classList.add("selected");el.tab_hard.classList.remove("selected")}break;case"newLineDefault":if(new_value=="windows"){el.newline_unix.classList.remove("selected");el.newline_windows.classList.add("selected")}else{el.newline_unix.classList.add("selected");el.newline_windows.classList.remove("selected")}break;case"fontSize":var scrollLine=dn.get_scroll_line();el.font_size_text.textContent=new_value.toFixed(1);break;case"theme":theme_drop_down.SetInd(theme_drop_down.IndexOf(new_value),true);break}};return{on_document_ready:on_document_ready}}();"use strict;";dn.open_pane=function(){var el={};var picker;var on_document_ready=function(){el.opener_button_a=document.getElementById("opener_button_a");el.opener_button_a.addEventListener("click",open_button_click)};var open_button_click=function(){gapi.load("picker",function(){var view=new google.picker.View(google.picker.ViewId.DOCS);try{if(!picker){picker=(new google.picker.PickerBuilder).enableFeature(google.picker.Feature.NAV_HIDDEN).setAppId(dn.client_id).setOAuthToken(gapi.auth.getToken().access_token).addView(view).setCallback(picker_callback).build();if(!picker)throw"could not build picker"}picker.setVisible(true)}catch(e){dn.show_error(""+e)}})};var picker_callback=function(data){if(data.action==google.picker.Action.PICKED){var file_id=data.docs[0].id;var url="?state="+JSON.stringify({action:"open",userId:dn.url_user_id,ids:[file_id]});window.location=url}else if(data.action=="cancel"){dn.focus_editor()}};return{on_document_ready:on_document_ready}}();"use strict";dn.help_pane=function(){var el={};var show_inner=function(inner_pane){el.inner_pane_shortcuts.style.display="none";el.inner_pane_tips.style.display="none";el.inner_pane_main.style.display="none";el.button_shortcuts.classList.remove("selected");el.button_tips.classList.remove("selected");if(inner_pane=="tips"){el.inner_pane_tips.style.display="";el.button_tips.classList.add("selected")}else if(inner_pane=="shortcuts"){el.inner_pane_shortcuts.style.display="";el.button_shortcuts.classList.add("selected")}else{el.inner_pane_main.style.display=""}};var render_user_name=function(val){el.user_name.textContent=val};var create_pane_shortcuts=function(){var arry=dn.shortcuts_list;var dict={};var platform=dn.platform;if(platform=="Windows"||platform=="Linux"){for(var i=0;i2?parts[2]:parts[1]}}else{}var html=[];for(var action in dict)html.push("
"+action+"
"+dict[action].replace(",","
")+"
");el.inner_pane_shortcuts.innerHTML=["
Keyboard Shortcuts ",platform?"("+platform+")":"","
","
action
key
","
",html.join(""),"
"].join("")};var on_document_ready=function(){el.user_name=document.getElementById("user_name");el.inner_pane_shortcuts=document.getElementById("pane_help_shortcuts");el.inner_pane_tips=document.getElementById("pane_help_tips");el.inner_pane_main=document.getElementById("pane_help_main");el.button_shortcuts=document.getElementById("button_view_shortcuts");el.button_tips=document.getElementById("button_view_tips");el.button_shortcuts.addEventListener("click",function(){if(dn.g_settings.get("help_inner")==="shortcuts")dn.g_settings.set("help_inner","main");else dn.g_settings.set("help_inner","shortcuts")});el.button_tips.addEventListener("click",function(){if(dn.g_settings.get("help_inner")==="tips")dn.g_settings.set("help_inner","main");else dn.g_settings.set("help_inner","tips")});create_pane_shortcuts();dn.g_settings.addEventListener("VALUE_CHANGED",function(e){if(e.property==="help_inner")show_inner(e.newValue)})};return{on_document_ready:on_document_ready,on_user_name_change:render_user_name}}();"use strict";dn.filter_api_errors=function(err){if(dn.is_auth_error(err)){dn.pr_auth.reject(err);return false}else{throw err}};dn.is_auth_error=function(err){if(!err)return 2;try{if(err.status>200){var str="status: "+err.status+" ";if(err.result&&err.result.error)str+=JSON.stringify(err.result.error);str+=" dn.status: "+JSON.stringify(dn.status);str+=" stack: "+(new Error).stack;ga("send","exception",{exDescription:str})}}catch(_){}if(err.type==="token_refresh_required"||err.status===401)return 1;if(err.status===403){var reason="";try{reason=err.result.error.errors[0].reason}catch(_){}if(reason==="domainPolicy")return 0;if(reason==="insufficientFilePermissions")return 0;if(reason==="cannotDownloadAbusiveFile")return 0;return 1}if(err.status===404)return 0;if(err==="timeout")return 3;if(err.result&&err.result.error&&err.result.error.code===-1)return 3;if(err.status===400)return 0;if(err.status===500)return 4;return 0};dn.api_error_to_string=function(err){if(!err)return"Error.";var reason="";try{reason=err.result.error.errors[0].reason}catch(_){}if(reason==="insufficientFilePermissions")return"You do not have permission to modify the file.";if(reason==="domainPolicy")return"Your domain administrators have disabled Drive apps.";if(err.result&&err.result.error&&err.result.error.message!==undefined){return""+err.result.error.message}else{console.log("Strangely structured error:");console.dir(err);return"Error. See developer console for details."}};dn.handle_auth_error=function(err){console.dir("ERROR: "+JSON.stringify(err));if(!err.status.signed_in){console.dir("ERROR user not signed in: "+JSON.stringify(err));return dn.toggle_permission(true);if(!err.status.google_logged_in){dn.reauth_auto()}}dn.status.authorization=-1;dn.status.popup_active=0;dn.show_status();var err_type=dn.is_auth_error(err);if(err_type===0){dn.show_error(dn.api_error_to_string(err))}else if(err_type==1){dn.reauth_auto()}else if(err_type==2){dn.toggle_permission(true)}else{dn.show_error("network error. retrying...");offline_simple.commence_testing()}};dn.reauth_auto_delay_chain={0:1,1:500,500:1e3,1e3:2500,2500:5e3,5e3:1e4,1e4:6e4,6e4:6e4};dn.reauth_auto=function(){if(!dn.reauth_auto_timer){if(!dn.reauth_auto_delay)dn.reauth_auto_delay=dn.reauth_auto_delay_chain[0];else dn.reauth_auto_delay=dn.reauth_auto_delay_chain[dn.reauth_auto_delay];dn.status.authorization=0;dn.show_status();console.log("issuing auto reauth with delay "+dn.reauth_auto_delay+"ms.");dn.reauth_auto_timer=setTimeout(function(){dn.reauth_auto_timer=undefined;console.log("and now running the auto reauth...");Promise.race([gapi.auth.authorize(dn.auth_map(true)),make_timeout(dn.const_.auth_timeout)]).then(dn.pr_auth.resolve.bind(dn.pr_auth),dn.pr_auth.reject.bind(dn.pr_auth))},dn.reauth_auto_delay)}else{console.log("auto reauth already due to be sent")}};dn.reauth_manual=function(){dn.status.popup_active=1;dn.status.authorization=0;dn.show_status();Promise.resolve(gapi.auth.authorize(dn.auth_map(false))).then(dn.pr_auth.resolve.bind(dn.pr_auth),dn.pr_auth.reject.bind(dn.pr_auth))};dn.request_user_info=function(){return gapi.client.request({path:"userinfo/v2/me?fields=name"})};dn.request_file_meta=function(){return gapi.client.request({path:"/drive/v3/files/"+dn.the_file.file_id,params:{fields:"id,name,mimeType,description,parents,capabilities,fileExtension,shared,properties"}})};dn.request_file_body=function(){return gapi.client.request({path:"/drive/v3/files/"+dn.the_file.file_id,params:{alt:"media"},headers:{contentType:"charset=utf-8"}})};dn.make_multipart_boundary=function(){return(new Date).getTime()+""+Math.random()*10};dn.request_new=function(folder_id,title){var meta={name:title};if(folder_id!==undefined)meta["parents"]=[folder_id];return function(){return gapi.client.request({path:"/drive/v3/files/",method:"POST",params:{fields:"id,name,mimeType,description,parents,capabilities,fileExtension,shared"},body:JSON.stringify(meta)})}};dn.request_revision_list=function(){return gapi.client.request({path:"/drive/v3/files/"+dn.the_file.file_id+"/revisions"})};dn.request_revision_body=function(revision_id){return function(){return gapi.client.request({path:"/download/drive/v3/files/"+dn.the_file.file_id+"/revisions/"+revision_id,params:{alt:"media"}})}};dn.request_save=function(parts){var has_body=parts.body!==undefined;var meta={properties:{}};var has_meta=false;if(parts.title!==undefined){has_meta=true;meta["name"]=parts.title}if(parts.description!==undefined){has_meta=true;meta["description"]=parts.description}if(parts.syntax!==undefined){has_meta=true;meta.properties["aceMode"]=parts.syntax}if(parts.newline!==undefined){has_meta=true;meta.properties["newline"]=parts.newline}if(parts.tabs!==undefined){has_meta=true;meta.properties["tabs"]=parts.tabs}var is_multipart=has_body&&has_meta;var params={fields:"version"};if(has_body)params["uploadType"]=is_multipart?"multipart":"media";var headers={};if(is_multipart){var boundary=dn.make_multipart_boundary();request_body="--"+boundary+"\nContent-Type: application/json; charset=UTF-8\n\n"+JSON.stringify(meta)+"\n--"+boundary+"\nContent-Type: "+parts.mimeType+"; charset=UTF-8\n\n"+parts.body+"\n--"+boundary+"--";headers["Content-Type"]='multipart/related; boundary="'+boundary+'"'}else if(has_body){request_body=parts.body;headers["Content-Type"]=parts.mimeType}else{request_body=JSON.stringify(meta)}return function(){return gapi.client.request({path:(has_body?"/upload":"")+"/drive/v3/files/"+dn.the_file.file_id,method:"PATCH",params:params,headers:headers,body:request_body})}};dn.request_app_data_document=function(){return new Promise(function(succ,fail){dn.app_data_realtime_error=function(err){if(dn.status.realtime_settings<1){fail(err)}else{if(err.type==="token_refresh_required"){dn.pr_auth.reject(err)}else{console.dir(err);dn.show_error(""+err)}}};gapi.drive.realtime.loadAppDataDocument(succ,null,dn.app_data_realtime_error)})};dn.request_screw_up_auth_counter=0;dn.request_screw_up_auth=function(){if(++dn.request_screw_up_auth_counter<10){console.log("INVALIDATING TOKEN");gapi.auth.setToken("this_is_no_longer_valid")}return true};"use strict";dn.clipboard_tool=function(const_){var is_active=false;var showing_pane=false;var clipboard_index=-1;var clipboard_info_timer=0;var document_clipboard_left=function(e){if(!is_active)return false;if(clipboard_index<=0)return true;clipboard_index--;dn.editor.undo();dn.editor.insert(dn.g_clipboard.get(clipboard_index));return true};var document_clipboard_right=function(e){if(!is_active)return false;dn.g_atomic_exec(function(){if(clipboard_index>=dn.g_clipboard.length-1)return true;clipboard_index++;dn.editor.undo();dn.editor.insert(dn.g_clipboard.get(clipboard_index))});return true};var document_clipboard_keyup=function(e){if(e.which==17||e.which==91||!e.ctrlKey){document.removeEventListener("keyup",document_clipboard_keyup);is_active=false;if(showing_pane){showing_pane=false;dn.show_pane(dn.g_settings.get("pane"));dn.toggle_widget(dn.g_settings.get("pane_open"))}if(clipboard_info_timer){clearTimeout(clipboard_info_timer);clipboard_info_timer=null}}};var on_paste=function(e){if(dn.g_clipboard===undefined)return;var text=e.text||"";is_active=true;document.addEventListener("keyup",document_clipboard_keyup);clipboard_index=dn.g_clipboard.lastIndexOf(text);if(clipboard_index==-1){clipboard_index=dn.g_clipboard.push(text);if(dn.g_clipboard.length>const_.clipboard_max_length){clipboard_index--;dn.g_clipboard.remove(0)}}if(clipboard_info_timer)clearTimeout(clipboard_info_timer);clipboard_info_timer=setTimeout(function(){clipboard_info_timer=null;showing_pane=true;dn.toggle_widget(true);dn.show_pane("pane_clipboard")},const_.clipboard_info_delay)};var on_copy=function(text){if(dn.g_clipboard===undefined)return;text=text||"";dn.g_atomic_exec(function(){var previous_idx=dn.g_clipboard.lastIndexOf(text);if(previous_idx===-1){dn.g_clipboard.push(text);if(dn.g_clipboard.length>const_.clipboard_max_length)dn.g_clipboard.remove(0)}else{dn.g_clipboard.move(previous_idx,0)}})};var on_document_ready=function(){dn.editor.on("paste",on_paste);dn.editor.on("copy",on_copy)};return{on_document_ready:on_document_ready,on_left:document_clipboard_left,on_right:document_clipboard_right,is_active:function(){return showing_pane}}}(dn.const_);"use strict";dn.save_pending_requests=[];dn.SaveTracker=function(){this.local=undefined;this.remote=undefined;return this};dn.save_local_version_counter=0;dn.save_server_state={};dn.save_local_state={};dn.save=function(parts,correction_with_undo_id){if(!dn.status.user_wants_file){dn.create_file();parts.title=undefined}var found_something=false;if(parts.body!==undefined){var editor_undo_id=correction_with_undo_id===undefined?dn.editor.getSession().getUndoManager().getCurrentId():correction_with_undo_id;if(dn.save_undo_id===editor_undo_id){delete parts.body}else{found_something=true;dn.save_undo_id=NaN;parts.undo_id=editor_undo_id;dn.check_unsaved();parts.mimeType=parts.mimeType||dn.the_file.chosen_mime_type;dn.status.save_body=0}}if(parts.title!==undefined){found_something=true;dn.status.save_title=0}if(parts.syntax!==undefined||parts.description!==undefined||parts.newline!==undefined||parts.tabs!==undefined){found_something=true;dn.status.save_other=0}if(!found_something)return;dn.show_status();dn.save_pending_requests.push(new dn.SaveRequest(parts))};dn.SaveRequest=function(parts){this._parts=parts;var displaced_requests=[];for(var k in this._parts)if(this._parts.hasOwnProperty(k)){if(dn.save_local_state[k]&&!dn.save_local_state[k]._is_settled)displaced_requests.push(dn.save_local_state[k]);dn.save_local_state[k]=this}for(var ii=0;iidn.save_server_state[k].remote){dn.save_server_state[k].remote=this._tracker.remote;dn.save_server_state[k].local=this._tracker.local}}return true};dn.SaveRequest.prototype._on_finally=function(){if(this._error!==undefined){dn.show_error("Saving failed. "+dn.api_error_to_string(this._error));console.dir(this._error);while(dn.save_pending_requests.length)dn.save_pending_requests.pop()._desired=false;dn.save_server_state={};dn.save_local_state={};dn.status.save_body=1;dn.status.save_title=1;dn.status.save_other=1;dn.show_status();return}this._is_settled=true;dn.save_pending_requests.splice(dn.save_pending_requests.indexOf(this),1);if(dn.save_pending_requests.length>0)return;var correction={};var correction_need=false;for(var k in dn.save_local_state)if(dn.save_local_state.hasOwnProperty(k))if(dn.save_server_state[k].local!==dn.save_local_state[k]._tracker.local){correction[k]=dn.save_local_state[k]._parts[k];correction_need=true}dn.status.save_body=1;dn.status.save_title=1;dn.status.save_other=1;var local_undo_id=dn.save_local_state.body?dn.save_local_state.body._parts.undo_id:undefined;if(correction.body===undefined&&local_undo_id!==undefined){dn.save_undo_id=dn.save_local_state.body._parts.undo_id;dn.check_unsaved()}if(correction_need)dn.save(correction,local_undo_id);else dn.show_status()};"use strict";dn.do_print=function(){var line_to_html=function(n){var printLayer=Object.create(ace.require("ace/layer/text").Text.prototype);var tokens=dn.editor.getSession().getTokens(n);var html=[];var screenColumn=0;for(var i=0;i
"+line_to_html(i)+"
";var printWindow=window.open("","");printWindow.document.writeln(""+dn.the_file.title+""+"
    "+html.join("")+"
");printWindow.print();return false}}();"use strict";dn.file_pane=function(){var el={};var history_active=false;var do_save=function(e){e.preventDefault();if(dn.the_file.is_read_only)return dn.show_error("Cannot save read-only file.");dn.save({body:dn.editor.getSession().getValue()})};var read_only_bail=function(e){dn.show_error("The file is read-only, so you cannot change its properties.");e.preventDefault()};var on_title_begin_edit=function(e){if(dn.the_file.is_read_only)return read_only_bail(e);el.title_text.style.display="none";el.title_input.style.display="";el.title_input.focus();el.title_input.select()};var on_title_keydown=function(e){if(e.which==WHICH.ESC){el.title_input.value=dn.the_file.title;e.stopPropagation();dn.focus_editor()}else if(e.which===WHICH.ENTER){e.preventDefault();dn.focus_editor()}};var on_description_begin_edit=function(e){if(dn.the_file.is_read_only)return read_only_bail(e);el.description_text.style.display="none";el.description_input.style.display="";el.description_input.focus();el.description_input.select()};var on_description_keydown=function(e){if(e.which==WHICH.ESC){el.description_input.value=dn.the_file.description;e.stopPropagation();dn.focus_editor()}else if(e.which===WHICH.ENTER&&!e.ctrlKey&&!e.shiftKey){e.preventDefault();dn.focus_editor()}};var do_share=function(){Promise.resolve(dn.pr_file_loaded).then(function(){dn.status.file_sharing=-1;dn.the_file.is_shared=0;dn.show_status();if(el.share_dialog){do_share_sub()}else{gapi.load("drive-share",function(){el.share_dialog=new gapi.drive.share.ShareClient(dn.client_id);do_share_sub()})}})};var do_share_sub=function(){el.share_dialog.setItemIds([dn.the_file.file_id]);el.share_dialog.setOAuthToken(gapi.auth.getToken().access_token);el.share_dialog.showSettingsDialog()};var do_print=dn.do_print;var on_description_end_edit=function(){el.description_input.style.display="none";el.description_text.style.display="";var new_val=el.description_input.value;if(dn.the_file.description!==new_val){dn.the_file.set({description:new_val});dn.save({description:new_val})}dn.focus_editor()};var on_title_end_edit=function(){el.title_input.style.display="none";el.title_text.style.display="";var new_val=el.title_input.value;if(dn.the_file.title!==new_val){dn.the_file.set({title:new_val});dn.save({title:new_val})}dn.focus_editor()};var on_newline_click=function(e){if(dn.the_file.is_read_only)return read_only_bail(e);var val="detect";if(e.currentTarget===el.newline_unix)val="unix";else if(e.currentTarget===el.newline_windows)val="windows";dn.the_file.set({newline:val});dn.save({newline:val})};var on_syntax_detect_click=function(e){if(dn.the_file.is_read_only)return read_only_bail(e);dn.the_file.set({syntax:"detect"});dn.save({syntax:"detect"})};var on_syntax_dropdown_click=function(e){if(dn.the_file.is_read_only)return read_only_bail(e);var val=syntax_drop_down.GetVal();dn.save({syntax:val});dn.the_file.set({syntax:val})};var on_tab_click=function(e){if(dn.the_file.is_read_only)return read_only_bail(e);var val={val:"detect"};if(e.currentTarget===el.tab_soft_inc){e.stopPropagation();val={val:"spaces",n:Math.min(dn.the_file.properties_chosen.tabs.n+1,dn.const_.max_soft_tab_n)}}else if(e.currentTarget===el.tab_soft_dec){e.stopPropagation();var n=dn.the_file.properties_chosen.tabs.n-1;val={val:"spaces",n:Math.max(dn.the_file.properties_chosen.tabs.n-1,dn.const_.min_soft_tab_n)}}else if(e.currentTarget===el.tab_soft){val={val:"spaces",n:dn.the_file.properties_chosen.tabs.n}}else if(e.currentTarget===el.tab_hard){val={val:"tab",n:dn.the_file.properties_chosen.tabs.n}}dn.the_file.set({tabs:val});dn.save({tabs:JSON.stringify(val)})};var render_title=function(){el.title_text_inner.textContent=dn.the_file.title;el.title_input.value=dn.the_file.title};var render_description=function(){text_multi(el.description_text_inner,dn.the_file.description,true);el.description_input.value=dn.the_file.description};var render_newline=function(){el.newline_detect.classList.remove("selected");el.newline_windows.classList.remove("selected");el.newline_unix.classList.remove("selected");var val=dn.the_file.properties.newline;if(val==="detect")el.newline_detect.classList.add("selected");else if(val==="windows")el.newline_windows.classList.add("selected");else el.newline_unix.classList.add("selected");el.newline_info.textContent=dn.the_file.properties_detected_info.newline};var render_syntax=function(){syntax_drop_down.SetInd(syntax_drop_down.IndexOf(dn.the_file.properties_chosen.syntax),true);if(dn.the_file.properties.syntax==="detect"){el.ace_mode_detect.classList.add("selected");syntax_drop_down.SetSelected(false)}else{el.ace_mode_detect.classList.remove("selected");syntax_drop_down.SetSelected(true)}el.ace_mode_info.textContent=dn.the_file.properties_detected_info.syntax};var render_tabs=function(){var user_tabs=dn.the_file.properties.tabs;el.tab_soft.classList.remove("selected");el.tab_hard.classList.remove("selected");el.tab_detect.classList.remove("selected");if(user_tabs.val==="tab")el.tab_hard.classList.add("selected");else if(user_tabs.val==="spaces")el.tab_soft.classList.add("selected");else el.tab_detect.classList.add("selected");el.tab_soft_text.textContent=dn.the_file.properties_chosen.tabs.n;el.tab_info.textContent=dn.the_file.properties_detected_info.tabs};var end_history=function(){if(!history_active)return;dn.history_tool.end();el.button_history.classList.remove("selected");el.button_save.style.display="";el.button_print.style.display="";el.inner_pane_history.style.display="none";el.inner_pane_main.style.display="";history_active=false};var do_history=function(){Promise.resolve(dn.pr_file_loaded).then(function(){el.button_history.classList.add("selected");el.button_save.style.display="none";el.button_print.style.display="none";el.inner_pane_history.style.display="";el.inner_pane_main.style.display="none";dn.history_tool.start();history_active=true})};var syntax_drop_down;var register_controllers=function(){el.title_text.addEventListener("click",on_title_begin_edit);el.title_input.addEventListener("blur",on_title_end_edit);el.title_input.addEventListener("keydown",on_title_keydown);el.description_text.addEventListener("click",on_description_begin_edit);el.description_input.addEventListener("blur",on_description_end_edit);el.description_input.addEventListener("keydown",on_description_keydown);el.newline_detect.addEventListener("click",on_newline_click);el.newline_windows.addEventListener("click",on_newline_click);el.newline_unix.addEventListener("click",on_newline_click);el.tab_detect.addEventListener("click",on_tab_click);el.tab_hard.addEventListener("click",on_tab_click);el.tab_soft_inc.addEventListener("click",on_tab_click);el.tab_soft_dec.addEventListener("click",on_tab_click);el.tab_soft.addEventListener("click",on_tab_click);el.ace_mode_detect.addEventListener("click",on_syntax_detect_click);syntax_drop_down.enabled=true;syntax_drop_down.addEventListener("click",on_syntax_dropdown_click);syntax_drop_down.addEventListener("change",on_syntax_dropdown_click);el.button_save.addEventListener("click",do_save);el.button_print.addEventListener("click",do_print);el.button_share.addEventListener("click",do_share);el.button_history.addEventListener("click",function(){if(history_active)end_history();else do_history()})};var on_document_ready=function(){el.title_input=document.getElementById("details_file_title_input");el.title_text=document.getElementById("details_file_title_text");el.title_text_inner=document.getElementById("details_file_title_text_inner");el.description_input=document.getElementById("details_file_description_input");el.description_text=document.getElementById("details_file_description_text");el.description_text_inner=document.getElementById("details_file_description_text_inner");el.ace_mode_choose=document.getElementById("file_ace_mode_choose");el.ace_mode_detect=document.getElementById("file_ace_mode_detect");el.ace_mode_info=document.getElementById("file_ace_mode_info");el.newline_detect=document.getElementById("file_newline_detect");el.newline_windows=document.getElementById("file_newline_windows");el.newline_unix=document.getElementById("file_newline_unix");el.newline_info=document.getElementById("file_newline_info");el.tab_detect=document.getElementById("file_tab_detect");el.tab_soft_inc=document.getElementById("file_tab_soft_inc");el.tab_soft_dec=document.getElementById("file_tab_soft_dec");el.tab_hard=document.getElementById("file_tab_hard");el.tab_soft=document.getElementById("file_tab_soft");el.tab_soft_text=document.getElementById("file_tab_soft_text");el.tab_info=document.getElementById("file_tab_info");el.button_save=document.getElementById("button_save");el.button_print=document.getElementById("button_print");el.button_share=document.getElementById("button_share");el.button_history=document.getElementById("button_history");el.inner_pane_main=document.getElementById("pane_file_main");el.inner_pane_history=document.getElementById("pane_file_history");var modes=require("ace/ext/modelist").modes;syntax_drop_down=new DropDown(modes.map(function(m){return m.caption}));syntax_drop_down.enabled=false;el.ace_mode_choose.appendChild(syntax_drop_down.el);dn.history_tool.on_document_ready();dn.the_file.addEventListener("change",function(e){switch(e.property){case"syntax":render_syntax();break;case"newline":render_newline();break;case"tabs":render_tabs();break;case"title":render_title();break;case"description":render_description();break;case"is_loaded":register_controllers();break}})};return{on_save_shorcut:do_save,on_print_shortcut:do_print,on_document_ready:on_document_ready,on_close_pane:end_history,do_history:function(e){e.preventDefault();dn.g_settings.set("pane","pane_file");dn.g_settings.set("pane_open",true);do_history()}}}();dn.patch_editor_history=function(editor){var Range=ace.require("./range").Range;var dom=ace.require("./lib/dom");var show_row=[];var row_line_number=[0];var markers=[];var first_rendered_row=-1;var rendered_row_transitions=[];var colors_background=[16777215,16777215,12381160,16763594];var transition_duration=1e3;editor.$blockScrolling=Infinity;editor.setHighlightActiveLine(false);editor.setHighlightGutterLine(false);Range.prototype.toScreenRange=function(session){var screenPosStart=session.documentToScreenPosition(this.start);var screenPosEnd=session.documentToScreenPosition(this.end);ret=new Range(screenPosStart.row,screenPosStart.column,screenPosEnd.row,screenPosEnd.column);ret.doc_range=this.clone();return ret};editor.session.gutterRenderer={getWidth:function(session,lastLineNumber,config){return(""+row_line_number[row_line_number.length-1]).length*config.characterWidth},getText:function(session,row){if(row>=row_line_number.length)return""+row;return row_line_number[row]===-1?"-":row_line_number[row]}};editor.session.removeAllGutterDecorations=function(){for(var ii=0;ii")};var insertFullLines_original=editor.session.doc.insertFullLines;editor.session.doc.insertFullLines=function(arg_0,arg_1){if(arg_0===-1){show_row=new Uint8Array(arg_1.length);for(var ii=0;iifirst_row){for(var row=Math.min(last_row,first_row_old)-1;row>=first_row;row--){rendered_row_transitions.unshift({row:row,from_time:undefined,from_color:undefined,to_time:time_now,to_color:colors_background[show_row[row]]})}}var all_marker_els=editor.renderer.$markerBack.element.children;var marker_els=[];for(var ii=0;iitime_now){var elapsed_frac=(time_now-transition.from_time)/(transition.to_time-transition.from_time);current_color=mix_color(transition.from_color,transition.to_color,elapsed_frac)}else{current_color=transition.to_color}if(transition.to_color!==to_color_new){transition.from_color=current_color;transition.from_time=time_now;transition.to_time=time_now+transition_duration;transition.to_color=to_color_new}el.style.backgroundColor=color_to_string(current_color);if(transition.to_time>time_now){el.style.transitionProperty="";el.style.transitionDuration=transition.to_time-time_now+"ms";els_to_set.push(el);colors_to_set.push(to_color_new);colors_current.push(current_color)}}if(els_to_set.length)window.getComputedStyle(els_to_set[0]).backgroundColor;while(els_to_set.length){var el=els_to_set.pop();el.style.transitionProperty="background-color";el.style.backgroundColor=color_to_string(colors_to_set.pop())}if(last_row_old>last_row){for(row=last_row_old-1;row>=last_row&&row>=first_row_old;row--)rendered_row_transitions.pop()}else if(last_row_old>16)*(1-frac)+((b&16711680)>>16)*frac<<16|((a&65280)>>8)*(1-frac)+((b&65280)>>8)*frac<<8|(a&255)*(1-frac)+(b&255)*frac};var color_to_string=function(color){return"rgb("+((color&16711680)>>16)+", "+((color&65280)>>8)+", "+(color&255)+")"};editor.show_rows=function(show_row_){show_row=new Uint8Array(show_row_);var n=editor.session.doc.getLength();if(show_row.length!==n)throw"bad mask length";editor.session.unfold();while(markers.length)editor.session.removeMarker(markers.pop());editor.session.removeAllGutterDecorations();var line_no=0;var fold_start=-1;row_line_number=[];var first_used_row=-1;for(var ii=0;ii0){editor.session.addFold("",new Range(fold_start-1,Infinity,ii-1,Infinity))}else{editor.session.addFold("",new Range(0,0,ii,0));row_line_number[0]=1;first_used_row=ii}}fold_start=-1}else{row_line_number.push(line_no);if(fold_start===-1)fold_start=ii}}if(fold_start!==-1)editor.session.addFold("",new Range(fold_start-1,Infinity,ii-1,Infinity));var previous=-1;if(first_used_row!==-1){if(show_row[first_used_row]>=1)editor.session.addGutterDecoration(0,"gutter_special_"+show_row[first_used_row])}for(var ii=0;ii=1){markers.push(editor.session.addMarker(new Range(ii,0,ii,Infinity),"special_"+show_row[ii]+(previous!==show_row[ii]?"_first":""),"fullLine",false));editor.session.addGutterDecoration(ii,"gutter_special_"+show_row[ii])}previous=show_row[ii]?show_row[ii]:previous}editor.renderer.updateFull()};editor.$resetCursorStyle=function(){var style=this.$cursorStyle||"ace";var cursorLayer=this.renderer.$cursorLayer;if(!cursorLayer)return;cursorLayer.setSmoothBlinking(/smooth/.test(style));cursorLayer.isBlinking=style!="wide";dom.setCssClass(cursorLayer.element,"ace_slim-cursors",/slim/.test(style))};editor.$mouseHandler.setOptions({dragEnabled:false})};"use strict";dn.history_tool=function(){ +var el={};var revision_meta=[];var worker_has_revision={};var revision_uses_line=[];var worker;var editor;var at_idx=0;var from_idx=0;var LineWidgets=ace.require("./line_widgets").LineWidgets;var start=function(){if(worker===undefined){worker=new Worker("js/history_tool_worker.js");worker.onmessage=on_worker_message}dn.el.editor.style.display="none";el.revisions_view.style.display="";el.revisions_view.innerHTML="";el.info_overflow.style.display="";editor=ace.edit("revisions_view");editor.setFontSize(dn.editor.getFontSize());dn.patch_editor_history(editor);editor.session.setUseWrapMode(true);editor.setReadOnly(true);refresh_revisions_list()};var end=function(){editor.destroy();editor=undefined;el.revisions_view.innerHTML="";var el_old=el.revisions_view;el.revisions_view=el_old.cloneNode(true);el_old.parentNode.replaceChild(el.revisions_view,el_old);dn.el.editor.style.display="";el.revisions_view.style.display="none";el.info_overflow.style.display="none"};var get_editor=function(){return editor};var on_worker_message=function(e){if(!editor)return;var session=editor.getSession();if(e.data.diffed_revision){revision_uses_line=[];if(e.data.diffed_revision.idx===0){session.doc.insertFullLines(-1,e.data.diffed_revision.lines)}else{session.doc.insertFullLines(e.data.diffed_revision.sections);revision_meta[e.data.diffed_revision.idx].el_tick.classList.add("diffed")}}if(e.data.line_is_used){var idx=e.data.line_is_used.idx;revision_uses_line[idx]=new Uint8Array(e.data.line_is_used.buffer);if(idx===Math.max(at_idx,from_idx)){if(at_idx===from_idx)render_single_revision(at_idx);else render_revision_pair(at_idx,from_idx)}else if(Math.max(at_idx,from_idx)>=e.data.line_is_used.diffed_n&&idx==Math.min(at_idx,from_idx)){render_single_revision(Math.min(at_idx,from_idx))}}};var render_single_revision=function(idx){editor.show_rows(revision_uses_line[idx]);var str="";if(idx===0){str="Showing the file:\n\t"+current_version_date_str}else{var time=date_str_to_local(revision_meta[idx].modifiedTime);str="Showing file as it was at:\n\t"+time[1]+" on "+time[0]}text_multi(el.info,str)};var fuse=function(at_is_used,from_is_used){var map=new Uint8Array([0,2,3,1]);var show_rows=new Uint8Array(at_is_used.length);for(var ii=0;iitop_of_history.length&&top_of_history.toLowerCase()===current_str.substr(0,top_of_history.length).toLowerCase()){dn.g_find_history.set(0,current_str)}else if(time_now>search_history_last_modified_time+dn.const_.find_history_add_delay){dn.g_find_history.insert(0,current_str);if(dn.g_find_history.length>dn.const_.find_history_max_len){dn.g_find_history.remove(dn.g_find_history.length-1)}}else{dn.g_find_history.set(0,current_str)}search_history_idx=0;search_history_last_modified_time=time_now})};var search_inputs_focus=function(e){if(e.currentTarget==el.find_input){el.find_input.tabIndex=101;el.replace_input.tabIndex=102}else{el.find_input.tabIndex=102;el.replace_input.tabIndex=101}if(search_inputs_have_focus)return;search_inputs_have_focus=true;dn.editor.setHighlightSelectedWord(false);perform_search()};var search_inputs_blur=function(e){if(e.relatedTarget==el.replace_input||e.relatedTarget==el.find_input)return;search_inputs_have_focus=false;var session=dn.editor.getSession();for(var ii=0;iiselected_range.start.row||search_results[ii].end.row==selected_range.start.row&&search_results[ii].end.column>=selected_range.start.column)break;var current_match_idx=ii==search_results.length?search_results.length-1:ii;for(var ii=0;ii=search_results.length){search_results_sub=search_results_sub.concat(search_results.slice(search_current_match_idx+1));search_results_sub=search_results_sub.concat(search_results.slice(0,n_post+1-(search_results.length-search_current_match_idx)))}else{search_results_sub=search_results_sub.concat(search_results.slice(search_current_match_idx+1,search_current_match_idx+n_post+1))}}var show_replace_buttons=dn.g_settings.get("find_replace");var html="";for(var ii=0;iiconst_.find_max_prefix_chars;row=search_results_sub[ii].range.end.row;col=search_results_sub[ii].range.end.column;var suffix_range=new AceRange(row,col,row,col+const_.find_max_suffix_chars);html+="
"+"
"+(row+1)+"
"+"
"+"
"+(pre_ellipses?"…":"")+escape_str(session.getTextRange(prefix_range))+""+escape_str(session.getTextRange(search_results_sub[ii].range))+""+escape_str(session.getTextRange(suffix_range))+"
"+"
"+(show_replace_buttons?"
r
":"")+"
"}el.search_results.innerHTML=html;var els=el.search_results.getElementsByClassName("find_result_item");for(var ii=0;iimax_search_results)el.info_overflow.textContent="... and "+(search_results.length-max_search_results)+" more matches";else el.info_overflow.textContent="";search_marker_current=session.addMarker(search_results[search_current_match_idx].range,"find_current_match_marker","find_current_match_marker",false);dn.editor.selection.setSelectionRange(search_results[search_current_match_idx].range,false);dn.editor.renderer.scrollSelectionIntoView()};var settings_changed=function(){if(search_inputs_have_focus||dn.g_settings.get("pane")==="pane_find"&&dn.g_settings.get("pane_open")&&el.find_input.value)perform_search()};var search_result_click=function(ii){return function(e){select_search_result_idx(ii)}};var search_replace_result_click=function(ii){return function(e){replace_result_idx(ii);e.stopPropagation()}};var find_input_keyup=function(e){if(e.which==WHICH.ENTER||e.which==WHICH.ESC||e.which==WHICH.UP||e.which==WHICH.DOWN)return;if(search_str==el.find_input.value)return;perform_search();update_search_history()};var find_input_keydown=function(e){if(e.which==WHICH.ENTER&&!e.shiftKey||!e.ctrlKey&&e.which==WHICH.DOWN){select_search_result_idx(search_current_match_idx+1dn.const_.drag_delay_ms||x*x+y*y>dn.const_.drag_shift_px*dn.const_.drag_shift_px}if(dn.widget_mouse_down_info.is_dragging)translate(dn.el.the_widget,x,y);e.stopPropagation()};dn.document_mouse_up_widget=function(e){document.removeEventListener("mousemove",dn.document_mouse_move_widget);document.removeEventListener("mouseup",dn.document_mouse_up_widget);if(dn.widget_mouse_down_info.is_dragging){ +var pos=dn.el.the_widget.getBoundingClientRect();translate(dn.el.the_widget,0,0);var widget_w=dn.el.the_widget.offsetWidth;var widget_h=dn.el.the_widget.offsetHeight;var window_w=window.innerWidth;var window_h=window.innerHeight;var anchor=[];if(pos.leftwindow_w){dn.el.the_widget.style.left="inherit";dn.el.the_widget.style.right="0px"}else{dn.el.the_widget.style.left=anchor[1]+"%";dn.el.the_widget.style.right=""}dn.el.widget_menu.classList.add("flipped");dn.el.widget_content.classList.add("flipped");var els=document.getElementsByClassName("widget_menu_icon");for(var ii=0;iiwindow_w){dn.el.the_widget.style.left="0px";dn.el.the_widget.style.right=""}else{dn.el.the_widget.style.left="inherit";dn.el.the_widget.style.right=anchor[1]+"%"}dn.el.widget_menu.classList.remove("flipped");dn.el.widget_content.classList.remove("flipped");var els=document.getElementsByClassName("widget_menu_icon");for(var ii=0;iiwindow_h){dn.el.the_widget.style.top="inherit";dn.el.the_widget.style.bottom="0px"}else{dn.el.the_widget.style.top=anchor[3]+"%";dn.el.the_widget.style.bottom=""}}else{if(window_h*anchor[3]/100+widget_h>window_h){dn.el.the_widget.style.top="0px";dn.el.the_widget.style.bottom=""}else{dn.el.the_widget.style.top="inherit";dn.el.the_widget.style.bottom=anchor[3]+"%"}}};dn.toggle_widget=function(state){if(state){dn.el.widget_menu.style.display="";dn.el.widget_content.style.display=""}else{dn.el.widget_menu.style.display="none";dn.el.widget_content.style.display="none";dn.file_pane.on_close_pane();dn.focus_editor()}};dn.check_unsaved=function(){if(dn.save_undo_id===dn.editor.getSession().getUndoManager().getCurrentId()){dn.status.unsaved_changes=false;dn.render_document_title();dn.show_status()}else if(!dn.status.unsaved_changes){dn.status.unsaved_changes=true;dn.render_document_title();dn.show_status()}};dn.g_settings=function(){var ob={};var keeps={};var change_listeners=[];return{get:function(k){return ob[k]},set:function(k,v){if(ob[k]===v)return;ob[k]=v;for(var ii=0;iidn.const_.clipboard_max_length){dn.g_clipboard.removeRange(0,dn.g_clipboard.length-dn.const_.clipboard_max_length)}dn.g_find_history=dn.g_settings.get("findHistory");if(!dn.g_find_history){dn.g_settings.set("findHistory",doc.getModel().createList());dn.g_find_history=dn.g_settings.get("findHistory")}else if(dn.g_find_history.length>dn.const_.find_history_max_len){dn.g_find_history.removeRange(dn.const_.find_history_max_len,dn.g_find_history.length)}var last_version=dn.g_settings.get("lastDNVersionUsed");if(last_version!=dn.version_str){if(last_version.length>0&&parseInt(last_version)!==2016){document.getElementById("tips_old_user").style.display="";document.getElementById("tips_general").style.display="none"}dn.g_settings.set("help_inner","tips");dn.g_settings.set("pane","pane_help");dn.g_settings.set("pane_open","true");dn.g_settings.set("lastDNVersionUsed",dn.version_str)}dn.status.realtime_settings=1};dn.settings_changed=function(e){var new_value=e.newValue;console.log("[user settings] "+e.property+": "+new_value);if(dn.impersonal_settings_keys.indexOf(e.property)>-1&&localStorage){localStorage["g_settings_"+e.property]=JSON.stringify(new_value)}try{switch(e.property){case"widget_anchor":dn.widget_apply_anchor(new_value);break;case"theme":dn.editor.setTheme("ace/theme/"+new_value);break;case"fontSize":var scrollLine=dn.get_scroll_line();dn.editor.setFontSize(new_value+"em");dn.editor.scrollToLine(scrollLine);break;case"wordWrap":var s=dn.editor.getSession();var scrollLine=dn.get_scroll_line();s.setUseWrapMode(new_value[0]);s.setWrapLimitRange(new_value[1],new_value[2]);dn.editor.scrollToLine(scrollLine);break;case"wordWrapAt":var curWrap=dn.g_settings.get("wordWrap");if(curWrap[1]&&curWrap[1]!=new_value)dn.g_settings.set("wordWrap",[1,new_value,new_value]);dn.editor.setPrintMarginColumn(new_value);break;case"showGutterHistory":var s=dn.editor.getSession();if(!new_value){var h=dn.change_line_history;for(var i=0;i1)h.splice(start_row,e.lines.length-1);h[start_row]=-n_classes}else{h[start_row]=n_classes;if(e.lines.length>1){var args_for_splice=[start_row,0];for(var ii=0;ii0)dn.the_file.file_id=state.ids[0];else if(state.folderId)dn.new_in_folder=state.folderId}catch(e){dn.show_error("Bad URL. This will be treated as a new file.")}}dn.the_file.addEventListener("change",function(e){switch(e.property){case"title":dn.render_document_title();break;case"syntax":dn.set_editor_syntax();break;case"newline":dn.set_editor_newline();break;case"tabs":dn.set_editor_tabs();break}});dn.pr_auth.on_error(dn.handle_auth_error);dn.pr_auth.on_success(function(){dn.reauth_auto_delay=0;dn.toggle_permission(false);dn.status.popup_active=0;dn.status.authentication=1;dn.show_status()});offline_simple.addEventListener("online",dn.pr_auth.resolve.bind(dn.pr_auth));until_success(function(succ,fail){Promise.resolve(dn.pr_auth).then(dn.request_user_info).then(dn.show_user_info).then(succ,fail)}).before_retry(dn.filter_api_errors).then(function(){console.log("succeeded getting user info.")}).catch(function(err){console.log("failed to load user info");console.dir(err);dn.show_error(dn.api_error_to_string(err))});if(dn.the_file.file_id){dn.status.file_meta=0;dn.status.file_body=0;dn.status.user_wants_file=1;dn.show_status();dn.editor.setReadOnly(true);var pr_meta=until_success(function(succ,fail){Promise.resolve(dn.pr_auth).then(dn.request_file_meta).then(dn.show_file_meta).then(succ,fail)}).before_retry(dn.filter_api_errors).catch(function(err){dn.status.file_meta=-1;dn.show_status();throw err});var pr_body=until_success(function(succ,fail){Promise.resolve(dn.pr_auth).then(dn.request_file_body).then(dn.show_file_body).then(succ,fail)}).before_retry(dn.filter_api_errors).catch(function(err){dn.status.file_body=-1;dn.show_status();throw err});Promise.all([pr_meta,pr_body]).then(function(vals){console.log("succeeded loading file body and metadata.");dn.the_file.set({is_loaded:true});dn.pr_file_loaded.resolve();dn.show_status()}).catch(function(err){console.log("failed to load file properly..");console.dir(err);dn.show_error(dn.api_error_to_string(err));document.title="Drive Notepad";dn.g_settings.set("pane","pane_help");dn.g_settings.set("pane_open",true)})}else{dn.show_status();dn.the_file.set({title:"untitled.txt",is_loaded:true});dn.g_settings.set("pane","pane_file");dn.g_settings.set("pane_open",true)}until_success(function(succ,fail){Promise.all([dn.pr_auth,dn.pr_realtime_loaded]).then(dn.request_app_data_document).then(dn.show_app_data_document).then(succ,fail)}).before_retry(dn.filter_api_errors).then(function(){console.log("succeeded loading settings")}).catch(function(err){console.log("failed to load realtime settings.");console.dir(err);dn.show_error(dn.api_error_to_string(err))})};if(document.readyState!="loading"&&document.getElementById("the_widget")){dn.document_ready()}else{document.addEventListener("DOMContentLoaded",dn.document_ready)} +//# sourceMappingURL=all.build.map.js \ No newline at end of file diff --git a/all.build.map.js b/all.build.map.js new file mode 100644 index 0000000..c858781 --- /dev/null +++ b/all.build.map.js @@ -0,0 +1 @@ +{"version":3,"sources":["node_modules/keymaster/keymaster.js","js/patch_ace.js","js/utils.js","js/offline_simple.js","js/drop_down.js","js/info.js","js/file_model.js","js/settings_pane.js","js/open_pane.js","js/help_pane.js","js/using_apis.js","js/clipboard.js","js/save.js","js/print.js","js/file_pane.js","js/patch_ace_history.js","js/history_tool.js","js/find_pane.js","js/keyboard.js","js/app.js"],"names":["global","k","_handlers","_mods","16","18","17","91","_scope","_MODIFIERS","⇧","shift","⌥","alt","option","⌃","ctrl","control","⌘","command","_MAP","backspace","tab","clear","enter","return","esc","escape","space","left","up","right","down","del","delete","home","end","pageup","pagedown",",",".","/","`","-","=",";","'","[","]","\\","code","x","toUpperCase","charCodeAt","_downKeys","index","array","item","i","length","compareArray","a1","a2","modifierMap","updateModifierKey","event","dispatch","key","handler","modifiersMatch","scope","keyCode","push","assignKey","filter","call","this","getScope","mods","method","preventDefault","returnValue","stopPropagation","cancelBubble","clearModifier","splice","resetModifiers","keys","getKeys","undefined","split","getMods","shortcut","unbindKey","multipleKeys","j","obj","isPressed","getPressedKeyCodes","slice","tagName","target","srcElement","setScope","deleteScope","handlers","replace","mi","addEvent","object","addEventListener","attachEvent","window","document","previousKey","noConflict","unbind","module","exports","UndoManager","ace","require","original_execute","prototype","execute","id_counter","options","deltaSets","args","ii","delta_array_id","getCurrentId","top_delta_set","$undoStack","oxford_comma","arr","rotate","el","deg","style","transform","webkitTansform","mozTransform","translate","y","str","webkitTransform","text_multi","text","truncate_long_words","textContent","innerHTML","escape_str","hex_print_string","c","toString","console","log","join","js_str_from_utf16","bom","Uint16Array","Uint8Array","buffer","endian","TextDecoder","decode","decode_body","body","substr","String","fromCharCode","decodeURIComponent","e","css_animation","timers","els","cls","callback","delay","classList","remove","offsetTop","old_idx","indexOf","clearTimeout","setTimeout","add","stop_propagation","prevent_default","prevent_default_and_stop_propagation","until_success","executor","before_retry","outer_executor","succeed","reject","rejection_handler","err","pre_retry_result","pre_retry_error","Promise","then","outer_promise","func","ext_from_filename","Math","max","lastIndexOf","Infinity","load_script_async","url","new_el","createElement","async","src","something_el","getElementsByTagName","parentNode","insertBefore","offline_simple","callbacks","delay_chain","0","1","500","1000","2500","5000","10000","60000","timer","commence_testing","run_test","request_test","kind","foo","trigger","is_online","xhr","XMLHttpRequest","open","Date","getTime","timeout","check_status","status","onprogress","onerror","ontimeout","onload","onreadystatechange","readyState","checkStatus","send","DropDown","val_array","map","val","el_list","className","tabindex","display","el_collapsed","appendChild","ind","event_callbacks","enabled","dd","document_mousedown","removeEventListener","focus","scrollTop","children","on_click","SetInd","getAttribute","setAttribute","FakeEvent","is_stopped","stopImmediatePropagation","evt","fe","IndexOf","GetVal","no_trigger","min","parseInt","title","isOpen","SetSelected","v","dn","menu_id_to_caption","menu_print","menu_sharing","menu_save","menu_history","menu_file","menu_new","menu_open","menu_find","menu_goto","menu_general_settings","menu_shortcuts","menu_drive","menu_help","shortcuts_list","ext_to_mime_type","html","htm","js","pl","xml","cpp","h","json","php","svg","css","java","py","scala","textile","tex","bib","rtf","rtx","sh","sql","as","tooltip_info","save","print","sharing","file history","drive","about","shortcuts","new","settings_file","settings_general","description","WHICH","ENTER","ESC","UP","DOWN","default_settings","ext","wordWrap","wordWrapAt","fontSize","widget_anchor","showGutterHistory","lastDNVersionUsed","newLineDefault","historyRemovedIsExpanded","softTabN","tabIsHard","widgetSub","theme","pane","pane_open","find_regex","find_whole_words","find_case_sensitive","help_inner","find_goto","find_replace","impersonal_settings_keys","const_","auth_timeout","drag_delay_ms","drag_shift_px","min_font_size","max_font_size","max_wrap_at","min_wrap_at","wrap_at_increment","max_soft_tab_n","min_soft_tab_n","detect_tabs_spaces_frac","detect_tabs_tabs_frac","detect_tabs_n_spaces_frac","detect_tabs_n_spaces_frac_for_default","font_size_increment","error_delay_ms","find_history_add_delay","find_history_max_len","clipboard_info_delay","clipboard_max_length","find_max_results_half","find_max_prefix_chars","find_max_suffix_chars","ad_initial_wait","platform","navigator","FileModel","is_loaded","file_id","folder_id","loaded_body","loaded_mime_type","chosen_mime_type","is_read_only","is_shared","properties_chosen","properties","properties_detected_info","change_callbacks","ob","set","syntax","compute_syntax","newline","compute_newline","tabs","n","compute_tabs","update_mime_type","property","old_title","new_title","old_ext","new_ext","first_n","g_settings","get","has_rn","has_solo_n","match","all_modes","modes","caption","detected","getModeForPath","re_whitepace","prop","JSON","parse","indents","n_only_tabs","n_only_space","space_hist","n_with_mixture","n_samp","indents_ii","without_tabs","space_mod_hist","ss","m","settings_pane","theme_drop_down","on_document_ready","theme_chooser","getElementById","button_clear_clipboard","button_clear_find_replace","gutter_history_show","gutter_history_hide","word_wrap_off","word_wrap_at","word_wrap_edge","font_size_dec","font_size_inc","font_size_text","tab_hard","tab_soft","newline_windows","newline_unix","tab_soft_text","tab_soft_dec","tab_soft_inc","word_wrap_at_text","word_wrap_at_dec","word_wrap_at_inc","on_change","themes","Object","themesByName","focus_editor","at","font_size_dec_click","font_size_inc_click","g_clipboard","g_find_history","font_size","new_value","newValue","s","editor","getSession","scrollLine","get_scroll_line","toFixed","open_pane","picker","opener_button_a","open_button_click","gapi","load","view","google","View","ViewId","DOCS","PickerBuilder","enableFeature","Feature","NAV_HIDDEN","setAppId","client_id","setOAuthToken","auth","getToken","access_token","addView","setCallback","picker_callback","build","setVisible","show_error","data","action","Action","PICKED","docs","id","stringify","userId","url_user_id","ids","location","help_pane","show_inner","inner_pane","inner_pane_shortcuts","inner_pane_tips","inner_pane_main","button_shortcuts","button_tips","render_user_name","user_name","create_pane_shortcuts","arry","dict","parts","on_user_name_change","filter_api_errors","is_auth_error","pr_auth","result","error","Error","stack","ga","exDescription","_","type","reason","errors","api_error_to_string","message","dir","handle_auth_error","signed_in","toggle_permission","google_logged_in","reauth_auto","authorization","popup_active","show_status","err_type","reauth_auto_delay_chain","reauth_auto_timer","reauth_auto_delay","race","authorize","auth_map","make_timeout","resolve","bind","reauth_manual","request_user_info","client","request","path","request_file_meta","the_file","params","fields","request_file_body","headers","contentType","make_multipart_boundary","random","request_new","meta","name","request_revision_list","request_revision_body","revision_id","request_save","has_body","has_meta","is_multipart","boundary","request_body","mimeType","request_app_data_document","succ","fail","app_data_realtime_error","realtime_settings","realtime","loadAppDataDocument","request_screw_up_auth_counter","request_screw_up_auth","setToken","clipboard_tool","is_active","showing_pane","clipboard_index","clipboard_info_timer","document_clipboard_left","undo","insert","document_clipboard_right","g_atomic_exec","document_clipboard_keyup","which","ctrlKey","show_pane","toggle_widget","on_paste","on_copy","previous_idx","move","on","on_left","on_right","save_pending_requests","SaveTracker","local","remote","save_local_version_counter","save_server_state","save_local_state","correction_with_undo_id","user_wants_file","create_file","found_something","editor_undo_id","getUndoManager","save_undo_id","NaN","undo_id","check_unsaved","save_body","save_title","save_other","SaveRequest","_parts","displaced_requests","hasOwnProperty","_is_settled","desired","_desired","_tracker","_error","self","_pr","all","pr_file_loaded","_throw_if_not_desired","_on_completion","catch","_on_error","_on_finally","res","version","pop","correction","correction_need","local_undo_id","do_print","line_to_html","printLayer","create","Text","tokens","getTokens","screenColumn","token","value","$renderToken","content","session","doc","getAllLines","Array","printWindow","writeln","cssText","file_pane","history_active","do_save","getValue","read_only_bail","on_title_begin_edit","title_text","title_input","select","on_title_keydown","on_description_begin_edit","description_text","description_input","on_description_keydown","shiftKey","do_share","file_sharing","share_dialog","do_share_sub","share","ShareClient","setItemIds","showSettingsDialog","on_description_end_edit","new_val","on_title_end_edit","on_newline_click","currentTarget","on_syntax_detect_click","on_syntax_dropdown_click","syntax_drop_down","on_tab_click","render_title","title_text_inner","render_description","description_text_inner","render_newline","newline_detect","newline_info","render_syntax","ace_mode_detect","ace_mode_info","render_tabs","user_tabs","tab_detect","tab_info","end_history","history_tool","button_history","button_save","button_print","inner_pane_history","do_history","start","register_controllers","button_share","ace_mode_choose","on_save_shorcut","on_print_shortcut","on_close_pane","patch_editor_history","Range","dom","show_row","row_line_number","markers","first_rendered_row","rendered_row_transitions","colors_background","transition_duration","$blockScrolling","setHighlightActiveLine","setHighlightGutterLine","toScreenRange","screenPosStart","documentToScreenPosition","screenPosEnd","ret","row","column","doc_range","clone","gutterRenderer","getWidth","lastLineNumber","config","characterWidth","getText","removeAllGutterDecorations","$decorations","_signal","renderer","$markerBack","drawFullLineMarker","stringBuilder","range","clazz","extraStyle","top","$getTop","height","lineHeight","insertFullLines_original","insertFullLines","arg_0","arg_1","len","getLength","getLine","insertMergedLines","kk","splice_args","lines","apply","show_rows","first_row","getFirstVisibleRow","last_row","getLastVisibleRow","first_row_old","last_row_old","time_now","now","unshift","from_time","from_color","to_time","to_color","all_marker_els","element","marker_els","dataset","els_to_set","colors_to_set","colors_current","transition","to_color_new","current_color","elapsed_frac","mix_color","backgroundColor","color_to_string","transitionProperty","transitionDuration","getComputedStyle","a","b","frac","color","show_row_","unfold","removeMarker","line_no","fold_start","first_used_row","addFold","previous","addGutterDecoration","addMarker","updateFull","$resetCursorStyle","$cursorStyle","cursorLayer","$cursorLayer","setSmoothBlinking","test","isBlinking","setCssClass","$mouseHandler","setOptions","dragEnabled","revision_meta","worker_has_revision","revision_uses_line","worker","at_idx","from_idx","LineWidgets","Worker","onmessage","on_worker_message","revisions_view","info_overflow","edit","setFontSize","getFontSize","setUseWrapMode","setReadOnly","refresh_revisions_list","destroy","el_old","cloneNode","replaceChild","get_editor","diffed_revision","idx","sections","el_tick","line_is_used","render_single_revision","render_revision_pair","diffed_n","current_version_date_str","time","date_str_to_local","modifiedTime","info","fuse","at_is_used","from_is_used","time_at","time_from","append_tick","tick_box","send_revisions_order_to_worker","resp","r_to_get","id_order","concat","revisions","reverse","at_range","from_range","postMessage","use_order","render_download_status","render_for_settings","send_revision_body_to_worker","revision","n_pending","reset_with_current_body","body_promises","d","toLocaleDateString","month","day","year","toLocaleTimeString","hour","minute","is_resolved","at_meta","from_meta","caption_at","at_time","caption_from","have_at","have_from","uses_line","render_removed_state","state","remove_expand","remove_collapse","ordered_list","debug","find_pane","goto_input_has_focus","AceSearch","AceRange","search_inputs_have_focus","search_results","search_current_match_idx","search_markers","search_marker_current","search_str","search_history_idx","search_history_left_behind_str","search_history_last_modified_time","focus_on_input","goto_input","find_input","Search","button_case_sensitive","button_whole_words","button_regex","replace_input","button_goto","button_replace","goto_wrapper","find_wrapper","replace_wrapper","button_find_replace_all","settings_changed","on_replace_toggled","on_goto_toggled","goto_input_keydown","goto_input_keyup","goto_input_blur","goto_input_focus","find_input_keyup","find_input_keydown","search_inputs_blur","search_inputs_focus","replace_input_keydown","replace_all","find_shortcut_used","sel","getTextRange","getSelectionRange","update_search_history","goto_shortcut_used","replace_shortcut_used","select_search_result_idx","perform_goto","validated_str","num","gotoLine","navigateLineEnd","current_str","top_of_history","toLowerCase","tabIndex","setHighlightSelectedWord","perform_search","relatedTarget","setSelectionRange","selectionEnd","build_search_options","use_reg_exp","sensitive","re","RegExp","needle","wrap","caseSensitive","wholeWord","regExp","search_options","selection","clearSelection","search","findAll","selected_range","getSelection","getRange","current_match_idx","new_idx","search_results_sub","replace_is_showing","max_search_results","n_pre","n_post","show_replace_buttons","col","prefix_range","pre_ellipses","suffix_range","getElementsByClassName","search_result_click","search_replace_result_click","scrollSelectionIntoView","replace_result_idx","replaceAll","$search","$tryReplace","on_find_shortcut","on_replace_shortcut","on_goto_shortcut","esc_pressed","make_keyboard_shortcuts","commands","removeCommands","do_print_shorcut","do_open","do_new","HashHandler","extraKeyEvents","bindKey","win","mac","descr","exec","keyBinding","addKeyboardHandler","ctrl_key","version_str","can_show_drag_drop_error","file_body","file_meta","file_new","authentication","local_settings","unsaved_changes","warned_read_only","change_line_history","last_change","change_line_classes","rootStr","trueN","factor","change_line_classes_rm","extra","widget_text","widget_pending","widget_error_text","widget_error","the_widget","pane_permissions","permissions_showing","widget_content","el_icon","menu_icon_from_pane_id","widget_mouse_down","widget_mouse_down_info","off_left","clientX","off_top","clientY","start_time","is_dragging","button","document_mouse_move_widget","document_mouse_up_widget","pos","getBoundingClientRect","widget_w","offsetWidth","widget_h","offsetHeight","window_w","innerWidth","window_h","innerHeight","anchor","widget_apply_anchor","isArray","widget_menu","bottom","render_document_title","keeps","change_listeners","keep","get_keeps","flag","transfer_to_true_model","real_model","EventType","VALUE_CHANGED","load_default_settings","localStorage","show_app_data_document","getModel","beginCompoundOperation","endCompoundOperation","old_temp_g_settings","getRoot","existing_cloud_keys","createList","removeRange","last_version","setTheme","scrollToLine","setWrapLimitRange","curWrap","setPrintMarginColumn","removeGutterDecoration","screenToDocumentPosition","getScrollTopRow","show_file_meta","props","capabilities","canEdit","shared","aceMode","parents","set_drive_link_to_folder","history","replaceState","host","pathname","show_file_body","setting_session_value","setValue","on_editor_change","n_classes","start_row","end_row","args_for_splice","query_unload","href","show_user_info","user_info","set_editor_newline","setNewLineMode","set_editor_tabs","setUseSoftTabs","setTabSize","set_editor_syntax","mode_str","modes_array","setMode","mode","new_in_folder","document_ready","setAnimatedScroll","enableBasicAutocompletion","enableLiveAutocompletion","pane_clipboard","pane_file","pane_general_settings","pane_help","pane_find","SpecialPromise","onbeforeunload","window_location_to_params_object","folderId","on_error","on_success","pr_meta","pr_body","vals","pr_realtime_loaded"],"mappings":"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","file":"all.build.js","sourcesContent":["// keymaster.js\n// (c) 2011-2013 Thomas Fuchs\n// keymaster.js may be freely distributed under the MIT license.\n\n;(function(global){\n var k,\n _handlers = {},\n _mods = { 16: false, 18: false, 17: false, 91: false },\n _scope = 'all',\n // modifier keys\n _MODIFIERS = {\n '⇧': 16, shift: 16,\n '⌥': 18, alt: 18, option: 18,\n '⌃': 17, ctrl: 17, control: 17,\n '⌘': 91, command: 91\n },\n // special keys\n _MAP = {\n backspace: 8, tab: 9, clear: 12,\n enter: 13, 'return': 13,\n esc: 27, escape: 27, space: 32,\n left: 37, up: 38,\n right: 39, down: 40,\n del: 46, 'delete': 46,\n home: 36, end: 35,\n pageup: 33, pagedown: 34,\n ',': 188, '.': 190, '/': 191,\n '`': 192, '-': 189, '=': 187,\n ';': 186, '\\'': 222,\n '[': 219, ']': 221, '\\\\': 220\n },\n code = function(x){\n return _MAP[x] || x.toUpperCase().charCodeAt(0);\n },\n _downKeys = [];\n\n for(k=1;k<20;k++) _MAP['f'+k] = 111+k;\n\n // IE doesn't support Array#indexOf, so have a simple replacement\n function index(array, item){\n var i = array.length;\n while(i--) if(array[i]===item) return i;\n return -1;\n }\n\n // for comparing mods before unassignment\n function compareArray(a1, a2) {\n if (a1.length != a2.length) return false;\n for (var i = 0; i < a1.length; i++) {\n if (a1[i] !== a2[i]) return false;\n }\n return true;\n }\n\n var modifierMap = {\n 16:'shiftKey',\n 18:'altKey',\n 17:'ctrlKey',\n 91:'metaKey'\n };\n function updateModifierKey(event) {\n for(k in _mods) _mods[k] = event[modifierMap[k]];\n };\n\n // handle keydown event\n function dispatch(event) {\n var key, handler, k, i, modifiersMatch, scope;\n key = event.keyCode;\n\n if (index(_downKeys, key) == -1) {\n _downKeys.push(key);\n }\n\n // if a modifier key, set the key. property to true and return\n if(key == 93 || key == 224) key = 91; // right command on webkit, command on Gecko\n if(key in _mods) {\n _mods[key] = true;\n // 'assignKey' from inside this closure is exported to window.key\n for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = true;\n return;\n }\n updateModifierKey(event);\n\n // see if we need to ignore the keypress (filter() can can be overridden)\n // by default ignore key presses if a select, textarea, or input is focused\n if(!assignKey.filter.call(this, event)) return;\n\n // abort if no potentially matching shortcuts found\n if (!(key in _handlers)) return;\n\n scope = getScope();\n\n // for each potential shortcut\n for (i = 0; i < _handlers[key].length; i++) {\n handler = _handlers[key][i];\n\n // see if it's in the current scope\n if(handler.scope == scope || handler.scope == 'all'){\n // check if modifiers match if any\n modifiersMatch = handler.mods.length > 0;\n for(k in _mods)\n if((!_mods[k] && index(handler.mods, +k) > -1) ||\n (_mods[k] && index(handler.mods, +k) == -1)) modifiersMatch = false;\n // call the handler and stop the event if neccessary\n if((handler.mods.length == 0 && !_mods[16] && !_mods[18] && !_mods[17] && !_mods[91]) || modifiersMatch){\n if(handler.method(event, handler)===false){\n if(event.preventDefault) event.preventDefault();\n else event.returnValue = false;\n if(event.stopPropagation) event.stopPropagation();\n if(event.cancelBubble) event.cancelBubble = true;\n }\n }\n }\n }\n };\n\n // unset modifier keys on keyup\n function clearModifier(event){\n var key = event.keyCode, k,\n i = index(_downKeys, key);\n\n // remove key from _downKeys\n if (i >= 0) {\n _downKeys.splice(i, 1);\n }\n\n if(key == 93 || key == 224) key = 91;\n if(key in _mods) {\n _mods[key] = false;\n for(k in _MODIFIERS) if(_MODIFIERS[k] == key) assignKey[k] = false;\n }\n };\n\n function resetModifiers() {\n for(k in _mods) _mods[k] = false;\n for(k in _MODIFIERS) assignKey[k] = false;\n };\n\n // parse and assign shortcut\n function assignKey(key, scope, method){\n var keys, mods;\n keys = getKeys(key);\n if (method === undefined) {\n method = scope;\n scope = 'all';\n }\n\n // for each shortcut\n for (var i = 0; i < keys.length; i++) {\n // set modifier keys if any\n mods = [];\n key = keys[i].split('+');\n if (key.length > 1){\n mods = getMods(key);\n key = [key[key.length-1]];\n }\n // convert to keycode and...\n key = key[0]\n key = code(key);\n // ...store handler\n if (!(key in _handlers)) _handlers[key] = [];\n _handlers[key].push({ shortcut: keys[i], scope: scope, method: method, key: keys[i], mods: mods });\n }\n };\n\n // unbind all handlers for given key in current scope\n function unbindKey(key, scope) {\n var multipleKeys, keys,\n mods = [],\n i, j, obj;\n\n multipleKeys = getKeys(key);\n\n for (j = 0; j < multipleKeys.length; j++) {\n keys = multipleKeys[j].split('+');\n\n if (keys.length > 1) {\n mods = getMods(keys);\n key = keys[keys.length - 1];\n }\n\n key = code(key);\n\n if (scope === undefined) {\n scope = getScope();\n }\n if (!_handlers[key]) {\n return;\n }\n for (i = 0; i < _handlers[key].length; i++) {\n obj = _handlers[key][i];\n // only clear handlers if correct scope and mods match\n if (obj.scope === scope && compareArray(obj.mods, mods)) {\n _handlers[key][i] = {};\n }\n }\n }\n };\n\n // Returns true if the key with code 'keyCode' is currently down\n // Converts strings into key codes.\n function isPressed(keyCode) {\n if (typeof(keyCode)=='string') {\n keyCode = code(keyCode);\n }\n return index(_downKeys, keyCode) != -1;\n }\n\n function getPressedKeyCodes() {\n return _downKeys.slice(0);\n }\n\n function filter(event){\n var tagName = (event.target || event.srcElement).tagName;\n // ignore keypressed in any elements that support keyboard data input\n return !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA');\n }\n\n // initialize key. to false\n for(k in _MODIFIERS) assignKey[k] = false;\n\n // set current scope (default 'all')\n function setScope(scope){ _scope = scope || 'all' };\n function getScope(){ return _scope || 'all' };\n\n // delete all handlers for a given scope\n function deleteScope(scope){\n var key, handlers, i;\n\n for (key in _handlers) {\n handlers = _handlers[key];\n for (i = 0; i < handlers.length; ) {\n if (handlers[i].scope === scope) handlers.splice(i, 1);\n else i++;\n }\n }\n };\n\n // abstract key logic for assign and unassign\n function getKeys(key) {\n var keys;\n key = key.replace(/\\s/g, '');\n keys = key.split(',');\n if ((keys[keys.length - 1]) == '') {\n keys[keys.length - 2] += ',';\n }\n return keys;\n }\n\n // abstract mods logic for assign and unassign\n function getMods(key) {\n var mods = key.slice(0, key.length - 1);\n for (var mi = 0; mi < mods.length; mi++)\n mods[mi] = _MODIFIERS[mods[mi]];\n return mods;\n }\n\n // cross-browser events\n function addEvent(object, event, method) {\n if (object.addEventListener)\n object.addEventListener(event, method, false);\n else if(object.attachEvent)\n object.attachEvent('on'+event, function(){ method(window.event) });\n };\n\n // set the handlers globally on document\n addEvent(document, 'keydown', function(event) { dispatch(event) }); // Passing _scope to a callback to ensure it remains the same by execution. Fixes #48\n addEvent(document, 'keyup', clearModifier);\n\n // reset modifiers to false whenever the window is (re)focused.\n addEvent(window, 'focus', resetModifiers);\n\n // store previously defined key\n var previousKey = global.key;\n\n // restore previously defined key and return reference to our key object\n function noConflict() {\n var k = global.key;\n global.key = previousKey;\n return k;\n }\n\n // set window.key and window.key.set/get/deleteScope, and the default filter\n global.key = assignKey;\n global.key.setScope = setScope;\n global.key.getScope = getScope;\n global.key.deleteScope = deleteScope;\n global.key.filter = filter;\n global.key.isPressed = isPressed;\n global.key.getPressedKeyCodes = getPressedKeyCodes;\n global.key.noConflict = noConflict;\n global.key.unbind = unbindKey;\n\n if(typeof module !== 'undefined') module.exports = assignKey;\n\n})(this);\n","\"use strict\";\n\n/* \n monkey patch UndoManager's execute function, so as to store unique ids with each \"delta\".\n\n Actually, it seems that a \"delta\" is the smallest unit of change in ace, above that is an \n \"array of deltas\", and above that is a \"deltaSet\". A deltaSet is the unit which is atomically\n undone/redone, so we might want to attach an id to that, but it is constructed in stages,\n with new \"arrays of deltas\" being \"merged in\". So instead we actually register the ids on\n each \"array of deltas\". The user dosen't need to care about this, they can just use\n .getCurrentId to read the unique value for the current state. \n\n Prior to Feb 2014, it seems there was some code to $serializeDeltas in some manner,\n but that is no longer being used. If it were to come back in to use we would have to\n change our monkey patching.\n\n */\n\n(function(){\n\nvar UndoManager = ace.require(\"./undomanager\").UndoManager;\n\nvar original_execute = UndoManager.prototype.execute;\n\nUndoManager.prototype.id_counter = 0;\n\nUndoManager.prototype.execute = function(options) {\n\n var deltaSets = options.args[0];\n for(var ii=0; ii').replace(/\\t/g,'    ');\n}\n\nvar escape_str = function(str){\n // http://stackoverflow.com/a/18750001/2399799\n str = str || \"\";\n return str.replace(/[\\u00A0-\\u9999<>\\&]/g, function(i) {\n return '&#' + i.charCodeAt(0) + ';';\n });\n}\n\nvar hex_print_string = function(str){\n // only for debugging\n var c = [];\n for(var ii=0; ii\n \n var str = val_array.map(function(val){\n return \"\";\n }).join(\"\");\n \n this.val_array = val_array.slice(0); \n this.el_list = document.createElement('div');\n this.el_list.className ='dropdown_item_list';\n this.el_list.tabindex =-1\n this.el_list.style.display = 'none';\n this.el_list.innerHTML = str;\n\n this.el_collapsed = document.createElement('div');\n this.el_collapsed.className = 'dropdown_collapsed';\n \n this.el = document.createElement('div');\n this.el.className = 'dropdown';\n this.el.appendChild(this.el_list)\n this.el.appendChild(this.el_collapsed);\n this.ind = 0;\n this.el_collapsed.textContent = val_array[0];\n this.event_callbacks = {}; //map of callback lists\n this.open = false;\n this.enabled = true;\n \n var dd = this;\n\n this.document_mousedown = function(e){\n dd.el_list.style.display = 'none';\n dd.open = false;\n dd.trigger(\"blur\");\n document.removeEventListener('mousedown', dd.document_mousedown);\n }\n\n this.el_collapsed.addEventListener('mousedown',function(){\n if(!dd.enabled)\n return;\n if(!dd.trigger(\"click\"))\n return;\n dd.el.parentNode.classList.add(\"selected\");\n dd.el_list.style.display = '';\n this.open = true;\n setTimeout(function(){\n dd.el_list.focus();\n dd.el_list.scrollTop = dd.el_list.children[dd.ind].offsetTop;\n document.addEventListener('mousedown', dd.document_mousedown)\n },1);\n });\n var on_click = function(e){\n dd.SetInd(this.getAttribute('data-ind'));\n dd.el_list.style.display = 'none';\n dd.open = false;\n e.stopPropagation();\n document.removeEventListener('mousedown', dd.document_mousedown);\n };\n for(var ii=0; ii-1)\n return \"Windows\";\n else if(navigator.platform.indexOf(\"Linux\") >-1)\n return \"Linux\";\n else if(navigator.platform.indexOf(\"Mac\")>-1)\n return \"Mac\"; \n return null;\n})();","\"use strict\"\n\ndn.FileModel = function(){\n this.is_loaded = false; // when this is set to true we compute tabs, newlines etc, and continue to do so whenver set() is called.\n this.file_id = null;\n this.folder_id = null;\n this.title = null;\n this.description = '';\n this.ext = '';\n this.loaded_body = '';\n this.loaded_mime_type = undefined;\n this.chosen_mime_type = 'text/plain';\n this.is_read_only = false;\n this.is_shared = false;\n this.properties_chosen = {}, // combines detection, settings, and file properties\n this.properties = {}, // values stored in the file's meta data, defines which button is currently selected\n this.properties_detected_info = {} // caption for detection \n this.change_callbacks = [];\n return this;\n}\n\n// basic events system for a single event called \"change\"\ndn.FileModel.prototype.addEventListener = function(kind, c){\n if(kind !== \"change\") throw \"only change listeners please!\";\n this.change_callbacks.push(c);\n}\ndn.FileModel.prototype.trigger = function(kind, ob){\n if(kind !== \"change\") throw \"only change events please!\";\n for(var ii=0; ii= dn.const_.min_soft_tab_n && prop.n <= dn.const_.max_soft_tab_n))\n prop.n = undefined; \n if(prop.val === \"spaces\" && prop.n === undefined) throw 0\n }catch(e){\n prop = {val: \"detect\"};\n }\n this.properties.tabs = prop; // force it to be whatever we parsed\n\n if(prop.val === \"tab\")\n this.properties_chosen.tabs = prop; // may need to chose n still\n else if(prop.val === \"spaces\")\n this.properties_chosen.tabs = prop; // n is definitely valid\n else\n this.properties_chosen.tabs = undefined; // we need to chose val and n \n \n\n // Now do detection....\n\n // find non-zero-length whitespace at start of all lines\n var indents = str.match(this.re_whitepace) || []; \n\n // build the stats for those lines...\n var n_only_tabs = 0;\n var n_only_space; // we compute this after the loop\n var space_hist = [];\n var n_with_mixture = 0;\n var n_samp = Math.min(indents.length, 1000);\n for(var ii=0; ii= dn.const_.detect_tabs_tabs_frac){\n // detected tab...\n this.properties_detected_info.tabs = \"hard tab indentation detected\";\n if(this.properties_chosen.tabs === undefined)\n this.properties_chosen.tabs = {val: 'tabs'}\n if(this.properties_chosen.tabs.n === undefined)\n this.properties_chosen.tabs.n = dn.g_settings.get('softTabN'); // we have to show something for n\n\n } else if(n_samp === 0 || n_only_space/n_samp < dn.const_.detect_tabs_spaces_frac){\n // no detection possible, use default....\n\n if(this.properties_chosen.tabs === undefined){\n this.properties_chosen.tabs = {\n val: dn.g_settings.get('tabIsHard') ? 'tabs' : 'spaces',\n n: dn.g_settings.get('softTabN')};\n }\n this.properties_detected_info.tabs =\n (n_samp === 0 ?\n \"no indentations detected\" \n : \"detected mixture of tabs\")\n + \", default is \" + (this.properties_chosen.tabs.val == 'tabs' ?\n \"hard tabs\"\n : dn.g_settings.get('softTabN') + \" spaces\");\n \n } else {\n // detected spaces, but exxactly how many? \n\n //Build a second space hist, using all \"harmonics\"....\n var space_mod_hist = [];\n for(var ss=dn.const_.min_soft_tab_n; ss<=dn.const_.max_soft_tab_n; ss++){\n for(var ii=ss, m=0; ii=dn.const_.min_soft_tab_n; ss--)\n if(space_mod_hist[ss]/n_only_space > dn.const_.detect_tabs_n_spaces_frac){\n this.properties_detected_info.tabs = \"detected soft-tabs of \" + ss + \" spaces\"\n break;\n }\n\n // if nothing was over threshold, use default space count\n if(ss < dn.const_.min_soft_tab_n){\n ss = dn.g_settings.get('softTabN'); \n if(space_mod_hist[ss]/n_only_space > dn.const_.detect_tabs_n_spaces_frac_for_default)\n this.properties_detected_info.tabs = \"detected close match to default of \" + ss + \" spaces\";\n else \n this.properties_detected_info.tabs = \"detected soft-tabs, assuming default \" + ss + \" spaces\";\n }\n\n // if we need to specify a space count use the ss value we ended up with...\n if(this.properties_chosen.tabs === undefined)\n this.properties_chosen.tabs = {val: 'spaces'};\n if(this.properties_chosen.tabs.n === undefined)\n this.properties_chosen.tabs.n = ss;\n }\n \n this.trigger(\"change\", {property: 'tabs'});\n}\n\n","\"use strict\";\n\ndn.settings_pane = (function(){\n\nvar el = {};\n\nvar theme_drop_down;\n\nvar on_document_ready = function(){\n el.theme_chooser = document.getElementById('theme_chooser')\n el.button_clear_clipboard = document.getElementById(\"button_clear_clipboard\");\n el.button_clear_find_replace = document.getElementById(\"button_clear_find_replace\");\n el.gutter_history_show = document.getElementById('gutter_history_show');\n el.gutter_history_hide = document.getElementById('gutter_history_hide');\n el.word_wrap_off = document.getElementById('word_wrap_off');\n el.word_wrap_at = document.getElementById('word_wrap_at');\n el.word_wrap_edge = document.getElementById('word_wrap_edge');\n el.font_size_dec = document.getElementById('font_size_dec');\n el.font_size_inc = document.getElementById('font_size_inc');\n el.font_size_text = document.getElementById('font_size_text');\n el.tab_hard = document.getElementById('tab_hard');\n el.tab_soft = document.getElementById('tab_soft');\n el.newline_windows = document.getElementById('newline_menu_windows');\n el.newline_unix = document.getElementById('newline_menu_unix');\n el.tab_soft_text = document.getElementById('tab_soft_text');\n el.tab_soft_dec = document.getElementById('tab_soft_dec');\n el.tab_soft_inc = document.getElementById('tab_soft_inc');\n el.word_wrap_at_text = document.getElementById('word_wrap_at_text');\n el.word_wrap_at_dec = document.getElementById('word_wrap_at_dec');\n el.word_wrap_at_inc = document.getElementById('word_wrap_at_inc');\n\n dn.g_settings.addEventListener(\"VALUE_CHANGED\", on_change); // this does all the view rendering\n\n var themes = require('ace/ext/themelist');\n theme_drop_down = new DropDown(Object.keys(themes.themesByName));\n\n // annonymous controler functions....\n theme_drop_down.addEventListener(\"change\",function(){\n dn.g_settings.set(\"theme\",theme_drop_down.GetVal());\n })\n theme_drop_down.addEventListener(\"blur\",function(){\n dn.focus_editor();\n })\n el.theme_chooser.appendChild(theme_drop_down.el);\n el.newline_windows.addEventListener('click', function(){\n dn.g_settings.set('newLineDefault', 'windows');\n });\n el.newline_unix.addEventListener('click', function(){\n dn.g_settings.set('newLineDefault', 'unix');\n });\n el.tab_hard.addEventListener('click', function(){\n dn.g_settings.set('tabIsHard', 1)\n });\n el.tab_soft.addEventListener('click', function(){\n dn.g_settings.set('tabIsHard', 0);\n });\n el.tab_soft_dec.addEventListener('click', function(){\n var at = dn.g_settings.get('softTabN') - 1;\n at = at < dn.const_.min_soft_tab_n ? dn.const_.min_soft_tab_n : at;\n dn.g_settings.set('softTabN',at);\n });\n el.tab_soft_inc.addEventListener('click', function(){\n var at = dn.g_settings.get('softTabN') + 1;\n at = at > dn.const_.max_soft_tab_n ? dn.const_.max_soft_tab_n : at;\n dn.g_settings.set('softTabN',at);\n });\n el.font_size_dec.addEventListener('click', font_size_dec_click);\n el.font_size_inc.addEventListener('click', font_size_inc_click); \n el.word_wrap_off.addEventListener('click', function(){\n dn.g_settings.set('wordWrap',[0,0,0])\n });\n el.word_wrap_at.addEventListener('click', function(){\n var at = dn.g_settings.get('wordWrapAt');\n dn.g_settings.set('wordWrap',[1,at,at]);\n });\n el.word_wrap_at_dec.addEventListener('click', function(){\n var at = dn.g_settings.get('wordWrapAt') - dn.const_.wrap_at_increment;\n at = at < dn.const_.min_wrap_at ? dn.const_.min_wrap_at : at;\n dn.g_settings.set('wordWrapAt',at);\n });\n el.word_wrap_at_inc.addEventListener('click', function(){\n var at = dn.g_settings.get('wordWrapAt') + dn.const_.wrap_at_increment;\n at = at > dn.const_.max_wrap_at ? dn.const_.max_wrap_at : at;\n dn.g_settings.set('wordWrapAt',at);\n });\n el.word_wrap_edge.addEventListener('click', function(){\n dn.g_settings.set('wordWrap',[1,null,null])\n });\n el.gutter_history_show.addEventListener('click', function(){\n dn.g_settings.set('showGutterHistory',1);\n });\n el.gutter_history_hide.addEventListener('click', function(){\n dn.g_settings.set('showGutterHistory',0);\n });\n\n // non-view interactivity...\n el.button_clear_clipboard.addEventListener('click', function(){\n dn.g_clipboard.clear();\n });\n el.button_clear_find_replace.addEventListener('click', function(){\n dn.g_find_history.clear();\n });\n\n}\n\n// additional controler functions ::::::::::::::::::::::::::::::::::\n\nvar font_size_dec_click = function(){\n var font_size = dn.g_settings.get('fontSize');\n font_size -= dn.const_.font_size_increment;\n font_size = font_size < dn.const_.min_font_size ? dn.const_.min_font_size: font_size;\n dn.g_settings.set('fontSize', font_size);\n}\n\nvar font_size_inc_click = function(){\n var font_size = dn.g_settings.get('fontSize');\n font_size += dn.const_.font_size_increment;\n font_size = font_size > dn.const_.max_font_size ? dn.const_.max_font_size:font_size;\n dn.g_settings.set('fontSize', font_size);\n}\n\n\n// view function ::::::::::::::::::::::::::::::::::\n\nvar on_change = function(e){\n var new_value = e.newValue;\n\n switch(e.property){\n\n case \"showGutterHistory\":\n var s = dn.editor.getSession(); \n if(new_value){\n el.gutter_history_show.classList.add('selected')\n el.gutter_history_hide.classList.remove('selected');\n }else{\n el.gutter_history_hide.classList.add('selected')\n el.gutter_history_show.classList.remove('selected');\n }\n break;\n\n case \"wordWrapAt\":\n el.word_wrap_at_text.textContent = new_value;\n break;\n\n case \"wordWrap\":\n if(!new_value[0])\n el.word_wrap_off.classList.add('selected');\n else\n el.word_wrap_off.classList.remove('selected');\n if(new_value[0] && !new_value[1])\n el.word_wrap_edge.classList.add('selected');\n else\n el.word_wrap_edge.classList.remove('selected');\n if(new_value[0] && new_value[1])\n el.word_wrap_at.classList.add('selected');\n else\n el.word_wrap_at.classList.remove('selected');\n break;\n\n case \"softTabN\":\n el.tab_soft_text.textContent = new_value;\n break;\n\n case \"tabIsHard\": \n if(new_value){\n el.tab_soft.classList.remove('selected');\n el.tab_hard.classList.add('selected');\n }else{\n el.tab_soft.classList.add('selected');\n el.tab_hard.classList.remove('selected');\n }\n break;\n \n case \"newLineDefault\":\n if(new_value == \"windows\"){\n el.newline_unix.classList.remove('selected');\n el.newline_windows.classList.add('selected');\n }else{\n el.newline_unix.classList.add('selected');\n el.newline_windows.classList.remove('selected');\n }\n break;\n \n case \"fontSize\":\n var scrollLine = dn.get_scroll_line();\n el.font_size_text.textContent = new_value.toFixed(1);\n break;\n\n case \"theme\":\n theme_drop_down.SetInd(theme_drop_down.IndexOf(new_value), true);\n break;\n \n }\n}\n\nreturn {\n on_document_ready: on_document_ready\n};\n\n\n\n})();\n","\"use strict;\"\n\ndn.open_pane = (function(){\n\nvar el = {};\nvar picker;\n\nvar on_document_ready = function(){\n el.opener_button_a = document.getElementById('opener_button_a');\n el.opener_button_a.addEventListener('click', open_button_click);\n}\n\n\nvar open_button_click = function(){\n gapi.load('picker', function(){\n var view = new google.picker.View(google.picker.ViewId.DOCS);\n try{\n if(!picker){\n picker = new google.picker.PickerBuilder()\n .enableFeature(google.picker.Feature.NAV_HIDDEN)\n .setAppId(dn.client_id) /* the drive scope requires explicit permission to open each file, and by providing the client_id here you get it for the chosen file */\n .setOAuthToken(gapi.auth.getToken().access_token) /* this gives permission to open the picker..you can do it wtihout a user-specific access_token, but we have one so lets use it */\n .addView(view)\n .setCallback(picker_callback)\n .build(); \n if(!picker)\n throw \"could not build picker\";\n }\n picker.setVisible(true);\n } catch (e){\n dn.show_error(\"\" + e);\n }\n });\n\n}\n\nvar picker_callback = function(data) {\n if (data.action == google.picker.Action.PICKED) {\n var file_id = data.docs[0].id;\n var url = \"?state=\" + JSON.stringify({\n action: \"open\",\n userId: dn.url_user_id,\n ids: [file_id]\n });\n window.location = url;\n }else if(data.action == \"cancel\"){\n dn.focus_editor();\n }\n}\n\n\nreturn {\n\ton_document_ready: on_document_ready\n};\n\n})();","\"use strict\";\n\ndn.help_pane = (function(){\n\nvar el = {};\n\nvar show_inner = function(inner_pane){\n\t// this is a view function for dn.g_settings['help_inner']\n // expects string 'shorcuts' or 'tips', any other values shows main\n\n el.inner_pane_shortcuts.style.display = 'none';\n el.inner_pane_tips.style.display = 'none';\n el.inner_pane_main.style.display = 'none';\n\n el.button_shortcuts.classList.remove('selected');\n el.button_tips.classList.remove('selected');\n \n if(inner_pane == 'tips'){\n el.inner_pane_tips.style.display = '';\n el.button_tips.classList.add('selected');\n } else if(inner_pane == 'shortcuts'){\n el.inner_pane_shortcuts.style.display = '';\n el.button_shortcuts.classList.add('selected');\n } else {\n el.inner_pane_main.style.display = '';\n }\n}\n\n\nvar render_user_name = function(val){\n\tel.user_name.textContent = val;\n}\n\nvar create_pane_shortcuts = function(){\n//This is hardly the world's most efficient way of doing this....(but it probably doesn't matter)...\n\n var arry = dn.shortcuts_list;\n var dict = {};\n var platform = dn.platform;\n\n if(platform == \"Windows\" || platform == \"Linux\"){\n for(var i=0;i 2? parts[2] : parts[1];\n }\n }else{\n //TODO: show something here, maybe let user switch, maybe have touch info for ipad & android.\n }\n \n var html = [];\n for(var action in dict)\n html.push(\"
\" + \n action + \"
\" + dict[action].replace(\",\",\"
\") +\n \"
\");\n \n // TODO: put shortcuts into element titles, see menu_id_to_caption\n //for(var action in dn.tooltip_info)if(action in dict)\n // dn.tooltip_info[action] += dict[action];\n\t\n el.inner_pane_shortcuts.innerHTML = [\n \"
Keyboard Shortcuts \",\n platform ? \"(\" + platform + \")\" : \"\" ,\n \"
\",\n \"
action
key
\",\n \"
\",\n html.join(''),\n \"
\"].join('');\n\n}\n\nvar on_document_ready = function(){\n el.user_name = document.getElementById('user_name');\n el.inner_pane_shortcuts = document.getElementById('pane_help_shortcuts');\n el.inner_pane_tips = document.getElementById('pane_help_tips');\n el.inner_pane_main = document.getElementById('pane_help_main');\n el.button_shortcuts = document.getElementById('button_view_shortcuts');\n el.button_tips = document.getElementById('button_view_tips');\n el.button_shortcuts.addEventListener('click', function(){\n if(dn.g_settings.get('help_inner') === 'shortcuts')\n dn.g_settings.set('help_inner', 'main');\n else\n dn.g_settings.set('help_inner', 'shortcuts');\n })\n el.button_tips.addEventListener('click', function(){\n if(dn.g_settings.get('help_inner') === 'tips')\n dn.g_settings.set('help_inner', 'main');\n else\n dn.g_settings.set('help_inner', 'tips');\n })\n create_pane_shortcuts();\n dn.g_settings.addEventListener(\"VALUE_CHANGED\", function(e){\n \tif(e.property === 'help_inner')\n \t\tshow_inner(e.newValue);\n });\n \n}\n\n\nreturn {\n\ton_document_ready: on_document_ready,\n\ton_user_name_change: render_user_name\n}\n\n})();","\"use strict\";\n\n/*\n Working with oauth2 APIs has its complexities, some of which\n are dealt with by the google client library, but some of which\n are exposed for us to deal with.\n\n These functions do the majority of the fiddly stuff. In particular,\n the dn.request_* functions are designed to be used in a promise chain\n within a until_success call. See the readme for additional explanation.\n\n You can insert the request_screw_up_auth into a promise chain to check \n how the chain handles unexpected invalidation.\n\n*/\n\ndn.filter_api_errors = function(err){\n // this is designed for use in conjunction with until_success\n if(dn.is_auth_error(err)){\n dn.pr_auth.reject(err); //will trigger some kind of re-authnetication\n return false; // continue with next attempt\n }else{\n throw err; // this is an unrecognised error\n }\n}\n\ndn.is_auth_error = function(err){\n // returns :\n // 0 for fatal errors\n // 1 for recommended auto refresh\n // 2 for recommended manual refresh\n // 3 for network error/timeout, recommend test network and retry\n // 4 for server error, recommend retry (ideally with exponential backoff)\n\n if(!err)\n return 2;\n\n \n try{\n if(err.status > 200){\n var str = \"status: \" + err.status + \" \";\n if(err.result && err.result.error)\n str += JSON.stringify(err.result.error);\n str += \" dn.status: \" + JSON.stringify(dn.status);\n str += \" stack: \" + (new Error()).stack;\n ga('send', 'exception', {'exDescription': str});\n }\n }catch(_){}\n \n\n if(err.type === \"token_refresh_required\" || err.status === 401)\n return 1;\n\n if(err.status === 403){\n var reason = \"\"\n try{reason = err.result.error.errors[0].reason;}catch(_){};\n\n if(reason === \"domainPolicy\")\n return 0;\n if(reason === \"insufficientFilePermissions\")\n return 0; // should only happen if file becomes read-only after the page loads\n if(reason === \"cannotDownloadAbusiveFile\")\n return 0; // this is not documented but appears in logs\n\n //TODO: handle other specifics, and include exponential backoff where appropriate\n return 1; // a variety of things here\n }\n if(err.status === 404)\n return 0; // file not found\n if(err === \"timeout\")\n return 3;\n if(err.result && err.result.error && err.result.error.code === -1)//network error\n return 3;\n if(err.status === 400)\n return 0; // bad request\n if(err.status === 500)\n return 4;\n return 0;\n}\n\ndn.api_error_to_string = function(err){\n\n if(!err)\n return \"Error.\";\n var reason = \"\"\n try{reason = err.result.error.errors[0].reason;}catch(_){};\n if(reason === \"insufficientFilePermissions\")\n return \"You do not have permission to modify the file.\";\n if(reason === \"domainPolicy\")\n return \"Your domain administrators have disabled Drive apps.\"\n\n if(err.result && err.result.error && err.result.error.message !== undefined){\n return \"\" + err.result.error.message;\n } else {\n console.log(\"Strangely structured error:\")\n console.dir(err);\n return \"Error. See developer console for details.\"\n }\n}\n\ndn.handle_auth_error = function(err){\n\n console.dir(\"ERROR: \"+JSON.stringify(err));\n if(!err.status.signed_in){\n console.dir(\"ERROR user not signed in: \"+JSON.stringify(err));\n\n return dn.toggle_permission(true);\n\n\n if(!err.status.google_logged_in){\n dn.reauth_auto();\n }\n }\n \n // this is the error handler for dn.pr_auth\n\n dn.status.authorization = -1;\n dn.status.popup_active = 0;\n dn.show_status();\n var err_type = dn.is_auth_error(err);\n\n if(err_type === 0){\n dn.show_error(dn.api_error_to_string(err));\n }else if(err_type == 1){\n dn.reauth_auto();\n }else if(err_type == 2){\n // user has to click button to trigger reauth-manual\n dn.toggle_permission(true);\n }else{\n // should be network error\n dn.show_error(\"network error. retrying...\");\n offline_simple.commence_testing(); // we have already registered a listener that will resolve pr_auth when the connection is restored\n }\n}\n\ndn.reauth_auto_delay_chain = {0: 1, 1:500, 500: 1000, 1000: 2500, 2500: 5000, 5000: 10000, 10000: 60000, 60000: 60000}\ndn.reauth_auto = function(){ \n // with roughly-exponetial backoff...\n if (!dn.reauth_auto_timer){\n // 1ms, 500ms, 1s, 2s, 5s, 10s, 60s.\n if(!dn.reauth_auto_delay)\n dn.reauth_auto_delay = dn.reauth_auto_delay_chain[0];\n else\n dn.reauth_auto_delay = dn.reauth_auto_delay_chain[dn.reauth_auto_delay];\n dn.status.authorization = 0;\n dn.show_status();\n console.log(\"issuing auto reauth with delay \" + dn.reauth_auto_delay + \"ms.\")\n dn.reauth_auto_timer = setTimeout(function(){\n dn.reauth_auto_timer = undefined;\n console.log(\"and now running the auto reauth...\")\n Promise.race([gapi.auth.authorize(dn.auth_map(true)), make_timeout(dn.const_.auth_timeout)])\n .then(dn.pr_auth.resolve.bind(dn.pr_auth),\n dn.pr_auth.reject.bind(dn.pr_auth));\n }, dn.reauth_auto_delay)\n } else {\n console.log(\"auto reauth already due to be sent\")\n }\n}\n\ndn.reauth_manual = function(){\n // if this succeeds it will trigger dn.pr_auth.resolve, which will call \n // any pending (and future) success callbacks.\n dn.status.popup_active = 1;\n dn.status.authorization = 0;\n dn.show_status(); \n Promise.resolve(gapi.auth.authorize(dn.auth_map(false)))\n .then(dn.pr_auth.resolve.bind(dn.pr_auth),\n dn.pr_auth.reject.bind(dn.pr_auth));\n}\n\ndn.request_user_info = function(){\n // returns thenable\n return gapi.client.request({'path' : 'userinfo/v2/me?fields=name'})\n}\n\ndn.request_file_meta = function(){\n // returns thenable\n return gapi.client.request({\n 'path': '/drive/v3/files/' + dn.the_file.file_id,\n 'params':{'fields': 'id,name,mimeType,description,parents,capabilities,fileExtension,shared,properties'}});\n}\n\ndn.request_file_body = function(){\n // returns thenable\n return gapi.client.request({\n 'path': '/drive/v3/files/' + dn.the_file.file_id,\n 'params':{'alt': 'media'},\n 'headers': {'contentType': 'charset=utf-8'}});\n}\n\ndn.make_multipart_boundary = function(){\n //for MIME protocol, require a boundary that doesn't exist in the message content.\n //we could check explicitly, but this is essentially guaranteed to be fine:\n // e.g. \"13860126288389.206091766245663\"\n return (new Date).getTime() + \"\" + Math.random()*10;\n}\n\ndn.request_new = function(folder_id, title){\n // this is a factory function for building a function-of-no-args-that-returns-a-thenable\n var meta = {name: title};\n if(folder_id !== undefined)\n meta['parents'] = [folder_id];\n return function(){\n return gapi.client.request({\n 'path': '/drive/v3/files/',\n 'method': 'POST',\n 'params' : {'fields': 'id,name,mimeType,description,parents,capabilities,fileExtension,shared'},\n 'body' : JSON.stringify(meta)\n });\n };\n}\n\ndn.request_revision_list = function(){\n // returns thenable\n return gapi.client.request({\n 'path': '/drive/v3/files/' + dn.the_file.file_id + \"/revisions\"});\n}\n\ndn.request_revision_body = function(revision_id){\n // returns a function that returns a thenable\n // note that annoyingly you cant use batch requests with alt=media,\n return function(){\n return gapi.client.request({\n 'path': '/download/drive/v3/files/' + dn.the_file.file_id + \"/revisions/\" + revision_id,\n 'params':{'alt': 'media'}});\n };\n}\n\n\ndn.request_save = function(parts){\n // this is a factory function for building a function-of-no-args-that-returns-a-thenable\n // note the save process is complicated and should only be done via dn.save in save.js\n var has_body = parts.body !== undefined;\n var meta = {properties: {}};\n var has_meta = false;\n if(parts.title !== undefined){\n has_meta = true;\n meta['name'] = parts.title;\n }\n if(parts.description !== undefined){\n has_meta = true;\n meta['description'] = parts.description;\n }\n if(parts.syntax !== undefined){\n has_meta = true;\n meta.properties['aceMode'] = parts.syntax;\n }\n if(parts.newline !== undefined){\n has_meta = true;\n meta.properties['newline'] = parts.newline;\n }\n if(parts.tabs !== undefined){\n has_meta = true;\n meta.properties['tabs'] = parts.tabs;\n }\n var is_multipart = has_body && has_meta;\n var params = {'fields': 'version'};\n if(has_body)\n params['uploadType'] = is_multipart ? 'multipart' : 'media';\n\n var headers = {}\n if(is_multipart){\n var boundary = dn.make_multipart_boundary();\n request_body = \"--\" + boundary\n + \"\\nContent-Type: application/json; charset=UTF-8\\n\\n\" \n + JSON.stringify(meta) \n + \"\\n--\" + boundary\n + \"\\nContent-Type: \" + parts.mimeType + \"; charset=UTF-8\\n\\n\" \n + parts.body\n + \"\\n--\" + boundary + \"--\" ;\n headers['Content-Type'] = 'multipart/related; boundary=\"' + boundary+'\"';\n // TODO: check if we need to add the content length ourselves\n // Content-Length: number_of_bytes_in_entire_request_body\n }else if(has_body){\n request_body = parts.body;\n headers[\"Content-Type\"] = parts.mimeType;\n } else {\n request_body = JSON.stringify(meta);\n }\n\n return function(){\n return gapi.client.request({\n 'path': (has_body ? '/upload' : '') + '/drive/v3/files/' + dn.the_file.file_id,\n 'method': 'PATCH',\n 'params' : params,\n 'headers' : headers,\n 'body' : request_body\n });\n }\n\n}\n\ndn.request_app_data_document = function(){\n return new Promise(function(succ, fail){\n\n // we want one error handler for loading, and one for subsequent errors, but the API doesn't\n // distinguish between the two, so it's up to us to do so....\n dn.app_data_realtime_error = function(err){\n if(dn.status.realtime_settings < 1){\n fail(err);\n }else{\n if(err.type === \"token_refresh_required\"){\n dn.pr_auth.reject(err);\n } else {\n console.dir(err);\n dn.show_error(\"\" + err);\n }\n }\n }\n\n gapi.drive.realtime.loadAppDataDocument(succ, null, dn.app_data_realtime_error);\n // the null argument is an omptional function for handling the initialization\n // the first time the document is loaded;\n });\n}\n\n\n//*\ndn.request_screw_up_auth_counter = 0;\ndn.request_screw_up_auth = function(){\n if(++dn.request_screw_up_auth_counter < 10){\n console.log(\"INVALIDATING TOKEN\")\n gapi.auth.setToken(\"this_is_no_longer_valid\");\n }\n return true;\n}\n//*/","\"use strict\";\n/*\n Note that the find history list has its most recent entries at the 0-end, but\n the clipboard tool has its most recent entries at the other end.\n\n*/\ndn.clipboard_tool = (function(const_){\n\nvar is_active = false;\nvar showing_pane = false; // there is a delay after being active before we show the pane, note the public is_active method actually uses this value\nvar clipboard_index = -1;\nvar clipboard_info_timer = 0;\n\nvar document_clipboard_left = function(e){\n if(!is_active)\n return false;\n if(clipboard_index <= 0)\n return true;\n clipboard_index--;\n dn.editor.undo();\n dn.editor.insert(dn.g_clipboard.get(clipboard_index));\n return true;\n}\n\nvar document_clipboard_right = function(e){\n if(!is_active)\n return false;\n\n dn.g_atomic_exec(function(){\n if(clipboard_index >= dn.g_clipboard.length-1)\n return true;\n clipboard_index++;\n dn.editor.undo();\n dn.editor.insert(dn.g_clipboard.get(clipboard_index));\n })\n return true;\n}\n\nvar document_clipboard_keyup = function(e){\n if(e.which == 17 || e.which == 91 || !e.ctrlKey){\n document.removeEventListener('keyup', document_clipboard_keyup);\n is_active = false;\n if(showing_pane){\n showing_pane = false;\n dn.show_pane(dn.g_settings.get('pane'));\n dn.toggle_widget(dn.g_settings.get('pane_open'));\n }\n if(clipboard_info_timer){\n clearTimeout(clipboard_info_timer);\n clipboard_info_timer = null;\n }\n }\n}\n\nvar on_paste = function(e){\n if (dn.g_clipboard === undefined)\n return; // don't bother implementing anything until cloud settings are properly loaded\n var text = e.text || \"\";\n is_active = true; \n document.addEventListener('keyup', document_clipboard_keyup);\n \n clipboard_index = dn.g_clipboard.lastIndexOf(text); \n if(clipboard_index == -1){ //it's possible the user copied some text from outside the DN, in which case we will add it to the clipboard now\n clipboard_index = dn.g_clipboard.push(text);\n if(dn.g_clipboard.length > const_.clipboard_max_length){\n clipboard_index--;\n dn.g_clipboard.remove(0);\n }\n }\n if(clipboard_info_timer)\n clearTimeout(clipboard_info_timer);\n\n clipboard_info_timer = setTimeout(function(){\n clipboard_info_timer = null;\n showing_pane = true; // this prevents g_settings 'pane_open' and 'pane' updates from being rendered\n dn.toggle_widget(true); // we can then temporarily exert manual control over the rendering of pane and pane_open\n dn.show_pane('pane_clipboard');\n }, const_.clipboard_info_delay);\n}\n\nvar on_copy = function(text){\n if (dn.g_clipboard === undefined)\n return; // don't bother implementing anything until cloud settings are properly loaded\n text = text || \"\";\n dn.g_atomic_exec(function(){\n\n var previous_idx = dn.g_clipboard.lastIndexOf(text); \n if(previous_idx === -1){\n // text is new, add it to the end of the clipboard\n dn.g_clipboard.push(text);\n if(dn.g_clipboard.length > const_.clipboard_max_length)\n dn.g_clipboard.remove(0); \n }else{\n // the text already exists in the clipboard history, lets bring it to the front\n dn.g_clipboard.move(previous_idx, 0)\n }\n\n }); //g_atomic_exec\n\n}\n\n\nvar on_document_ready = function(){\n dn.editor.on(\"paste\", on_paste);\n dn.editor.on(\"copy\", on_copy);\n}\n\n\nreturn {\n on_document_ready: on_document_ready,\n on_left: document_clipboard_left, // this and...\n on_right: document_clipboard_right, // this, are registered in keyboard.js\n is_active: function(){return showing_pane}\n};\n\n})(dn.const_);\n\n","\"use strict\";\n\ndn.save_pending_requests = [];\n\ndn.SaveTracker = function(){\n this.local = undefined;\n this.remote = undefined;\n return this;\n}\n\ndn.save_local_version_counter = 0;\n\n// this list tracks the state of the server, to the best of our knowledge,\n// i.e. based on all the respones we have recieved to date (we use the \n// server's \"version\" number to ensure we maintain the same chronology as the server).\ndn.save_server_state = {};\n\n// this is similar to the above but holds SaveRequest instances. Every time\n// we construct a new SaveRequest, we update this list.\ndn.save_local_state = { };\n\n\ndn.save = function(parts, correction_with_undo_id){\n // this is the only method that should be called by other bits of the program\n\n if(!dn.status.user_wants_file){\n // this is the first sign the user has given that they actually want a file \n // i.e. they want a new file to be created.\n // This is different to all other saves because we wait for it to return before\n // issuing any later requests, although we can still put requests into the queue.\n dn.create_file(); // this only saves the title, it will set user_wants_file to 1, \n // and evetunally settle the Promise dn.pr_file_loaded.\n parts.title = undefined; // we don't need to deal with title here\n }\n\n // update the status, and deal undo manager tracking...\n var found_something = false;\n if(parts.body !== undefined){\n var editor_undo_id = correction_with_undo_id === undefined ? \n dn.editor.getSession().getUndoManager().getCurrentId()\n : correction_with_undo_id;\n if(dn.save_undo_id === editor_undo_id){ // during correction requests, save_undo_id will already be NaN, so this test will fail\n delete parts.body; // no need to save the body if it's already on the server\n // TODO: actually, saves could be in progress, in which case we don't actually know for sure what is on the server\n // i.e. you might want to send an \"undo\" save before a mistake save has completed\n } else {\n found_something = true;\n dn.save_undo_id = NaN; // while we are saving the body the document can only be \"dirty\"\n parts.undo_id = editor_undo_id; // TODO: when making corrections, we need to copy this across\n dn.check_unsaved();\n parts.mimeType = parts.mimeType || dn.the_file.chosen_mime_type;\n dn.status.save_body = 0;\n }\n }\n if(parts.title !== undefined){\n found_something = true;\n dn.status.save_title = 0;\n }\n if(parts.syntax !== undefined ||\n parts.description !== undefined ||\n parts.newline !== undefined ||\n parts.tabs !== undefined){\n found_something = true;\n dn.status.save_other = 0;\n }\n \n if(!found_something)\n return;\n\n dn.show_status();\n\n // and construct the (complicated) request..\n dn.save_pending_requests.push(new dn.SaveRequest(parts));\n}\n\ndn.SaveRequest = function(parts){\n //console.log(\"SaveRequest: \" + JSON.stringify(parts));\n this._parts = parts\n\n // update save_local_state \n var displaced_requests = [];\n for(var k in this._parts) if(this._parts.hasOwnProperty(k)){\n if(dn.save_local_state[k] && !dn.save_local_state[k]._is_settled)\n displaced_requests.push(dn.save_local_state[k]);\n dn.save_local_state[k] = this;\n }\n\n // see if any of the displaced requests that are still pending, are no longer desired.\n // We can't competely cancel pending requests, but we can make it known that they\n // should stop trying so hard to complete.\n for(var ii=0; ii< displaced_requests.length; ii++){\n var desired = false; // if displaced_requests[ii] is responsible for any of save_local_state, then it is desired still \n for(var k in dn.save_local_state) if(dn.save_local_state.hasOwnProperty(k))\n if(dn.save_local_state[k] == displaced_requests[ii]){\n desired = true;\n break;\n }\n if(!desired)\n displaced_requests[ii]._desired = false;\n }\n\n\n this._desired = true; // see above description and _throw_if_not_desired, to see how this is used\n this._tracker = new dn.SaveTracker(); // hold local and remote version numbers\n this._tracker.local = ++dn.save_local_version_counter;\n this._is_settled = false;\n this._error = undefined;\n\n var self = this;\n this._pr =\n until_success(function(succ, fail){\n Promise.all([dn.pr_auth, dn.pr_file_loaded])\n .then(self._throw_if_not_desired.bind(self))\n .then(dn.request_save(self._parts))\n .then(self._on_completion.bind(self))\n .then(succ, fail);\n }).before_retry(dn.filter_api_errors)\n .catch(self._on_error.bind(self))\n .then(self._on_finally.bind(self))\n\n return this;\n}\n\ndn.SaveRequest.prototype._throw_if_not_desired = function(){\n if(!this._desired)\n throw \"not desired\"; //caught by on_error, and turned into success\n return true;\n}\n\ndn.SaveRequest.prototype._on_error = function(err){\n if(err !== \"not desired\")\n this._error = err; // an actual error, record it\n}\n\ndn.SaveRequest.prototype._on_completion = function(res){\n this._tracker.remote = parseInt(res.result.version);\n // update 0 or more entries in dn.save_server_state (see description above)\n for(var k in this._parts) if(this._parts.hasOwnProperty(k)){\n if(dn.save_server_state[k] === undefined)\n dn.save_server_state[k] = new dn.SaveTracker();\n if(dn.save_server_state[k].remote === undefined || this._tracker.remote > dn.save_server_state[k].remote){\n dn.save_server_state[k].remote = this._tracker.remote;\n dn.save_server_state[k].local = this._tracker.local;\n }\n } \n return true; \n}\n\ndn.SaveRequest.prototype._on_finally = function(){\n // called when the until_success deems that success has occured\n // but that means the request was a legitimate failure, or canaceled,\n // though at this point we don't care what happened exactly.\n\n if(this._error !== undefined){\n dn.show_error(\"Saving failed. \" + dn.api_error_to_string(this._error));\n console.dir(this._error);\n // abandon all requests, but note they may still continue executing\n while(dn.save_pending_requests.length)\n dn.save_pending_requests.pop()._desired = false;\n // and reset out records to be totally \"naive\"\n dn.save_server_state = {};\n dn.save_local_state = {};\n \n // show that we're no longer trying to save...\n dn.status.save_body = 1;\n dn.status.save_title = 1;\n dn.status.save_other = 1;\n dn.show_status();\n return;\n }\n\n // remove from the list of pending requests\n this._is_settled = true;\n dn.save_pending_requests.splice(dn.save_pending_requests.indexOf(this), 1);\n\n // if other requests are still pending, let them clean up any mess when they're done..\n // TODO: actually, we could do this separately for each key in save_*_state.\n if(dn.save_pending_requests.length > 0)\n return;\n\n // dn.save_local_state holds the state we want the server to have, and \n // dn.save_server_state holds the state the server ended up with \n // (and remember there are no pending requests), so lets build a list\n // of corrections to make to the server\n var correction = {};\n var correction_need = false;\n for(var k in dn.save_local_state) if(dn.save_local_state.hasOwnProperty(k))\n if(dn.save_server_state[k].local !== dn.save_local_state[k]._tracker.local){\n correction[k] = dn.save_local_state[k]._parts[k];\n correction_need = true;\n }\n\n // and now we can make the request, if we need to..\n dn.status.save_body = 1; \n dn.status.save_title = 1;\n dn.status.save_other = 1;\n\n var local_undo_id = dn.save_local_state.body ? dn.save_local_state.body._parts.undo_id : undefined;\n if(correction.body === undefined && local_undo_id !== undefined){\n dn.save_undo_id = dn.save_local_state.body._parts.undo_id; // we know the server now has this undo point\n dn.check_unsaved();\n }\n\n if (correction_need)\n dn.save(correction, local_undo_id); // this will set some of the status's to 0 and call show_status\n else\n dn.show_status();\n\n}\n\n\n\n\n","\"use strict\";\n\ndn.do_print = (function(){\n\n\n var line_to_html = function (n){\n var printLayer = Object.create(ace.require('ace/layer/text').Text.prototype); \n var tokens = dn.editor.getSession().getTokens(n);\n var html = [];\n var screenColumn = 0;\n for (var i = 0; i < tokens.length; i++) {\n var token = tokens[i];\n var value = token.value.replace(/\\t/g,' ');//TODO:deal with tabs properly\n if(value)\n printLayer.$renderToken(html, 0, token, value);\n }\n return html.join('').replace(/ /g,' ');\n}\n\nreturn function(){\n var content = dn.editor.session.doc.getAllLines();\n var html = Array(content.length);\n\n for(var i=0; i
\" + line_to_html(i) + '
';\n\n var printWindow = window.open('','');\n printWindow.document.writeln(\n \"\" + dn.the_file.title \n + \"\" + \n \"
    \" + \n html.join(\"\") +\n \"
\");\n printWindow.print();\n return false;\n}\n\n\n})()\n","\"use strict\";\ndn.file_pane = (function(){\n\n// this uses an MVC paradigm, with the model described in file_model.js\n\nvar el = {};\n\nvar history_active = false;\n\n// non-MVC functions ::::::::::::::::::::::::::::::::::\n\nvar do_save = function (e){\n e.preventDefault(); //needed for when called as shortcut\n if(dn.the_file.is_read_only)\n return dn.show_error(\"Cannot save read-only file.\");\n dn.save({body: dn.editor.getSession().getValue()});\n}\n\nvar read_only_bail = function(e){\n dn.show_error(\"The file is read-only, so you cannot change its properties.\");\n e.preventDefault(); // probably redundant here\n}\n\nvar on_title_begin_edit = function(e){ \n if(dn.the_file.is_read_only)\n return read_only_bail(e); \n el.title_text.style.display = 'none';\n el.title_input.style.display = '';\n el.title_input.focus();\n el.title_input.select();\n}\n\nvar on_title_keydown = function(e){\n if(e.which == WHICH.ESC){\n el.title_input.value = dn.the_file.title;\n e.stopPropagation();\n dn.focus_editor();\n }else if(e.which === WHICH.ENTER){\n e.preventDefault();\n dn.focus_editor(); // calls blur\n }\n}\n\nvar on_description_begin_edit =function(e){ \n if(dn.the_file.is_read_only)\n return read_only_bail(e); \n el.description_text.style.display = 'none';\n el.description_input.style.display = '';\n el.description_input.focus();\n el.description_input.select();\n}\n\nvar on_description_keydown = function(e){\n if(e.which == WHICH.ESC){\n el.description_input.value = dn.the_file.description;\n e.stopPropagation();\n dn.focus_editor();\n } else if(e.which === WHICH.ENTER && !e.ctrlKey && !e.shiftKey){\n e.preventDefault();\n dn.focus_editor(); // calls blur\n }\n}\n\nvar do_share = function(){\n Promise.resolve(dn.pr_file_loaded)\n .then(function(){\n dn.status.file_sharing = -1; //TODO: see SO question about no callback for share dialog...how are we supposed to know when it's closed and what happened?\n dn.the_file.is_shared = 0;\n dn.show_status();\n\n if(el.share_dialog){\n do_share_sub();\n } else {\n gapi.load('drive-share', function(){\n el.share_dialog = new gapi.drive.share.ShareClient(dn.client_id);\n do_share_sub();\n });\n }\n });\n}\n\nvar do_share_sub = function(){\n el.share_dialog.setItemIds([dn.the_file.file_id]);\n el.share_dialog.setOAuthToken(gapi.auth.getToken().access_token);\n el.share_dialog.showSettingsDialog();\n}\n\nvar do_print = dn.do_print;\n\n\n// controler functions ::::::::::::::::::::::::::::::::::\n\nvar on_description_end_edit = function(){\n el.description_input.style.display = 'none';\n el.description_text.style.display = '';\n var new_val = el.description_input.value;\n if(dn.the_file.description !== new_val){\n dn.the_file.set({description: new_val}); \n dn.save({description: new_val});\n }\n dn.focus_editor();\n}\n\nvar on_title_end_edit = function(){\n el.title_input.style.display = 'none';\n el.title_text.style.display = '';\n var new_val = el.title_input.value;\n if(dn.the_file.title !== new_val){\n dn.the_file.set({title: new_val});\n dn.save({title: new_val});\n }\n dn.focus_editor();\n}\n\nvar on_newline_click = function(e){\n if(dn.the_file.is_read_only)\n return read_only_bail(e); \n\n var val = \"detect\";\n if(e.currentTarget === el.newline_unix)\n val = \"unix\";\n else if (e.currentTarget === el.newline_windows)\n val = \"windows\";\n dn.the_file.set({newline: val});\n dn.save({newline: val});\n}\n\nvar on_syntax_detect_click = function(e){\n if(dn.the_file.is_read_only)\n return read_only_bail(e); \n\n dn.the_file.set({syntax: \"detect\"});\n dn.save({syntax: \"detect\"});\n}\n\nvar on_syntax_dropdown_click = function(e){\n if(dn.the_file.is_read_only)\n return read_only_bail(e); \n\n var val = syntax_drop_down.GetVal();\n dn.save({syntax: val}); \n dn.the_file.set({syntax: val});\n}\n\nvar on_tab_click = function(e){\n if(dn.the_file.is_read_only)\n return read_only_bail(e); \n\n var val = {val: \"detect\"};\n\n if (e.currentTarget === el.tab_soft_inc){\n e.stopPropagation();\n val = {val: \"spaces\",\n n: Math.min(dn.the_file.properties_chosen.tabs.n + 1, dn.const_.max_soft_tab_n)};\n } else if (e.currentTarget === el.tab_soft_dec){\n e.stopPropagation();\n var n = dn.the_file.properties_chosen.tabs.n - 1;\n val = {val: \"spaces\",\n n: Math.max(dn.the_file.properties_chosen.tabs.n - 1, dn.const_.min_soft_tab_n)};\n }else if(e.currentTarget === el.tab_soft){\n val = {val: \"spaces\", n: dn.the_file.properties_chosen.tabs.n};\n } else if(e.currentTarget === el.tab_hard){\n val = {val: \"tab\", n: dn.the_file.properties_chosen.tabs.n};\n }\n\n dn.the_file.set({tabs: val});\n dn.save({tabs: JSON.stringify(val)});\n}\n\n// view functions ::::::::::::::::::::::::::::::::::\n\nvar render_title = function(){\n el.title_text_inner.textContent = dn.the_file.title;\n el.title_input.value = dn.the_file.title;\n}\n\nvar render_description = function(){\n text_multi(el.description_text_inner, dn.the_file.description, true);\n el.description_input.value = dn.the_file.description;\n}\n\nvar render_newline = function(){\n el.newline_detect.classList.remove('selected');\n el.newline_windows.classList.remove('selected');\n el.newline_unix.classList.remove('selected');\n var val = dn.the_file.properties.newline;\n if(val === \"detect\")\n el.newline_detect.classList.add('selected');\n else if(val === \"windows\")\n el.newline_windows.classList.add('selected');\n else\n el.newline_unix.classList.add('selected'); \n el.newline_info.textContent = dn.the_file.properties_detected_info.newline; \n}\n\nvar render_syntax = function(){\n syntax_drop_down.SetInd(syntax_drop_down.IndexOf(dn.the_file.properties_chosen.syntax), true);\n if(dn.the_file.properties.syntax === \"detect\"){\n el.ace_mode_detect.classList.add('selected');\n syntax_drop_down.SetSelected(false);\n }else{\n el.ace_mode_detect.classList.remove('selected');\n syntax_drop_down.SetSelected(true);\n }\n el.ace_mode_info.textContent = dn.the_file.properties_detected_info.syntax;\n}\n\nvar render_tabs = function(){\n var user_tabs = dn.the_file.properties.tabs;\n\n el.tab_soft.classList.remove('selected');\n el.tab_hard.classList.remove('selected');\n el.tab_detect.classList.remove('selected');\n\n if(user_tabs.val === \"tab\")\n el.tab_hard.classList.add('selected');\n else if(user_tabs.val === \"spaces\")\n el.tab_soft.classList.add('selected');\n else\n el.tab_detect.classList.add('selected');\n \n el.tab_soft_text.textContent = dn.the_file.properties_chosen.tabs.n;\n el.tab_info.textContent = dn.the_file.properties_detected_info.tabs;\n}\n\nvar end_history = function(){\n if(!history_active)\n return;\n dn.history_tool.end();\n el.button_history.classList.remove('selected');\n el.button_save.style.display = '';\n el.button_print.style.display = '';\n el.inner_pane_history.style.display = 'none';\n el.inner_pane_main.style.display = '';\n history_active = false;\n}\n\nvar do_history = function(){\n Promise.resolve(dn.pr_file_loaded)\n .then(function(){\n el.button_history.classList.add('selected');\n el.button_save.style.display = 'none';\n el.button_print.style.display = 'none';\n el.inner_pane_history.style.display = '';\n el.inner_pane_main.style.display = 'none';\n dn.history_tool.start();\n history_active = true; \n });\n}\n\nvar syntax_drop_down;\n\nvar register_controllers = function(){\n // We wait until the file model is loaded before registering all these controllers.\n // Note that when creating a new file, the file model is said to be loaded before\n // we get the file_id back from the server, that is because we don't need to wait\n // for the server to tell us about existing metadata. In this pre-file_id state,\n // we can issue save requests because the save machienery knows to queued them\n // up until it the file_id is available.\n\n // title and description\n\n el.title_text.addEventListener('click', on_title_begin_edit) \n el.title_input.addEventListener(\"blur\", on_title_end_edit); \n el.title_input.addEventListener('keydown', on_title_keydown);\n\n el.description_text.addEventListener('click', on_description_begin_edit) \n el.description_input.addEventListener(\"blur\", on_description_end_edit); \n el.description_input.addEventListener('keydown', on_description_keydown);\n\n // File custom props stuff, make use of currentTarget to identify src\n\n el.newline_detect.addEventListener('click', on_newline_click);\n el.newline_windows.addEventListener('click', on_newline_click);\n el.newline_unix.addEventListener('click', on_newline_click);\n\n el.tab_detect.addEventListener('click', on_tab_click);\n el.tab_hard.addEventListener('click', on_tab_click);\n el.tab_soft_inc.addEventListener('click', on_tab_click);\n el.tab_soft_dec.addEventListener('click', on_tab_click);\n el.tab_soft.addEventListener('click', on_tab_click); // propagation is stopped if inc or dec are clicked rather than the base button\n\n el.ace_mode_detect.addEventListener('click', on_syntax_detect_click); \n syntax_drop_down.enabled = true; \n syntax_drop_down.addEventListener(\"click\", on_syntax_dropdown_click);\n syntax_drop_down.addEventListener(\"change\", on_syntax_dropdown_click);\n\n // File action buttons stuff\n el.button_save.addEventListener('click', do_save);\n el.button_print.addEventListener('click', do_print);\n el.button_share.addEventListener('click', do_share);\n el.button_history.addEventListener('click', function(){\n if(history_active)\n end_history();\n else \n do_history();\n });\n}\n\nvar on_document_ready = function(){\n el.title_input = document.getElementById('details_file_title_input');\n el.title_text = document.getElementById('details_file_title_text');\n el.title_text_inner = document.getElementById('details_file_title_text_inner');\n el.description_input = document.getElementById('details_file_description_input');\n el.description_text = document.getElementById('details_file_description_text'); \n el.description_text_inner = document.getElementById('details_file_description_text_inner'); \n el.ace_mode_choose = document.getElementById('file_ace_mode_choose')\n el.ace_mode_detect = document.getElementById('file_ace_mode_detect');\n el.ace_mode_info = document.getElementById('file_ace_mode_info');\n el.newline_detect = document.getElementById('file_newline_detect');\n el.newline_windows = document.getElementById('file_newline_windows');\n el.newline_unix = document.getElementById('file_newline_unix');\n el.newline_info = document.getElementById('file_newline_info');\n el.tab_detect = document.getElementById('file_tab_detect');\n el.tab_soft_inc = document.getElementById('file_tab_soft_inc');\n el.tab_soft_dec = document.getElementById('file_tab_soft_dec');\n el.tab_hard = document.getElementById('file_tab_hard');\n el.tab_soft = document.getElementById('file_tab_soft');\n el.tab_soft_text = document.getElementById('file_tab_soft_text');\n el.tab_info = document.getElementById('file_tab_info');\n el.button_save = document.getElementById('button_save');\n el.button_print = document.getElementById('button_print');\n el.button_share = document.getElementById('button_share');\n el.button_history = document.getElementById('button_history'); \n el.inner_pane_main = document.getElementById('pane_file_main'); \n el.inner_pane_history = document.getElementById('pane_file_history'); \n \n var modes = require(\"ace/ext/modelist\").modes; \n syntax_drop_down = new DropDown(modes.map(function(m){return m.caption;}));\n syntax_drop_down.enabled = false;\n el.ace_mode_choose.appendChild(syntax_drop_down.el); \n\n dn.history_tool.on_document_ready();\n\n dn.the_file.addEventListener('change', function(e){\n switch(e.property){\n case \"syntax\":\n render_syntax();\n break;\n\n case \"newline\":\n render_newline();\n break;\n\n case \"tabs\":\n render_tabs();\n break;\n\n case \"title\":\n render_title();\n break;\n\n case \"description\":\n render_description();\n break;\n\n case \"is_loaded\":\n register_controllers();\n break;\n }\n })\n\n}\n\n\n\nreturn {\n on_save_shorcut: do_save,\n on_print_shortcut: do_print,\n on_document_ready: on_document_ready,\n on_close_pane: end_history,\n do_history: function(e){\n e.preventDefault();\n dn.g_settings.set('pane', 'pane_file');\n dn.g_settings.set('pane_open', true);\n do_history();\n }\n}\n\n\n\n})();","\n/*\nThe following would probably have been better implemented as a fork of ace. We basically add to and overwrite whatever methods\nwe need to in order to acomplish our goals. It's not pretty, but hopefully it's not appaling, given what the result is.\n\nThe main method exposed to the \"user\" is show_rows, which accepts a 1d array of 0s,1s,2s, and 3s. There is one entry for\neach of the lines in the document. 0 means hide the row, 1 means show it in white, 2 means render it marked as \"added\", \nand 3 means render it marked as \"removed\".\n\nThe implementation tries to use as much of ace's machienry as possible, but does have to build some of its own. \n\nLines are hidden using ace's folding system, with the fold-markers being hidden with css.\n\nThe gutter numbering is overridden with a custom gutterRenderer.\n\nLines are marked with ace's addMarker and addGutterDecoration, but transitions are implemented \"manually\"...every time\nace completes its rendering, we explicitly apply our own styling logic to the markers it has produced. Specifically, \nwe modify the markers that were already visible the last time there was a render, with the state of the markers tracked\nwith the array rendered_row_transitions (and the variable first_rendered_row). i.e. markers off-screeen, or newly on screen\nare not transitioned to their final state.\n\nI would ideally like to animate the height transition from show_row[ii] = 0, to show_row[ii] > 0. But that is going to require\na lot more messing around with ace.\n\nSome of the css in app.css is critical to making this look right, but we also have some styles hardcoded here. That's obviously \nnot ideal.\n\ninsertFullLines has also been overriden to ensure the show_rows is updated when lines are inserted.\nIt is intended that the document is only modified using that method, i.e. it is readOnly and no other insertion/deletion methods are used.\n\n\nTODO:\n transitions possibly dont work on the last line of the document.\n*/\n\ndn.patch_editor_history = function(editor){\n var Range = ace.require('./range').Range;\n var dom = ace.require(\"./lib/dom\");\n\n var show_row = [];\n var row_line_number = [0];\n var markers = [];\n var first_rendered_row = -1;\n var rendered_row_transitions = []; // array of {from_time, to_time, from_color, to_color}, first element is first_rendered_row\n var colors_background = [0xffffff, 0xffffff, 0xbcebe8, 0xffcaca]; //0,1,2,3, TODO: expose this as a setting, or read from css\n var transition_duration = 1000; // ms\n editor.$blockScrolling = Infinity;\n editor.setHighlightActiveLine(false);\n editor.setHighlightGutterLine(false);\n\n // Note that unlike other patches below, this bit changes the actual Range prototype for everyone\n // we need to keep the doc range, so we can porvide data-row when rendering markers\n Range.prototype.toScreenRange = function(session) {\n var screenPosStart = session.documentToScreenPosition(this.start);\n var screenPosEnd = session.documentToScreenPosition(this.end);\n\n ret = new Range(\n screenPosStart.row, screenPosStart.column,\n screenPosEnd.row, screenPosEnd.column\n );\n ret.doc_range = this.clone();\n return ret;\n };\n \n\n editor.session.gutterRenderer = {\n getWidth: function(session, lastLineNumber, config) {\n return (\"\" + row_line_number[row_line_number.length-1]).length * config.characterWidth;\n },\n getText: function(session, row) {\n if(row >= row_line_number.length)\n return \"\" + row;\n return row_line_number[row] === -1 ? \"-\" : row_line_number[row];\n }\n };\n\n editor.session.removeAllGutterDecorations = function(){\n for(var ii=0; ii\"\n );\n };\n\n var insertFullLines_original = editor.session.doc.insertFullLines;\n editor.session.doc.insertFullLines = function(arg_0, arg_1){\n // Takes either two args: at, lines[]\n // or 1 arg: [{at, lines}, {at, lines}, ...]\n // in the first case, if at=-1, we reset using the new data.\n if(arg_0 === -1){\n show_row = new Uint8Array(arg_1.length);\n for(var ii=0;ii first_row ) {\n // add some finished-transitioning rows at the start\n for(var row=Math.min(last_row, first_row_old)-1; row>=first_row; row--){\n rendered_row_transitions.unshift({row: row,\n from_time: undefined,\n from_color: undefined,\n to_time: time_now,\n to_color: colors_background[show_row[row]]});\n }\n }\n\n // Get the randomly ordered marker elements into a simple map from row to element\n var all_marker_els = editor.renderer.$markerBack.element.children;\n var marker_els = [];\n for(var ii=0; ii time_now){\n // transition unfinished\n var elapsed_frac = (time_now - transition.from_time)/ (transition.to_time - transition.from_time); // denom is just transition_duration, unless we make things more complicated \n current_color = mix_color(transition.from_color, transition.to_color, elapsed_frac);\n }else{\n // last transition already finished\n current_color = transition.to_color;\n }\n if(transition.to_color !== to_color_new){\n // new transition\n transition.from_color = current_color; \n transition.from_time = time_now;\n transition.to_time = time_now + transition_duration;\n transition.to_color = to_color_new;\n }\n el.style.backgroundColor = color_to_string(current_color);\n if(transition.to_time > time_now){\n el.style.transitionProperty = ''; // force the color above to take effect before we call getComputedStyle, below (not sure this is neccessarry)\n el.style.transitionDuration = (transition.to_time - time_now) + \"ms\";\n els_to_set.push(el);\n colors_to_set.push(to_color_new);\n colors_current.push(current_color);\n }\n }\n if(els_to_set.length)\n window.getComputedStyle(els_to_set[0]).backgroundColor;\n\n while(els_to_set.length){\n var el = els_to_set.pop();\n el.style.transitionProperty = 'background-color';\n el.style.backgroundColor = color_to_string(colors_to_set.pop());\n }\n\n if(last_row_old > last_row){\n // remove unneeded rows from the end\n for(row=last_row_old-1; row>=last_row && row>=first_row_old; row--)\n rendered_row_transitions.pop();\n \n } else if(last_row_old < last_row) {\n // add some finished-transitioning rows at the end\n for(row=Math.max(last_row_old, first_row); row>16)*(1-frac) + ((b&0xff0000)>>16)*frac) << 16 ) |\n ((((a&0xff00)>>8)*(1-frac) + ((b&0xff00)>>8)*frac) << 8) |\n (a&0xff)*(1-frac) + ((b&0xff)*frac);\n }\n var color_to_string = function(color){\n return \"rgb(\" + ((color & 0xff0000) >> 16) + \", \" + ((color & 0xff00) >> 8) + \", \" + (color & 0xff) + \")\";\n }\n\n editor.show_rows = function(show_row_){\n /* show_row is a 1d array the same length as the number of lines in the document,\n entries that are falsey are silently folded, the remaining rows have their \n numbering altered.\n show_row[ii]>=1 are marked with the class \"special_2\", \"special_3\", etc,\n and the gutter is marked with gutter_special_2, _3, etc..\n\n show_row[ii]=3, is shown, but doesn't have a line number\n\n TODO: check zero-hack for when nothing is showing and/or there are no rows,\n and possibly other variations on that.\n */\n show_row = new Uint8Array(show_row_); //clone from whatever kind of array show_row_ was\n\n var n = editor.session.doc.getLength();\n if(show_row.length !== n) \n throw \"bad mask length\";\n\n editor.session.unfold();\n while(markers.length)\n editor.session.removeMarker(markers.pop());\n editor.session.removeAllGutterDecorations();\n\n var line_no = 0;\n var fold_start = -1;\n row_line_number = [];\n var first_used_row = -1;\n for(var ii=0; ii 0){\n editor.session.addFold(\"\", new Range(fold_start-1, Infinity, ii-1, Infinity));\n } else {\n // TODO: folding the lines from the very top is a bit messier...\n // it may be this version 0,0 rather than Inf, Inf version can be used more generally,\n // but it requires changing various other things too.\n editor.session.addFold(\"\", new Range(0, 0, ii, 0));\n row_line_number[0] = 1;\n first_used_row = ii;\n }\n }\n fold_start = -1;\n }else{\n row_line_number.push(line_no);\n if(fold_start === -1)\n fold_start = ii;\n }\n }\n if(fold_start !== -1)\n editor.session.addFold(\"\", new Range(fold_start-1, Infinity, ii-1, Infinity));\n\n var previous = -1;\n if(first_used_row !== -1){\n //dealing further with the top-row hack thing...it's confusing, but this does the job...\n if(show_row[first_used_row]>=1)\n editor.session.addGutterDecoration(0, \"gutter_special_\" + show_row[first_used_row]);\n }\n for(var ii=0; ii=1){\n markers.push(editor.session.addMarker(new Range(ii, 0, ii, Infinity),\n \"special_\" + show_row[ii] + (previous !== show_row[ii] ? \"_first\" : \"\"), \"fullLine\", false));\n editor.session.addGutterDecoration(ii, \"gutter_special_\" + show_row[ii]);\n }\n previous = show_row[ii] ? show_row[ii] : previous;\n }\n\n editor.renderer.updateFull();\n };\n\n\n // this isn't that important, but we override the original version here so as to let the cursor blink in readonly mode\n editor.$resetCursorStyle = function() {\n var style = this.$cursorStyle || \"ace\";\n var cursorLayer = this.renderer.$cursorLayer;\n if (!cursorLayer)\n return;\n cursorLayer.setSmoothBlinking(/smooth/.test(style));\n cursorLayer.isBlinking = /*!this.$readOnly && */ style != \"wide\";\n dom.setCssClass(cursorLayer.element, \"ace_slim-cursors\", /slim/.test(style));\n };\n // but we have to disable dragging, or the cursor will stop blinking for some reason on failed drags\n editor.$mouseHandler.setOptions({dragEnabled: false})\n\n}\n","\"use strict\";\n\ndn.history_tool = (function(){\n\nvar el = {};\n\nvar revision_meta = []; // we clear this each time we call refresh_revisions_list\nvar worker_has_revision = {}; // we cache revision bodies on the worker, recording true here when we do using revision id as the key\nvar revision_uses_line = []; // for each revision this has a 1d boolean array, giving 1 if the line is used in that revision.\n // every time we get a \"delivery\" of new lines from the worker we invalidate all of this. In future,\n // when we want to display a particular revision we have to ask the worker for the data.\n\nvar worker;\nvar editor;\nvar at_idx = 0; \nvar from_idx = 0;\n\n\nvar LineWidgets = ace.require(\"./line_widgets\").LineWidgets;\nvar start = function(){\n // TODO: add current state to revisions meta and body\n\n if(worker === undefined){\n worker = new Worker(\"js/history_tool_worker.js\");\n worker.onmessage = on_worker_message;\n }\n\n dn.el.editor.style.display = 'none';\n el.revisions_view.style.display = '';\n el.revisions_view.innerHTML = '';\n el.info_overflow.style.display = '';\n editor = ace.edit(\"revisions_view\");\n editor.setFontSize(dn.editor.getFontSize());\n dn.patch_editor_history(editor); \n editor.session.setUseWrapMode(true);\n editor.setReadOnly(true);\n refresh_revisions_list();\n}\n\nvar end = function(){\n // destroy the editor, and replace its dom element with a newly cloned instance\n // this wipes out any event listeners. https://github.com/ajaxorg/ace/issues/2085\n // also set the element's contents to be empty\n editor.destroy();\n editor = undefined;\n el.revisions_view.innerHTML = '';\n var el_old = el.revisions_view;\n el.revisions_view = el_old.cloneNode(true);\n el_old.parentNode.replaceChild(el.revisions_view, el_old);\n\n dn.el.editor.style.display = ''; \n el.revisions_view.style.display = 'none';\n el.info_overflow.style.display = 'none';\n}\n\nvar get_editor = function(){\n return editor;\n}\n\nvar on_worker_message = function(e){\n if(!editor) return; // if we closed history tool while worker was busy, we can safely ignore the two possible types of message it might be sending\n\n var session = editor.getSession();\n if(e.data.diffed_revision){\n revision_uses_line = []; // invalidate everything we knew about uses_line\n // TODO: perhaps we should batch up the newly delivered data and only append it when the user requests an earlier revision\n if(e.data.diffed_revision.idx === 0){\n session.doc.insertFullLines(-1, e.data.diffed_revision.lines); // resets to supplied lines\n } else {\n session.doc.insertFullLines(e.data.diffed_revision.sections); // inserts multiple batches of lines\n revision_meta[e.data.diffed_revision.idx].el_tick.classList.add('diffed');\n }\n }\n\n if(e.data.line_is_used){\n var idx = e.data.line_is_used.idx;\n revision_uses_line[idx] = new Uint8Array(e.data.line_is_used.buffer);\n if(idx === Math.max(at_idx, from_idx)){\n // hooray, we've got both at and from, lets render 'em, quick!\n if(at_idx === from_idx)\n render_single_revision(at_idx);\n else\n render_revision_pair(at_idx, from_idx);\n }else if(Math.max(at_idx, from_idx) >= e.data.line_is_used.diffed_n && idx == Math.min(at_idx, from_idx)){\n // well, we've got the mroe recent of the two, and the other one is going to be a while, so lets render what we have\n render_single_revision(Math.min(at_idx, from_idx));\n }\n }\n\n\n}\n\n\nvar render_single_revision = function(idx){\n editor.show_rows(revision_uses_line[idx]); // 1=show, 0=hide, which is exactly what we want\n var str = \"\";\n if(idx === 0){\n str = \"Showing the file:\\n\\t\" + current_version_date_str;\n }else{\n var time = date_str_to_local(revision_meta[idx].modifiedTime)\n str = \"Showing file as it was at:\\n\\t\" + time[1] + \" on \" + time[0];\n }\n text_multi(el.info, str);\n}\n\nvar fuse = function(at_is_used, from_is_used){\n // maps: (0,0) => 0 (1,1) => 1 (1,0) => 3 (0,1) => 2\n // TODO: maybe there would have been a slightly clever maping to have chosen, but it doesn't matter much.\n var map = new Uint8Array([0,2,3,1]);\n var show_rows = new Uint8Array(at_is_used.length);\n for(var ii=0; ii< show_rows.length; ii++)\n show_rows[ii] = map[at_is_used[ii] | (from_is_used[ii] << 1)];\n return show_rows;\n}\n\nvar current_version_date_str = \"as it exists in the editor\";\n\nvar render_revision_pair = function(at_idx, from_idx){\n editor.show_rows(fuse(revision_uses_line[at_idx], revision_uses_line[from_idx]));\n\n var str = \"\"\n if(at_idx === 0){\n str += \"Showing the file:\\n\\t\" + current_version_date_str;\n }else{\n var time_at = date_str_to_local(revision_meta[at_idx].modifiedTime);\n str += \"Showing file as it was at:\\n\\t\" + time_at[1] + \" on \" + time_at[0];\n }\n if(from_idx === 0){\n str += \"\\nWith changes relative to the file:\\n\\t\" + current_version_date_str;\n }else{\n var time_from = date_str_to_local(revision_meta[from_idx].modifiedTime);\n str += \"\\nWith changes relative to the file at:\\n\\t\" + time_from[1] + \" on \" + time_from[0];\n }\n text_multi(el.info, str);\n}\n\nvar append_tick = function(){\n var el_tick = document.createElement('div');\n el_tick.classList.add('revision_tick');\n el.tick_box.appendChild(el_tick);\n return el_tick;\n}\n\nvar send_revisions_order_to_worker = function(resp){\n var r_to_get = [], id_order = [];\n revision_meta = revision_meta.concat(resp.result.revisions.reverse()); \n el.at_range.max = revision_meta.length - 1;\n el.from_range.max = revision_meta.length - 1;\n\n for(var ii=1; ii=0\nvar search_history_left_behind_str = \"\"; // although we call update_search_history after every change in search string, \n // it won't always result in modifying the 0th entry in history, in such cases,\n // we record the actual string here so that we can come back to it if we walk the history\nvar search_history_last_modified_time = -1; // set each time we change the history\n\n\n\nvar focus_on_input = function(){\n if(dn.g_settings.get('find_goto'))\n el.goto_input.focus();\n else\n el.find_input.focus();\n}\n\nvar on_document_ready = function(){\n AceSearch = ace.require(\"./search\").Search;\n AceRange = ace.require(\"./range\").Range;\n\n el.button_case_sensitive = document.getElementById('button_find_case_sensitive');\n el.button_whole_words = document.getElementById('button_find_whole_words');\n el.button_regex = document.getElementById('button_find_regex');\n el.find_input = document.getElementById('find_input');\n el.goto_input = document.getElementById('goto_input');\n el.replace_input = document.getElementById('find_replace_input');\n el.info = document.getElementById('find_info');\n el.search_results = document.getElementById('find_results');\n el.info_overflow = document.getElementById('find_info_overflow');\n el.button_goto = document.getElementById('button_goto');\n el.button_replace = document.getElementById('button_replace');\n el.goto_wrapper = document.getElementById('find_goto_wrapper');\n el.find_wrapper = document.getElementById('find_find_wrapper');\n el.replace_wrapper = document.getElementById('find_replace_wrapper');\n el.button_find_replace_all = document.getElementById('button_find_replace_all');\n\n dn.g_settings.addEventListener('VALUE_CHANGED', function(e){\n var new_value = e.newValue;\n switch(e.property){\n case 'find_regex':\n if(new_value)\n el.button_regex.classList.add('selected');\n else\n el.button_regex.classList.remove('selected');\n settings_changed();\n break;\n\n case 'find_whole_words':\n if(new_value)\n el.button_whole_words.classList.add('selected');\n else\n el.button_whole_words.classList.remove('selected');\n settings_changed();\n break;\n\n case 'find_case_sensitive':\n if(new_value)\n el.button_case_sensitive.classList.add('selected');\n else\n el.button_case_sensitive.classList.remove('selected');\n settings_changed();\n break;\n\n case 'find_replace':\n on_replace_toggled(new_value);\n break;\n\n case 'find_goto':\n on_goto_toggled(new_value);\n break;\n }\n })\n\n el.button_case_sensitive.addEventListener('click', function(){\n dn.g_settings.set('find_case_sensitive', !dn.g_settings.get('find_case_sensitive'));\n })\n el.button_whole_words.addEventListener('click', function(){\n dn.g_settings.set('find_whole_words', !dn.g_settings.get('find_whole_words'));\n })\n el.button_regex.addEventListener('click', function(){\n dn.g_settings.set('find_regex', !dn.g_settings.get('find_regex'));\n })\n el.goto_input.addEventListener('keydown', goto_input_keydown);\n el.goto_input.addEventListener('keyup', goto_input_keyup);\n el.goto_input.addEventListener('blur', goto_input_blur);\n el.goto_input.addEventListener('focus', goto_input_focus);\n el.find_input.addEventListener('keyup', find_input_keyup);\n el.find_input.addEventListener('keydown', find_input_keydown);\n el.find_input.addEventListener('blur', search_inputs_blur);\n el.find_input.addEventListener('focus', search_inputs_focus);\n el.replace_input.addEventListener('blur', search_inputs_blur);\n el.replace_input.addEventListener('focus', search_inputs_focus);\n el.replace_input.addEventListener('keydown', replace_input_keydown);\n el.button_find_replace_all.addEventListener('click', replace_all);\n el.button_replace.addEventListener('click', function(){\n dn.g_settings.set('find_replace', !dn.g_settings.get('find_replace'));\n dn.g_settings.set('find_goto', false);\n el.find_input.focus();\n })\n el.button_goto.addEventListener('click', function(){\n dn.g_settings.set('find_goto', !dn.g_settings.get('find_goto'));\n if(dn.g_settings.get('find_goto'))\n el.goto_input.focus();\n else\n el.find_input.focus();\n })\n}\n\nvar find_shortcut_used = function(e){\n var sel = dn.editor.session.getTextRange(dn.editor.getSelectionRange());\n dn.g_settings.set('find_goto', false);\n dn.g_settings.set('pane', 'pane_find');\n dn.g_settings.set('pane_open', true);\n if(sel){\n if(sel !== search_str){\n search_str = sel;\n search_history_idx = -1;\n update_search_history();\n }\n el.find_input.value = sel;\n el.find_input.select();\n }\n el.find_input.focus();\n e.preventDefault();\n}\n\nvar goto_shortcut_used = function(e){\n dn.g_settings.set('find_goto', true);\n dn.g_settings.set('pane', 'pane_find'); // doing this after the find_active=true, tells the change handler not to put focus back to editor\n dn.g_settings.set('pane_open', true);\n el.goto_input.focus();\n e.preventDefault();\n}\n\nvar replace_shortcut_used = function(e){\n dn.g_settings.set('find_replace', true);\n find_shortcut_used(e); \n}\n\nvar on_goto_toggled = function(new_value){\n // This just toggles the display, it does not deal with focus/blur, which may happen afterwards\n // as a consequence if the relevant inputs previously had the focus.\n\n if(new_value){\n el.goto_wrapper.style.display = '';\n el.find_wrapper.style.display = 'none';\n el.button_goto.classList.add('selected');\n el.info.textContent = 'goto line inactive';\n el.replace_wrapper.style.display = 'none';\n }else{\n el.goto_wrapper.style.display = 'none';\n el.find_wrapper.style.display = '';\n el.button_goto.classList.remove('selected');\n el.info.textContent = 'search inactive';\n if (dn.g_settings.get('find_replace'))\n el.replace_wrapper.style.display = '';\n }\n}\n\nvar on_replace_toggled = function(new_value){\n if(new_value){\n el.button_replace.classList.add('selected');\n if(!dn.g_settings.get('find_goto'))\n el.replace_wrapper.style.display = '';\n }else{\n el.replace_wrapper.style.display = 'none';\n el.button_replace.classList.remove('selected');\n }\n if(search_inputs_have_focus)\n select_search_result_idx(search_current_match_idx);\n}\n\n// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n// goto :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n// the implementation of goto is simpler than for search, so we start with it...\n\nvar goto_input_focus = function(){\n goto_input_has_focus = true;\n el.info.textContent = \"type to goto line\";\n perform_goto();\n}\n\nvar goto_input_blur = function(e){\n goto_input_has_focus = false;\n el.info.textContent = \"goto line inactive\"; \n //if(!e.relatedTarget)\n // dn.focus_editor();\n}\n\nvar perform_goto = function(){\n // called by find_goto_input_focus and find_goto_keyup\n var validated_str = el.goto_input.value.replace(/[^\\d]/,'');\n if (validated_str !== el.goto_input.value)\n el.goto_input.value = validated_str;\n if(validated_str === \"\")\n return;\n var num = parseInt(validated_str);\n dn.editor.gotoLine(num);\n dn.editor.navigateLineEnd();\n}\n\nvar goto_input_keyup = perform_goto; //alias\n\nvar goto_input_keydown = function(e){\n // keydown is fired repeatedly when key remains down\n if(e.which == WHICH.DOWN){\n el.goto_input.value = parseInt(el.goto_input.value.replace(/[^\\d]/,''))+1;\n perform_goto();\n e.preventDefault();\n }else if(e.which == WHICH.UP){\n el.goto_input.value = parseInt(el.goto_input.value.replace(/[^\\d]/,''))-1;\n perform_goto();\n e.preventDefault();\n } else if(e.which == WHICH.ESC){\n dn.g_settings.set('pane_open', false);\n e.preventDefault();\n e.stopPropagation();\n dn.focus_editor();\n }\n}\n\n\n// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n// search :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::\n\n \nvar update_search_history = function(){\n // called when the user types in the search box, or when we launch find from shortcut with selection\n var current_str = search_str;\n search_history_left_behind_str = current_str;\n\n if(current_str.length === 0 || !dn.g_atomic_exec){ \n search_history_idx = -1;\n return;\n }\n\n dn.g_atomic_exec(function(){\n var time_now = Date.now();\n\n if(dn.g_find_history.length === 0){\n // create a history entry for the first ever time\n dn.g_find_history.push(current_str);\n search_history_idx = 0;\n search_history_last_modified_time = time_now;\n return;\n }\n\n var top_of_history = dn.g_find_history.get(0);\n\n if(current_str.lengthtop_of_history.length \n && top_of_history.toLowerCase() === current_str.substr(0, top_of_history.length).toLowerCase()){\n // top_of_history is a case-insensitive prefix of current_str, replace top_of_history with current\n dn.g_find_history.set(0, current_str);\n } else if(time_now > search_history_last_modified_time + dn.const_.find_history_add_delay){\n // it's been a while since changes were made, add the current string as the new top\n dn.g_find_history.insert(0, current_str);\n if(dn.g_find_history.length > dn.const_.find_history_max_len){\n dn.g_find_history.remove(dn.g_find_history.length-1);\n }\n } else {\n // although the current string is at least somewhat different to the top, it's not been that\n // long since we modified the top, so lets just replace it with the new string\n dn.g_find_history.set(0, current_str);\n }\n search_history_idx = 0;\n search_history_last_modified_time = time_now;\n\n // TODO: we may like to remove duplicates in history, but without allowing recall to obliterate lots of existing memories\n\n }); // g_atomic_exec\n}\n\n\nvar search_inputs_focus = function(e){\n if(e.currentTarget == el.find_input){\n el.find_input.tabIndex = 101;\n el.replace_input.tabIndex = 102; \n } else {\n el.find_input.tabIndex = 102;\n el.replace_input.tabIndex = 101; \n }\n if(search_inputs_have_focus)\n return; // focus was transfered between replace/find inputs\n\n search_inputs_have_focus = true;\n dn.editor.setHighlightSelectedWord(false); \n perform_search();\n}\n\nvar search_inputs_blur = function(e){\n if(e.relatedTarget == el.replace_input || e.relatedTarget == el.find_input)\n return; // focus is transfering between replace/find inputs\n search_inputs_have_focus = false;\n\n // remove all search_markers\n var session = dn.editor.getSession(); \n for(var ii=0; ii selected_range.start.row || \n (search_results[ii].end.row == selected_range.start.row &&\n search_results[ii].end.column >= selected_range.start.column))\n break;\n var current_match_idx = (ii == search_results.length ? search_results.length-1 : ii);\n\n // Add search_markers into the editor to show *all* the search_results\n for(var ii=0; ii= search_results.length){\n search_results_sub = search_results_sub.concat(search_results.slice(search_current_match_idx + 1));\n search_results_sub = search_results_sub.concat(search_results.slice(0, n_post + 1 - (search_results.length - search_current_match_idx)));\n } else {\n search_results_sub = search_results_sub.concat(search_results.slice(search_current_match_idx + 1, search_current_match_idx + n_post + 1));\n }\n }\n\n // Now lets build the html to show the subset of search_results in the widget\n var show_replace_buttons = dn.g_settings.get('find_replace');\n var html = \"\";\n for(var ii=0; ii const_.find_max_prefix_chars; //TODO: deal with indent better\n row = search_results_sub[ii].range.end.row;\n col = search_results_sub[ii].range.end.column;\n var suffix_range = new AceRange(row, col, row, col+const_.find_max_suffix_chars);\n html += \"
\" +\n \"
\" + (row+1) + \"
\" +\n \"
\" +\n \"
\" +\n (pre_ellipses ? \"…\" : \"\") + escape_str(session.getTextRange(prefix_range)) +\n \"\" + escape_str(session.getTextRange(search_results_sub[ii].range)) + \"\" +\n escape_str(session.getTextRange(suffix_range)) +\n \"
\" +\n \"
\" +\n (show_replace_buttons ? \"
r
\" : \"\") + \n \"
\";\n }\n el.search_results.innerHTML = html;\n var els = el.search_results.getElementsByClassName('find_result_item');\n for(var ii=0; ii max_search_results)\n el.info_overflow.textContent = \"... and \" + (search_results.length - max_search_results) + \" more matches\";\n else\n el.info_overflow.textContent = \"\";\n\n // do the special marker for the current selection and actually select it\n search_marker_current = session.addMarker(search_results[search_current_match_idx].range, \"find_current_match_marker\", \"find_current_match_marker\", false);\n dn.editor.selection.setSelectionRange(search_results[search_current_match_idx].range, false);\n dn.editor.renderer.scrollSelectionIntoView();\n}\n\nvar settings_changed = function(){\n if(search_inputs_have_focus || \n (dn.g_settings.get('pane') === 'pane_find' && dn.g_settings.get('pane_open') && el.find_input.value))\n perform_search();\n}\n\nvar search_result_click = function(ii){\n // this can only be called while find input has the focus\n return function(e){select_search_result_idx(ii);};\n}\n\nvar search_replace_result_click = function(ii){\n return function(e){\n replace_result_idx(ii);\n e.stopPropagation(); // prevent selecting item\n }\n}\n\nvar find_input_keyup = function(e){ \n //we need keyup here in order that the val has the new character or new backspace\n if(e.which == WHICH.ENTER || e.which == WHICH.ESC || e.which == WHICH.UP || e.which == WHICH.DOWN)\n return; \n if(search_str == el.find_input.value)\n return;\n perform_search();\n update_search_history();\n}\n\nvar find_input_keydown = function(e){ \n // we want keydown here so that we can get repeated firing with keydown (i think on most browsers)\n\n if ((e.which == WHICH.ENTER && !e.shiftKey) || (!e.ctrlKey && e.which == WHICH.DOWN)){\n //find next\n select_search_result_idx(search_current_match_idx + 1 < search_results.length ? \n search_current_match_idx + 1 \n : 0);\n e.preventDefault();\n return;\n }else if((e.which == WHICH.ENTER && e.shiftKey) || (!e.ctrlKey && e.which == WHICH.UP)){\n //find previous\n select_search_result_idx(search_current_match_idx - 1 < 0 ? \n search_results.length -1 \n : search_current_match_idx - 1);\n e.preventDefault();\n return;\n }\n\n if(e.which == WHICH.ESC){\n dn.g_settings.set('pane_open', false); // blurs the find_input\n dn.focus_editor();\n e.preventDefault();\n e.stopPropagation();\n return; \n }\n\n if(e.ctrlKey && dn.g_find_history && (e.which == WHICH.DOWN || e.which == WHICH.UP)){\n dn.g_atomic_exec(function(){\n if(e.which == WHICH.UP) // up means go to more recent item\n search_history_idx = Math.max(-1, search_history_idx-1);\n else // down means move further into the past\n search_history_idx++;\n search_history_idx = Math.min(search_history_idx, dn.g_find_history.length-1);\n if(search_history_idx == -1){\n el.find_input.value = search_history_left_behind_str;\n }else{\n el.find_input.value = dn.g_find_history.get(search_history_idx);\n }\n el.find_input.setSelectionRange(el.find_input.value.length, el.find_input.value.length+10);\n });\n perform_search();\n e.preventDefault();\n }\n\n}\n\nvar replace_input_keydown = function(e){\n if(e.which == WHICH.ENTER){\n if(e.ctrlKey || e.shiftKey)\n replace_all();\n else\n replace_result_idx(search_current_match_idx);\n e.preventDefault();\n }else{\n find_input_keydown(e); // up, down search_results and esc\n }\n}\n\nvar replace_all = function(e){\n try{\n var options = build_search_options();\n } catch (e) {\n dn.show_error(e.message);\n return;\n }\n dn.editor.replaceAll(el.replace_input.value, options);\n dn.focus_editor();\n}\n\nvar replace_result_idx = function(idx){\n var range = search_results[idx].range;\n // we use undocumented ACE API to avoid messing around tryinng to force it to use the exact range we wanted\n dn.editor.$search.set(build_search_options()); //this is needed so that $tryReplace knows what to do with regex'es\n dn.editor.$tryReplace(range, el.replace_input.value) // returns true on success, but do we care?\n perform_search();\n}\n\n\n\n\n\nreturn {\n focus_on_input: focus_on_input,\n on_document_ready: on_document_ready,\n on_find_shortcut: find_shortcut_used,\n on_replace_shortcut: replace_shortcut_used,\n on_goto_shortcut: goto_shortcut_used\n}\n\n})(dn.const_);","\"use strict\";\n\n\n\ndn.esc_pressed = function(e){\n dn.g_settings.set('pane_open', !dn.g_settings.get('pane_open'));\n\n if(dn.g_settings.get('pane_open') && dn.g_settings.get('pane') == 'pane_find'){\n dn.find_pane.focus_on_input();\n }else{\n dn.focus_editor();\n }\n e.preventDefault();\n}\n\ndn.make_keyboard_shortcuts = function(){\n //perviously was using ace for handling these shorcuts because it neater (and efficient?) but it was\n //annoying trying to ensure the editor always had focus, and not clear what to do when the editor wasn't showing.\n \n //we have to delete the default ace commands linked to the keys we care about\n dn.editor.commands.removeCommands([\n \"find\",\"findprevious\",\"findnext\",\"replace\",\"jumptomatching\",\"sortlines\",\"selecttomatching\",\"gotoline\"]);\n\n //then add new commands on to the document using keymaster.js...\n key('command+s, ctrl+s, ctrl+alt+s, command+alt+s', dn.file_pane.on_save_shorcut);\n key('command+p, ctrl+p, ctrl+alt+p, command+alt+p', dn.file_pane.do_print_shorcut);\n key('command+o, ctrl+o, ctrl+alt+o, command+alt+o', dn.do_open);\n key('command+n, ctrl+n, ctrl+alt+n, command+alt+n', dn.do_new);\n key('command+l, ctrl+l, ctrl+alt+l, command+alt+l', dn.find_pane.on_goto_shortcut);\n key('command+f, ctrl+f, ctrl+alt+f, command+alt+f', dn.find_pane.on_find_shortcut); \n key('command+r, ctrl+r, ctrl+alt+r, command+alt+r' + \n ', command+g, ctrl+g, ctrl+alt+g, command+alt+g', dn.find_pane.on_replace_shortcut);\n key('command+h, ctrl+h, ctrl+alt+h, command+alt+h', dn.file_pane.do_history);\n key('esc', dn.esc_pressed);\n key.filter = function(){return 1;}\n\n // it seems like the clipboard history cycling only works the old way, i.e. using ace....\n var HashHandler = require(\"ace/keyboard/hash_handler\").HashHandler\n var extraKeyEvents = new HashHandler([\n {bindKey: {win: \"Ctrl-Left\",mac: \"Command-Left\"}, descr: \"Clipboard cyle back on paste\", exec: dn.clipboard_tool.on_left},\n {bindKey: {win: \"Ctrl-Down\",mac: \"Command-Down\"}, descr: \"Clipboard cyle back on paste\", exec: dn.clipboard_tool.on_left},\n {bindKey: {win: \"Ctrl-Right\",mac:\"Command-Right\"}, descr: \"Clipboard cyle forward on paste\", exec: dn.clipboard_tool.on_right},\n {bindKey: {win: \"Ctrl-Up\",mac:\"Command-Up\"}, descr: \"Clipboard cyle forward on paste\", exec: dn.clipboard_tool.on_right}\n ]);\n dn.editor.keyBinding.addKeyboardHandler(extraKeyEvents);\n\n // Change \"ctrl\" to \"cmd\" if on Mac\n dn.ctrl_key = \"crtl\"\n if(dn.platform == 'Mac'){\n dn.ctrl_key = 'cmd';\n var els = document.getElementsByClassName('ctrl_key');\n for(var ii=0; ii dn.const_.drag_delay_ms)\n || (x*x + y*y > dn.const_.drag_shift_px * dn.const_.drag_shift_px);\n }\n if(dn.widget_mouse_down_info.is_dragging)\n translate(dn.el.the_widget, x, y);\n e.stopPropagation();\n\n};\n\ndn.document_mouse_up_widget = function(e){\n document.removeEventListener('mousemove', dn.document_mouse_move_widget);\n document.removeEventListener('mouseup', dn.document_mouse_up_widget);\n\n if(dn.widget_mouse_down_info.is_dragging){\n var pos = dn.el.the_widget.getBoundingClientRect();\n translate(dn.el.the_widget, 0, 0);\n \n //work out what widget_anchor should be\n var widget_w = dn.el.the_widget.offsetWidth;\n var widget_h = dn.el.the_widget.offsetHeight;\n var window_w = window.innerWidth;\n var window_h = window.innerHeight;\n var anchor = []\n if(pos.left < window_w - (pos.left + widget_w)){\n anchor[0] = 'l'; //anchor left side by window width percentage\n anchor[1] = Math.max(0,pos.left/window_w * 100);\n }else{\n anchor[0] = 'r'; //anchor right side by window width percentage\n anchor[1] = Math.max(0,(window_w - (pos.left + widget_w))/window_w * 100);\n }\n if(pos.top < window_h - (pos.top+ widget_h)){\n anchor[2] = 't'; //anchor top side by window height percentage\n anchor[3] = Math.max(0,pos.top/window_h * 100);\n }else{\n anchor[2] = 'b'; //anchor bottom side by window height percentage\n anchor[3] = Math.max(0,(window_h - (pos.top + widget_h))/window_h * 100);\n }\n\n if(dn.g_settings)\n dn.g_settings.set(\"widget_anchor\",anchor); \n\n }else{\n dn.g_settings.set('pane_open', !dn.g_settings.get('pane_open'));\n }\n dn.widget_mouse_down_info = undefined;\n};\n\ndn.widget_apply_anchor = function(anchor){\n anchor = Array.isArray(anchor) ? anchor : dn.g_settings.get('widget_anchor');\n var widget_w = dn.el.the_widget.offsetWidth;\n var widget_h = dn.el.the_widget.offsetHeight;\n var window_w = window.innerWidth;\n var window_h = window.innerHeight;\n\n if(anchor[0] == 'l'){\n // horizontal position is anchored to a fixed percentage of window width on left of widget\n if(window_w * anchor[1]/100 + widget_w > window_w){\n dn.el.the_widget.style.left = 'inherit';\n dn.el.the_widget.style.right = '0px'; //if the widget would overlap the right edge, then instead put it precisely on the right edge\n }else{\n dn.el.the_widget.style.left = anchor[1] + '%';\n dn.el.the_widget.style.right = ''; //use the anchor exactly\n }\n\n // set toolbar position\n dn.el.widget_menu.classList.add('flipped');\n dn.el.widget_content.classList.add('flipped');\n var els = document.getElementsByClassName('widget_menu_icon');\n for(var ii=0; ii window_w){\n dn.el.the_widget.style.left = '0px';\n dn.el.the_widget.style.right = ''; //if the widget would overlap the left edge, then instead put it precisely on the left edge\n }else{\n dn.el.the_widget.style.left = 'inherit';\n dn.el.the_widget.style.right = anchor[1] + '%'; //use the anchor exactly\n }\n\n // set toolbar position\n dn.el.widget_menu.classList.remove('flipped');\n dn.el.widget_content.classList.remove('flipped');\n var els = document.getElementsByClassName('widget_menu_icon');\n for(var ii=0; ii window_h){\n dn.el.the_widget.style.top = 'inherit';\n dn.el.the_widget.style.bottom = '0px'; \n }else{\n dn.el.the_widget.style.top = anchor[3] + '%';\n dn.el.the_widget.style.bottom = ''; \n }\n }else{\n // vertical position is anchored to a fixed percentage of window height on bottom of widget\n if(window_h * anchor[3]/100 + widget_h > window_h){\n dn.el.the_widget.style.top = '0px';\n dn.el.the_widget.style.bottom = ''; \n }else{\n dn.el.the_widget.style.top = 'inherit';\n dn.el.the_widget.style.bottom = anchor[3] + '%'; \n }\n }\n\n\n\n}\n\ndn.toggle_widget = function(state){\n // provide argument \"true\" to open widget, \"false\" to close\n if(state){\n dn.el.widget_menu.style.display = '';\n dn.el.widget_content.style.display = '';\n }else{\n dn.el.widget_menu.style.display = 'none';\n dn.el.widget_content.style.display = 'none';\n dn.file_pane.on_close_pane(); // we could check if it file pane was open, but who cares\n dn.focus_editor();\n }\n}\n\ndn.check_unsaved = function(){\n /* called:\n (a) before issuing save-body requests, at which point we set dn.save_undo_id to Nan, and\n record (in the SaveRequest instance) the current UndoManager.getCurrentId() value for \n later use if and when the save completes.\n (b) after all pending saves are completed, when we read the undo_id value for the last saved\n body version and set dn.save_undo_id to that.\n (c) in some kind of regular async manner in response to editor input\n\n Importantly, note we have monkey-patched the UndoManager class in patch_ace.js. This is what\n gives us the concept of an undo_id and the ability to query .getCurrentId().\n */\n if(dn.save_undo_id === dn.editor.getSession().getUndoManager().getCurrentId()){\n // changes match what we know is on the server\n dn.status.unsaved_changes = false;\n dn.render_document_title();\n dn.show_status();\n }else if (!dn.status.unsaved_changes){\n // changes no longer match the server\n dn.status.unsaved_changes = true;\n dn.render_document_title();\n dn.show_status();\n } // else, we already there were unsaved changes\n}\n\n\n\n// ############################\n// Settings stuff\n// ############################\n\ndn.g_settings = (function(){ \n // This acts as a mock realtime model to be used until the real model is initialised\n var ob = {};\n var keeps = {};\n var change_listeners = [];\n return {\n get: function(k){\n return ob[k]\n }, set: function(k,v){\n if(ob[k] === v) return;\n ob[k] = v;\n for(var ii=0;ii dn.const_.clipboard_max_length){\n // trim clipboard to current length limit, note the oldest stuff is at the 0-end\n dn.g_clipboard.removeRange(0, dn.g_clipboard.length-dn.const_.clipboard_max_length);\n }\n\n dn.g_find_history = dn.g_settings.get('findHistory');\n if(!dn.g_find_history){\n dn.g_settings.set('findHistory', doc.getModel().createList());\n dn.g_find_history = dn.g_settings.get('findHistory');\n }else if(dn.g_find_history.length > dn.const_.find_history_max_len){\n // trim find history to current length limit, the oldest stuff is at the non-zero end.\n dn.g_find_history.removeRange(dn.const_.find_history_max_len, dn.g_find_history.length);\n }\n \n //Check lastDNVersionUsed at this point - by default it's blank, bust could also have an out-of-date value\n var last_version = dn.g_settings.get('lastDNVersionUsed') \n if(last_version != dn.version_str){\n if (last_version.length > 0 && parseInt(last_version) !== 2016){\n // from this point onwards during this page's lifetime, change the tips \n // section to show the update message rather than the tips.\n document.getElementById('tips_old_user').style.display = '';\n document.getElementById('tips_general').style.display = 'none';\n }\n dn.g_settings.set('help_inner', 'tips');\n dn.g_settings.set('pane', 'pane_help');\n dn.g_settings.set('pane_open', 'true');\n dn.g_settings.set('lastDNVersionUsed', dn.version_str);\n }\n\n dn.status.realtime_settings = 1;\n}\n\n\ndn.settings_changed = function(e){\n var new_value = e.newValue;\n console.log(\"[user settings] \" + e.property +\": \" + new_value);\n if(dn.impersonal_settings_keys.indexOf(e.property)>-1 && localStorage){\n localStorage[\"g_settings_\" + e.property] = JSON.stringify(new_value);\n }\n try{\n switch(e.property){\n case \"widget_anchor\":\n dn.widget_apply_anchor(new_value);\n break;\n\n case \"theme\":\n dn.editor.setTheme('ace/theme/' + new_value);\n break;\n\n case \"fontSize\":\n var scrollLine = dn.get_scroll_line();\n dn.editor.setFontSize(new_value + 'em') \n dn.editor.scrollToLine(scrollLine);\n break;\n\n case \"wordWrap\":\n var s = dn.editor.getSession();\n var scrollLine = dn.get_scroll_line();\n s.setUseWrapMode(new_value[0]);\n s.setWrapLimitRange(new_value[1],new_value[2]);\n dn.editor.scrollToLine(scrollLine);\n break;\n\n case \"wordWrapAt\":\n var curWrap = dn.g_settings.get('wordWrap');\n if(curWrap[1] && curWrap[1] != new_value)\n dn.g_settings.set('wordWrap',[1,new_value,new_value]);\n dn.editor.setPrintMarginColumn(new_value);\n break;\n\n case \"showGutterHistory\":\n var s = dn.editor.getSession(); \n if(!new_value){\n var h = dn.change_line_history;\n for(var i=0;i 1)\n h.splice(start_row, e.lines.length-1); \n h[start_row] = -n_classes;\n }else{\n h[start_row] = n_classes;\n if(e.lines.length > 1){\n var args_for_splice = [start_row, 0];\n for(var ii=0; ii< e.lines.length-1; ii++)\n args_for_splice.push(n_classes);\n h.splice.apply(h, args_for_splice);\n }\n }\n\n for(var ii=0; ii 0)\n dn.the_file.file_id = state.ids[0];\n else if (state.folderId)\n dn.new_in_folder = state.folderId; // could be invalid nonsense\n }catch(e){\n dn.show_error(\"Bad URL. This will be treated as a new file.\");\n }\n }\n\n dn.the_file.addEventListener(\"change\", function(e){\n switch(e.property){\n case \"title\":\n dn.render_document_title();\n break;\n\n case \"syntax\":\n dn.set_editor_syntax();\n break;\n\n case \"newline\":\n dn.set_editor_newline();\n break;\n\n case \"tabs\":\n dn.set_editor_tabs();\n break;\n } \n });\n\n // The auth promise can be rejected and resolved multiple times during the lifetime of the app.\n // These two handlers will always be called for those events.\n dn.pr_auth.on_error(dn.handle_auth_error); \n dn.pr_auth.on_success(function(){\n // reset some things, could be no-ops...\n dn.reauth_auto_delay = 0;\n dn.toggle_permission(false);\n dn.status.popup_active = 0;\n\n // and show the good news...\n dn.status.authentication = 1;\n dn.show_status(); \n })\n\n // if we ever find that we have gone offline, we have to call offline_simple.commence_testing,\n // that will then trigger the following event when the connection is restored.\n offline_simple.addEventListener('online', dn.pr_auth.resolve.bind(dn.pr_auth)); \n\n // get user info...\n until_success(function(succ, fail){\n Promise.resolve(dn.pr_auth)\n .then(dn.request_user_info)\n .then(dn.show_user_info)\n .then(succ, fail);\n }).before_retry(dn.filter_api_errors)\n .then(function(){\n console.log('succeeded getting user info.')\n }).catch(function(err){\n console.log(\"failed to load user info\")\n console.dir(err);\n dn.show_error(dn.api_error_to_string(err));\n });\n \n if(dn.the_file.file_id){\n // load existing file :::::::::::::::::::::::::::::::::::::::::::::::::::\n dn.status.file_meta = 0;\n dn.status.file_body = 0;\n dn.status.user_wants_file = 1;\n\n dn.show_status();\n dn.editor.setReadOnly(true);\n // metadata...\n var pr_meta =\n until_success(function(succ, fail){\n Promise.resolve(dn.pr_auth)\n .then(dn.request_file_meta)\n .then(dn.show_file_meta)\n .then(succ, fail);\n }).before_retry(dn.filter_api_errors)\n .catch(function(err){\n dn.status.file_meta = -1;\n dn.show_status();\n throw err;\n });\n\n // body...\n var pr_body = \n until_success(function(succ, fail){\n Promise.resolve(dn.pr_auth)\n .then(dn.request_file_body)\n .then(dn.show_file_body)\n .then(succ, fail);\n }).before_retry(dn.filter_api_errors)\n .catch(function(err){\n dn.status.file_body = -1;\n dn.show_status();\n throw err;\n });\n\n // wait for both meta data and body...\n Promise.all([pr_meta, pr_body])\n .then(function(vals){\n console.log(\"succeeded loading file body and metadata.\");\n dn.the_file.set({is_loaded: true});\n dn.pr_file_loaded.resolve(); \n dn.show_status();\n }).catch(function(err){\n console.log(\"failed to load file properly..\");\n console.dir(err);\n dn.show_error(dn.api_error_to_string(err));\n document.title = \"Drive Notepad\";\n dn.g_settings.set('pane', 'pane_help');\n dn.g_settings.set('pane_open', true);\n });\n\n } else {\n\n // create new file :::::::::::::::::::::::::::::::::::::::::::::::::::\n // or rather, wait for the first save action before creating.\n dn.show_status();\n dn.the_file.set({title: \"untitled.txt\", is_loaded: true}); // there's nothing to load for this model\n dn.g_settings.set('pane', 'pane_file');\n dn.g_settings.set('pane_open', true);\n }\n \n // load cloud settings ::::::::::::::::::::::::::::::::::::::::::::::::\n until_success(function(succ, fail){ \n Promise.all([dn.pr_auth, dn.pr_realtime_loaded])\n .then(dn.request_app_data_document)\n .then(dn.show_app_data_document)\n .then(succ, fail)\n }).before_retry(dn.filter_api_errors)\n .then(function(){\n console.log('succeeded loading settings');\n }).catch(function(err){\n console.log(\"failed to load realtime settings.\")\n console.dir(err);\n dn.show_error(dn.api_error_to_string(err));\n });\n\n\n // load ads at some point in future...\n //setTimeout(load_script_async, dn.const_.ad_initial_wait, 'js/banner_ads.js');\n}\n\nif (document.readyState != 'loading' && document.getElementById('the_widget')){ //second test is hack for IEi\n dn.document_ready();\n}else{\n document.addEventListener('DOMContentLoaded', dn.document_ready);\n}\n"]} \ No newline at end of file diff --git a/app.build.css b/app.build.css new file mode 100644 index 0000000..bcfab47 --- /dev/null +++ b/app.build.css @@ -0,0 +1 @@ +html{height:100%;overflow:hidden}body{position:fixed;height:100%;width:100%;overflow:hidden;margin:0}a{text-decoration:none}a:active,a:hover,a:link,a:visited{color:inherit}.the_editor{position:fixed!important;top:0;right:0;bottom:0;left:0}.widget_content{margin-left:34px;padding-bottom:5px;margin-bottom:-3px;margin-right:3px;padding-right:5px;padding-left:5px;padding-top:5px;min-height:208px;cursor:default;border:1px solid rgba(0,0,0,.3);box-shadow:0 0 5px #0b53c3;-webkit-box-shadow:0 0 5px #0b53c3;-moz-box-shadow:0 0 5px #0b53c3;background:#4973b9;border-radius:2px;display:flex;flex-flow:column}.the_widget{background-color:#3262b1;color:#fff;border-radius:2px;display:block;width:290px;position:fixed;top:0;left:0;z-index:100;box-shadow:2px 2px 5px #4285f4;-webkit-box-shadow:2px 2px 5px #4285f4;-moz-box-shadow:2px 2px 5px #4285f4;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:.8em;border:rgba(0,0,0,.3) 1px solid}.widget_text{padding:5px;display:block;margin:2px;border-radius:3px 3px 0 0;min-height:2.2em;cursor:default}.widget_pending{position:absolute;left:0;right:0;top:0;height:4px;background:#d04bb2;border-radius:2px 2px 0 0;box-shadow:0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);-webkit-box-shadow:0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);-moz-box-shadow:0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);overflow-x:hidden}.widget_error_text{display:block;margin-left:35px;right:0;background-color:red;color:#fff;cursor:default;padding:5px;min-height:25px}.widget_error{position:relative}.widget_error_mark{position:absolute;width:21px;display:inline-block;text-align:right;background-color:red;color:#555;font-weight:900;padding:5px;top:0;bottom:0}.widget_menu{cursor:default;width:34px;position:absolute;padding-top:8px}.widget_menu_icon{position:relative;background:#4973b9;padding-top:4px;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;border-radius:2px;margin-bottom:4px;border:rgba(0,0,0,.3) 1px solid;border-left:1px solid #4285f4;margin-left:-1px;width:32px;height:32px;text-align:center;text-decoration:none;color:#fff;cursor:pointer;vertical-align:top;box-shadow:0 0 2px #0b53c3;-webkit-box-shadow:0 0 2px #0b53c3;-moz-box-shadow:0 0 2px #0b53c3}.widget_menu_icon:hover{background-color:#6ea0f3;box-shadow:0 0 5px #c2d9fd;-webkit-box-shadow:0 0 5px #c2d9fd;-moz-box-shadow:0 0 5px #c2d9fd}.icon_selected,.icon_selected:hover{background-color:#3e71c5;box-shadow:0 0 6px #0b1629 inset;-webkit-box-shadow:0 0 6px #0b1629 inset;-moz-box-shadow:0 0 6px #0b1629 inset}.button.icon{padding:4px 4px 4px 4px}.wiget_item_icon{display:inline-block;background-color:#5892fd;border-radius:2px;padding:1px 3px 1px 3px}.button.icon:after,.widget_menu_icon:after,.wiget_item_icon:after{display:inline-block;width:22px;height:22px;background-size:cover;content:" "}.wiget_item_icon:after{width:16px;height:16px;position:relative;bottom:-1px}.widget_content.flipped{margin-left:3px;margin-right:34px}.widget_menu.flipped{right:0;text-align:right}.widget_menu_icon.flipped{margin-left:3px;margin-right:-1px;border:rgba(0,0,0,.3) 1px solid;border-right:1px solid #4285f4}.icon_goto:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtAQAAAAASYd83AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAnRSTlMAAHaTzTgAAAACYktHRAAB3YoTpAAAAAlwSFlzAAAOwwAADsMBx2+oZAAAAAd0SU1FB+ADAQ4DKt+EG4gAAAAnSURBVBjTY2AgE/B/+P///wHSKXyGcQiAKe4LuCmoEiIMo47L8AAAw4pvQ77peO0AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTYtMDMtMDFUMTQ6MDM6NDItMDU6MDBBZS5oAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE2LTAzLTAxVDE0OjAzOjQyLTA1OjAwMDiW1AAAAABJRU5ErkJggg==)}.icon_replace:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAwENNRnrDlWyAAAAhElEQVRIx+3VsQ2AMAwEwIeChtGyLCPgIdgBZYiYggpTIIE/RIq/jJSTHNsK0Eq2qSx6S1n3OfDA28XVJSc+WNqhGAAqOZFoQIVGA6MfVY1WIdEqOdkjx+H7FNo+dgQ/XQyYD9fvei/wm9BgQ3vChvaErzTxb2Q+CLGN1OGjrkzggf+BHwa1kHkrdOrtAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTAzLTAxVDEzOjUzOjI1LTA1OjAwTomzewAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wMy0wMVQxMzo1MzoyNS0wNTowMD/UC8cAAAAASUVORK5CYII=)}.icon_demo:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAwEKEB6Y1gZzAAADMElEQVRIx+2WT2hcVRTGvzuNE+ogQpF2IZQiEhARgpKFSEsNgqgwKDS4aHGRKCKTRVUiSEXGboQIRQipFEpcVCgNQYgi3RRTUwqShQoythT/UGroECVhHBom8949PxfvpvM32qZPUcjZnXcfv/Ode7/z7pO24n8VpSwD7CvnUkRWdpBnnAvUAKwSDd4xsvYgh/wJK5kB2KLdAABb3qTyuR4G/GGboUwIqzPCHvaFbBEYui3k8r3xM/6onQvaanaRywnMH5VKWbsEYFX6gclbQrI7fpEJ+y5pO8RL9LKLFQC7wnbJvxtWRiUr2fm/ABYz9X5f8KdtMbT8NRNMh5ZnJInZJIsGpVofqwAszPVI/gw1ejuQ5Vz0FO/YWas0aSR+WfrtnlCmunq/FB8IS6ckyb4EsJh+qdZnMbC/Tal/36rhpRlf4JWwCV9JEhNhZwtNZX6v7pQ4FFaONcr4t1vQ/vC6Sn9Mmuvh22Qz1h6SGLC4UcZPNrr54z5bAuBqOSfFBwNiugVt34THV8s5yb/ROP+2MsFmoczJkA0xwGjSDXCtOzovsTsxmf3Idsm/1sVmLWXMwiwu2ae8GT1RyrbabLLz/MlLG9jsZHzQn7DrIbvsp+LhWt9GDh4Cu1F7oHH+SRl/pmGztUeCzcIc2kXGyVd2/M1wVHeC/6jdZtHTAXOJcRaSw7RlZhmL9nZx74aTt2TnGzZjVGKP/dyk8oqf8q+uPVzM3DLyJnqapXWbWd0+D+pjFvyH8QF23TawydkFsGs3NVbsrD8SDabycedxAH7hlC/U+zfRdpdwAd3Ldc2zmAZS2lZoQkuQDlaSnJOkltaZ/aHXuegxVpLcPn5vm3Pxk6yGFz5wzjn/AlHI33LOOT+SyAI/4pyOd1QCmy9lpfqjthyGe6qYkaL96zcf45IUP2/1kI9JUjwcbkiLhyXJn+7oP7l87hTMGHRFpwPugrb5dMDdVJMOeB3dYT4ifeZM4jl3tySx6r6QyCjv7pIkVtw5iazyicUouwsSOfdsu/n+LV+nG1voLfR/AP1rasyf2tB2fLOk9rBP2h4UM7xu34e/0s1H2Rfnev6hHW7En9IBXncI9iF/AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTAzLTAxVDEwOjE2OjMwLTA1OjAwOyFISgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wMy0wMVQxMDoxNjozMC0wNTowMEp88PYAAAAASUVORK5CYII=)}.icon_drive:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAACW0lEQVR42u1bvUoDQRC+N/FFfA9fwzewCSTNVWkMCLGKjcEmWBmwClYS6yOtKBZ2KgoqXzFBQ+JdbufbmY07sJBcwuZ2b/f7mdkURY4cOXLkyJEjRw69uJvPX97fXr+022BwfOJ64J1OZw+tLMtDxgQ8PT58on+3EzAen9+ejUbXeD2dXt0zJgG/4XLwvd7RvtwkXv98r93Qt7sJuJnNnuUG8fRxDauBMQH4LVeDX7fncQ37dVFVH4xJ6Pf7XTcTsG6QuIbPgNyMCZD+zeOvZX46HF6sbg/NJoBrSnugpjraKrvdAxYtmgLi5WRS1d0kvtP0u22a9O8C+DY1rIC61RLScC+mtNeUtoAJO0GLbZBddDyLFqP5hLZLGQPfCZ8Qou7YPoFOixr6PmmfoCFokvUJmntXfEJStKiJ3sgYJeUTGPydjE9gLVX0qb21KLQYQ8O79QmxXJxbQIy5P93RogVCu/EJVrk8FiCKD4mi90OXozktWut0c5/goaLDWoHiQ4rYe3BbUWJGi56yNdFZiJWvE+PjqcwuPqTwrsSibUkAlNecPbYCQFG7LR/MzlZtrMFGhAdL2KiCszb6i/SE7PU6+F9soA02ovdZtEoBZy0FKHqfpeZoilBLg7MLoVRPEPrURO+zUlx0VxiSB1gehiCJl2h5gba0yE5zR/Uk2w6CXeiInhvcVh2yS10mnqQpkLGLnWaepMkTFb3PTGOZVojqcgQp6P3gGuEmWmQfeXFTJd40wCT1vlaJLAW9r3pSZBXkktb7oafD2Edf3Z4WE5/APPz8L/5X5C2+AYmN7rykLUrGAAAAAElFTkSuQmCC)}.icon_bug:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAwEJOg+fS1TwAAACu0lEQVRIx+2WTUhUURiGv3sdR2qQJhRLCBGJJCxXRbgRW4TYKrIWIZVY0CKQdm0iBsOVFVS0EZE2LtpFILXSWkQkUZsmp9Kk7GdQcNJpbH7O+d4WM+Nc9Zz7N0EEvZvhnvOeZ77zfufMXKL/+utK1fM4p/jlr0b/Do3wFAAAfuLfoVuYzi/EstaxbO8wtewXhc93WkdhBm89Vp1PEuAkmlXz4hjAgoWPrPOSYwC/R3jjeHoPEoC86Aua12I1YgA/yLXJmxzlFKc4Ku+hGzEAw2WAiYjQilWoFMMW+5WmI7sZUH5lk+wpq2ZxmhkaMYvePx9GEZ5Fuy9wPIQYnBSPh1xlndmLhtJTTZs65XX7Mms7LU9htKptVwBmfiROoGptrF4cx3We4Gle4iQLZqzyEk/zhByRF0qgiIkOOYY0gGvFMaOE5nHjaAGYwKj5ndOZh1vn7aterN5+hGoqdtA5aiysfWx2bUJn9lfeMg5v2Mms8ZzfmB9zHzLfPv9oyRJFgw3hynDVTtlUsY8O0UGqWuePibPBKWUV6SY5gE+6nhERaRuawN3sAYfWREx08DMvaH5l7Y9T50c8VT2iYugu+i6XNdi4dejdntBObjnISfurpw3EqjtFnuXwOd89w3DhWjG2bQqEb+CnpxjUuu8wjxlPhy+qYujaOOOlUEPp1qG/eAph1qVvMiBO8bSnEzIn+xerHbDxkOzneT+HjxdkJFmnwUaDchCJss51GsPKfx05YK1A3naLlkPWncoBBRqXAYDn87kl6zjlCr2arCOaDOAMRwFAXlUGInpFz2RgbRdDbtByqOiPmKJLXnL147pSy18d0Qva1tkr187CDs2MTl9gIiLRZ317Wo9mFn2+wUREOFlqpxXNWXG+LDARUaaFJzahX+faygYXau+Qo5giIsIcj6M74vyG+4/qN/nGPQCtT8I2AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTAzLTAxVDA5OjU4OjE1LTA1OjAwn7bIPwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wMy0wMVQwOTo1ODoxNS0wNTowMO7rcIMAAAAASUVORK5CYII=)}.icon_about:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAwEKChW/KSUgAAACJklEQVRIx+2VQUgVQRjHZ56b8hDqJRR4EB4idghPQdGtS4cIIgIRpGuCRBehUyCeO3WpDkGdIjCR8hJBmCHi1csTEhEhIkkxXrHbru18/w47u+7Ozrxm3/pO+T/tvO8/v/nm/y1vGTvWsf5zYRR3OoBtdIunACBe7fQe/hreENM0T5slwP4grSHWRjCS3EOqTBBNpOXFwZRCx0GoioIpgc4EoWojGGkbnQtCldcW2hSEXsWCWLUHF0CHt2ivCBjAbPptNwfxiKggGAA1/MEjDSID3w+vpVld2SCcBT5seFsE+8Sfs7e0wndR5915B6/y8Wm/srqkJt86CJrzBg69v8628M7unyoSxMOZitqjmDK2sRWcT1+3Tq7R+i52NftwFbV4RR8Mfhfnsl3cNaH/XJaTuAkPwA9ckuvrer+YUi44U6FFrfN70uU32dVitPYGtP7lj07+HaiTSwdiUrE2ZPVMcmH5x4+TinOU3HQYqRP4djiB7RMreJI5sF88ZowxqkaTBOiBDORitj3+OljvuuB8ZmahpcS9JKD5bIX9W2YsHYRjieu+Wi2Fxu3I4fbT+3yxBFq8jOr+EH3V1ct0fUVmvKAvt4/20SPrX+zQFYuzIv3kgXzqsdvg2NkYQ42W4idutUPjapnab1Y1ohSWfSCMXrDT6zX2zH6Hpmv9GKMPK6rwj3qMUnuO7RjtuwbN+cPNPnpjquey16Hba6nEGIuqg+gO6i8I2MuT5gMfBQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wMy0wMVQxMDoxMDoyMS0wNTowMFziMycAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDMtMDFUMTA6MTA6MjEtMDU6MDAtv4ubAAAAAElFTkSuQmCC)}.icon_menu_help:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAhkNNzLdSZiwAAACOElEQVRIx+2XPWsUURSG3ztOZpG1sImkCQoiQRetLC22EyximmARsBJE2MbYCq7+BItACsGPSiv9BWLMEj9AEnACFmJAhZgRU+iGzGbmvBabHSd3587HZtZG32qGOfOcM+fcuedc4L/+llS2iX/SOSdn1RkcRxUj+IUfeM/XVuv2YlMG9stKeJUrNOkTb/LwANimxcvymVna5A1WCoG3xuVlJnZXsswTucE75+V7XjBJSjuYygUOpqRTBEyS0gmms0t3wQyWFhtsJFdAOsFkOvgYN43gpec2APinDc9/ciJlVUjL/NHhbBSAaeW86TpPUHgtLZ/h3a6V63DbaNRIBK9XZSO9VLzkOjwYPkyx2VivJsU8y0xJJ2v1/ElbTOJmo3M4d/vAfq0MMEn6tS4xqqhdNy9JuS7L8fsD99VRs7Vdx97I+SQlEM0t01P3qGtlReY1lKQeKWoF3IZxc+QzfgWsx2qhFzVOpbA9dWRPrpGy66qLCgBcLBSJ3ipinFMVHe2XhvY1ND+WReYXDa3cQVG6eqQILS/KQssrDR0ulYUOFzW0846rZYC56qxoaID3SkFHlBjam6e3b7DnzfeuY71srB3eUnNJL8gDrAHW2+h+DqOAmlZ9v7u6M9ZO9Glsu/XECPv3SnPbNQ4LudD6sKB5UWuc4VM1oiWkztEE9Hh8guaOzNgfMkoxtMEMAILJYuMkt3KOk8AQh2AAaFrBlaGM7rul2deBo8gxaQKHYKONbyUck/5F/QY186l/0kIl9wAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wMi0yNVQxMzo1NTo1MC0wNTowMMyFuZoAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDItMjVUMTM6NTU6NTAtMDU6MDC92AEmAAAAAElFTkSuQmCC)}.button_history:after{background-image:url(data:image/png;base64,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)}.icon_tips:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAwEKMzT9xLjEAAACsElEQVRIx9WXv0sbcRjGn28SorZqlyZaVDyqRWpoQUG6FbfuhXR2KQX7F3Tr4tSlIKWLU0cFKUKHTpJJUIhUiZTWwhVqLUkx1JiQi7n36RA1l5rk+72LS5/pfrzv533vee89OOB/lDILY0/1YeSODAGhAxwWUv2/r6Q6J7gkf+iRVOR95UGH2F/X3dcss4lE3HfHNwODS0OyyzaSL+XbwYyw5IAaySEnfIMzUdnUgUmSn9jjt+cFIzBJ960vcCEuRVO0VMvjPtDuK1MwSbpLzRgtVoZZxHx0klPxyxdDTcEzXjBLTGELAPiTKXwFAO4xxdxFSIwzpna8aHjeZYBJknSfA3xDkk4CkIwnZt6w61CDGbIHSAIAQhmACQBOdJ9daswTZGpIo8+hDBCaBICTPUBNAvymnMo4ujxBw6boBjnbAKYB/OjLlkYQA1QaiE41BB0bomXXm9S9z36MAUgDPVMAIOfF6rIN0aer9WNeYGQbkGkACKUBetB0saZ/+vO+P1zMvizZ2tdaCpJliSTlSLJS9eyjORhw7nlTNYtece76QANcNF7zl77AQK6Pn43Im+sRn2iA92vOtlW2NOIbDAB8qnFZ+CgQGADcpbbshcBgIBOVdMueNwK47FV1rhW6Otc+U/sNCRf93zFEB5ce7dANhtYOQq2td88OVy1lKQuWstQoR1T4StBOIjLr2mLntwbPvF2P1EqFdzRN6dBMYvnsKKds2LDlO23XztuDRV2uFt3y5XvcoSEnqd4nsMRSFixY6lr9TljjuBbdl8VK/awQ7x2FVSvl5jv0+nQ2Mh/MX23XkRiStdc/jAGIZ5TFjRtH5oWaqPUYmeywa7VSGKj7++8oO/L6ss5HiY+q7dKY/jfekmfcCaeVHcjVtujEmb95prhYiHdOvIyuKWGS8xenkI2pw9OgUQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wMy0wMVQxMDo1MTo1Mi0wNTowMDjUOB8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDMtMDFUMTA6NTE6NTItMDU6MDBJiYCjAAAAAElFTkSuQmCC)}.icon_shortcuts:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAACS0lEQVR42u2YT0hUQRzHV0Ot7B+kpAcLoi5h4IodRALRMiiIyEuX6t4hAj0kIh26dJcO0aGLipo38RoidAj2ELKHYvFgy3bYdXdrefu/3e0zy1rb25ktlXKC3w++zLz5vvnt583OvDfveTwSEhISEhJ/K+Lx+IlkMulNpVL9NqlUKnX7fL6mX2Adx+nI5XKPisViFJUs1DfiTTabvfADmobb6KulwGUVCoUcehoIBFrK0Bw8thm4CnyGqdK+Df2k2szn8+8Z+bn9Fhyr8GSroBeB7tRCq+NIJHJ0vwX4KDzxP4WeUO2s3C4WqLriLY1ekKCVxB/dHgvmDuVVXT9yb1IOkveBziffBuWVylq7vmNoTjhDfdkwv+Yqo7Hl9mi7T98bhn4OUCOcM2aYu18UrEALtED/hG5HUwrcLdrHg8HgIeqzGm8I9en6odfcObz4twx55/H7dg3t9/ubM5nMeZJcciudTp8lQSP1Hp1fR73RaPQY+51TBt8bi8WO72WkO6lPo3WNnoVCocMkXjP4WnH+O8D6Ke8ZznnL9Ln8z+f0b/YPdi5Egd7F3uM0HZeQ4xY//CocDh+h/KTz6yhMn2HKhwb/M/61vYz0QbWa1ci4hXcRHUCDOr+OhhOJxEn1Lxp8dbts2zE0oCtozAK9hCdlgp78T95cFoDuKEOz/71b/YZg8cvtc/VgKkPz1DtHwyJG0lLgAnwfmO83GekGT2XBqQWl7hSjai5hTtgkdaehHFBP4JqPNeoqUBNqtkk1H2okJCQkJCQkKvEdVcqwyLugx0oAAAAASUVORK5CYII=)}.button_share:after{background-image:url(data:image/png;base64,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)}.button_save:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAv0lEQVR42u3ZPw6CMBTHcVYP4DFcPIDxCC6egE3P43l06mFY26bpn1Tbwa0khNBQwveXvIXwXj8LUNKuI4S0GaXUyTn3bKGyZRI6hPCIMX5bqGzZHzpdd977T43Ks2uhh1rPUZ4NGjRo0KD3id7eF5ENE2jQoEGDBj0ysE91n1n9Kmgp5XHuBin3ggYNemG0MeZaektorc/NolPPe2TRF2jQa6OnHl8IIQ7/HmvtrXRP+tO+lNbIvYseXxCy4fwA+HnCV+xLsV4AAAAASUVORK5CYII=)}.icon_menu_open:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAmCAYAAACoPemuAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAADSSURBVFhH7dcxjgIxDEDRdHMhas44N+BaHGUUKYEk+s00sS1hi8JPohlsvldLQ5k+wVZUg/kwZGXMhyErYz4MWRnzYcjKmA9DVsZ8iN77i6yMna3xge/xeo7XwZo/2lu11gfjcWhvMRqL9hajS2vtHP/Si7d+6vYd5NkWowuPXMw/mMx/HTaRycPUyORhamTyMDUyeZgamTxMjUwepkYmD1Mjk4epkcnD1MjIPy5uPxAGHrshY8e+GzJ27LshY8e+GzJ27LshY8e+GzJ27LsppZQvqUwO6HT/APoAAAAASUVORK5CYII=)}.button_print:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAWElEQVR42u3YwQ0AIAgEMPcfGl2CAIaS+CV9HeA5alhFxK140NBd6Ol9oaGhp6DXjujULIeG3oCeHBLQ0NA/obvOLWhoaJFXgLaaQkMXo/1PQ0NDQ0Nnoh/MPNs/4Cp2kwAAAABJRU5ErkJggg==)}.icon_menu_general_settings:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAADNklEQVR42u1ZS2gTQRguIoqID4JFRMQg4qUXEaEnwZuIICIUEXoQ9aQgIhYJiBEVvHjxUIrgIR6kEIoIUjz2IAUrooRSDMTQQwiFPDYJeT/1++lGlmUnO9P9dzSSgSGQ3fnnm2/+946NjcZo+DuSyeQ+mfeq1eqpSqVy8q+CrdfrZ1qt1rt2u10ulUoBt/c7nc5Sr9f7hfdXsO56IpHYqQVoOBze3mw2r2LjrwSgPwFiZtC6crk8YX2fJg5hQNaLWCy221fQAPvSvrnJXmYQcwA467QO/6/7zrQTYxa2rzmtISaJVcFhQ1pUBOAWBQB+wthOE3iAnDHnNFTgmYDlTjabPaQFdKPROCdiW2UCc1Sr5wCra15B4/AXtAEmHQXoZQ6m2TwHCSLX5vSMdBCAv3Goh2kHa4VCISjCEo1Gd0iBhuE8h7ANzKcIIH8ExuPxPWDnu9Pm3W63AQNcIMNDoDkBIPtTqdQuwzCOQg3O49kcnpUEjMesjGNdAO/fx/4/CItU8CDAFoE9CPiIxZfx+1bg6j4Ui8VjbrIRwg/i3YhAxnvse5b2IAIsN7EhunVrEJhS0Ek60AMs26boMm+Su1PYZ0oqP5CZ2PyeB19/WwH00painQPgeYYgNS+7H2ETgqZot3lzAy2+msvlDnsFTTpOsiQ8zEqtVpt0SzmDpgfJCViOMKYEERExePZaOf+mrA2LHysbhsJwMnwijFymF6HTdqH5fP4IF2gAnHBg+aLXHCNkF8pZccCOxh1u8hY7aM48Bre2l9OV9tXjhoP7GecCjZB/nNVmdBgipQcshjhULu9fDi7ANfn/hPGhTJiGNjU1PUZGsQhY8LEIyEgFM1G5ZRa0X9zKLToAlWZU35HBupVbkLlqdXHK5ZZkYbvMWNiushS2boMEgbU3DC2Ez+l0+oC23gdHl4naB1o7TNRo4VAPOrwWwKTXIpcFw3mCR1fIh8M4H+H3LrW/qDkp8BqLuvp4IYGOGqI2F3VStxTtGFVjXQB6Vtb/29h+5Stg2hzX/hAAUqqM0ScOez8b/90hn67z28ulflbomh9sJvwBM+X8RBFWNfxzf+UKyuqlts7/aDCM3yjY7cMWhovnAAAAAElFTkSuQmCC)}.icon_menu_file:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAhkOAhnRgh0fAAAAqElEQVRIx+2S0Q2AIAxEizH+uP8ejuAS7uAU6I/EagK9I0Ex0s+WPu44RD5eG1l+XsdCaALOo2F4DhqEh8OsBADOov0EwzU6Zl/PlgGGs2gRGM6jYXgOGoTnoSE4+0POzhUeuk6vHC1nodPzsN9z69a1ujr8KFsF0ZEHSRmPze6P+Lxq+wvaTn4TY72qW4yAwfpVtxgBg/WrbjECButWzUb4gupvogvWDhbQRLGuGTBeAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTAyLTI1VDE0OjAyOjI1LTA1OjAweoAuRwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wMi0yNVQxNDowMjoyNS0wNTowMAvdlvsAAAAASUVORK5CYII=)}.icon_menu_find:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAhkOBSzIcE/7AAABz0lEQVRIx+2Vv0tCURTHj/JQQtSGMCTeUv+BS4SLg7TY0A/c3aI/oD2IaJFo7QdhQ1tDS0uLQkPgIP3AJpewSB4hpLyX9N49p8H7/JH6fO/pGwS/y7vc+70f7jmcdw7AVFNNgvbc6gqlKY9lamCZ8ixDa+QdA5aSWKJeVdh2VhgBLIfxngYKXxqLNsG/EfwkQ2GVlm2AlQX8aCFkdqYlFJG8iqhG2SF+teiSIloEZwXMt8DX9VD3Kc3SaQv+ZDHnWkq/ydL9HexAd2gpa2/mVcGuBrvokkdVslCKalzP8f9UdKoeQrnpU+PtXbcxWthofl0ZvzTY5ZdcF91+E8ICT2PM2EcxHt2DaTRJHB0w9iki95XMo7mG+gLc+N3ecw+7pF81Pv8J8kXNNJpe+SJi7JtZ4v5302hXji+SQ8La4uhnc1kAAG3Tfl0PEXlRMv830pulwcB2HeohRQ/edHTl8XW+bjDv1ydaguazAs2rUdq32a97wUZTRo05A7YyG/ukIsd2OsJvy9pE7weu+ACKHnWVHeMjyohUwQLLaOsVn+2qaINH1uSBAdiRQ2DyUsMRMEA95BAYAIDuHAIDyGG8RSSi8zGDm6oGa3MOYKdyUH+ZeN9fBECCTQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wMi0yNVQxNDowNTo0NC0wNTowMPhENw0AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDItMjVUMTQ6MDU6NDQtMDU6MDCJGY+xAAAAAElFTkSuQmCC)}.button_clear_find_replace:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAhsMIBioundMAAAB2klEQVRIx+2Vv0sCYRjHH0WUELUhFAmX+g9cIlwcpMWGfuDu1l/gHkS0SLT2g7ChIWhoaWlRaAgcpB/Y5BIWyRFCyl3S3fs8Db53+OM879QbQr/Lve+93/fz3vvw3PMAzDTT1GvXKa9SlopYpRZWqchytE6eCWAphRXqV43t5F1jgMUw3tNA4UtraUTwbxQ/yVBYp5URwNIifmgIkZ0qSSlCHikix9gBfml0QYpYBOddWNTA181g9yrN04kGf7IYcyWt7mRZfQfbVx1K2to386xgl4NddMFvVbGQinJCjXFvKDrVDKLY9skJ9Z1zGNq12X46cj5hsMsnOM67/SaEJR7GuLGP4vx2D6bRJHC0HwBAP6cBAKQIn1TMozu2G6HJzyffpmOtHeE3Xv8J8EHDNJpe+SAKAODQFQDA3DL3v5tGOwp8kBpi3OboZ9OxVrZGzeuhIg8K5v9GerPUGFjGphpSdrOrjqo8ucpXduNNT8kX2bGSpFDeRSE5Rnsj1ut+sFGXkeP2gK30Rp1QFFhGzZYuWevoeuCaF6DsltfYET6iiEg1LLGcslHzWsoKffDY+n9gAHZoE5g81LIFDNAM2gQGAKA7m8AAYhhvEYnobMLgtuqBxoIN2GnXH6JDC1rOy1oRAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTAyLTI3VDEyOjMyOjI0LTA1OjAwYlC5TAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wMi0yN1QxMjozMjoyNC0wNTowMBMNAfAAAAAASUVORK5CYII=)}.button_clear_clipboard:after{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAhsMHhWXzhCMAAAB0klEQVRIx+3XMUvDQBQH8IdDHBwEBzuEiogUxKU4BBwC2f0ofoQugqOze12dCtLBr+DQLUsGN8FBKkUS0lzynkNMc5dcLsmlcdE3lrtfr+n732sB/uuvVWThHF/iqx5Y+qkt8jy7RV7GboFXsR34JqwG34ZtweuwDfgurJJPrruyWSX3v3fqXp91zx3Sc1+34Vuzy/0mPM/mO2rOinEyDU9VPM9+HSZ36NecX7iVK/kyW/N4Igvn+Jovk/PVrIKPLHoITOYUF+MqGJYPImdrvlh2iR/cQp856euu0YmlgWsARBe45GHXoAEAHSWTYKjFAgQmejhzDYD1GT3lMM7QC0yAcISeBpvCREQpDsAcZqcwEVGKZ2tahYbflOE5XIU3yiId4xu3ZeYaIpzRqwNcyLqbbhVvEo5E/H2vGpZ3t+IziDh9FmHaxYUqi0q+gAswAEBk1WWRSDrA5HgO56XZ3etzRG5pHJ4AANBjdptossWuyLslusAlxslUk5XBIk6kxVbBarxRaIoBYbaQOwnecC7KklcItYC3+XEw5sbQpt2Em8WPxgCugc+tp3g2X8Q+3tyHPnMAbnaSidY/AeagXw5IYKKXzxrtYnY5eQCByez21jfS7c0ah6R+cwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wMi0yN1QxMjozMDoyMS0wNTowMDSdRtYAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDItMjdUMTI6MzA6MjEtMDU6MDBFwP5qAAAAAElFTkSuQmCC)}.widget_pane{flex:2;display:flex;flex-flow:column}.pane_item{padding-bottom:3px;cursor:default;display:block}.pane_item.input{display:flex;height:20px;min-height:20px;flex-flow:row}.pane_item.input input{flex:2}.input .inline_button{width:21px;text-align:center;padding-left:0;padding-right:0}.input .inline_button_tripple{width:67px;font-size:.9em}.auth_button_wrapper{margin:10px 0 20px 0}.button.auth_button{background:#7d18ff;padding-left:38px;position:relative}.auth_button:before{content:'';position:absolute;top:1px;left:1px;width:25px;height:25px;background-size:contain;background-repeat:no-repeat;background-image:url(data:image/png;base64,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)}.find_result_line_num{color:#1b2c48;text-align:right;padding-right:3px;border-right:1px solid #3f5b8a;font-weight:700}.find_result_text{width:100%}.find_result_text_inner{position:absolute;left:3px;right:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.find_result_match{text-decoration:underline;color:#1b2c48}.find_info{text-align:right;padding-right:5px}.file_info_overflow,.find_info_overflow{vertical-align:top;margin-right:5px}.clickable{cursor:pointer}.widget_pane_bottom{margin-top:3px;text-align:right}.widget_pane_bottom_before{flex:2}.pane_item:not(.no_select):hover{background-color:rgba(110,160,243,.28)}.find_results{display:table;width:100%;border-collapse:collapse;white-space:nowrap}.find_result_item{display:table-row;cursor:pointer}.find_result_line_num,.find_result_text{display:table-cell;padding:2px;position:relative;white-space:-moz-pre-space}.find_result_current{background:#5084de;cursor:default}.find_current_match_marker,.find_match_marker{box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;position:absolute;border-bottom:1px solid red;z-index:10}.find_current_match_marker{border:3px solid red}.editable_text{font-style:italic}input{min-width:20px}.details_file_description_input,.details_file_title_input,.gotoline_input{font-family:inherit;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;width:100%}.details_file_description_text{max-height:6em;overflow-y:auto}.find_input,.replace_input{width:100%;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box}.details_file_description_input{min-height:6em;width:100%;box-sizing:border-box;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;min-height:6em;max-height:6em;max-width:100%}.widget_divider{background:rgba(0,0,0,.3);height:1px;margin-top:3px;margin-bottom:3px;display:block}.widget_box{border-top:1px solid #fff;margin:3px;padding:3px}.widget_box_title{font-weight:700;margin-bottom:5px}.widget_firstime ol{padding-left:20px}.opener_button{text-decoration:none;display:block}.shortcuts_header_action,.shortcuts_header_key{display:inline-block;width:120px;text-align:center;text-decoration:underline}.shortcuts_list{max-height:132px;overflow-y:auto;overflow-x:hidden}.shortcut_item{border-bottom:1px solid rgba(0,0,0,.3)}.shortcut_action,.shortcut_key{width:120px;display:inline-block;vertical-align:top}.shortcut_action,.shortcuts_header_action{width:100px}.pane_spacer{height:.3em}.noselect{-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-o-user-select:none;user-select:none}.ace_selected-word{background:#f3e99d!important}.ace_gutter{-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:-moz-none;-o-user-select:none;user-select:none}.ace_editor,.find_results{font-family:Monaco,Menlo,'Ubuntu Mono',Consolas,source-code-pro,'droid sans mono',monospace!important}.dropdown{width:120px;cursor:pointer;padding:3px 6px 3px 6px}.dropdown_item_list{height:200px;width:120px;position:absolute;background-color:#f6f6f6;color:#555;overflow-y:scroll;overflow-x:hidden;line-height:1.1em;moz-box-shadow:5px 5px 5px #888;-webkit-box-shadow:5px 5px 5px #888;-moz-box-shadow:5px 5px 5px #888;z-index:100}.dropdown_collapsed{overflow-x:hidden;text-overflow:ellipsis;margin-right:12px}.dropdown_collapsed:after{position:absolute;top:1px;right:4px;content:'\25a4'}.dropdown_collapsed.selected:after{color:#555}.dropdown_item.selected{color:#dd9430}.dropdown_collapsed.selected:hover,.dropdown_item.selected:hover{color:#ee9430}.dropdown_item:hover{background:#fff;color:#333}.button_wrapper{text-align:center}.button,.button_like{display:inline-block;width:auto;padding:6px 15px 6px 15px;background-color:#5892fd;border-radius:2px;box-shadow:0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);-webkit-box-shadow:0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);-moz-box-shadow:0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);color:#fff;font-weight:700;position:relative}.button{cursor:pointer}.button_like,.inline_button{padding:3px 6px 3px 6px;margin:0 0 0 2px}.button_like{box-shadow:none;-webkit-box-shadow:none;-moz-box-shadow:none;margin-bottom:1px}.button:hover{color:#e5e5e5;box-shadow:0 0 8px rgba(0,0,0,.12),0 2px 10px rgba(0,0,0,.24);-webkit-box-shadow:0 0 8px rgba(0,0,0,.12),0 2px 10px rgba(0,0,0,.24);-moz-box-shadow:0 0 8px rgba(0,0,0,.12),0 2px 10px rgba(0,0,0,.24)}.button.selected:not(.no_select),.button:not(.no_select):active{color:#adc7f1;box-shadow:0 0 4px #17396f inset;-webkit-box-shadow:0 0 4px #17396f inset;-moz-box-shadow:0 0 4px #17396f inset;background:#3963ab}.inline_button.selected,.inline_button:active{padding-bottom:4px}.dropdown_button.selected,.dropdown_button:active{padding-bottom:2px;padding-top:3px}.replace_single_result{padding:0 3px 0 3px}.button_up_down_wrapper{display:inline-block;margin:-3px -6px -5px 2px;line-height:0;font-size:9px;position:relative}.button_like .button_up_down_wrapper{border-radius:2px;box-shadow:0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);-webkit-box-shadow:0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);-moz-box-shadow:0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);cursor:pointer}.button_up_down_wrapper:after{position:absolute;top:-2px;border-left:1px solid #3262b1;height:21px;content:' '}.button_down,.button_up{height:9px;width:19px;display:block;position:relative}.button_up{border-bottom:1px solid #3262b1}.button.selected .button_up_down_wrapper:after{border-color:#2b5192}.button.selected .button_up_down_wrapper .button_up{border-color:#2b5192}.button_up:after{content:'\25B2';position:absolute;top:4px;left:5px}.button_up:hover:after{top:3px;color:#fff}.button_down:after{content:'\25BC';position:absolute;top:5px;left:5px}.button_down:hover:after{top:6px;color:#fff}.dropdown_valign_fix{width:0;padding:3px 6px;margin:0;display:inline-block;position:relative}.dropdown_button,.dropdown_button.selected{padding:0;vertical-align:top}.file_details_save{margin-top:20px}.font_size_decrement{font-variant:small-caps}.font_size_increment{text-transform:uppercase}.file_info{font-size:.8em;min-height:1em}.recent_line_1,.recent_line_2,.recent_line_3,.recent_line_4,.recent_line_5,.recent_line_6,.recent_line_7,.recent_line_8,.recent_line_rm1,.recent_line_rm2,.recent_line_rm3,.recent_line_rm4,.recent_line_rm5,.recent_line_rm6,.recent_line_rm7,.recent_line_rm8{border-right:4px solid;padding-right:9px!important}.recent_line_rm8{border-color:#e2f4d4}.recent_line_rm7{border-color:#e2e4d4}.recent_line_rm6{border-color:#e3d4d4}.recent_line_rm5{border-color:#e4a4a4}.recent_line_rm4{border-color:#e68383}.recent_line_rm3{border-color:#e75b5b}.recent_line_rm2{border-color:#e74646}.recent_line_rm1{border-color:#f31a1a}.recent_line_8{border-color:#f4e2d4}.recent_line_7{border-color:#e4e2d4}.recent_line_6{border-color:#d4e3d4}.recent_line_5{border-color:#a4e4a4}.recent_line_4{border-color:#83e683}.recent_line_3{border-color:#5be75b}.recent_line_2{border-color:#46e746}.recent_line_1{border-color:#1af31a}.revisions_view{overflow-y:auto;height:100%;width:100%;font-family:monospace;position:fixed;top:0;left:0;counter-reset:trueLine}ol{margin:0;padding:0}ol .rev_line{padding-left:2.5em}ol[digits='###'] .rev_line{padding-left:3em}ol[digits='####'] .rev_line{padding-left:3.5em}ol[digits='#####'] .rev_line{padding-left:4em}.revision_tick_box{position:relative;display:table;table-layout:fixed;width:100%;background:#fff;height:3px;border-top:10px solid #3963ab;border-bottom:10px solid #3963ab;border-radius:10px}.revision_tick{background-color:#fff;height:3px;width:0%;display:table-cell;position:relative}.revision_timeline{position:relative;margin:5px 0 5px 0}.revision_at_range,.revision_from_range{-webkit-appearance:none!important;width:100%;background:0 0;position:absolute;z-index:2;display:block;box-sizing:border-box;padding:0 7px 0 7px;margin:inherit}.revision_at_range{top:-15px}.revision_from_range{top:7px}.revision_at_range:focus,.revision_from_range:focus{outline:0}::-webkit-slider-thumb{-webkit-appearance:none!important;width:6px;height:15px;background-color:#5892fd;border-radius:2px;-webkit-box-shadow:0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);cursor:pointer}::-moz-range-thumb{width:6px;height:15px;background-color:#5892fd;border-radius:2px;-moz-box-shadow:0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);cursor:pointer}::-moz-range-track{background:0 0;border:none}.revision_at_range:focus::-webkit-slider-thumb,.revision_from_range:focus::-webkit-slider-thumb{background-color:#32c6ce}.revision_at_range:focus::-moz-range-thumb,.revision_from_range:focus::-moz-range-thumb{background-color:#32c6ce}.revision_at_range::-webkit-slider-thumb,.revision_from_range::-webkit-slider-thumb{margin-top:5px}.revision_at_range::-moz-range-thumb,.revision_from_range::-moz-range-thumb{margin-bottom:5px}.revision_tick.downloaded{background-color:#ffa300}.revision_tick.diffed{background-color:#5892fd}.revision_caption_at,.revision_caption_from{padding:4px 3px 4px 3px;font-size:10px;line-height:9px;min-height:18px}.revision_caption_from{text-align:right}.revisions_view .ace_line .ace_fold{display:none}.special_1,.special_1_first{position:absolute}.special_2,.special_2_first{background-color:#bcebe8;border-right:4px solid #069147;color:#069147;position:absolute}.special_3,.special_3_first{background-color:#ffcaca;border-right:4px solid red;color:red;position:absolute}.special_2_first:after{position:absolute;right:4px;top:1px;content:'lines added';font-family:sans-serif;font-style:italic;font-size:.6em}.special_3_first:after{position:absolute;right:4px;top:1px;content:'lines removed';font-family:sans-serif;font-style:italic;font-size:.6em}.gutter_special_2{background:#9edcd8}.gutter_special_3{color:#bfacac}.revisions_view.ace-tm .ace_marker-layer .ace_selection{opacity:.75}@keyframes progress{0%{left:0}100%{left:100%}}.widget_pending_inner{position:absolute;height:0;width:5px;top:2px;box-shadow:0 0 20px 10px #bda1b3;-webkit-box-shadow:0 0 20px 10px #bda1b3;-moz-box-shadow:0 0 20px 10px #bda1b3;webkit-animation:progress 1s 0s infinite;-moz-animation:progress 1s 0s infinite;-ms-animation:progress 1s 0s infinite;-o-animation:progress 1s 0s infinite;animation:progress 1s 0s infinite}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px)}}@-moz-keyframes shake{0%,100%{-moz-transform:translateX(0)}10%,30%,50%,70%,90%{-moz-transform:translateX(-10px)}20%,40%,60%,80%{-moz-transform:translateX(10px)}}@-o-keyframes shake{0%,100%{-o-transform:translateX(0)}10%,30%,50%,70%,90%{-o-transform:translateX(-10px)}20%,40%,60%,80%{-o-transform:translateX(10px)}}@keyframes shake{0%,100%{transform:translateX(0)}10%,30%,50%,70%,90%{transform:translateX(-10px)}20%,40%,60%,80%{transform:translateX(10px)}}.shake{webkit-animation-name:shake;-moz-animation-name:shake;-o-animation-name:shake;animation-name:shake;-webkit-animation-duration:1s;-moz-animation-duration:1s;-ms-animation-duration:1s;-o-animation-duration:1s;animation-duration:1s}::-webkit-scrollbar{color:inherit}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.3)}::-webkit-scrollbar-thumb{background:rgba(200,200,200,.8);-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.5)} \ No newline at end of file diff --git a/css/app.css b/css/app.css new file mode 100644 index 0000000..17542ab --- /dev/null +++ b/css/app.css @@ -0,0 +1,894 @@ +html{ +height: 100%; +overflow: hidden; +} +body{ +position: fixed; +height: 100%; +width: 100%; +overflow: hidden; +margin:0; +} + +a{ +text-decoration: none; +} +a:hover, a:visited, a:link, a:active{ +color: inherit; +} +.the_editor{ +position: fixed !important; +top: 0; +right: 0; +bottom: 0; +left: 0; +} +.widget_content{ +margin-left: 34px; +padding-bottom: 5px; +margin-bottom: -3px; +margin-right: 3px; +padding-right: 5px; +padding-left: 5px; +padding-top: 5px; +min-height: 208px; +cursor: default; +border: 1px solid rgba(0,0,0,0.3); +box-shadow: 0px 0px 5px rgb(11, 83, 195); -webkit-box-shadow: 0px 0px 5px rgb(11, 83, 195);-moz-box-shadow: 0px 0px 5px rgb(11, 83, 195); +background: #4973B9; +border-radius: 2px; +display: flex; +flex-flow: column; +} +.the_widget{ +background-color: rgb(50, 98, 177); +color: #fff; +border-radius: 2px; +display: block; +width: 290px; +position: fixed; +top: 0; +left: 0; +z-index: 100; +box-shadow: 2px 2px 5px rgb(66, 133, 244);-webkit-box-shadow: 2px 2px 5px rgb(66, 133, 244);-moz-box-shadow: 2px 2px 5px rgb(66, 133, 244); +font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; +font-size: 0.8em; +border: rgba(0,0,0,0.3) 1px solid; +} +.widget_text{ +padding: 5px; +display: block; +margin: 2px; +border-radius: 3px 3px 0px 0px; +min-height: 2.2em; +cursor: default; +} +.widget_pending{ +position: absolute; +left: 0px; +right: 0px; +top: 0px; +height: 4px; +background: #D04BB2; +border-radius: 2px 2px 0px 0px; +box-shadow: 0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);-webkit-box-shadow: 0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);-moz-box-shadow: 0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24); +overflow-x: hidden; +} +.widget_error_text{ +display: block; +margin-left: 35px; +right: 0px; +background-color: #f00; +color: #fff; +cursor: default; +padding: 5px; +min-height: 25px; +} +.widget_error{ +position: relative; +} +.widget_error_mark{ +position: absolute; +width: 21px; +display: inline-block; +text-align: right; +background-color: #f00; +color: #555; +font-weight: 900; +padding: 5px; +top: 0px; +bottom: 0px; +} +.widget_menu{ +cursor: default; +width: 34px; +position: absolute; +padding-top: 8px; +} +.widget_menu_icon{ +position: relative; +background: #4973B9; +padding-top: 4px; +box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; +border-radius: 2px; +margin-bottom: 4px; +border: rgba(0,0,0,0.3) 1px solid; +border-left: 1px solid #4285F4; +margin-left: -1px; +width: 32px; +height: 32px; +text-align: center; +text-decoration: none; +color: #fff; +cursor: pointer; +vertical-align: top; +box-shadow: 0px 0px 2px rgb(11, 83, 195);-webkit-box-shadow: 0px 0px 2px rgb(11, 83, 195);-moz-box-shadow: 0px 0px 2px rgb(11, 83, 195); +} +.widget_menu_icon:hover{ +background-color: #6EA0F3; +box-shadow: 0px 0px 5px rgb(194, 217, 253);-webkit-box-shadow: 0px 0px 5px rgb(194, 217, 253);-moz-box-shadow: 0px 0px 5px rgb(194, 217, 253); +} +.icon_selected, .icon_selected:hover{ +background-color: rgb(62, 113, 197); +box-shadow: 0px 0px 6px rgb(11, 22, 41) inset;-webkit-box-shadow: 0px 0px 6px rgb(11, 22, 41) inset;-moz-box-shadow: 0px 0px 6px rgb(11, 22, 41) inset; +} +.button.icon{ +padding: 4px 4px 4px 4px; +} +.wiget_item_icon{ +display: inline-block; +background-color: #5892FD; +border-radius: 2px; +padding: 1px 3px 1px 3px; +} +.widget_menu_icon:after, +.button.icon:after, +.wiget_item_icon:after{ +display:inline-block; +width: 22px; +height: 22px; +background-size: cover; +content: " "; +} +.wiget_item_icon:after{ +width: 16px; +height: 16px; +position: relative; +bottom: -1px; +} +.widget_content.flipped{ +margin-left: 3px; +margin-right: 34px; +} +.widget_menu.flipped{ +right: 0px; +text-align: right; +} + +.widget_menu_icon.flipped{ +margin-left: 3px; +margin-right: -1px; +border: rgba(0,0,0,0.3) 1px solid; +border-right: 1px solid #4285F4; +} +.icon_goto:after{ +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtAQAAAAASYd83AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAnRSTlMAAHaTzTgAAAACYktHRAAB3YoTpAAAAAlwSFlzAAAOwwAADsMBx2+oZAAAAAd0SU1FB+ADAQ4DKt+EG4gAAAAnSURBVBjTY2AgE/B/+P///wHSKXyGcQiAKe4LuCmoEiIMo47L8AAAw4pvQ77peO0AAAAldEVYdGRhdGU6Y3JlYXRlADIwMTYtMDMtMDFUMTQ6MDM6NDItMDU6MDBBZS5oAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE2LTAzLTAxVDE0OjAzOjQyLTA1OjAwMDiW1AAAAABJRU5ErkJggg==); +} +.icon_replace:after{ +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAwENNRnrDlWyAAAAhElEQVRIx+3VsQ2AMAwEwIeChtGyLCPgIdgBZYiYggpTIIE/RIq/jJSTHNsK0Eq2qSx6S1n3OfDA28XVJSc+WNqhGAAqOZFoQIVGA6MfVY1WIdEqOdkjx+H7FNo+dgQ/XQyYD9fvei/wm9BgQ3vChvaErzTxb2Q+CLGN1OGjrkzggf+BHwa1kHkrdOrtAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTAzLTAxVDEzOjUzOjI1LTA1OjAwTomzewAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wMy0wMVQxMzo1MzoyNS0wNTowMD/UC8cAAAAASUVORK5CYII=); +} +.icon_demo:after{ +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAwEKEB6Y1gZzAAADMElEQVRIx+2WT2hcVRTGvzuNE+ogQpF2IZQiEhARgpKFSEsNgqgwKDS4aHGRKCKTRVUiSEXGboQIRQipFEpcVCgNQYgi3RRTUwqShQoythT/UGroECVhHBom8949PxfvpvM32qZPUcjZnXcfv/Ode7/z7pO24n8VpSwD7CvnUkRWdpBnnAvUAKwSDd4xsvYgh/wJK5kB2KLdAABb3qTyuR4G/GGboUwIqzPCHvaFbBEYui3k8r3xM/6onQvaanaRywnMH5VKWbsEYFX6gclbQrI7fpEJ+y5pO8RL9LKLFQC7wnbJvxtWRiUr2fm/ABYz9X5f8KdtMbT8NRNMh5ZnJInZJIsGpVofqwAszPVI/gw1ejuQ5Vz0FO/YWas0aSR+WfrtnlCmunq/FB8IS6ckyb4EsJh+qdZnMbC/Tal/36rhpRlf4JWwCV9JEhNhZwtNZX6v7pQ4FFaONcr4t1vQ/vC6Sn9Mmuvh22Qz1h6SGLC4UcZPNrr54z5bAuBqOSfFBwNiugVt34THV8s5yb/ROP+2MsFmoczJkA0xwGjSDXCtOzovsTsxmf3Idsm/1sVmLWXMwiwu2ae8GT1RyrbabLLz/MlLG9jsZHzQn7DrIbvsp+LhWt9GDh4Cu1F7oHH+SRl/pmGztUeCzcIc2kXGyVd2/M1wVHeC/6jdZtHTAXOJcRaSw7RlZhmL9nZx74aTt2TnGzZjVGKP/dyk8oqf8q+uPVzM3DLyJnqapXWbWd0+D+pjFvyH8QF23TawydkFsGs3NVbsrD8SDabycedxAH7hlC/U+zfRdpdwAd3Ldc2zmAZS2lZoQkuQDlaSnJOkltaZ/aHXuegxVpLcPn5vm3Pxk6yGFz5wzjn/AlHI33LOOT+SyAI/4pyOd1QCmy9lpfqjthyGe6qYkaL96zcf45IUP2/1kI9JUjwcbkiLhyXJn+7oP7l87hTMGHRFpwPugrb5dMDdVJMOeB3dYT4ifeZM4jl3tySx6r6QyCjv7pIkVtw5iazyicUouwsSOfdsu/n+LV+nG1voLfR/AP1rasyf2tB2fLOk9rBP2h4UM7xu34e/0s1H2Rfnev6hHW7En9IBXncI9iF/AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTAzLTAxVDEwOjE2OjMwLTA1OjAwOyFISgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wMy0wMVQxMDoxNjozMC0wNTowMEp88PYAAAAASUVORK5CYII=); +} +.icon_drive:after{ +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAACW0lEQVR42u1bvUoDQRC+N/FFfA9fwzewCSTNVWkMCLGKjcEmWBmwClYS6yOtKBZ2KgoqXzFBQ+JdbufbmY07sJBcwuZ2b/f7mdkURY4cOXLkyJEjRw69uJvPX97fXr+022BwfOJ64J1OZw+tLMtDxgQ8PT58on+3EzAen9+ejUbXeD2dXt0zJgG/4XLwvd7RvtwkXv98r93Qt7sJuJnNnuUG8fRxDauBMQH4LVeDX7fncQ37dVFVH4xJ6Pf7XTcTsG6QuIbPgNyMCZD+zeOvZX46HF6sbg/NJoBrSnugpjraKrvdAxYtmgLi5WRS1d0kvtP0u22a9O8C+DY1rIC61RLScC+mtNeUtoAJO0GLbZBddDyLFqP5hLZLGQPfCZ8Qou7YPoFOixr6PmmfoCFokvUJmntXfEJStKiJ3sgYJeUTGPydjE9gLVX0qb21KLQYQ8O79QmxXJxbQIy5P93RogVCu/EJVrk8FiCKD4mi90OXozktWut0c5/goaLDWoHiQ4rYe3BbUWJGi56yNdFZiJWvE+PjqcwuPqTwrsSibUkAlNecPbYCQFG7LR/MzlZtrMFGhAdL2KiCszb6i/SE7PU6+F9soA02ovdZtEoBZy0FKHqfpeZoilBLg7MLoVRPEPrURO+zUlx0VxiSB1gehiCJl2h5gba0yE5zR/Uk2w6CXeiInhvcVh2yS10mnqQpkLGLnWaepMkTFb3PTGOZVojqcgQp6P3gGuEmWmQfeXFTJd40wCT1vlaJLAW9r3pSZBXkktb7oafD2Edf3Z4WE5/APPz8L/5X5C2+AYmN7rykLUrGAAAAAElFTkSuQmCC); +} +.icon_bug:after{ +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAwEJOg+fS1TwAAACu0lEQVRIx+2WTUhUURiGv3sdR2qQJhRLCBGJJCxXRbgRW4TYKrIWIZVY0CKQdm0iBsOVFVS0EZE2LtpFILXSWkQkUZsmp9Kk7GdQcNJpbH7O+d4WM+Nc9Zz7N0EEvZvhnvOeZ77zfufMXKL/+utK1fM4p/jlr0b/Do3wFAAAfuLfoVuYzi/EstaxbO8wtewXhc93WkdhBm89Vp1PEuAkmlXz4hjAgoWPrPOSYwC/R3jjeHoPEoC86Aua12I1YgA/yLXJmxzlFKc4Ku+hGzEAw2WAiYjQilWoFMMW+5WmI7sZUH5lk+wpq2ZxmhkaMYvePx9GEZ5Fuy9wPIQYnBSPh1xlndmLhtJTTZs65XX7Mms7LU9htKptVwBmfiROoGptrF4cx3We4Gle4iQLZqzyEk/zhByRF0qgiIkOOYY0gGvFMaOE5nHjaAGYwKj5ndOZh1vn7aterN5+hGoqdtA5aiysfWx2bUJn9lfeMg5v2Mms8ZzfmB9zHzLfPv9oyRJFgw3hynDVTtlUsY8O0UGqWuePibPBKWUV6SY5gE+6nhERaRuawN3sAYfWREx08DMvaH5l7Y9T50c8VT2iYugu+i6XNdi4dejdntBObjnISfurpw3EqjtFnuXwOd89w3DhWjG2bQqEb+CnpxjUuu8wjxlPhy+qYujaOOOlUEPp1qG/eAph1qVvMiBO8bSnEzIn+xerHbDxkOzneT+HjxdkJFmnwUaDchCJss51GsPKfx05YK1A3naLlkPWncoBBRqXAYDn87kl6zjlCr2arCOaDOAMRwFAXlUGInpFz2RgbRdDbtByqOiPmKJLXnL147pSy18d0Qva1tkr187CDs2MTl9gIiLRZ317Wo9mFn2+wUREOFlqpxXNWXG+LDARUaaFJzahX+faygYXau+Qo5giIsIcj6M74vyG+4/qN/nGPQCtT8I2AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTAzLTAxVDA5OjU4OjE1LTA1OjAwn7bIPwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wMy0wMVQwOTo1ODoxNS0wNTowMO7rcIMAAAAASUVORK5CYII=); +} +.icon_about:after{ +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAwEKChW/KSUgAAACJklEQVRIx+2VQUgVQRjHZ56b8hDqJRR4EB4idghPQdGtS4cIIgIRpGuCRBehUyCeO3WpDkGdIjCR8hJBmCHi1csTEhEhIkkxXrHbru18/w47u+7Ozrxm3/pO+T/tvO8/v/nm/y1vGTvWsf5zYRR3OoBtdIunACBe7fQe/hreENM0T5slwP4grSHWRjCS3EOqTBBNpOXFwZRCx0GoioIpgc4EoWojGGkbnQtCldcW2hSEXsWCWLUHF0CHt2ivCBjAbPptNwfxiKggGAA1/MEjDSID3w+vpVld2SCcBT5seFsE+8Sfs7e0wndR5915B6/y8Wm/srqkJt86CJrzBg69v8628M7unyoSxMOZitqjmDK2sRWcT1+3Tq7R+i52NftwFbV4RR8Mfhfnsl3cNaH/XJaTuAkPwA9ckuvrer+YUi44U6FFrfN70uU32dVitPYGtP7lj07+HaiTSwdiUrE2ZPVMcmH5x4+TinOU3HQYqRP4djiB7RMreJI5sF88ZowxqkaTBOiBDORitj3+OljvuuB8ZmahpcS9JKD5bIX9W2YsHYRjieu+Wi2Fxu3I4fbT+3yxBFq8jOr+EH3V1ct0fUVmvKAvt4/20SPrX+zQFYuzIv3kgXzqsdvg2NkYQ42W4idutUPjapnab1Y1ohSWfSCMXrDT6zX2zH6Hpmv9GKMPK6rwj3qMUnuO7RjtuwbN+cPNPnpjquey16Hba6nEGIuqg+gO6i8I2MuT5gMfBQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wMy0wMVQxMDoxMDoyMS0wNTowMFziMycAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDMtMDFUMTA6MTA6MjEtMDU6MDAtv4ubAAAAAElFTkSuQmCC); +} +.icon_menu_help:after{ +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAhkNNzLdSZiwAAACOElEQVRIx+2XPWsUURSG3ztOZpG1sImkCQoiQRetLC22EyximmARsBJE2MbYCq7+BItACsGPSiv9BWLMEj9AEnACFmJAhZgRU+iGzGbmvBabHSd3587HZtZG32qGOfOcM+fcuedc4L/+llS2iX/SOSdn1RkcRxUj+IUfeM/XVuv2YlMG9stKeJUrNOkTb/LwANimxcvymVna5A1WCoG3xuVlJnZXsswTucE75+V7XjBJSjuYygUOpqRTBEyS0gmms0t3wQyWFhtsJFdAOsFkOvgYN43gpec2APinDc9/ciJlVUjL/NHhbBSAaeW86TpPUHgtLZ/h3a6V63DbaNRIBK9XZSO9VLzkOjwYPkyx2VivJsU8y0xJJ2v1/ElbTOJmo3M4d/vAfq0MMEn6tS4xqqhdNy9JuS7L8fsD99VRs7Vdx97I+SQlEM0t01P3qGtlReY1lKQeKWoF3IZxc+QzfgWsx2qhFzVOpbA9dWRPrpGy66qLCgBcLBSJ3ipinFMVHe2XhvY1ND+WReYXDa3cQVG6eqQILS/KQssrDR0ulYUOFzW0846rZYC56qxoaID3SkFHlBjam6e3b7DnzfeuY71srB3eUnNJL8gDrAHW2+h+DqOAmlZ9v7u6M9ZO9Glsu/XECPv3SnPbNQ4LudD6sKB5UWuc4VM1oiWkztEE9Hh8guaOzNgfMkoxtMEMAILJYuMkt3KOk8AQh2AAaFrBlaGM7rul2deBo8gxaQKHYKONbyUck/5F/QY186l/0kIl9wAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wMi0yNVQxMzo1NTo1MC0wNTowMMyFuZoAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDItMjVUMTM6NTU6NTAtMDU6MDC92AEmAAAAAElFTkSuQmCC); +} +.button_history:after{ +background-image:url(data:image/png;base64,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); +} +.icon_tips:after{ +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAwEKMzT9xLjEAAACsElEQVRIx9WXv0sbcRjGn28SorZqlyZaVDyqRWpoQUG6FbfuhXR2KQX7F3Tr4tSlIKWLU0cFKUKHTpJJUIhUiZTWwhVqLUkx1JiQi7n36RA1l5rk+72LS5/pfrzv533vee89OOB/lDILY0/1YeSODAGhAxwWUv2/r6Q6J7gkf+iRVOR95UGH2F/X3dcss4lE3HfHNwODS0OyyzaSL+XbwYyw5IAaySEnfIMzUdnUgUmSn9jjt+cFIzBJ960vcCEuRVO0VMvjPtDuK1MwSbpLzRgtVoZZxHx0klPxyxdDTcEzXjBLTGELAPiTKXwFAO4xxdxFSIwzpna8aHjeZYBJknSfA3xDkk4CkIwnZt6w61CDGbIHSAIAQhmACQBOdJ9daswTZGpIo8+hDBCaBICTPUBNAvymnMo4ujxBw6boBjnbAKYB/OjLlkYQA1QaiE41BB0bomXXm9S9z36MAUgDPVMAIOfF6rIN0aer9WNeYGQbkGkACKUBetB0saZ/+vO+P1zMvizZ2tdaCpJliSTlSLJS9eyjORhw7nlTNYtece76QANcNF7zl77AQK6Pn43Im+sRn2iA92vOtlW2NOIbDAB8qnFZ+CgQGADcpbbshcBgIBOVdMueNwK47FV1rhW6Otc+U/sNCRf93zFEB5ce7dANhtYOQq2td88OVy1lKQuWstQoR1T4StBOIjLr2mLntwbPvF2P1EqFdzRN6dBMYvnsKKds2LDlO23XztuDRV2uFt3y5XvcoSEnqd4nsMRSFixY6lr9TljjuBbdl8VK/awQ7x2FVSvl5jv0+nQ2Mh/MX23XkRiStdc/jAGIZ5TFjRtH5oWaqPUYmeywa7VSGKj7++8oO/L6ss5HiY+q7dKY/jfekmfcCaeVHcjVtujEmb95prhYiHdOvIyuKWGS8xenkI2pw9OgUQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wMy0wMVQxMDo1MTo1Mi0wNTowMDjUOB8AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDMtMDFUMTA6NTE6NTItMDU6MDBJiYCjAAAAAElFTkSuQmCC); +} +.icon_shortcuts:after{ +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAACS0lEQVR42u2YT0hUQRzHV0Ot7B+kpAcLoi5h4IodRALRMiiIyEuX6t4hAj0kIh26dJcO0aGLipo38RoidAj2ELKHYvFgy3bYdXdrefu/3e0zy1rb25ktlXKC3w++zLz5vvnt583OvDfveTwSEhISEhJ/K+Lx+IlkMulNpVL9NqlUKnX7fL6mX2Adx+nI5XKPisViFJUs1DfiTTabvfADmobb6KulwGUVCoUcehoIBFrK0Bw8thm4CnyGqdK+Df2k2szn8+8Z+bn9Fhyr8GSroBeB7tRCq+NIJHJ0vwX4KDzxP4WeUO2s3C4WqLriLY1ekKCVxB/dHgvmDuVVXT9yb1IOkveBziffBuWVylq7vmNoTjhDfdkwv+Yqo7Hl9mi7T98bhn4OUCOcM2aYu18UrEALtED/hG5HUwrcLdrHg8HgIeqzGm8I9en6odfcObz4twx55/H7dg3t9/ubM5nMeZJcciudTp8lQSP1Hp1fR73RaPQY+51TBt8bi8WO72WkO6lPo3WNnoVCocMkXjP4WnH+O8D6Ke8ZznnL9Ln8z+f0b/YPdi5Egd7F3uM0HZeQ4xY//CocDh+h/KTz6yhMn2HKhwb/M/61vYz0QbWa1ci4hXcRHUCDOr+OhhOJxEn1Lxp8dbts2zE0oCtozAK9hCdlgp78T95cFoDuKEOz/71b/YZg8cvtc/VgKkPz1DtHwyJG0lLgAnwfmO83GekGT2XBqQWl7hSjai5hTtgkdaehHFBP4JqPNeoqUBNqtkk1H2okJCQkJCQkKvEdVcqwyLugx0oAAAAASUVORK5CYII=); +} +.button_share:after{ +background-image:url(data:image/png;base64,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); +} +.button_save:after{ +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAv0lEQVR42u3ZPw6CMBTHcVYP4DFcPIDxCC6egE3P43l06mFY26bpn1Tbwa0khNBQwveXvIXwXj8LUNKuI4S0GaXUyTn3bKGyZRI6hPCIMX5bqGzZHzpdd977T43Ks2uhh1rPUZ4NGjRo0KD3id7eF5ENE2jQoEGDBj0ysE91n1n9Kmgp5XHuBin3ggYNemG0MeZaektorc/NolPPe2TRF2jQa6OnHl8IIQ7/HmvtrXRP+tO+lNbIvYseXxCy4fwA+HnCV+xLsV4AAAAASUVORK5CYII=) +} +.icon_menu_open:after{ +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAmCAYAAACoPemuAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAADSSURBVFhH7dcxjgIxDEDRdHMhas44N+BaHGUUKYEk+s00sS1hi8JPohlsvldLQ5k+wVZUg/kwZGXMhyErYz4MWRnzYcjKmA9DVsZ8iN77i6yMna3xge/xeo7XwZo/2lu11gfjcWhvMRqL9hajS2vtHP/Si7d+6vYd5NkWowuPXMw/mMx/HTaRycPUyORhamTyMDUyeZgamTxMjUwepkYmD1Mjk4epkcnD1MjIPy5uPxAGHrshY8e+GzJ27LshY8e+GzJ27LshY8e+GzJ27LsppZQvqUwO6HT/APoAAAAASUVORK5CYII=); +} +.button_print:after{ +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAAAWElEQVR42u3YwQ0AIAgEMPcfGl2CAIaS+CV9HeA5alhFxK140NBd6Ol9oaGhp6DXjujULIeG3oCeHBLQ0NA/obvOLWhoaJFXgLaaQkMXo/1PQ0NDQ0Nnoh/MPNs/4Cp2kwAAAABJRU5ErkJggg==) +} +.icon_menu_general_settings:after{ +background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAYAAAA6GuKaAAADNklEQVR42u1ZS2gTQRguIoqID4JFRMQg4qUXEaEnwZuIICIUEXoQ9aQgIhYJiBEVvHjxUIrgIR6kEIoIUjz2IAUrooRSDMTQQwiFPDYJeT/1++lGlmUnO9P9dzSSgSGQ3fnnm2/+946NjcZo+DuSyeQ+mfeq1eqpSqVy8q+CrdfrZ1qt1rt2u10ulUoBt/c7nc5Sr9f7hfdXsO56IpHYqQVoOBze3mw2r2LjrwSgPwFiZtC6crk8YX2fJg5hQNaLWCy221fQAPvSvrnJXmYQcwA467QO/6/7zrQTYxa2rzmtISaJVcFhQ1pUBOAWBQB+wthOE3iAnDHnNFTgmYDlTjabPaQFdKPROCdiW2UCc1Sr5wCra15B4/AXtAEmHQXoZQ6m2TwHCSLX5vSMdBCAv3Goh2kHa4VCISjCEo1Gd0iBhuE8h7ANzKcIIH8ExuPxPWDnu9Pm3W63AQNcIMNDoDkBIPtTqdQuwzCOQg3O49kcnpUEjMesjGNdAO/fx/4/CItU8CDAFoE9CPiIxZfx+1bg6j4Ui8VjbrIRwg/i3YhAxnvse5b2IAIsN7EhunVrEJhS0Ek60AMs26boMm+Su1PYZ0oqP5CZ2PyeB19/WwH00painQPgeYYgNS+7H2ETgqZot3lzAy2+msvlDnsFTTpOsiQ8zEqtVpt0SzmDpgfJCViOMKYEERExePZaOf+mrA2LHysbhsJwMnwijFymF6HTdqH5fP4IF2gAnHBg+aLXHCNkF8pZccCOxh1u8hY7aM48Bre2l9OV9tXjhoP7GecCjZB/nNVmdBgipQcshjhULu9fDi7ANfn/hPGhTJiGNjU1PUZGsQhY8LEIyEgFM1G5ZRa0X9zKLToAlWZU35HBupVbkLlqdXHK5ZZkYbvMWNiushS2boMEgbU3DC2Ez+l0+oC23gdHl4naB1o7TNRo4VAPOrwWwKTXIpcFw3mCR1fIh8M4H+H3LrW/qDkp8BqLuvp4IYGOGqI2F3VStxTtGFVjXQB6Vtb/29h+5Stg2hzX/hAAUqqM0ScOez8b/90hn67z28ulflbomh9sJvwBM+X8RBFWNfxzf+UKyuqlts7/aDCM3yjY7cMWhovnAAAAAElFTkSuQmCC); +} +.icon_menu_file:after{ +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAhkOAhnRgh0fAAAAqElEQVRIx+2S0Q2AIAxEizH+uP8ejuAS7uAU6I/EagK9I0Ex0s+WPu44RD5eG1l+XsdCaALOo2F4DhqEh8OsBADOov0EwzU6Zl/PlgGGs2gRGM6jYXgOGoTnoSE4+0POzhUeuk6vHC1nodPzsN9z69a1ujr8KFsF0ZEHSRmPze6P+Lxq+wvaTn4TY72qW4yAwfpVtxgBg/WrbjECButWzUb4gupvogvWDhbQRLGuGTBeAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTAyLTI1VDE0OjAyOjI1LTA1OjAweoAuRwAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wMi0yNVQxNDowMjoyNS0wNTowMAvdlvsAAAAASUVORK5CYII=); +} +.icon_menu_find:after{ +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAhkOBSzIcE/7AAABz0lEQVRIx+2Vv0tCURTHj/JQQtSGMCTeUv+BS4SLg7TY0A/c3aI/oD2IaJFo7QdhQ1tDS0uLQkPgIP3AJpewSB4hpLyX9N49p8H7/JH6fO/pGwS/y7vc+70f7jmcdw7AVFNNgvbc6gqlKY9lamCZ8ixDa+QdA5aSWKJeVdh2VhgBLIfxngYKXxqLNsG/EfwkQ2GVlm2AlQX8aCFkdqYlFJG8iqhG2SF+teiSIloEZwXMt8DX9VD3Kc3SaQv+ZDHnWkq/ydL9HexAd2gpa2/mVcGuBrvokkdVslCKalzP8f9UdKoeQrnpU+PtXbcxWthofl0ZvzTY5ZdcF91+E8ICT2PM2EcxHt2DaTRJHB0w9iki95XMo7mG+gLc+N3ecw+7pF81Pv8J8kXNNJpe+SJi7JtZ4v5302hXji+SQ8La4uhnc1kAAG3Tfl0PEXlRMv830pulwcB2HeohRQ/edHTl8XW+bjDv1ydaguazAs2rUdq32a97wUZTRo05A7YyG/ukIsd2OsJvy9pE7weu+ACKHnWVHeMjyohUwQLLaOsVn+2qaINH1uSBAdiRQ2DyUsMRMEA95BAYAIDuHAIDyGG8RSSi8zGDm6oGa3MOYKdyUH+ZeN9fBECCTQAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wMi0yNVQxNDowNTo0NC0wNTowMPhENw0AAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDItMjVUMTQ6MDU6NDQtMDU6MDCJGY+xAAAAAElFTkSuQmCC); +} +.button_clear_find_replace:after{ +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAhsMIBioundMAAAB2klEQVRIx+2Vv0sCYRjHH0WUELUhFAmX+g9cIlwcpMWGfuDu1l/gHkS0SLT2g7ChIWhoaWlRaAgcpB/Y5BIWyRFCyl3S3fs8Db53+OM879QbQr/Lve+93/fz3vvw3PMAzDTT1GvXKa9SlopYpRZWqchytE6eCWAphRXqV43t5F1jgMUw3tNA4UtraUTwbxQ/yVBYp5URwNIifmgIkZ0qSSlCHikix9gBfml0QYpYBOddWNTA181g9yrN04kGf7IYcyWt7mRZfQfbVx1K2to386xgl4NddMFvVbGQinJCjXFvKDrVDKLY9skJ9Z1zGNq12X46cj5hsMsnOM67/SaEJR7GuLGP4vx2D6bRJHC0HwBAP6cBAKQIn1TMozu2G6HJzyffpmOtHeE3Xv8J8EHDNJpe+SAKAODQFQDA3DL3v5tGOwp8kBpi3OboZ9OxVrZGzeuhIg8K5v9GerPUGFjGphpSdrOrjqo8ucpXduNNT8kX2bGSpFDeRSE5Rnsj1ut+sFGXkeP2gK30Rp1QFFhGzZYuWevoeuCaF6DsltfYET6iiEg1LLGcslHzWsoKffDY+n9gAHZoE5g81LIFDNAM2gQGAKA7m8AAYhhvEYnobMLgtuqBxoIN2GnXH6JDC1rOy1oRAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE2LTAyLTI3VDEyOjMyOjI0LTA1OjAwYlC5TAAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNi0wMi0yN1QxMjozMjoyNC0wNTowMBMNAfAAAAAASUVORK5CYII=); +} +.button_clear_clipboard:after{ +background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAtCAQAAACQEyoRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAHdElNRQfgAhsMHhWXzhCMAAAB0klEQVRIx+3XMUvDQBQH8IdDHBwEBzuEiogUxKU4BBwC2f0ofoQugqOze12dCtLBr+DQLUsGN8FBKkUS0lzynkNMc5dcLsmlcdE3lrtfr+n732sB/uuvVWThHF/iqx5Y+qkt8jy7RV7GboFXsR34JqwG34ZtweuwDfgurJJPrruyWSX3v3fqXp91zx3Sc1+34Vuzy/0mPM/mO2rOinEyDU9VPM9+HSZ36NecX7iVK/kyW/N4Igvn+Jovk/PVrIKPLHoITOYUF+MqGJYPImdrvlh2iR/cQp856euu0YmlgWsARBe45GHXoAEAHSWTYKjFAgQmejhzDYD1GT3lMM7QC0yAcISeBpvCREQpDsAcZqcwEVGKZ2tahYbflOE5XIU3yiId4xu3ZeYaIpzRqwNcyLqbbhVvEo5E/H2vGpZ3t+IziDh9FmHaxYUqi0q+gAswAEBk1WWRSDrA5HgO56XZ3etzRG5pHJ4AANBjdptossWuyLslusAlxslUk5XBIk6kxVbBarxRaIoBYbaQOwnecC7KklcItYC3+XEw5sbQpt2Em8WPxgCugc+tp3g2X8Q+3tyHPnMAbnaSidY/AeagXw5IYKKXzxrtYnY5eQCByez21jfS7c0ah6R+cwAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAxNi0wMi0yN1QxMjozMDoyMS0wNTowMDSdRtYAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMTYtMDItMjdUMTI6MzA6MjEtMDU6MDBFwP5qAAAAAElFTkSuQmCC); +} +.widget_pane{ +flex: 2; +display: flex; +flex-flow: column; +} +.pane_item{ +padding-bottom: 3px; +cursor:default; +display: block; +} +.pane_item.input{ +display: flex; +height: 20px; +min-height: 20px; /* oh IE! */ +flex-flow: row; +} +.pane_item.input input{ +flex: 2; +} +.input .inline_button{ +width: 21px; +text-align: center; +padding-left: 0px; +padding-right: 0px; +} +.input .inline_button_tripple{ +width: 67px; +font-size: 0.9em; +} +.auth_button_wrapper{ +margin: 10px 0px 20px 0px; +} +.button.auth_button{ +background: #7D18FF; +padding-left: 38px; +position: relative; +} +.auth_button:before{ +content: ''; +position: absolute; +top: 1px; +left: 1px; +width: 25px; +height: 25px; +background-size: contain; +background-repeat: no-repeat; +background-image: url(data:image/png;base64,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); +} +.find_result_line_num { +color: #1B2C48; +text-align: right; +padding-right: 3px; +border-right: 1px solid #3F5B8A; +font-weight: bold; +} +.find_result_text { +width: 100%; +} +.find_result_text_inner{ +position: absolute; +left: 3px; +right: 0; +white-space: nowrap; +overflow: hidden; +text-overflow: ellipsis; +} +.find_result_match{ +text-decoration: underline; +color: #1B2C48; +} +.find_info{ +text-align: right; +padding-right: 5px; +} +.find_info_overflow, +.file_info_overflow{ +vertical-align: top; +margin-right: 5px; +} +.clickable{ +cursor: pointer; +} +.widget_pane_bottom{ +margin-top: 3px; +text-align: right; +} +.widget_pane_bottom_before{ +flex: 2; +} +.pane_item:not(.no_select):hover{ +background-color: rgba(110, 160, 243, 0.28); +} +.find_results{ +display: table; +width: 100%; +border-collapse: collapse; +white-space: nowrap; +} +.find_result_item{ +display: table-row; +cursor: pointer; +} +.find_result_line_num, +.find_result_text{ +display: table-cell; +padding: 2px; +position: relative; +white-space: -moz-pre-space; +} +.find_result_current{ +background: rgb(80, 132, 222); +cursor: default; +} +.find_match_marker, +.find_current_match_marker{ +box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; + +position: absolute; +border-bottom: 1px solid #f00; +z-index:10; +} +.find_current_match_marker{ +border: 3px solid #f00; +} +.editable_text{ +font-style: italic; +} +input{ +min-width: 20px; +} +.details_file_description_input, +.details_file_title_input, +.gotoline_input{ +font-family: inherit; +box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; +width: 100%; +} +.details_file_description_text{ +max-height: 6em; +overflow-y: auto; +} +.find_input, +.replace_input{ +width: 100%; +box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; +} +.details_file_description_input{ +min-height: 6em; +width: 100%; +box-sizing: border-box; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; +min-height: 6em; +max-height: 6em; +max-width: 100%; +} +.widget_divider{ +background: rgba(0,0,0,0.3); +height: 1px; +margin-top: 3px; +margin-bottom: 3px; +display: block; +} +.widget_box{ +border-top:1px solid #fff; +margin: 3px; +padding: 3px; +} +.widget_box_title{ +font-weight: bold; +margin-bottom: 5px; +} +.widget_firstime ol{ +padding-left: 20px; +} +.opener_button{ +text-decoration: none; +display: block; +} +.shortcuts_header_action, +.shortcuts_header_key{ +display: inline-block; +width: 120px; +text-align: center; +text-decoration: underline; +} +.shortcuts_list{ +max-height: 132px; /*TODO: really want this to be a flex thing*/ +overflow-y: auto; +overflow-x: hidden; +} +.shortcut_item{ +border-bottom: 1px solid rgba(0,0,0,0.3); +} +.shortcut_key, +.shortcut_action{ +width: 120px; +display: inline-block; +vertical-align: top; +} +.shortcuts_header_action, +.shortcut_action{ +width: 100px; +} +.pane_spacer{ +height: 0.3em; +} +.noselect{ +-webkit-user-select: none; +-khtml-user-select: none; +-moz-user-select: -moz-none; +-o-user-select: none; +user-select: none; +} +.ace_selected-word{ +background: rgb(243, 233, 157) !important; +} +.ace_gutter{ +-webkit-user-select: none; +-khtml-user-select: none; +-moz-user-select: -moz-none; +-o-user-select: none; +user-select: none; +} +.ace_editor, +.find_results{ +font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', 'droid sans mono', monospace !important; +} +.dropdown{ +width: 120px; +cursor: pointer; +padding: 3px 6px 3px 6px; +} +.dropdown_item_list{ +height: 200px; +width: 120px; +position: absolute; +background-color: #f6f6f6; +color: #555; +overflow-y: scroll; +overflow-x: hidden; +line-height: 1.1em; +moz-box-shadow: 5px 5px 5px #888;-webkit-box-shadow: 5px 5px 5px #888;-moz-box-shadow: 5px 5px 5px #888; +z-index: 100; +} +.dropdown_collapsed { + overflow-x: hidden; + text-overflow: ellipsis; + margin-right: 12px; +} +.dropdown_collapsed:after{ +position: absolute; +top: 1px; +right: 4px; +content: '\25a4'; +} +.dropdown_collapsed.selected:after{ +color: #555; +} +.dropdown_item.selected{ +color: #dd9430; +} +.dropdown_collapsed.selected:hover, +.dropdown_item.selected:hover{ +color: #EE9430; +} +.dropdown_item:hover{ +background: #fff; +color: #333; +} +.button_wrapper{ +text-align: center; +} +.button, +.button_like{ +display: inline-block; +width: auto; +padding: 6px 15px 6px 15px; +background-color: #5892FD; +border-radius: 2px; +box-shadow: 0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);-webkit-box-shadow: 0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);-moz-box-shadow: 0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24); +color: #fff; +font-weight: bold; +position: relative; +} +.button{ +cursor: pointer; +} +.inline_button, +.button_like{ +padding: 3px 6px 3px 6px; +margin: 0px 0px 0px 2px; +} +.button_like{ +box-shadow: none;-webkit-box-shadow: none;-moz-box-shadow: none; +margin-bottom: 1px; +} +.button:hover{ +color: #e5e5e5; +box-shadow: 0 0 8px rgba(0,0,0,.12),0 2px 10px rgba(0,0,0,.24);-webkit-box-shadow: 0 0 8px rgba(0,0,0,.12),0 2px 10px rgba(0,0,0,.24);-moz-box-shadow: 0 0 8px rgba(0,0,0,.12),0 2px 10px rgba(0,0,0,.24); +} +.button.selected:not(.no_select), +.button:not(.no_select):active{ +color: #ADC7F1; +box-shadow: 0px 0px 4px rgb(23, 57, 111) inset;-webkit-box-shadow: 0px 0px 4px rgb(23, 57, 111) inset;-moz-box-shadow: 0px 0px 4px rgb(23, 57, 111) inset; +background: #3963AB; +} +.inline_button.selected, +.inline_button:active{ +padding-bottom: 4px; +} +.dropdown_button.selected, +.dropdown_button:active{ +padding-bottom: 2px; +padding-top: 3px; +} +.replace_single_result{ +padding: 0px 3px 0px 3px; +} +.button_up_down_wrapper{ +display: inline-block; +margin: -3px -6px -5px 2px; +line-height: 0px; +font-size: 9px; +position: relative; +} +.button_like .button_up_down_wrapper{ +border-radius: 2px; +box-shadow: 0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);-webkit-box-shadow: 0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24);-moz-box-shadow: 0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24); +cursor: pointer; +} +.button_up_down_wrapper:after{ +position: absolute; +top: -2px; +border-left: 1px solid #3262B1; +height: 21px; +content: ' '; +} +.button_up, +.button_down{ +height: 9px; +width: 19px; +display: block; +position: relative; +} +.button_up{ +border-bottom: 1px solid #3262B1; +} +.button.selected .button_up_down_wrapper:after{ +border-color: #2B5192; +} +.button.selected .button_up_down_wrapper .button_up{ +border-color: #2B5192; +} +.button_up:after{ +content:'\25B2'; +position: absolute; +top: 4px; +left: 5px; +} +.button_up:hover:after{ +top: 3px; +color: #fff; +} +.button_down:after{ +content:'\25BC'; +position: absolute; +top: 5px; +left: 5px; +} +.button_down:hover:after{ +top: 6px; +color: #fff; +} +.dropdown_valign_fix{ +width: 0; +padding: 3px 6px; +margin: 0px; +display: inline-block; +position: relative; +} +.dropdown_button, +.dropdown_button.selected{ +padding: 0px; +vertical-align: top; +} +.file_details_save{ +margin-top: 20px; +} +.font_size_decrement{ +font-variant: small-caps; +} +.font_size_increment{ +text-transform: uppercase; +} +.file_info{ +font-size: 0.8em; +min-height: 1em; +} + + + +/* --- Recent Changes stuff --- */ +.recent_line_rm8, .recent_line_rm7, .recent_line_rm6, .recent_line_rm5, .recent_line_rm4, .recent_line_rm3, .recent_line_rm2, .recent_line_rm1, +.recent_line_8, .recent_line_7, .recent_line_6, .recent_line_5, .recent_line_4, .recent_line_3, .recent_line_2, .recent_line_1{ +border-right: 4px solid; +padding-right: 9px !important; /* compensate for right border protuding into padding */ +} +.recent_line_rm8{ border-color: #E2F4D4; } +.recent_line_rm7{ border-color: #E2E4D4; } +.recent_line_rm6{ border-color: #E3D4D4; } +.recent_line_rm5{ border-color: #E4A4A4; } +.recent_line_rm4{ border-color: #E68383; } +.recent_line_rm3{ border-color: #E75B5B; } +.recent_line_rm2{ border-color: #E74646; } +.recent_line_rm1{ border-color: #F31A1A; } +.recent_line_8{ border-color: #F4E2D4; } +.recent_line_7{ border-color: #E4E2D4; } +.recent_line_6{ border-color: #D4E3D4; } +.recent_line_5{ border-color: #A4E4A4; } +.recent_line_4{ border-color: #83E683; } +.recent_line_3{ border-color: #5BE75B; } +.recent_line_2{ border-color: #46E746; } +.recent_line_1{ border-color: #1AF31A; } +/* --------------------------------------------- */ + + + + +/* --- History explorer stuff --- */ +.revisions_view{ +overflow-y: auto; +height: 100%; +width: 100%; +font-family: monospace; +position: fixed; +top: 0px; +left: 0px; +counter-reset: trueLine; +} +ol{ +margin: 0; +padding: 0; +} +ol .rev_line{ +padding-left: 2.5em; +} +ol[digits='###'] .rev_line{ +padding-left: 3em; +} +ol[digits='####'] .rev_line{ +padding-left: 3.5em; +} +ol[digits='#####'] .rev_line{ +padding-left: 4em; +} +.revision_tick_box{ +position: relative; +display: table; +table-layout: fixed; +width: 100%; +background: #fff; +height: 3px; +border-top: 10px solid #3963AB; +border-bottom: 10px solid #3963AB; +border-radius: 10px; +} +.revision_tick{ +background-color: #fff; +height: 3px; +width: 0%; /* odd hack that works in combination with "table-layout: fixed;" above */ +display: table-cell; +position: relative; +} +.revision_timeline{ +position: relative; +margin: 5px 0px 5px 0px; +} +.revision_at_range, +.revision_from_range{ +-webkit-appearance: none !important; +width: 100%; +background: none; +position: absolute; +z-index: 2; +display: block; +box-sizing: border-box; +padding: 0px 7px 0px 7px; +margin: inherit; +} +.revision_at_range{ +top:-15px; +} +.revision_from_range{ +top:7px; +} +.revision_at_range:focus, +.revision_from_range:focus{ +outline: none; +} + +::-webkit-slider-thumb { +-webkit-appearance: none !important; +width: 6px; +height: 15px; +background-color: #5892FD; +border-radius: 2px; +-webkit-box-shadow: 0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24); +cursor: pointer; +} +::-moz-range-thumb { +width: 6px; +height: 15px; +background-color: #5892FD; +border-radius: 2px; +-moz-box-shadow: 0 0 2px rgba(0,0,0,.12),0 2px 4px rgba(0,0,0,.24); +cursor: pointer; +} +::-moz-range-track { +background: none; +border: none; +} +.revision_at_range:focus::-webkit-slider-thumb, +.revision_from_range:focus::-webkit-slider-thumb{ +background-color: #32C6CE; +} +.revision_at_range:focus::-moz-range-thumb, +.revision_from_range:focus::-moz-range-thumb{ +background-color: #32C6CE; +} +.revision_at_range::-webkit-slider-thumb, +.revision_from_range::-webkit-slider-thumb{ +margin-top: 5px ; +} +.revision_at_range::-moz-range-thumb, +.revision_from_range::-moz-range-thumb{ +margin-bottom: 5px ; +} +.revision_tick.downloaded{ +background-color: #FFA300; +} +.revision_tick.diffed{ +background-color: #5892FD; +} +.revision_caption_from, +.revision_caption_at{ +padding: 4px 3px 4px 3px; +font-size: 10px; +line-height: 9px; +min-height: 18px; +} +.revision_caption_from{ +text-align: right; +} + +.revisions_view .ace_line .ace_fold{ +display: none; +} + +.special_1_first, +.special_1{ +position: absolute; +} +.special_2_first, +.special_2{ +background-color:#bcebe8; +border-right: 4px solid #069147; +color: #069147; +position: absolute; +} +.special_3_first, +.special_3{ +background-color:#ffcaca; +border-right: 4px solid #ff0000; +color: #ff0000; +position: absolute; +} +.special_2_first:after{ +position: absolute; +right: 4px; +top: 1px; +content: 'lines added'; +font-family: sans-serif; +font-style: italic; +font-size: 0.6em; +} +.special_3_first:after{ +position: absolute; +right: 4px; +top: 1px; +content: 'lines removed'; +font-family: sans-serif; +font-style: italic; +font-size: 0.6em; +} +.gutter_special_2{ +background: #9EDCD8; +} +.gutter_special_3{ +color: #BFACAC; +} +.revisions_view.ace-tm .ace_marker-layer .ace_selection{ +opacity: 0.75; +} +/* progress width animation */ +@keyframes progress{ + 0%{left: 0%} + 100%{left: 100%} +} +.widget_pending_inner{ +position: absolute; +height: 0px; +width: 5px; +top: 2px; +box-shadow: 0px 0px 20px 10px #BDA1B3;-webkit-box-shadow: 0px 0px 20px 10px #BDA1B3;-moz-box-shadow: 0px 0px 20px 10px #BDA1B3; +webkit-animation: progress 1s 0s infinite; +-moz-animation: progress 1s 0s infinite; +-ms-animation: progress 1s 0s infinite; +-o-animation: progress 1s 0s infinite; +animation: progress 1s 0s infinite; +} +/* ---------------------------- */ + +/*shake css from daneden.me */ +@-webkit-keyframes shake{ +0%,100%{-webkit-transform:translateX(0)} +10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px)} +20%,40%,60%,80%{-webkit-transform:translateX(10px)} +} +@-moz-keyframes shake{ +0%,100%{-moz-transform:translateX(0)} +10%,30%,50%,70%,90%{-moz-transform:translateX(-10px)} +20%,40%,60%,80%{-moz-transform:translateX(10px)} +} +@-o-keyframes shake{ +0%,100%{-o-transform:translateX(0)} +10%,30%,50%,70%,90%{-o-transform:translateX(-10px)} +20%,40%,60%,80%{-o-transform:translateX(10px)} +} +@keyframes shake{ +0%,100%{transform:translateX(0)} +10%,30%,50%,70%,90%{transform:translateX(-10px)} +20%,40%,60%,80%{transform:translateX(10px)} +} +.shake{ +webkit-animation-name:shake; +-moz-animation-name:shake; +-o-animation-name:shake; +animation-name:shake; +-webkit-animation-duration: 1s; +-moz-animation-duration: 1s; +-ms-animation-duration: 1s; +-o-animation-duration: 1s; +animation-duration: 1s; +} + + +/* --- all scrollbars --- */ +::-webkit-scrollbar { color: inherit;} /* no-op, but required in order to force styling on scrollbars */ +::-webkit-scrollbar-track { +-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3); +} +::-webkit-scrollbar-thumb { +background: rgba(200,200,200,0.8); +-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.5); +} diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..9daf9114e421861acbcb12429116e796772a9cb7 GIT binary patch literal 99678 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 literal 0 HcmV?d00001 diff --git a/html/app.html b/html/app.html new file mode 100644 index 0000000..8a6972b --- /dev/null +++ b/html/app.html @@ -0,0 +1,444 @@ + + + + + + + + + + + + + + Drive Notepad + + + + + + + +
+ + +
ex nihilo omnia
+ +
+ + + + + +
+ +
+ + + + + + + + + +
+ + + +
+
+
+
+
+
+ + + + + +
+ +
+
Javascript disabled or encountering errors.
+
+ +
+ +
+ + + + \ No newline at end of file diff --git a/icon-128.png b/icon-128.png new file mode 100644 index 0000000000000000000000000000000000000000..2f3477dbd423fbb5c236c53c59e70e29f4775a40 GIT binary patch literal 980 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
GNJ0`7-XhH0+MbulsN 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 literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 0000000..a7815fd --- /dev/null +++ b/index.html @@ -0,0 +1 @@ + Drive Notepad
ex nihilo omnia
Javascript disabled or encountering errors.
\ No newline at end of file diff --git a/js/ad_data.jsonp b/js/ad_data.jsonp new file mode 100644 index 0000000..c50b5ef --- /dev/null +++ b/js/ad_data.jsonp @@ -0,0 +1,86 @@ +/* Note that the data on this page is trusted, i.e. it is not escaped when used */ + +(function(){ + + + var data = [ + + { + width: 160, + height: 600, + alt: "", + href: "http://www.kqzyfj.com/click-8032815-11139959-1358368119000", + img: "https://www.lduhtrp.net/image-8032815-11139959-1358368119000", + ga_id: 2 + }, + + { + width: 160, + height: 600, + alt: "Green Man Gaming - Load, Play, Trade !", + href: "http://www.tkqlhce.com/click-8032815-12115797-1456738702000", + img: "https://www.lduhtrp.net/image-8032815-12115797-1456738702000", + ga_id: 3 + }, + + { + width: 160, + height: 600, + alt: "Great Games - Better Prices - Shop like a Boss", + href: "http://www.anrdoezrs.net/click-8032815-12467804-1456738702000", + img: "https://www.tqlkg.com/image-8032815-12467804-1456738702000", + ga_id: 4 + }, + + { + width: 160, + height: 600, + alt: "", + href: "http://www.jdoqocy.com/click-8032815-12193127-1444339039000", + img: "https://www.awltovhc.com/image-8032815-12193127-1444339039000", + ga_id: 5 + }, + + { + width: 120, + height: 600, + alt: "", + href: "http://www.kqzyfj.com/click-8032815-11410216-1446809454000", + img: "https://www.awltovhc.com/image-8032815-11410216-1446809454000", + ga_id: 6 + }, + + { + width: 160, + height: 600, + alt: "", + href: "http://www.tkqlhce.com/click-8032815-12229803-1433342091000", + img: "https://www.tqlkg.com/image-8032815-12229803-1433342091000", + ga_id: 7 + }, + + { + width: 161, + height: 600, + alt: "Drive Notepad in the Chrome Webstore", + href: "https://chrome.google.com/webstore/detail/drive-notepad/gpgjomejfimnbmobcocilppikhncegaj", + img: "https://drivenotepad.github.io/images/dn_review_ad.png", + ga_id: 8 + }, + + { + width: 120, + height: 600, + alt: "", + href: "http://www.tkqlhce.com/click-8032815-10777950-1420040554000", + img: "https://www.ftjcfx.com/image-8032815-10777950-1420040554000", + ga_id: 9 + } + + ] + + + + dn.ads.on_load_data(data); + +})(); diff --git a/js/app.js b/js/app.js new file mode 100644 index 0000000..3750960 --- /dev/null +++ b/js/app.js @@ -0,0 +1,1058 @@ +"use strict"; +// DRIVE NOTEPAD 2016 +// by DM + +dn.version_str = '2016a'; + +// ############################ +// Constants and defaults, see alsp info.js +// ############################ + +dn.can_show_drag_drop_error = true; +dn.save_undo_id = 0; + +dn.status = { + + file_body: 1, // 0 while getting, 1 when done or irrelevant, -1 if failed + file_meta: 1, // 0 while getting, 1 when done or irrelevant, -1 if failed + file_new: 1, // 0 while creating a new file, 1 when done or irrelevant, -1 if failed + + file_sharing: 0, // after launching the sharing dialog this is set to -1 for everafter + + authentication: 0, // 0 while authenticating, 1 when done + + popup_active: 0, // 0 or 1, i.e. true or false + local_settings: 0, // 1 when local settings have been loaded + realtime_settings: 0, // 1 when realtime settings have been loaded + + // 1: success/no save active, + // 0: in progress + // -1: failure, and abandonded further attempts (never used) + save_body: 1, + save_title: 1, + save_other: 1, + + unsaved_changes: 0, // 1 true, 0 false + user_wants_file: 0, // 1 when page loads with open request, or when users initially saves a new file, 0 otherwise + warned_read_only: 0 // if file is read-only this is set to 1 when user first tries editing the document body +} + +dn.the_file = new dn.FileModel(); + +dn.change_line_history = []; +dn.last_change = null; +dn.change_line_classes =(function(rootStr,trueN,factor){ + var x = ['']; + for(var i=trueN;i;i--)for(var k=0;k dn.const_.drag_delay_ms) + || (x*x + y*y > dn.const_.drag_shift_px * dn.const_.drag_shift_px); + } + if(dn.widget_mouse_down_info.is_dragging) + translate(dn.el.the_widget, x, y); + e.stopPropagation(); + +}; + +dn.document_mouse_up_widget = function(e){ + document.removeEventListener('mousemove', dn.document_mouse_move_widget); + document.removeEventListener('mouseup', dn.document_mouse_up_widget); + + if(dn.widget_mouse_down_info.is_dragging){ + var pos = dn.el.the_widget.getBoundingClientRect(); + translate(dn.el.the_widget, 0, 0); + + //work out what widget_anchor should be + var widget_w = dn.el.the_widget.offsetWidth; + var widget_h = dn.el.the_widget.offsetHeight; + var window_w = window.innerWidth; + var window_h = window.innerHeight; + var anchor = [] + if(pos.left < window_w - (pos.left + widget_w)){ + anchor[0] = 'l'; //anchor left side by window width percentage + anchor[1] = Math.max(0,pos.left/window_w * 100); + }else{ + anchor[0] = 'r'; //anchor right side by window width percentage + anchor[1] = Math.max(0,(window_w - (pos.left + widget_w))/window_w * 100); + } + if(pos.top < window_h - (pos.top+ widget_h)){ + anchor[2] = 't'; //anchor top side by window height percentage + anchor[3] = Math.max(0,pos.top/window_h * 100); + }else{ + anchor[2] = 'b'; //anchor bottom side by window height percentage + anchor[3] = Math.max(0,(window_h - (pos.top + widget_h))/window_h * 100); + } + + if(dn.g_settings) + dn.g_settings.set("widget_anchor",anchor); + + }else{ + dn.g_settings.set('pane_open', !dn.g_settings.get('pane_open')); + } + dn.widget_mouse_down_info = undefined; +}; + +dn.widget_apply_anchor = function(anchor){ + anchor = Array.isArray(anchor) ? anchor : dn.g_settings.get('widget_anchor'); + var widget_w = dn.el.the_widget.offsetWidth; + var widget_h = dn.el.the_widget.offsetHeight; + var window_w = window.innerWidth; + var window_h = window.innerHeight; + + if(anchor[0] == 'l'){ + // horizontal position is anchored to a fixed percentage of window width on left of widget + if(window_w * anchor[1]/100 + widget_w > window_w){ + dn.el.the_widget.style.left = 'inherit'; + dn.el.the_widget.style.right = '0px'; //if the widget would overlap the right edge, then instead put it precisely on the right edge + }else{ + dn.el.the_widget.style.left = anchor[1] + '%'; + dn.el.the_widget.style.right = ''; //use the anchor exactly + } + + // set toolbar position + dn.el.widget_menu.classList.add('flipped'); + dn.el.widget_content.classList.add('flipped'); + var els = document.getElementsByClassName('widget_menu_icon'); + for(var ii=0; ii window_w){ + dn.el.the_widget.style.left = '0px'; + dn.el.the_widget.style.right = ''; //if the widget would overlap the left edge, then instead put it precisely on the left edge + }else{ + dn.el.the_widget.style.left = 'inherit'; + dn.el.the_widget.style.right = anchor[1] + '%'; //use the anchor exactly + } + + // set toolbar position + dn.el.widget_menu.classList.remove('flipped'); + dn.el.widget_content.classList.remove('flipped'); + var els = document.getElementsByClassName('widget_menu_icon'); + for(var ii=0; ii window_h){ + dn.el.the_widget.style.top = 'inherit'; + dn.el.the_widget.style.bottom = '0px'; + }else{ + dn.el.the_widget.style.top = anchor[3] + '%'; + dn.el.the_widget.style.bottom = ''; + } + }else{ + // vertical position is anchored to a fixed percentage of window height on bottom of widget + if(window_h * anchor[3]/100 + widget_h > window_h){ + dn.el.the_widget.style.top = '0px'; + dn.el.the_widget.style.bottom = ''; + }else{ + dn.el.the_widget.style.top = 'inherit'; + dn.el.the_widget.style.bottom = anchor[3] + '%'; + } + } + + + +} + +dn.toggle_widget = function(state){ + // provide argument "true" to open widget, "false" to close + if(state){ + dn.el.widget_menu.style.display = ''; + dn.el.widget_content.style.display = ''; + }else{ + dn.el.widget_menu.style.display = 'none'; + dn.el.widget_content.style.display = 'none'; + dn.file_pane.on_close_pane(); // we could check if it file pane was open, but who cares + dn.focus_editor(); + } +} + +dn.check_unsaved = function(){ + /* called: + (a) before issuing save-body requests, at which point we set dn.save_undo_id to Nan, and + record (in the SaveRequest instance) the current UndoManager.getCurrentId() value for + later use if and when the save completes. + (b) after all pending saves are completed, when we read the undo_id value for the last saved + body version and set dn.save_undo_id to that. + (c) in some kind of regular async manner in response to editor input + + Importantly, note we have monkey-patched the UndoManager class in patch_ace.js. This is what + gives us the concept of an undo_id and the ability to query .getCurrentId(). + */ + if(dn.save_undo_id === dn.editor.getSession().getUndoManager().getCurrentId()){ + // changes match what we know is on the server + dn.status.unsaved_changes = false; + dn.render_document_title(); + dn.show_status(); + }else if (!dn.status.unsaved_changes){ + // changes no longer match the server + dn.status.unsaved_changes = true; + dn.render_document_title(); + dn.show_status(); + } // else, we already there were unsaved changes +} + + + +// ############################ +// Settings stuff +// ############################ + +dn.g_settings = (function(){ + // This acts as a mock realtime model to be used until the real model is initialised + var ob = {}; + var keeps = {}; + var change_listeners = []; + return { + get: function(k){ + return ob[k] + }, set: function(k,v){ + if(ob[k] === v) return; + ob[k] = v; + for(var ii=0;ii dn.const_.clipboard_max_length){ + // trim clipboard to current length limit, note the oldest stuff is at the 0-end + dn.g_clipboard.removeRange(0, dn.g_clipboard.length-dn.const_.clipboard_max_length); + } + + dn.g_find_history = dn.g_settings.get('findHistory'); + if(!dn.g_find_history){ + dn.g_settings.set('findHistory', doc.getModel().createList()); + dn.g_find_history = dn.g_settings.get('findHistory'); + }else if(dn.g_find_history.length > dn.const_.find_history_max_len){ + // trim find history to current length limit, the oldest stuff is at the non-zero end. + dn.g_find_history.removeRange(dn.const_.find_history_max_len, dn.g_find_history.length); + } + + //Check lastDNVersionUsed at this point - by default it's blank, bust could also have an out-of-date value + var last_version = dn.g_settings.get('lastDNVersionUsed') + if(last_version != dn.version_str){ + if (last_version.length > 0 && parseInt(last_version) !== 2016){ + // from this point onwards during this page's lifetime, change the tips + // section to show the update message rather than the tips. + document.getElementById('tips_old_user').style.display = ''; + document.getElementById('tips_general').style.display = 'none'; + } + dn.g_settings.set('help_inner', 'tips'); + dn.g_settings.set('pane', 'pane_help'); + dn.g_settings.set('pane_open', 'true'); + dn.g_settings.set('lastDNVersionUsed', dn.version_str); + } + + dn.status.realtime_settings = 1; +} + + +dn.settings_changed = function(e){ + var new_value = e.newValue; + console.log("[user settings] " + e.property +": " + new_value); + if(dn.impersonal_settings_keys.indexOf(e.property)>-1 && localStorage){ + localStorage["g_settings_" + e.property] = JSON.stringify(new_value); + } + try{ + switch(e.property){ + case "widget_anchor": + dn.widget_apply_anchor(new_value); + break; + + case "theme": + dn.editor.setTheme('ace/theme/' + new_value); + break; + + case "fontSize": + var scrollLine = dn.get_scroll_line(); + dn.editor.setFontSize(new_value + 'em') + dn.editor.scrollToLine(scrollLine); + break; + + case "wordWrap": + var s = dn.editor.getSession(); + var scrollLine = dn.get_scroll_line(); + s.setUseWrapMode(new_value[0]); + s.setWrapLimitRange(new_value[1],new_value[2]); + dn.editor.scrollToLine(scrollLine); + break; + + case "wordWrapAt": + var curWrap = dn.g_settings.get('wordWrap'); + if(curWrap[1] && curWrap[1] != new_value) + dn.g_settings.set('wordWrap',[1,new_value,new_value]); + dn.editor.setPrintMarginColumn(new_value); + break; + + case "showGutterHistory": + var s = dn.editor.getSession(); + if(!new_value){ + var h = dn.change_line_history; + for(var i=0;i 1) + h.splice(start_row, e.lines.length-1); + h[start_row] = -n_classes; + }else{ + h[start_row] = n_classes; + if(e.lines.length > 1){ + var args_for_splice = [start_row, 0]; + for(var ii=0; ii< e.lines.length-1; ii++) + args_for_splice.push(n_classes); + h.splice.apply(h, args_for_splice); + } + } + + for(var ii=0; ii 0) + dn.the_file.file_id = state.ids[0]; + else if (state.folderId) + dn.new_in_folder = state.folderId; // could be invalid nonsense + }catch(e){ + dn.show_error("Bad URL. This will be treated as a new file."); + } + } + + dn.the_file.addEventListener("change", function(e){ + switch(e.property){ + case "title": + dn.render_document_title(); + break; + + case "syntax": + dn.set_editor_syntax(); + break; + + case "newline": + dn.set_editor_newline(); + break; + + case "tabs": + dn.set_editor_tabs(); + break; + } + }); + + // The auth promise can be rejected and resolved multiple times during the lifetime of the app. + // These two handlers will always be called for those events. + dn.pr_auth.on_error(dn.handle_auth_error); + dn.pr_auth.on_success(function(){ + // reset some things, could be no-ops... + dn.reauth_auto_delay = 0; + dn.toggle_permission(false); + dn.status.popup_active = 0; + + // and show the good news... + dn.status.authentication = 1; + dn.show_status(); + }) + + // if we ever find that we have gone offline, we have to call offline_simple.commence_testing, + // that will then trigger the following event when the connection is restored. + offline_simple.addEventListener('online', dn.pr_auth.resolve.bind(dn.pr_auth)); + + // get user info... + until_success(function(succ, fail){ + Promise.resolve(dn.pr_auth) + .then(dn.request_user_info) + .then(dn.show_user_info) + .then(succ, fail); + }).before_retry(dn.filter_api_errors) + .then(function(){ + console.log('succeeded getting user info.') + }).catch(function(err){ + console.log("failed to load user info") + console.dir(err); + dn.show_error(dn.api_error_to_string(err)); + }); + + if(dn.the_file.file_id){ + // load existing file ::::::::::::::::::::::::::::::::::::::::::::::::::: + dn.status.file_meta = 0; + dn.status.file_body = 0; + dn.status.user_wants_file = 1; + + dn.show_status(); + dn.editor.setReadOnly(true); + // metadata... + var pr_meta = + until_success(function(succ, fail){ + Promise.resolve(dn.pr_auth) + .then(dn.request_file_meta) + .then(dn.show_file_meta) + .then(succ, fail); + }).before_retry(dn.filter_api_errors) + .catch(function(err){ + dn.status.file_meta = -1; + dn.show_status(); + throw err; + }); + + // body... + var pr_body = + until_success(function(succ, fail){ + Promise.resolve(dn.pr_auth) + .then(dn.request_file_body) + .then(dn.show_file_body) + .then(succ, fail); + }).before_retry(dn.filter_api_errors) + .catch(function(err){ + dn.status.file_body = -1; + dn.show_status(); + throw err; + }); + + // wait for both meta data and body... + Promise.all([pr_meta, pr_body]) + .then(function(vals){ + console.log("succeeded loading file body and metadata."); + dn.the_file.set({is_loaded: true}); + dn.pr_file_loaded.resolve(); + dn.show_status(); + }).catch(function(err){ + console.log("failed to load file properly.."); + console.dir(err); + dn.show_error(dn.api_error_to_string(err)); + document.title = "Drive Notepad"; + dn.g_settings.set('pane', 'pane_help'); + dn.g_settings.set('pane_open', true); + }); + + } else { + + // create new file ::::::::::::::::::::::::::::::::::::::::::::::::::: + // or rather, wait for the first save action before creating. + dn.show_status(); + dn.the_file.set({title: "untitled.txt", is_loaded: true}); // there's nothing to load for this model + dn.g_settings.set('pane', 'pane_file'); + dn.g_settings.set('pane_open', true); + } + + // load cloud settings :::::::::::::::::::::::::::::::::::::::::::::::: + until_success(function(succ, fail){ + Promise.all([dn.pr_auth, dn.pr_realtime_loaded]) + .then(dn.request_app_data_document) + .then(dn.show_app_data_document) + .then(succ, fail) + }).before_retry(dn.filter_api_errors) + .then(function(){ + console.log('succeeded loading settings'); + }).catch(function(err){ + console.log("failed to load realtime settings.") + console.dir(err); + dn.show_error(dn.api_error_to_string(err)); + }); + + + // load ads at some point in future... + //setTimeout(load_script_async, dn.const_.ad_initial_wait, 'js/banner_ads.js'); +} + +if (document.readyState != 'loading' && document.getElementById('the_widget')){ //second test is hack for IEi + dn.document_ready(); +}else{ + document.addEventListener('DOMContentLoaded', dn.document_ready); +} diff --git a/js/banner_ads.js b/js/banner_ads.js new file mode 100644 index 0000000..15ca241 --- /dev/null +++ b/js/banner_ads.js @@ -0,0 +1,94 @@ +"use strict" + +/* + Making a website takes time, why not get paid for it, right? + + This script is designed to be loaded a few minutes after page load, + in turn it loads ad_data.jsonp, which calls back to dn.ads.on_load_data + with an array of ads to choose from. + + The first ad is shown more or less immediatley after this script loads, + so it's up to the caller to decide when that will be. +*/ + + +dn.ads = (function(){ + +var display_time = 75 *1000;//ms +var no_display_time = 15 * 60 * 1000; //ms +var timer = 0; + +var data = []; +var el = {}; + +el.ace_gutter = document.getElementsByClassName('ace_gutter')[0] +el.ad = document.createElement('div'); +el.ad.id='banner_ad' +el.ad.style.position = 'fixed'; +el.ad.style.right = '0px'; +el.ad.style.top = '0px'; +el.ad.style.bottom = '0px'; +var on_load_data = function(loaded_data){ + data = loaded_data; + display_random(); +} + +var display_random = function(){ + clearTimeout(timer); + var d = data[(data.length * Math.random()) | 0]; + var img = new Image(); + img.onload = function() { + // we wait till img is in available before building the ad + var editor_style = getComputedStyle(el.ace_gutter); + el.ad.innerHTML = "
" + + "
" + + "why have ads?" + + "
close this ad
" + + "
" + + "" + + "
" + img.width = d.width; + img.height = d.height; + img.alt = d.alt; + img.border = '0'; + el.ad.getElementsByClassName('ad_img_wrapper')[0].appendChild(img); + el.ad.style.width = d.width + 'px'; + el.ad.style.zIndex = 200; + el.ad.getElementsByClassName('close_ad')[0].addEventListener('click', hide_ad); + el.ad.style.opacity = '0'; + el.ad.style.transitionProperty = 'opacity'; + el.ad.style.transitionDuration = '1s'; + el.ad.style.pointerEvents = 'none'; //during gradual entrance + document.getElementsByTagName('body')[0].appendChild(el.ad); + getComputedStyle(el.ad).backgroundColor; // force inital opacity + el.ad.style.opacity = '1'; + ga('send', 'event', 'ad', 'show', 'id', d.ga_id); + setTimeout(function(){ + el.ad.style.pointerEvents = ''; + }, 1200); + timer = setTimeout(hide_ad, display_time); + } + img.src = d.img; +} + +var hide_ad = function(){ + clearTimeout(timer); + el.ad.parentNode.removeChild(el.ad); + el.ad.innerHTML = ""; + timer = setTimeout(display_random, no_display_time); +} + +// load the data (and run on_load_data callback +load_script_async('js/ad_data.jsonp'); + +return { + on_load_data: on_load_data, + debug: function(){ + display_time = 2000; + no_display_time = 2000; + } +} + +})(); diff --git a/js/clipboard.js b/js/clipboard.js new file mode 100644 index 0000000..80c0841 --- /dev/null +++ b/js/clipboard.js @@ -0,0 +1,117 @@ +"use strict"; +/* + Note that the find history list has its most recent entries at the 0-end, but + the clipboard tool has its most recent entries at the other end. + +*/ +dn.clipboard_tool = (function(const_){ + +var is_active = false; +var showing_pane = false; // there is a delay after being active before we show the pane, note the public is_active method actually uses this value +var clipboard_index = -1; +var clipboard_info_timer = 0; + +var document_clipboard_left = function(e){ + if(!is_active) + return false; + if(clipboard_index <= 0) + return true; + clipboard_index--; + dn.editor.undo(); + dn.editor.insert(dn.g_clipboard.get(clipboard_index)); + return true; +} + +var document_clipboard_right = function(e){ + if(!is_active) + return false; + + dn.g_atomic_exec(function(){ + if(clipboard_index >= dn.g_clipboard.length-1) + return true; + clipboard_index++; + dn.editor.undo(); + dn.editor.insert(dn.g_clipboard.get(clipboard_index)); + }) + return true; +} + +var document_clipboard_keyup = function(e){ + if(e.which == 17 || e.which == 91 || !e.ctrlKey){ + document.removeEventListener('keyup', document_clipboard_keyup); + is_active = false; + if(showing_pane){ + showing_pane = false; + dn.show_pane(dn.g_settings.get('pane')); + dn.toggle_widget(dn.g_settings.get('pane_open')); + } + if(clipboard_info_timer){ + clearTimeout(clipboard_info_timer); + clipboard_info_timer = null; + } + } +} + +var on_paste = function(e){ + if (dn.g_clipboard === undefined) + return; // don't bother implementing anything until cloud settings are properly loaded + var text = e.text || ""; + is_active = true; + document.addEventListener('keyup', document_clipboard_keyup); + + clipboard_index = dn.g_clipboard.lastIndexOf(text); + if(clipboard_index == -1){ //it's possible the user copied some text from outside the DN, in which case we will add it to the clipboard now + clipboard_index = dn.g_clipboard.push(text); + if(dn.g_clipboard.length > const_.clipboard_max_length){ + clipboard_index--; + dn.g_clipboard.remove(0); + } + } + if(clipboard_info_timer) + clearTimeout(clipboard_info_timer); + + clipboard_info_timer = setTimeout(function(){ + clipboard_info_timer = null; + showing_pane = true; // this prevents g_settings 'pane_open' and 'pane' updates from being rendered + dn.toggle_widget(true); // we can then temporarily exert manual control over the rendering of pane and pane_open + dn.show_pane('pane_clipboard'); + }, const_.clipboard_info_delay); +} + +var on_copy = function(text){ + if (dn.g_clipboard === undefined) + return; // don't bother implementing anything until cloud settings are properly loaded + text = text || ""; + dn.g_atomic_exec(function(){ + + var previous_idx = dn.g_clipboard.lastIndexOf(text); + if(previous_idx === -1){ + // text is new, add it to the end of the clipboard + dn.g_clipboard.push(text); + if(dn.g_clipboard.length > const_.clipboard_max_length) + dn.g_clipboard.remove(0); + }else{ + // the text already exists in the clipboard history, lets bring it to the front + dn.g_clipboard.move(previous_idx, 0) + } + + }); //g_atomic_exec + +} + + +var on_document_ready = function(){ + dn.editor.on("paste", on_paste); + dn.editor.on("copy", on_copy); +} + + +return { + on_document_ready: on_document_ready, + on_left: document_clipboard_left, // this and... + on_right: document_clipboard_right, // this, are registered in keyboard.js + is_active: function(){return showing_pane} +}; + +})(dn.const_); + diff --git a/js/drag_drop.js b/js/drag_drop.js new file mode 100644 index 0000000..cc3383a --- /dev/null +++ b/js/drag_drop.js @@ -0,0 +1,55 @@ +"use strict;" + +/* + This file has not been tested in a while and is not currently included in the build. + To get it functioning again, note that you need to register handlers in the main + document_ready function in app.js: + + document.addEventListener('dragover', dn.document_drag_over); + document.addEventListener('drop', dn.document_drop_file); + +*/ + +dn.document_drag_over = function (evt) { + evt = evt.originalEvent; + evt.stopPropagation(); + evt.preventDefault(); + if(!(dn.the_file.is_brand_new && !dn.status.unsaved_changes)){ + evt.dataTransfer.dropEffect = 'none'; + if(dn.can_show_drag_drop_error){ + dn.show_error("File drag-drop is only permitted when the Drive Notpad page is displaying a new and unmodified file.") + dn.can_show_drag_drop_error = false; //wait at least dn.const_.error_delay_ms until displaying the error again + setTimeout(function(){dn.can_show_drag_drop_error = true;},dn.const_.error_delay_ms); + } + return; + } + evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy. +} + +dn.document_drop_file = function(evt){ + if(!(dn.the_file.is_brand_new && !dn.status.unsaved_changes)) + return; + + evt = evt.originalEvent; + evt.stopPropagation(); + evt.preventDefault(); + + var files = evt.dataTransfer.files; + if(files.length > 1){ + dn.show_error("You cannot drag-drop multiple files onto the Drive Notepad page, only individual files.") + } + var file = files[0]; + dn.the_file.title = file.name; + dn.create_file(); + dn.the_file.isReading_file_object = true; + dn.show_status(); + var r = new FileReader(); + r.onload = dn.dropped_file_read; + r.readAsText(file); +} + +dn.dropped_file_read = function(e){ + dn.the_file.isReading_file_object = false; + dn.editor.getSession().setValue(e.target.result); + // Note we don't encolse the above in a dn.setting_session_value = true block so the change event will fire and set pristine to false and ShowStatus etc. +} \ No newline at end of file diff --git a/js/drop_down.js b/js/drop_down.js new file mode 100644 index 0000000..d904915 --- /dev/null +++ b/js/drop_down.js @@ -0,0 +1,121 @@ +"use strict"; + +var DropDown = function(val_array){ + //constructor, must use + + var str = val_array.map(function(val){ + return ""; + }).join(""); + + this.val_array = val_array.slice(0); + this.el_list = document.createElement('div'); + this.el_list.className ='dropdown_item_list'; + this.el_list.tabindex =-1 + this.el_list.style.display = 'none'; + this.el_list.innerHTML = str; + + this.el_collapsed = document.createElement('div'); + this.el_collapsed.className = 'dropdown_collapsed'; + + this.el = document.createElement('div'); + this.el.className = 'dropdown'; + this.el.appendChild(this.el_list) + this.el.appendChild(this.el_collapsed); + this.ind = 0; + this.el_collapsed.textContent = val_array[0]; + this.event_callbacks = {}; //map of callback lists + this.open = false; + this.enabled = true; + + var dd = this; + + this.document_mousedown = function(e){ + dd.el_list.style.display = 'none'; + dd.open = false; + dd.trigger("blur"); + document.removeEventListener('mousedown', dd.document_mousedown); + } + + this.el_collapsed.addEventListener('mousedown',function(){ + if(!dd.enabled) + return; + if(!dd.trigger("click")) + return; + dd.el.parentNode.classList.add("selected"); + dd.el_list.style.display = ''; + this.open = true; + setTimeout(function(){ + dd.el_list.focus(); + dd.el_list.scrollTop = dd.el_list.children[dd.ind].offsetTop; + document.addEventListener('mousedown', dd.document_mousedown) + },1); + }); + var on_click = function(e){ + dd.SetInd(this.getAttribute('data-ind')); + dd.el_list.style.display = 'none'; + dd.open = false; + e.stopPropagation(); + document.removeEventListener('mousedown', dd.document_mousedown); + }; + for(var ii=0; ii= dn.const_.min_soft_tab_n && prop.n <= dn.const_.max_soft_tab_n)) + prop.n = undefined; + if(prop.val === "spaces" && prop.n === undefined) throw 0 + }catch(e){ + prop = {val: "detect"}; + } + this.properties.tabs = prop; // force it to be whatever we parsed + + if(prop.val === "tab") + this.properties_chosen.tabs = prop; // may need to chose n still + else if(prop.val === "spaces") + this.properties_chosen.tabs = prop; // n is definitely valid + else + this.properties_chosen.tabs = undefined; // we need to chose val and n + + + // Now do detection.... + + // find non-zero-length whitespace at start of all lines + var indents = str.match(this.re_whitepace) || []; + + // build the stats for those lines... + var n_only_tabs = 0; + var n_only_space; // we compute this after the loop + var space_hist = []; + var n_with_mixture = 0; + var n_samp = Math.min(indents.length, 1000); + for(var ii=0; ii= dn.const_.detect_tabs_tabs_frac){ + // detected tab... + this.properties_detected_info.tabs = "hard tab indentation detected"; + if(this.properties_chosen.tabs === undefined) + this.properties_chosen.tabs = {val: 'tabs'} + if(this.properties_chosen.tabs.n === undefined) + this.properties_chosen.tabs.n = dn.g_settings.get('softTabN'); // we have to show something for n + + } else if(n_samp === 0 || n_only_space/n_samp < dn.const_.detect_tabs_spaces_frac){ + // no detection possible, use default.... + + if(this.properties_chosen.tabs === undefined){ + this.properties_chosen.tabs = { + val: dn.g_settings.get('tabIsHard') ? 'tabs' : 'spaces', + n: dn.g_settings.get('softTabN')}; + } + this.properties_detected_info.tabs = + (n_samp === 0 ? + "no indentations detected" + : "detected mixture of tabs") + + ", default is " + (this.properties_chosen.tabs.val == 'tabs' ? + "hard tabs" + : dn.g_settings.get('softTabN') + " spaces"); + + } else { + // detected spaces, but exxactly how many? + + //Build a second space hist, using all "harmonics".... + var space_mod_hist = []; + for(var ss=dn.const_.min_soft_tab_n; ss<=dn.const_.max_soft_tab_n; ss++){ + for(var ii=ss, m=0; ii=dn.const_.min_soft_tab_n; ss--) + if(space_mod_hist[ss]/n_only_space > dn.const_.detect_tabs_n_spaces_frac){ + this.properties_detected_info.tabs = "detected soft-tabs of " + ss + " spaces" + break; + } + + // if nothing was over threshold, use default space count + if(ss < dn.const_.min_soft_tab_n){ + ss = dn.g_settings.get('softTabN'); + if(space_mod_hist[ss]/n_only_space > dn.const_.detect_tabs_n_spaces_frac_for_default) + this.properties_detected_info.tabs = "detected close match to default of " + ss + " spaces"; + else + this.properties_detected_info.tabs = "detected soft-tabs, assuming default " + ss + " spaces"; + } + + // if we need to specify a space count use the ss value we ended up with... + if(this.properties_chosen.tabs === undefined) + this.properties_chosen.tabs = {val: 'spaces'}; + if(this.properties_chosen.tabs.n === undefined) + this.properties_chosen.tabs.n = ss; + } + + this.trigger("change", {property: 'tabs'}); +} + diff --git a/js/file_pane.js b/js/file_pane.js new file mode 100644 index 0000000..a21919d --- /dev/null +++ b/js/file_pane.js @@ -0,0 +1,382 @@ +"use strict"; +dn.file_pane = (function(){ + +// this uses an MVC paradigm, with the model described in file_model.js + +var el = {}; + +var history_active = false; + +// non-MVC functions :::::::::::::::::::::::::::::::::: + +var do_save = function (e){ + e.preventDefault(); //needed for when called as shortcut + if(dn.the_file.is_read_only) + return dn.show_error("Cannot save read-only file."); + dn.save({body: dn.editor.getSession().getValue()}); +} + +var read_only_bail = function(e){ + dn.show_error("The file is read-only, so you cannot change its properties."); + e.preventDefault(); // probably redundant here +} + +var on_title_begin_edit = function(e){ + if(dn.the_file.is_read_only) + return read_only_bail(e); + el.title_text.style.display = 'none'; + el.title_input.style.display = ''; + el.title_input.focus(); + el.title_input.select(); +} + +var on_title_keydown = function(e){ + if(e.which == WHICH.ESC){ + el.title_input.value = dn.the_file.title; + e.stopPropagation(); + dn.focus_editor(); + }else if(e.which === WHICH.ENTER){ + e.preventDefault(); + dn.focus_editor(); // calls blur + } +} + +var on_description_begin_edit =function(e){ + if(dn.the_file.is_read_only) + return read_only_bail(e); + el.description_text.style.display = 'none'; + el.description_input.style.display = ''; + el.description_input.focus(); + el.description_input.select(); +} + +var on_description_keydown = function(e){ + if(e.which == WHICH.ESC){ + el.description_input.value = dn.the_file.description; + e.stopPropagation(); + dn.focus_editor(); + } else if(e.which === WHICH.ENTER && !e.ctrlKey && !e.shiftKey){ + e.preventDefault(); + dn.focus_editor(); // calls blur + } +} + +var do_share = function(){ + Promise.resolve(dn.pr_file_loaded) + .then(function(){ + dn.status.file_sharing = -1; //TODO: see SO question about no callback for share dialog...how are we supposed to know when it's closed and what happened? + dn.the_file.is_shared = 0; + dn.show_status(); + + if(el.share_dialog){ + do_share_sub(); + } else { + gapi.load('drive-share', function(){ + el.share_dialog = new gapi.drive.share.ShareClient(dn.client_id); + do_share_sub(); + }); + } + }); +} + +var do_share_sub = function(){ + el.share_dialog.setItemIds([dn.the_file.file_id]); + el.share_dialog.setOAuthToken(gapi.auth.getToken().access_token); + el.share_dialog.showSettingsDialog(); +} + +var do_print = dn.do_print; + + +// controler functions :::::::::::::::::::::::::::::::::: + +var on_description_end_edit = function(){ + el.description_input.style.display = 'none'; + el.description_text.style.display = ''; + var new_val = el.description_input.value; + if(dn.the_file.description !== new_val){ + dn.the_file.set({description: new_val}); + dn.save({description: new_val}); + } + dn.focus_editor(); +} + +var on_title_end_edit = function(){ + el.title_input.style.display = 'none'; + el.title_text.style.display = ''; + var new_val = el.title_input.value; + if(dn.the_file.title !== new_val){ + dn.the_file.set({title: new_val}); + dn.save({title: new_val}); + } + dn.focus_editor(); +} + +var on_newline_click = function(e){ + if(dn.the_file.is_read_only) + return read_only_bail(e); + + var val = "detect"; + if(e.currentTarget === el.newline_unix) + val = "unix"; + else if (e.currentTarget === el.newline_windows) + val = "windows"; + dn.the_file.set({newline: val}); + dn.save({newline: val}); +} + +var on_syntax_detect_click = function(e){ + if(dn.the_file.is_read_only) + return read_only_bail(e); + + dn.the_file.set({syntax: "detect"}); + dn.save({syntax: "detect"}); +} + +var on_syntax_dropdown_click = function(e){ + if(dn.the_file.is_read_only) + return read_only_bail(e); + + var val = syntax_drop_down.GetVal(); + dn.save({syntax: val}); + dn.the_file.set({syntax: val}); +} + +var on_tab_click = function(e){ + if(dn.the_file.is_read_only) + return read_only_bail(e); + + var val = {val: "detect"}; + + if (e.currentTarget === el.tab_soft_inc){ + e.stopPropagation(); + val = {val: "spaces", + n: Math.min(dn.the_file.properties_chosen.tabs.n + 1, dn.const_.max_soft_tab_n)}; + } else if (e.currentTarget === el.tab_soft_dec){ + e.stopPropagation(); + var n = dn.the_file.properties_chosen.tabs.n - 1; + val = {val: "spaces", + n: Math.max(dn.the_file.properties_chosen.tabs.n - 1, dn.const_.min_soft_tab_n)}; + }else if(e.currentTarget === el.tab_soft){ + val = {val: "spaces", n: dn.the_file.properties_chosen.tabs.n}; + } else if(e.currentTarget === el.tab_hard){ + val = {val: "tab", n: dn.the_file.properties_chosen.tabs.n}; + } + + dn.the_file.set({tabs: val}); + dn.save({tabs: JSON.stringify(val)}); +} + +// view functions :::::::::::::::::::::::::::::::::: + +var render_title = function(){ + el.title_text_inner.textContent = dn.the_file.title; + el.title_input.value = dn.the_file.title; +} + +var render_description = function(){ + text_multi(el.description_text_inner, dn.the_file.description, true); + el.description_input.value = dn.the_file.description; +} + +var render_newline = function(){ + el.newline_detect.classList.remove('selected'); + el.newline_windows.classList.remove('selected'); + el.newline_unix.classList.remove('selected'); + var val = dn.the_file.properties.newline; + if(val === "detect") + el.newline_detect.classList.add('selected'); + else if(val === "windows") + el.newline_windows.classList.add('selected'); + else + el.newline_unix.classList.add('selected'); + el.newline_info.textContent = dn.the_file.properties_detected_info.newline; +} + +var render_syntax = function(){ + syntax_drop_down.SetInd(syntax_drop_down.IndexOf(dn.the_file.properties_chosen.syntax), true); + if(dn.the_file.properties.syntax === "detect"){ + el.ace_mode_detect.classList.add('selected'); + syntax_drop_down.SetSelected(false); + }else{ + el.ace_mode_detect.classList.remove('selected'); + syntax_drop_down.SetSelected(true); + } + el.ace_mode_info.textContent = dn.the_file.properties_detected_info.syntax; +} + +var render_tabs = function(){ + var user_tabs = dn.the_file.properties.tabs; + + el.tab_soft.classList.remove('selected'); + el.tab_hard.classList.remove('selected'); + el.tab_detect.classList.remove('selected'); + + if(user_tabs.val === "tab") + el.tab_hard.classList.add('selected'); + else if(user_tabs.val === "spaces") + el.tab_soft.classList.add('selected'); + else + el.tab_detect.classList.add('selected'); + + el.tab_soft_text.textContent = dn.the_file.properties_chosen.tabs.n; + el.tab_info.textContent = dn.the_file.properties_detected_info.tabs; +} + +var end_history = function(){ + if(!history_active) + return; + dn.history_tool.end(); + el.button_history.classList.remove('selected'); + el.button_save.style.display = ''; + el.button_print.style.display = ''; + el.inner_pane_history.style.display = 'none'; + el.inner_pane_main.style.display = ''; + history_active = false; +} + +var do_history = function(){ + Promise.resolve(dn.pr_file_loaded) + .then(function(){ + el.button_history.classList.add('selected'); + el.button_save.style.display = 'none'; + el.button_print.style.display = 'none'; + el.inner_pane_history.style.display = ''; + el.inner_pane_main.style.display = 'none'; + dn.history_tool.start(); + history_active = true; + }); +} + +var syntax_drop_down; + +var register_controllers = function(){ + // We wait until the file model is loaded before registering all these controllers. + // Note that when creating a new file, the file model is said to be loaded before + // we get the file_id back from the server, that is because we don't need to wait + // for the server to tell us about existing metadata. In this pre-file_id state, + // we can issue save requests because the save machienery knows to queued them + // up until it the file_id is available. + + // title and description + + el.title_text.addEventListener('click', on_title_begin_edit) + el.title_input.addEventListener("blur", on_title_end_edit); + el.title_input.addEventListener('keydown', on_title_keydown); + + el.description_text.addEventListener('click', on_description_begin_edit) + el.description_input.addEventListener("blur", on_description_end_edit); + el.description_input.addEventListener('keydown', on_description_keydown); + + // File custom props stuff, make use of currentTarget to identify src + + el.newline_detect.addEventListener('click', on_newline_click); + el.newline_windows.addEventListener('click', on_newline_click); + el.newline_unix.addEventListener('click', on_newline_click); + + el.tab_detect.addEventListener('click', on_tab_click); + el.tab_hard.addEventListener('click', on_tab_click); + el.tab_soft_inc.addEventListener('click', on_tab_click); + el.tab_soft_dec.addEventListener('click', on_tab_click); + el.tab_soft.addEventListener('click', on_tab_click); // propagation is stopped if inc or dec are clicked rather than the base button + + el.ace_mode_detect.addEventListener('click', on_syntax_detect_click); + syntax_drop_down.enabled = true; + syntax_drop_down.addEventListener("click", on_syntax_dropdown_click); + syntax_drop_down.addEventListener("change", on_syntax_dropdown_click); + + // File action buttons stuff + el.button_save.addEventListener('click', do_save); + el.button_print.addEventListener('click', do_print); + el.button_share.addEventListener('click', do_share); + el.button_history.addEventListener('click', function(){ + if(history_active) + end_history(); + else + do_history(); + }); +} + +var on_document_ready = function(){ + el.title_input = document.getElementById('details_file_title_input'); + el.title_text = document.getElementById('details_file_title_text'); + el.title_text_inner = document.getElementById('details_file_title_text_inner'); + el.description_input = document.getElementById('details_file_description_input'); + el.description_text = document.getElementById('details_file_description_text'); + el.description_text_inner = document.getElementById('details_file_description_text_inner'); + el.ace_mode_choose = document.getElementById('file_ace_mode_choose') + el.ace_mode_detect = document.getElementById('file_ace_mode_detect'); + el.ace_mode_info = document.getElementById('file_ace_mode_info'); + el.newline_detect = document.getElementById('file_newline_detect'); + el.newline_windows = document.getElementById('file_newline_windows'); + el.newline_unix = document.getElementById('file_newline_unix'); + el.newline_info = document.getElementById('file_newline_info'); + el.tab_detect = document.getElementById('file_tab_detect'); + el.tab_soft_inc = document.getElementById('file_tab_soft_inc'); + el.tab_soft_dec = document.getElementById('file_tab_soft_dec'); + el.tab_hard = document.getElementById('file_tab_hard'); + el.tab_soft = document.getElementById('file_tab_soft'); + el.tab_soft_text = document.getElementById('file_tab_soft_text'); + el.tab_info = document.getElementById('file_tab_info'); + el.button_save = document.getElementById('button_save'); + el.button_print = document.getElementById('button_print'); + el.button_share = document.getElementById('button_share'); + el.button_history = document.getElementById('button_history'); + el.inner_pane_main = document.getElementById('pane_file_main'); + el.inner_pane_history = document.getElementById('pane_file_history'); + + var modes = require("ace/ext/modelist").modes; + syntax_drop_down = new DropDown(modes.map(function(m){return m.caption;})); + syntax_drop_down.enabled = false; + el.ace_mode_choose.appendChild(syntax_drop_down.el); + + dn.history_tool.on_document_ready(); + + dn.the_file.addEventListener('change', function(e){ + switch(e.property){ + case "syntax": + render_syntax(); + break; + + case "newline": + render_newline(); + break; + + case "tabs": + render_tabs(); + break; + + case "title": + render_title(); + break; + + case "description": + render_description(); + break; + + case "is_loaded": + register_controllers(); + break; + } + }) + +} + + + +return { + on_save_shorcut: do_save, + on_print_shortcut: do_print, + on_document_ready: on_document_ready, + on_close_pane: end_history, + do_history: function(e){ + e.preventDefault(); + dn.g_settings.set('pane', 'pane_file'); + dn.g_settings.set('pane_open', true); + do_history(); + } +} + + + +})(); \ No newline at end of file diff --git a/js/find_pane.js b/js/find_pane.js new file mode 100644 index 0000000..5d361a4 --- /dev/null +++ b/js/find_pane.js @@ -0,0 +1,644 @@ +"use strict"; +dn.find_pane = (function(const_){ + +var el = {}; +var goto_input_has_focus = false; // we don't actually need this, but we keep it for analogy with search +var AceSearch; +var AceRange; +var search_inputs_have_focus = false; // either find itself or replace +var search_results = []; +var search_current_match_idx = -1; +var search_markers = []; +var search_marker_current = undefined; +var search_str = ""; +var search_history_idx = -1; // when walking the find history this is >=0 +var search_history_left_behind_str = ""; // although we call update_search_history after every change in search string, + // it won't always result in modifying the 0th entry in history, in such cases, + // we record the actual string here so that we can come back to it if we walk the history +var search_history_last_modified_time = -1; // set each time we change the history + + + +var focus_on_input = function(){ + if(dn.g_settings.get('find_goto')) + el.goto_input.focus(); + else + el.find_input.focus(); +} + +var on_document_ready = function(){ + AceSearch = ace.require("./search").Search; + AceRange = ace.require("./range").Range; + + el.button_case_sensitive = document.getElementById('button_find_case_sensitive'); + el.button_whole_words = document.getElementById('button_find_whole_words'); + el.button_regex = document.getElementById('button_find_regex'); + el.find_input = document.getElementById('find_input'); + el.goto_input = document.getElementById('goto_input'); + el.replace_input = document.getElementById('find_replace_input'); + el.info = document.getElementById('find_info'); + el.search_results = document.getElementById('find_results'); + el.info_overflow = document.getElementById('find_info_overflow'); + el.button_goto = document.getElementById('button_goto'); + el.button_replace = document.getElementById('button_replace'); + el.goto_wrapper = document.getElementById('find_goto_wrapper'); + el.find_wrapper = document.getElementById('find_find_wrapper'); + el.replace_wrapper = document.getElementById('find_replace_wrapper'); + el.button_find_replace_all = document.getElementById('button_find_replace_all'); + + dn.g_settings.addEventListener('VALUE_CHANGED', function(e){ + var new_value = e.newValue; + switch(e.property){ + case 'find_regex': + if(new_value) + el.button_regex.classList.add('selected'); + else + el.button_regex.classList.remove('selected'); + settings_changed(); + break; + + case 'find_whole_words': + if(new_value) + el.button_whole_words.classList.add('selected'); + else + el.button_whole_words.classList.remove('selected'); + settings_changed(); + break; + + case 'find_case_sensitive': + if(new_value) + el.button_case_sensitive.classList.add('selected'); + else + el.button_case_sensitive.classList.remove('selected'); + settings_changed(); + break; + + case 'find_replace': + on_replace_toggled(new_value); + break; + + case 'find_goto': + on_goto_toggled(new_value); + break; + } + }) + + el.button_case_sensitive.addEventListener('click', function(){ + dn.g_settings.set('find_case_sensitive', !dn.g_settings.get('find_case_sensitive')); + }) + el.button_whole_words.addEventListener('click', function(){ + dn.g_settings.set('find_whole_words', !dn.g_settings.get('find_whole_words')); + }) + el.button_regex.addEventListener('click', function(){ + dn.g_settings.set('find_regex', !dn.g_settings.get('find_regex')); + }) + el.goto_input.addEventListener('keydown', goto_input_keydown); + el.goto_input.addEventListener('keyup', goto_input_keyup); + el.goto_input.addEventListener('blur', goto_input_blur); + el.goto_input.addEventListener('focus', goto_input_focus); + el.find_input.addEventListener('keyup', find_input_keyup); + el.find_input.addEventListener('keydown', find_input_keydown); + el.find_input.addEventListener('blur', search_inputs_blur); + el.find_input.addEventListener('focus', search_inputs_focus); + el.replace_input.addEventListener('blur', search_inputs_blur); + el.replace_input.addEventListener('focus', search_inputs_focus); + el.replace_input.addEventListener('keydown', replace_input_keydown); + el.button_find_replace_all.addEventListener('click', replace_all); + el.button_replace.addEventListener('click', function(){ + dn.g_settings.set('find_replace', !dn.g_settings.get('find_replace')); + dn.g_settings.set('find_goto', false); + el.find_input.focus(); + }) + el.button_goto.addEventListener('click', function(){ + dn.g_settings.set('find_goto', !dn.g_settings.get('find_goto')); + if(dn.g_settings.get('find_goto')) + el.goto_input.focus(); + else + el.find_input.focus(); + }) +} + +var find_shortcut_used = function(e){ + var sel = dn.editor.session.getTextRange(dn.editor.getSelectionRange()); + dn.g_settings.set('find_goto', false); + dn.g_settings.set('pane', 'pane_find'); + dn.g_settings.set('pane_open', true); + if(sel){ + if(sel !== search_str){ + search_str = sel; + search_history_idx = -1; + update_search_history(); + } + el.find_input.value = sel; + el.find_input.select(); + } + el.find_input.focus(); + e.preventDefault(); +} + +var goto_shortcut_used = function(e){ + dn.g_settings.set('find_goto', true); + dn.g_settings.set('pane', 'pane_find'); // doing this after the find_active=true, tells the change handler not to put focus back to editor + dn.g_settings.set('pane_open', true); + el.goto_input.focus(); + e.preventDefault(); +} + +var replace_shortcut_used = function(e){ + dn.g_settings.set('find_replace', true); + find_shortcut_used(e); +} + +var on_goto_toggled = function(new_value){ + // This just toggles the display, it does not deal with focus/blur, which may happen afterwards + // as a consequence if the relevant inputs previously had the focus. + + if(new_value){ + el.goto_wrapper.style.display = ''; + el.find_wrapper.style.display = 'none'; + el.button_goto.classList.add('selected'); + el.info.textContent = 'goto line inactive'; + el.replace_wrapper.style.display = 'none'; + }else{ + el.goto_wrapper.style.display = 'none'; + el.find_wrapper.style.display = ''; + el.button_goto.classList.remove('selected'); + el.info.textContent = 'search inactive'; + if (dn.g_settings.get('find_replace')) + el.replace_wrapper.style.display = ''; + } +} + +var on_replace_toggled = function(new_value){ + if(new_value){ + el.button_replace.classList.add('selected'); + if(!dn.g_settings.get('find_goto')) + el.replace_wrapper.style.display = ''; + }else{ + el.replace_wrapper.style.display = 'none'; + el.button_replace.classList.remove('selected'); + } + if(search_inputs_have_focus) + select_search_result_idx(search_current_match_idx); +} + +// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +// goto ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +// the implementation of goto is simpler than for search, so we start with it... + +var goto_input_focus = function(){ + goto_input_has_focus = true; + el.info.textContent = "type to goto line"; + perform_goto(); +} + +var goto_input_blur = function(e){ + goto_input_has_focus = false; + el.info.textContent = "goto line inactive"; + //if(!e.relatedTarget) + // dn.focus_editor(); +} + +var perform_goto = function(){ + // called by find_goto_input_focus and find_goto_keyup + var validated_str = el.goto_input.value.replace(/[^\d]/,''); + if (validated_str !== el.goto_input.value) + el.goto_input.value = validated_str; + if(validated_str === "") + return; + var num = parseInt(validated_str); + dn.editor.gotoLine(num); + dn.editor.navigateLineEnd(); +} + +var goto_input_keyup = perform_goto; //alias + +var goto_input_keydown = function(e){ + // keydown is fired repeatedly when key remains down + if(e.which == WHICH.DOWN){ + el.goto_input.value = parseInt(el.goto_input.value.replace(/[^\d]/,''))+1; + perform_goto(); + e.preventDefault(); + }else if(e.which == WHICH.UP){ + el.goto_input.value = parseInt(el.goto_input.value.replace(/[^\d]/,''))-1; + perform_goto(); + e.preventDefault(); + } else if(e.which == WHICH.ESC){ + dn.g_settings.set('pane_open', false); + e.preventDefault(); + e.stopPropagation(); + dn.focus_editor(); + } +} + + +// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +// search ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +// :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + + +var update_search_history = function(){ + // called when the user types in the search box, or when we launch find from shortcut with selection + var current_str = search_str; + search_history_left_behind_str = current_str; + + if(current_str.length === 0 || !dn.g_atomic_exec){ + search_history_idx = -1; + return; + } + + dn.g_atomic_exec(function(){ + var time_now = Date.now(); + + if(dn.g_find_history.length === 0){ + // create a history entry for the first ever time + dn.g_find_history.push(current_str); + search_history_idx = 0; + search_history_last_modified_time = time_now; + return; + } + + var top_of_history = dn.g_find_history.get(0); + + if(current_str.lengthtop_of_history.length + && top_of_history.toLowerCase() === current_str.substr(0, top_of_history.length).toLowerCase()){ + // top_of_history is a case-insensitive prefix of current_str, replace top_of_history with current + dn.g_find_history.set(0, current_str); + } else if(time_now > search_history_last_modified_time + dn.const_.find_history_add_delay){ + // it's been a while since changes were made, add the current string as the new top + dn.g_find_history.insert(0, current_str); + if(dn.g_find_history.length > dn.const_.find_history_max_len){ + dn.g_find_history.remove(dn.g_find_history.length-1); + } + } else { + // although the current string is at least somewhat different to the top, it's not been that + // long since we modified the top, so lets just replace it with the new string + dn.g_find_history.set(0, current_str); + } + search_history_idx = 0; + search_history_last_modified_time = time_now; + + // TODO: we may like to remove duplicates in history, but without allowing recall to obliterate lots of existing memories + + }); // g_atomic_exec +} + + +var search_inputs_focus = function(e){ + if(e.currentTarget == el.find_input){ + el.find_input.tabIndex = 101; + el.replace_input.tabIndex = 102; + } else { + el.find_input.tabIndex = 102; + el.replace_input.tabIndex = 101; + } + if(search_inputs_have_focus) + return; // focus was transfered between replace/find inputs + + search_inputs_have_focus = true; + dn.editor.setHighlightSelectedWord(false); + perform_search(); +} + +var search_inputs_blur = function(e){ + if(e.relatedTarget == el.replace_input || e.relatedTarget == el.find_input) + return; // focus is transfering between replace/find inputs + search_inputs_have_focus = false; + + // remove all search_markers + var session = dn.editor.getSession(); + for(var ii=0; ii selected_range.start.row || + (search_results[ii].end.row == selected_range.start.row && + search_results[ii].end.column >= selected_range.start.column)) + break; + var current_match_idx = (ii == search_results.length ? search_results.length-1 : ii); + + // Add search_markers into the editor to show *all* the search_results + for(var ii=0; ii= search_results.length){ + search_results_sub = search_results_sub.concat(search_results.slice(search_current_match_idx + 1)); + search_results_sub = search_results_sub.concat(search_results.slice(0, n_post + 1 - (search_results.length - search_current_match_idx))); + } else { + search_results_sub = search_results_sub.concat(search_results.slice(search_current_match_idx + 1, search_current_match_idx + n_post + 1)); + } + } + + // Now lets build the html to show the subset of search_results in the widget + var show_replace_buttons = dn.g_settings.get('find_replace'); + var html = ""; + for(var ii=0; ii const_.find_max_prefix_chars; //TODO: deal with indent better + row = search_results_sub[ii].range.end.row; + col = search_results_sub[ii].range.end.column; + var suffix_range = new AceRange(row, col, row, col+const_.find_max_suffix_chars); + html += "
" + + "
" + (row+1) + "
" + + "
" + + "
" + + (pre_ellipses ? "…" : "") + escape_str(session.getTextRange(prefix_range)) + + "" + escape_str(session.getTextRange(search_results_sub[ii].range)) + "" + + escape_str(session.getTextRange(suffix_range)) + + "
" + + "
" + + (show_replace_buttons ? "
r
" : "") + + "
"; + } + el.search_results.innerHTML = html; + var els = el.search_results.getElementsByClassName('find_result_item'); + for(var ii=0; ii max_search_results) + el.info_overflow.textContent = "... and " + (search_results.length - max_search_results) + " more matches"; + else + el.info_overflow.textContent = ""; + + // do the special marker for the current selection and actually select it + search_marker_current = session.addMarker(search_results[search_current_match_idx].range, "find_current_match_marker", "find_current_match_marker", false); + dn.editor.selection.setSelectionRange(search_results[search_current_match_idx].range, false); + dn.editor.renderer.scrollSelectionIntoView(); +} + +var settings_changed = function(){ + if(search_inputs_have_focus || + (dn.g_settings.get('pane') === 'pane_find' && dn.g_settings.get('pane_open') && el.find_input.value)) + perform_search(); +} + +var search_result_click = function(ii){ + // this can only be called while find input has the focus + return function(e){select_search_result_idx(ii);}; +} + +var search_replace_result_click = function(ii){ + return function(e){ + replace_result_idx(ii); + e.stopPropagation(); // prevent selecting item + } +} + +var find_input_keyup = function(e){ + //we need keyup here in order that the val has the new character or new backspace + if(e.which == WHICH.ENTER || e.which == WHICH.ESC || e.which == WHICH.UP || e.which == WHICH.DOWN) + return; + if(search_str == el.find_input.value) + return; + perform_search(); + update_search_history(); +} + +var find_input_keydown = function(e){ + // we want keydown here so that we can get repeated firing with keydown (i think on most browsers) + + if ((e.which == WHICH.ENTER && !e.shiftKey) || (!e.ctrlKey && e.which == WHICH.DOWN)){ + //find next + select_search_result_idx(search_current_match_idx + 1 < search_results.length ? + search_current_match_idx + 1 + : 0); + e.preventDefault(); + return; + }else if((e.which == WHICH.ENTER && e.shiftKey) || (!e.ctrlKey && e.which == WHICH.UP)){ + //find previous + select_search_result_idx(search_current_match_idx - 1 < 0 ? + search_results.length -1 + : search_current_match_idx - 1); + e.preventDefault(); + return; + } + + if(e.which == WHICH.ESC){ + dn.g_settings.set('pane_open', false); // blurs the find_input + dn.focus_editor(); + e.preventDefault(); + e.stopPropagation(); + return; + } + + if(e.ctrlKey && dn.g_find_history && (e.which == WHICH.DOWN || e.which == WHICH.UP)){ + dn.g_atomic_exec(function(){ + if(e.which == WHICH.UP) // up means go to more recent item + search_history_idx = Math.max(-1, search_history_idx-1); + else // down means move further into the past + search_history_idx++; + search_history_idx = Math.min(search_history_idx, dn.g_find_history.length-1); + if(search_history_idx == -1){ + el.find_input.value = search_history_left_behind_str; + }else{ + el.find_input.value = dn.g_find_history.get(search_history_idx); + } + el.find_input.setSelectionRange(el.find_input.value.length, el.find_input.value.length+10); + }); + perform_search(); + e.preventDefault(); + } + +} + +var replace_input_keydown = function(e){ + if(e.which == WHICH.ENTER){ + if(e.ctrlKey || e.shiftKey) + replace_all(); + else + replace_result_idx(search_current_match_idx); + e.preventDefault(); + }else{ + find_input_keydown(e); // up, down search_results and esc + } +} + +var replace_all = function(e){ + try{ + var options = build_search_options(); + } catch (e) { + dn.show_error(e.message); + return; + } + dn.editor.replaceAll(el.replace_input.value, options); + dn.focus_editor(); +} + +var replace_result_idx = function(idx){ + var range = search_results[idx].range; + // we use undocumented ACE API to avoid messing around tryinng to force it to use the exact range we wanted + dn.editor.$search.set(build_search_options()); //this is needed so that $tryReplace knows what to do with regex'es + dn.editor.$tryReplace(range, el.replace_input.value) // returns true on success, but do we care? + perform_search(); +} + + + + + +return { + focus_on_input: focus_on_input, + on_document_ready: on_document_ready, + on_find_shortcut: find_shortcut_used, + on_replace_shortcut: replace_shortcut_used, + on_goto_shortcut: goto_shortcut_used +} + +})(dn.const_); \ No newline at end of file diff --git a/js/help_pane.js b/js/help_pane.js new file mode 100644 index 0000000..9150369 --- /dev/null +++ b/js/help_pane.js @@ -0,0 +1,111 @@ +"use strict"; + +dn.help_pane = (function(){ + +var el = {}; + +var show_inner = function(inner_pane){ + // this is a view function for dn.g_settings['help_inner'] + // expects string 'shorcuts' or 'tips', any other values shows main + + el.inner_pane_shortcuts.style.display = 'none'; + el.inner_pane_tips.style.display = 'none'; + el.inner_pane_main.style.display = 'none'; + + el.button_shortcuts.classList.remove('selected'); + el.button_tips.classList.remove('selected'); + + if(inner_pane == 'tips'){ + el.inner_pane_tips.style.display = ''; + el.button_tips.classList.add('selected'); + } else if(inner_pane == 'shortcuts'){ + el.inner_pane_shortcuts.style.display = ''; + el.button_shortcuts.classList.add('selected'); + } else { + el.inner_pane_main.style.display = ''; + } +} + + +var render_user_name = function(val){ + el.user_name.textContent = val; +} + +var create_pane_shortcuts = function(){ +//This is hardly the world's most efficient way of doing this....(but it probably doesn't matter)... + + var arry = dn.shortcuts_list; + var dict = {}; + var platform = dn.platform; + + if(platform == "Windows" || platform == "Linux"){ + for(var i=0;i 2? parts[2] : parts[1]; + } + }else{ + //TODO: show something here, maybe let user switch, maybe have touch info for ipad & android. + } + + var html = []; + for(var action in dict) + html.push("
" + + action + "
" + dict[action].replace(",","
") + + "
"); + + // TODO: put shortcuts into element titles, see menu_id_to_caption + //for(var action in dn.tooltip_info)if(action in dict) + // dn.tooltip_info[action] += dict[action]; + + el.inner_pane_shortcuts.innerHTML = [ + "
Keyboard Shortcuts ", + platform ? "(" + platform + ")" : "" , + "
", + "
action
key
", + "
", + html.join(''), + "
"].join(''); + +} + +var on_document_ready = function(){ + el.user_name = document.getElementById('user_name'); + el.inner_pane_shortcuts = document.getElementById('pane_help_shortcuts'); + el.inner_pane_tips = document.getElementById('pane_help_tips'); + el.inner_pane_main = document.getElementById('pane_help_main'); + el.button_shortcuts = document.getElementById('button_view_shortcuts'); + el.button_tips = document.getElementById('button_view_tips'); + el.button_shortcuts.addEventListener('click', function(){ + if(dn.g_settings.get('help_inner') === 'shortcuts') + dn.g_settings.set('help_inner', 'main'); + else + dn.g_settings.set('help_inner', 'shortcuts'); + }) + el.button_tips.addEventListener('click', function(){ + if(dn.g_settings.get('help_inner') === 'tips') + dn.g_settings.set('help_inner', 'main'); + else + dn.g_settings.set('help_inner', 'tips'); + }) + create_pane_shortcuts(); + dn.g_settings.addEventListener("VALUE_CHANGED", function(e){ + if(e.property === 'help_inner') + show_inner(e.newValue); + }); + +} + + +return { + on_document_ready: on_document_ready, + on_user_name_change: render_user_name +} + +})(); \ No newline at end of file diff --git a/js/history_tool.js b/js/history_tool.js new file mode 100644 index 0000000..0fbb094 --- /dev/null +++ b/js/history_tool.js @@ -0,0 +1,366 @@ +"use strict"; + +dn.history_tool = (function(){ + +var el = {}; + +var revision_meta = []; // we clear this each time we call refresh_revisions_list +var worker_has_revision = {}; // we cache revision bodies on the worker, recording true here when we do using revision id as the key +var revision_uses_line = []; // for each revision this has a 1d boolean array, giving 1 if the line is used in that revision. + // every time we get a "delivery" of new lines from the worker we invalidate all of this. In future, + // when we want to display a particular revision we have to ask the worker for the data. + +var worker; +var editor; +var at_idx = 0; +var from_idx = 0; + + +var LineWidgets = ace.require("./line_widgets").LineWidgets; +var start = function(){ + // TODO: add current state to revisions meta and body + + if(worker === undefined){ + worker = new Worker("js/history_tool_worker.js"); + worker.onmessage = on_worker_message; + } + + dn.el.editor.style.display = 'none'; + el.revisions_view.style.display = ''; + el.revisions_view.innerHTML = ''; + el.info_overflow.style.display = ''; + editor = ace.edit("revisions_view"); + editor.setFontSize(dn.editor.getFontSize()); + dn.patch_editor_history(editor); + editor.session.setUseWrapMode(true); + editor.setReadOnly(true); + refresh_revisions_list(); +} + +var end = function(){ + // destroy the editor, and replace its dom element with a newly cloned instance + // this wipes out any event listeners. https://github.com/ajaxorg/ace/issues/2085 + // also set the element's contents to be empty + editor.destroy(); + editor = undefined; + el.revisions_view.innerHTML = ''; + var el_old = el.revisions_view; + el.revisions_view = el_old.cloneNode(true); + el_old.parentNode.replaceChild(el.revisions_view, el_old); + + dn.el.editor.style.display = ''; + el.revisions_view.style.display = 'none'; + el.info_overflow.style.display = 'none'; +} + +var get_editor = function(){ + return editor; +} + +var on_worker_message = function(e){ + if(!editor) return; // if we closed history tool while worker was busy, we can safely ignore the two possible types of message it might be sending + + var session = editor.getSession(); + if(e.data.diffed_revision){ + revision_uses_line = []; // invalidate everything we knew about uses_line + // TODO: perhaps we should batch up the newly delivered data and only append it when the user requests an earlier revision + if(e.data.diffed_revision.idx === 0){ + session.doc.insertFullLines(-1, e.data.diffed_revision.lines); // resets to supplied lines + } else { + session.doc.insertFullLines(e.data.diffed_revision.sections); // inserts multiple batches of lines + revision_meta[e.data.diffed_revision.idx].el_tick.classList.add('diffed'); + } + } + + if(e.data.line_is_used){ + var idx = e.data.line_is_used.idx; + revision_uses_line[idx] = new Uint8Array(e.data.line_is_used.buffer); + if(idx === Math.max(at_idx, from_idx)){ + // hooray, we've got both at and from, lets render 'em, quick! + if(at_idx === from_idx) + render_single_revision(at_idx); + else + render_revision_pair(at_idx, from_idx); + }else if(Math.max(at_idx, from_idx) >= e.data.line_is_used.diffed_n && idx == Math.min(at_idx, from_idx)){ + // well, we've got the mroe recent of the two, and the other one is going to be a while, so lets render what we have + render_single_revision(Math.min(at_idx, from_idx)); + } + } + + +} + + +var render_single_revision = function(idx){ + editor.show_rows(revision_uses_line[idx]); // 1=show, 0=hide, which is exactly what we want + var str = ""; + if(idx === 0){ + str = "Showing the file:\n\t" + current_version_date_str; + }else{ + var time = date_str_to_local(revision_meta[idx].modifiedTime) + str = "Showing file as it was at:\n\t" + time[1] + " on " + time[0]; + } + text_multi(el.info, str); +} + +var fuse = function(at_is_used, from_is_used){ + // maps: (0,0) => 0 (1,1) => 1 (1,0) => 3 (0,1) => 2 + // TODO: maybe there would have been a slightly clever maping to have chosen, but it doesn't matter much. + var map = new Uint8Array([0,2,3,1]); + var show_rows = new Uint8Array(at_is_used.length); + for(var ii=0; ii< show_rows.length; ii++) + show_rows[ii] = map[at_is_used[ii] | (from_is_used[ii] << 1)]; + return show_rows; +} + +var current_version_date_str = "as it exists in the editor"; + +var render_revision_pair = function(at_idx, from_idx){ + editor.show_rows(fuse(revision_uses_line[at_idx], revision_uses_line[from_idx])); + + var str = "" + if(at_idx === 0){ + str += "Showing the file:\n\t" + current_version_date_str; + }else{ + var time_at = date_str_to_local(revision_meta[at_idx].modifiedTime); + str += "Showing file as it was at:\n\t" + time_at[1] + " on " + time_at[0]; + } + if(from_idx === 0){ + str += "\nWith changes relative to the file:\n\t" + current_version_date_str; + }else{ + var time_from = date_str_to_local(revision_meta[from_idx].modifiedTime); + str += "\nWith changes relative to the file at:\n\t" + time_from[1] + " on " + time_from[0]; + } + text_multi(el.info, str); +} + +var append_tick = function(){ + var el_tick = document.createElement('div'); + el_tick.classList.add('revision_tick'); + el.tick_box.appendChild(el_tick); + return el_tick; +} + +var send_revisions_order_to_worker = function(resp){ + var r_to_get = [], id_order = []; + revision_meta = revision_meta.concat(resp.result.revisions.reverse()); + el.at_range.max = revision_meta.length - 1; + el.from_range.max = revision_meta.length - 1; + + for(var ii=1; ii0) + attempt_send_line_is_used(); + } + +} + + +var attempt_send_line_is_used = function(){ + // if any of the requests can be dealt with now, then + // send the data for everything now. Anything left over + // will have to wait. Note that we will have to resend + // everything next time, because it will have been invalidated by + // the fact we added new data. + for(var ii=0; ii + +Copyright (c) 2007, Snowtide Informatics Systems, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the Snowtide Informatics Systems nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED +TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. +***/ +/* Author: Chas Emerick */ +//JSlint made happy by DM. +// +//opcodes are 5-tuples of the form [tag,a_start,a_end,b_start,b_end]. +//the tag has one of the following 4 values: r=replace, d=delete, i=insert, e=equal +//where the indicies define the relavant sections in seq_a and seq_b +//Only replace and equal actually require all 4 indicies, but they are present in all cases. +//a_start from opp_{n+1} = a_end from opp_{n}, and same for b_start and b_end +// see http://docs.python.org/2/library/difflib.html#difflib.SequenceMatcher +// +var __whitespace = {" ":true, "\t":true, "\n":true, "\f":true, "\r":true}; + +var difflib = { + defaultJunkFunction: function (c) { + return __whitespace.hasOwnProperty(c); + }, + + stripLinebreaks: function (str) { return str.replace(/^[\n\r]*|[\n\r]*$/g, ""); }, + + stringAsLines: function (str) { + var lfpos = str.indexOf("\n"); + var crpos = str.indexOf("\r"); + var linebreak = ((lfpos > -1 && crpos > -1) || crpos < 0) ? "\n" : "\r"; + + var lines = str.split(linebreak); + for (var i = 0; i < lines.length; i++) { + lines[i] = difflib.stripLinebreaks(lines[i]); + } + + return lines; + }, + + // iteration-based reduce implementation + __reduce: function (func, list, initial) { + var value, idx; + if (initial !== null) { + value = initial; + idx = 0; + } else if (list) { + value = list[0]; + idx = 1; + } else { + return null; + } + + for (; idx < list.length; idx++) { + value = func(value, list[idx]); + } + + return value; + }, + + // comparison function for sorting lists of numeric tuples + __ntuplecomp: function (a, b) { + var mlen = Math.max(a.length, b.length); + for (var i = 0; i < mlen; i++) { + if (a[i] < b[i]) return -1; + if (a[i] > b[i]) return 1; + } + + return a.length == b.length ? 0 : (a.length < b.length ? -1 : 1); + }, + + __calculate_ratio: function (matches, length) { + return length ? 2.0 * matches / length : 1.0; + }, + + // returns a function that returns true if a key passed to the returned function + // is in the dict (js object) provided to this function; replaces being able to + // carry around dict.has_key in python... + __isindict: function (dict) { + return function (key) { return dict.hasOwnProperty(key); }; + }, + + // replacement for python's dict.get function -- need easy default values + __dictget: function (dict, key, defaultValue) { + return dict.hasOwnProperty(key) ? dict[key] : defaultValue; + }, + + SequenceMatcher: function (a, b, isjunk) { + this.set_seqs = function (a, b) { + this.set_seq1(a); + this.set_seq2(b); + }; + + this.set_seq1 = function (a) { + if (a == this.a) return; + this.a = a; + this.matching_blocks = this.opcodes = null; + }; + + this.set_seq2 = function (b) { + if (b == this.b) return; + this.b = b; + this.matching_blocks = this.opcodes = this.fullbcount = null; + this.__chain_b(); + }; + + this.__chain_b = function () { + var b = this.b; + var n = b.length; + var b2j = this.b2j = {}; + var populardict = {}; + var elt; + for (var i = 0; i < b.length; i++) { + elt = b[i]; + if (b2j.hasOwnProperty(elt)) { + var indices = b2j[elt]; + if (n >= 200 && indices.length * 100 > n) { + populardict[elt] = 1; + delete b2j[elt]; + } else { + indices.push(i); + } + } else { + b2j[elt] = [i]; + } + } + + for (elt in populardict) { + if (populardict.hasOwnProperty(elt)) { + delete b2j[elt]; + } + } + + var isjunk = this.isjunk; + var junkdict = {}; + if (isjunk) { + for (elt in populardict) { + if (populardict.hasOwnProperty(elt) && isjunk(elt)) { + junkdict[elt] = 1; + delete populardict[elt]; + } + } + for (elt in b2j) { + if (b2j.hasOwnProperty(elt) && isjunk(elt)) { + junkdict[elt] = 1; + delete b2j[elt]; + } + } + } + + this.isbjunk = difflib.__isindict(junkdict); + this.isbpopular = difflib.__isindict(populardict); + }; + + this.find_longest_match = function (alo, ahi, blo, bhi) { + var a = this.a; + var b = this.b; + var b2j = this.b2j; + var isbjunk = this.isbjunk; + var besti = alo; + var bestj = blo; + var bestsize = 0; + var j = null; + + var j2len = {}; + var nothing = []; + for (var i = alo; i < ahi; i++) { + var newj2len = {}; + var jdict = difflib.__dictget(b2j, a[i], nothing); + for (var jkey in jdict) { + if (jdict.hasOwnProperty(jkey)) { + j = jdict[jkey]; + if (j < blo) continue; + if (j >= bhi) break; + var k; + newj2len[j] = k = difflib.__dictget(j2len, j - 1, 0) + 1; + if (k > bestsize) { + besti = i - k + 1; + bestj = j - k + 1; + bestsize = k; + } + } + } + j2len = newj2len; + } + + while (besti > alo && bestj > blo && !isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) { + besti--; + bestj--; + bestsize++; + } + + while (besti + bestsize < ahi && bestj + bestsize < bhi && + !isbjunk(b[bestj + bestsize]) && + a[besti + bestsize] == b[bestj + bestsize]) { + bestsize++; + } + + while (besti > alo && bestj > blo && isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) { + besti--; + bestj--; + bestsize++; + } + + while (besti + bestsize < ahi && bestj + bestsize < bhi && isbjunk(b[bestj + bestsize]) && + a[besti + bestsize] == b[bestj + bestsize]) { + bestsize++; + } + + return [besti, bestj, bestsize]; + }; + + this.get_matching_blocks = function () { + if (this.matching_blocks !== null) return this.matching_blocks; + var la = this.a.length; + var lb = this.b.length; + + var queue = [[0, la, 0, lb]]; + var matching_blocks = []; + var alo, ahi, blo, bhi, qi, i, j, k, x; + while (queue.length) { + qi = queue.pop(); + alo = qi[0]; + ahi = qi[1]; + blo = qi[2]; + bhi = qi[3]; + x = this.find_longest_match(alo, ahi, blo, bhi); + i = x[0]; + j = x[1]; + k = x[2]; + + if (k) { + matching_blocks.push(x); + if (alo < i && blo < j) + queue.push([alo, i, blo, j]); + if (i+k < ahi && j+k < bhi) + queue.push([i + k, ahi, j + k, bhi]); + } + } + + matching_blocks.sort(difflib.__ntuplecomp); + + var i1 , j1, k1, block, i2, j2, k2; + i1 = j1 = k1 = block = 0; + var non_adjacent = []; + for (var idx in matching_blocks) { + if (matching_blocks.hasOwnProperty(idx)) { + block = matching_blocks[idx]; + i2 = block[0]; + j2 = block[1]; + k2 = block[2]; + if (i1 + k1 == i2 && j1 + k1 == j2) { + k1 += k2; + } else { + if (k1) non_adjacent.push([i1, j1, k1]); + i1 = i2; + j1 = j2; + k1 = k2; + } + } + } + + if (k1) non_adjacent.push([i1, j1, k1]); + + non_adjacent.push([la, lb, 0]); + this.matching_blocks = non_adjacent; + return this.matching_blocks; + }; + + this.get_opcodes = function () { + if (this.opcodes !== null) return this.opcodes; + var i = 0; + var j = 0; + var answer = []; + this.opcodes = answer; + var block, ai, bj, size, tag; + var blocks = this.get_matching_blocks(); + for (var idx in blocks) { + if (blocks.hasOwnProperty(idx)) { + block = blocks[idx]; + ai = block[0]; + bj = block[1]; + size = block[2]; + tag = ''; + if (i < ai && j < bj) { + tag = 'r'; + } else if (i < ai) { + tag = 'd'; + } else if (j < bj) { + tag = 'i'; + } + if (tag) answer.push([tag, i, ai, j, bj]); + i = ai + size; + j = bj + size; + + if (size) answer.push(['e', ai, i, bj, j]); + } + } + + return answer; + }; + + // this is a generator function in the python lib, which of course is not supported in javascript + // the reimplementation builds up the grouped opcodes into a list in their entirety and returns that. + this.get_grouped_opcodes = function (n) { + if (!n) n = 3; + var codes = this.get_opcodes(); + if (!codes) codes = [['e', 0, 1, 0, 1]]; + var code, tag, i1, i2, j1, j2; + if (codes[0][0] == 'e') { + code = codes[0]; + tag = code[0]; + i1 = code[1]; + i2 = code[2]; + j1 = code[3]; + j2 = code[4]; + codes[0] = [tag, Math.max(i1, i2 - n), i2, Math.max(j1, j2 - n), j2]; + } + if (codes[codes.length - 1][0] == 'e') { + code = codes[codes.length - 1]; + tag = code[0]; + i1 = code[1]; + i2 = code[2]; + j1 = code[3]; + j2 = code[4]; + codes[codes.length - 1] = [tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]; + } + + var nn = n + n; + var group = []; + var groups = []; + for (var idx in codes) { + if (codes.hasOwnProperty(idx)) { + code = codes[idx]; + tag = code[0]; + i1 = code[1]; + i2 = code[2]; + j1 = code[3]; + j2 = code[4]; + if (tag == 'e' && i2 - i1 > nn) { + group.push([tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]); + groups.push(group); + group = []; + i1 = Math.max(i1, i2-n); + j1 = Math.max(j1, j2-n); + } + + group.push([tag, i1, i2, j1, j2]); + } + } + + if (group && !(group.length == 1 && group[0][0] == 'e')) groups.push(group); + + return groups; + }; + + this.ratio = function () { + var matches = difflib.__reduce( + function (sum, triple) { return sum + triple[triple.length - 1]; }, + this.get_matching_blocks(), 0); + return difflib.__calculate_ratio(matches, this.a.length + this.b.length); + }; + + this.quick_ratio = function () { + var fullbcount, elt, i; + if (this.fullbcount === null) { + this.fullbcount = fullbcount = {}; + for (i = 0; i < this.b.length; i++) { + elt = this.b[i]; + fullbcount[elt] = difflib.__dictget(fullbcount, elt, 0) + 1; + } + } + fullbcount = this.fullbcount; + + var avail = {}; + var availhas = difflib.__isindict(avail); + var matches = 0, numb = 0; + for (i = 0; i < this.a.length; i++) { + elt = this.a[i]; + if (availhas(elt)) { + numb = avail[elt]; + } else { + numb = difflib.__dictget(fullbcount, elt, 0); + } + avail[elt] = numb - 1; + if (numb > 0) matches++; + } + + return difflib.__calculate_ratio(matches, this.a.length + this.b.length); + }; + + this.real_quick_ratio = function () { + var la = this.a.length; + var lb = this.b.length; + return difflib.__calculate_ratio(Math.min(la, lb), la + lb); + }; + + this.isjunk = isjunk ? isjunk : difflib.defaultJunkFunction; + this.a = this.b = null; + this.set_seqs(a, b); + } +}; diff --git a/js/info.js b/js/info.js new file mode 100644 index 0000000..a95b330 --- /dev/null +++ b/js/info.js @@ -0,0 +1,200 @@ +"use strict"; + +dn.menu_id_to_caption = { +'menu_print': 'print', +'menu_sharing': 'sharing', +'menu_save': 'save', +'menu_history': 'history', +'menu_file': 'current file', +'menu_new': 'new', +'menu_open': 'new/open', +'menu_find': 'find/replace', +'menu_goto': 'goto line', +'menu_general_settings': 'general settings', +'menu_shortcuts': 'shortcuts', +'menu_drive': 'drive', +'menu_help': 'about/help'}; + + +dn.shortcuts_list = [ +"cut|Ctrl-X|Cmd-X", +"copy|Ctrl-C|Cmd-C", +"paste|Ctrl-V|Cmd-V", +"cycle clipboard|Cltr-[V then left or right arrow]|Cmd-[V then left or right arrow]", +"select all|Ctrl-A|Cmd-A", +"find|Ctrl(-Alt)-F", +"replace|Ctrl-R", +"go to line|Ctrl(-Alt)-L", +"undo|Ctrl-Z|Cmd-Z", +"redo|Ctrl-Shift-Z,Ctrl-Y|Cmd-Shift-Z,Cmd-Y", +"autocomplete|Ctrl-Space|Cmd-Space", +" | ", +"toggle widget|Esc", +"save|Ctrl-S|Cmd-S", +"print|Ctrl(-Alt)-P|Cmd-P", +"file history|Ctrl-H|Cmd-H", +"new|Ctrl(-Alt)-N", +"open|Ctrl(-Alt)-O", +" | ", +"to upper case|Ctrl-U", +"to lower case|Ctr-Shift-U", +"modify selection|Shift-(Ctrl-)(Alt-) {Down, Up, Left, Right, End, Home, PageDown, PageUp, End}|Shift-(Cmd-)(Alt-) {Down, Up, Left, Right, End, Home, PageDown,End}", +"copy lines down|Ctrl-Alt-Down|Cmd-Option-Down", +"copy lines up|Ctrl-Alt-Up|Cmd-Option-Up", +"center selection||Ctrl-L", +"fold all|Alt-0|Option-0", +"unfold all|Alt-Shift-0|Option-Shift-0", +"go to end|Ctrl-End,Ctrl-Down|Cmd-End,Cmd-Down", +"go to line end|Alt-Right,End|Cmd-Right,End,Ctrl-E", +"go to line start|Alt-Left,Home|Cmd-Left,Home,Ctrl-A", +"go to page down|PageDown|Option-PageDown,Ctrl-V", +"go to page up|PageUp|Option-PageUp", +"go to start|Ctrl-Home,Ctrl-Up|Cmd-Home,Cmd-Up", +"go to word left|Ctrl-Left|Option-Left", +"go to word right|Ctrl-Right|Option-Right", +"indent|Tab", +"outdent|Shift-Tab", +"overwrite|Insert", +"remove line|Ctrl-D|Cmd-D", +"remove to line end||Ctrl-K", +"remove to linestart||Option-Backspace", +"remove word left||Alt-Backspace,Ctrl-Alt-Backspace", +"remove word right||Alt-Delete", +"split line||Ctrl-O", +"toggle comment|Ctrl-7|Cmd-7", +"transpose letters|Ctrl-T" +] + +dn.ext_to_mime_type = { +html:"text/html", +htm:"text/html", +js:"text/javascript", +pl:"application/x-perl", +xml:"text/xml", +c:"text/x-csrc", +cpp:"text/x-c++src", +h:"text/x-chdr", +json:"application/json", +php:"application/x-php", +svg:"text/html", +css:"text/css", +java:"text/x-java", +py:"text/x-python", +scala:"scala", +textile:"textile", +tex:"application/x-tex", +bib:"application/x-tex", +rtf:"application/rtf", +rtx:"application/rtf", +sh:"application/x-sh", +sql:"text/x-sql", +as:"text/x-actionscript" +//everything else is hopefully ok to be text/plain. +} + +dn.tooltip_info = { //keys correspond to icon data-info attr, which will be the same as keys in SHORTCUTS_LIST + "save" : "Save file contents. ", + "print": "Open print view in a new tab. ", + "sharing": "View and modify file's sharing status.", + "file history": "Explore the file history. ", + "drive": "Show this file in Google Drive. ", + "about": "Drive Notepad website.", + "shortcuts": "Keyboard shortcuts.", + "new": "Create new file in a new tab. ", + "open": "Launch open dialoag. ", + "settings_file": "Properties of the current file.", + "settings_general": "Your general Drive Notepad preferences.", + "title": "Click to edit the file's title.", + "description": "Click to edit the file's description." +} + +// TODO: use keymaster rather than relying on this +var WHICH = { +ENTER: 13, +ESC: 27, +UP: 38, +DOWN: 40 +}; + +dn.default_settings = { +ext: 'txt', +wordWrap: [true,null,null], +wordWrapAt: 80, +fontSize: 1, +widget_anchor: ['l',50,'t',10], +showGutterHistory: 1, +lastDNVersionUsed: '', +newLineDefault: 'windows', +historyRemovedIsExpanded: true, +softTabN: 4, +tabIsHard: 0, +widgetSub: 'general', +theme: "chrome", +pane: '', +pane_open: true, +find_regex: false, +find_whole_words: false, +find_case_sensitive: false, +help_inner: 'main', +find_goto: false, +find_replace: false +} + +dn.impersonal_settings_keys = [ +"wordWrap", +"wordWrapAt", +"fontSize", +"widget_anchor", +"showGutterHistory", +"historyRemovedIsExpanded", +"tabIsHard", +"softTabN", +"newLineDefault", +"widgetSub", +"theme", +"pane", +"pane_open", +"find_regex", +"find_whole_words", +"find_case_sensitive", +"help_inner", +"find_goto", +"find_replace" +]; + +dn.const_ = { +auth_timeout: dn.const_.auth_timeout, // already provided in app.html +drag_delay_ms: 400, +drag_shift_px: 40, +min_font_size: 0.3, +max_font_size: 5, +max_wrap_at: 200, +min_wrap_at: 20, +wrap_at_increment: 10, +max_soft_tab_n: 10, +min_soft_tab_n: 2, +detect_tabs_spaces_frac: 0.9, +detect_tabs_tabs_frac: 0.9, +detect_tabs_n_spaces_frac: 0.99, +detect_tabs_n_spaces_frac_for_default: 0.6, //check +font_size_increment: 0.15, //check +error_delay_ms: 5000,//5 seconds +find_history_add_delay: 3000, //ms +find_history_max_len: 100, +clipboard_info_delay: 500, //ms +clipboard_max_length: 20, //TODO: decide whether a large clipboard slows page loads and whether we can do anything about it. +find_max_results_half: 3, +find_max_prefix_chars: 10, +find_max_suffix_chars: 60, +ad_initial_wait: 4 * 60 * 1000 //ms +}; + +dn.platform = (function(){ + if(navigator.platform.indexOf("Win") >-1) + return "Windows"; + else if(navigator.platform.indexOf("Linux") >-1) + return "Linux"; + else if(navigator.platform.indexOf("Mac")>-1) + return "Mac"; + return null; +})(); \ No newline at end of file diff --git a/js/keyboard.js b/js/keyboard.js new file mode 100644 index 0000000..262b19d --- /dev/null +++ b/js/keyboard.js @@ -0,0 +1,55 @@ +"use strict"; + + + +dn.esc_pressed = function(e){ + dn.g_settings.set('pane_open', !dn.g_settings.get('pane_open')); + + if(dn.g_settings.get('pane_open') && dn.g_settings.get('pane') == 'pane_find'){ + dn.find_pane.focus_on_input(); + }else{ + dn.focus_editor(); + } + e.preventDefault(); +} + +dn.make_keyboard_shortcuts = function(){ + //perviously was using ace for handling these shorcuts because it neater (and efficient?) but it was + //annoying trying to ensure the editor always had focus, and not clear what to do when the editor wasn't showing. + + //we have to delete the default ace commands linked to the keys we care about + dn.editor.commands.removeCommands([ + "find","findprevious","findnext","replace","jumptomatching","sortlines","selecttomatching","gotoline"]); + + //then add new commands on to the document using keymaster.js... + key('command+s, ctrl+s, ctrl+alt+s, command+alt+s', dn.file_pane.on_save_shorcut); + key('command+p, ctrl+p, ctrl+alt+p, command+alt+p', dn.file_pane.do_print_shorcut); + key('command+o, ctrl+o, ctrl+alt+o, command+alt+o', dn.do_open); + key('command+n, ctrl+n, ctrl+alt+n, command+alt+n', dn.do_new); + key('command+l, ctrl+l, ctrl+alt+l, command+alt+l', dn.find_pane.on_goto_shortcut); + key('command+f, ctrl+f, ctrl+alt+f, command+alt+f', dn.find_pane.on_find_shortcut); + key('command+r, ctrl+r, ctrl+alt+r, command+alt+r' + + ', command+g, ctrl+g, ctrl+alt+g, command+alt+g', dn.find_pane.on_replace_shortcut); + key('command+h, ctrl+h, ctrl+alt+h, command+alt+h', dn.file_pane.do_history); + key('esc', dn.esc_pressed); + key.filter = function(){return 1;} + + // it seems like the clipboard history cycling only works the old way, i.e. using ace.... + var HashHandler = require("ace/keyboard/hash_handler").HashHandler + var extraKeyEvents = new HashHandler([ + {bindKey: {win: "Ctrl-Left",mac: "Command-Left"}, descr: "Clipboard cyle back on paste", exec: dn.clipboard_tool.on_left}, + {bindKey: {win: "Ctrl-Down",mac: "Command-Down"}, descr: "Clipboard cyle back on paste", exec: dn.clipboard_tool.on_left}, + {bindKey: {win: "Ctrl-Right",mac:"Command-Right"}, descr: "Clipboard cyle forward on paste", exec: dn.clipboard_tool.on_right}, + {bindKey: {win: "Ctrl-Up",mac:"Command-Up"}, descr: "Clipboard cyle forward on paste", exec: dn.clipboard_tool.on_right} + ]); + dn.editor.keyBinding.addKeyboardHandler(extraKeyEvents); + + // Change "ctrl" to "cmd" if on Mac + dn.ctrl_key = "crtl" + if(dn.platform == 'Mac'){ + dn.ctrl_key = 'cmd'; + var els = document.getElementsByClassName('ctrl_key'); + for(var ii=0; ii