Implement remember document position
This commit is contained in:
		
							parent
							
								
									693072218e
								
							
						
					
					
						commit
						c99f927205
					
				| @ -598,7 +598,7 @@ dt, dd { | ||||
| } | ||||
| 
 | ||||
| dd { | ||||
| 	margin-left: 40px; | ||||
|     margin-left: 40px; | ||||
| } | ||||
| 
 | ||||
| /* Table style */ | ||||
|  | ||||
| @ -736,6 +736,9 @@ | ||||
| 				<dd> | ||||
| 					<a target="_blank" href="http://jquery.com/">jQuery</a> | ||||
| 				</dd> | ||||
| 				<dd> | ||||
| 					<a target="_blank" href="https://github.com/brandonaaron/jquery-mousewheel">jQuery Mouse Wheel Plugin</a> | ||||
| 				</dd> | ||||
| 				<dd> | ||||
| 					<a target="_blank" href="https://code.google.com/p/pagedown/">PageDown</a> | ||||
| 					/ <a target="_blank" | ||||
|  | ||||
							
								
								
									
										45
									
								
								js/core.js
									
									
									
									
									
								
							
							
						
						
									
										45
									
								
								js/core.js
									
									
									
									
									
								
							| @ -200,15 +200,31 @@ define([ | ||||
| 
 | ||||
|     // Create the PageDown editor
 | ||||
|     var editor = undefined; | ||||
|     var fileDesc = undefined; | ||||
|     var documentContent = undefined; | ||||
|     core.createEditor = function(onTextChange) { | ||||
|     var undoManager = undefined; | ||||
|     core.createEditor = function(fileDescParam) { | ||||
|         fileDesc = fileDescParam; | ||||
|         documentContent = undefined; | ||||
|         $("#wmd-input, .preview-container").scrollTop(0); | ||||
|         var initDocumentContent = fileDesc.content; | ||||
|         $("#wmd-input").val(initDocumentContent); | ||||
|         if(editor !== undefined) { | ||||
|             // Only restart if the editor is already created
 | ||||
|             editor.restart(); | ||||
|             // If the editor is already created
 | ||||
|             undoManager.reinit(initDocumentContent, fileDesc.editorStart, fileDesc.editorEnd, fileDesc.editorScrollTop); | ||||
|             editor.refreshPreview(); | ||||
|             return; | ||||
|         } | ||||
|         // Store scrollTop on scroll event
 | ||||
|         $("#wmd-input").scroll(function() { | ||||
|             if(documentContent !== undefined) { | ||||
|                 fileDesc.editorScrollTop = $(this).scrollTop(); | ||||
|             } | ||||
|         }); | ||||
|         $(".preview-container").scroll(function() { | ||||
|             if(documentContent !== undefined) { | ||||
|                 fileDesc.previewScrollTop = $(this).scrollTop(); | ||||
|             } | ||||
|         }); | ||||
|         var converter = new Markdown.Converter(); | ||||
|         editor = new Markdown.Editor(converter); | ||||
|         // Custom insert link dialog
 | ||||
| @ -229,7 +245,7 @@ define([ | ||||
|         function checkDocumentChanges() { | ||||
|             var newDocumentContent = $("#wmd-input").val(); | ||||
|             if(documentContent !== undefined && documentContent != newDocumentContent) { | ||||
|                 onTextChange(); | ||||
|                 fileDesc.content = newDocumentContent; | ||||
|             } | ||||
|             documentContent = newDocumentContent; | ||||
|         } | ||||
| @ -240,6 +256,8 @@ define([ | ||||
|                 return function() { | ||||
|                     if(documentContent === undefined) { | ||||
|                         makePreview(); | ||||
|                         $("#wmd-input").scrollTop(fileDesc.editorScrollTop); | ||||
|                         $(".preview-container").scrollTop(fileDesc.previewScrollTop); | ||||
|                     } | ||||
|                     else { | ||||
|                         debouncedMakePreview(); | ||||
| @ -251,14 +269,22 @@ define([ | ||||
|         else { | ||||
|             previewWrapper = function(makePreview) { | ||||
|                 return function() { | ||||
|                     checkDocumentChanges(); | ||||
|                     makePreview(); | ||||
|                     if(documentContent === undefined) { | ||||
|                         $(".preview-container").scrollTop(fileDesc.previewScrollTop); | ||||
|                     } | ||||
|                     checkDocumentChanges(); | ||||
|                 }; | ||||
|             }; | ||||
|         } | ||||
|         extensionMgr.onEditorConfigure(editor); | ||||
|         editor.hooks.chain("onPreviewRefresh", extensionMgr.onAsyncPreview); | ||||
|         editor.run(previewWrapper); | ||||
|         undoManager = editor.run(previewWrapper); | ||||
|         undoManager.reinit(initDocumentContent, fileDesc.editorStart, fileDesc.editorEnd, fileDesc.editorScrollTop); | ||||
|         $("#wmd-input").bind("keydown click focus", function(event) { | ||||
|             fileDesc.editorStart = this.selectionStart; | ||||
|             fileDesc.editorEnd = this.selectionEnd; | ||||
|         }); | ||||
| 
 | ||||
|         // Hide default buttons
 | ||||
|         $(".wmd-button-row").addClass("btn-group").find("li:not(.wmd-spacer)").addClass("btn").css("left", 0).find("span").hide(); | ||||
| @ -482,11 +508,6 @@ define([ | ||||
|                 checkOnline(); | ||||
|             } | ||||
|         }, 1000); | ||||
|          | ||||
|         // Focus on the editor at startup
 | ||||
|         _.defer(function() { | ||||
|             $("#wmd-input").focus(); | ||||
|         }); | ||||
|     }); | ||||
| 
 | ||||
|     return core; | ||||
|  | ||||
| @ -7,6 +7,11 @@ define([ | ||||
|     var documentSelector = { | ||||
|         extensionId: "documentSelector", | ||||
|         extensionName: "Document selector", | ||||
|         /* | ||||
|         defaultConfig: { | ||||
|             keyShortcut: 223 | ||||
|         }, | ||||
|         */ | ||||
|         settingsBloc: '<p>Builds the "Open document" dropdown menu.</p>' | ||||
|     }; | ||||
| 
 | ||||
| @ -56,7 +61,8 @@ define([ | ||||
|         $("#file-selector li:not(.stick)").removeClass("disabled"); | ||||
|         var li = liMap[fileDesc.fileIndex]; | ||||
|         if(li === undefined) { | ||||
|             // It means that we are showing a temporary file (not in the selector)
 | ||||
|             // It means that we are showing a temporary file (not in the
 | ||||
|             // selector)
 | ||||
|             return; | ||||
|         } | ||||
|         liMap[fileDesc.fileIndex].addClass("disabled"); | ||||
| @ -104,6 +110,12 @@ define([ | ||||
|         }).click(function(event) { | ||||
|             event.stopPropagation(); | ||||
|         }); | ||||
|         /* | ||||
|         $("#wmd-input").keydown(function(event) { | ||||
|             if(event.ctrlKey && event.keyCode == documentSelector.config.keyShortcut) { | ||||
|                 console.log(event.keyCode); | ||||
|             } | ||||
|         });*/ | ||||
|     }; | ||||
| 
 | ||||
|     return documentSelector; | ||||
|  | ||||
| @ -1,7 +1,8 @@ | ||||
| define([ | ||||
|     "jquery", | ||||
|     "underscore", | ||||
|     "libs/css_browser_selector" | ||||
|     "libs/css_browser_selector", | ||||
|     "libs/jquery.mousewheel" | ||||
| ], function($, _) { | ||||
| 
 | ||||
|     var scrollLink = { | ||||
| @ -95,13 +96,14 @@ define([ | ||||
| 
 | ||||
|         // apply Scroll Link
 | ||||
|         lastEditorScrollTop = -10; | ||||
|         isScrollPreview = false; | ||||
|         lastPreviewScrollTop = -10; | ||||
|         runScrollLink(); | ||||
|     }, 500); | ||||
| 
 | ||||
|     // -10 to be sure the gap is > 9
 | ||||
|     // -10 to be sure the gap is more than 9px
 | ||||
|     var lastEditorScrollTop = -10; | ||||
|     var lastPreviewScrollTop = -10; | ||||
|     var isScrollEditor = false; | ||||
|     var isScrollPreview = false; | ||||
|     var runScrollLink = _.debounce(function() { | ||||
|         if(mdSectionList.length === 0 || mdSectionList.length !== htmlSectionList.length) { | ||||
| @ -120,7 +122,8 @@ define([ | ||||
|             }); | ||||
|             if(srcSection === undefined) { | ||||
|                 // Something wrong in the algorithm...
 | ||||
|                 return -10; | ||||
|                 callback(-10); | ||||
|                 return; | ||||
|             } | ||||
|             var posInSection = (srcScrollTop - srcSection.startOffset) / srcSection.height; | ||||
|             var destSection = destSectionList[sectionIndex]; | ||||
| @ -131,50 +134,58 @@ define([ | ||||
|             ]); | ||||
|             if(Math.abs(destScrollTop - lastDestScrollTop) < 9) { | ||||
|                 // Skip the animation in case it's not necessary
 | ||||
|                 callback(lastDestScrollTop); | ||||
|                 return; | ||||
|             } | ||||
|             destElt.animate({ | ||||
|                 scrollTop: destScrollTop | ||||
|             }, 600, function() { | ||||
|             }, 500, function() { | ||||
|                 callback(destScrollTop); | ||||
|             }); | ||||
|         } | ||||
|         // Perform the animation if diff > 9px
 | ||||
|         if(isScrollPreview === false && Math.abs(editorScrollTop - lastEditorScrollTop) > 9) { | ||||
|         if(isScrollEditor === true && Math.abs(editorScrollTop - lastEditorScrollTop) > 9) { | ||||
|             isScrollEditor = false; | ||||
|             // Animate the preview
 | ||||
|             lastEditorScrollTop = editorScrollTop; | ||||
|             animate(editorScrollTop, mdSectionList, previewElt, htmlSectionList, lastPreviewScrollTop, function(destScrollTop) { | ||||
|                 lastPreviewScrollTop = destScrollTop; | ||||
|             }); | ||||
|         } | ||||
|         else if(Math.abs(previewScrollTop - lastPreviewScrollTop) > 9) { | ||||
|         else if(isScrollPreview === true && Math.abs(previewScrollTop - lastPreviewScrollTop) > 9) { | ||||
|             isScrollPreview = false; | ||||
|             // Animate the editor
 | ||||
|             lastPreviewScrollTop = previewScrollTop; | ||||
|             animate(previewScrollTop, htmlSectionList, editorElt, mdSectionList, lastEditorScrollTop, function(destScrollTop) { | ||||
|                 lastEditorScrollTop = destScrollTop; | ||||
|             }); | ||||
|         } | ||||
|     }, 600); | ||||
|     }, 500); | ||||
| 
 | ||||
|     scrollLink.onLayoutConfigure = function(layoutConfig) { | ||||
|         layoutConfig.onresize = buildSections; | ||||
|         layoutConfig.onresize = function() { | ||||
|             isScrollEditor = true; | ||||
|             buildSections(); | ||||
|         }; | ||||
|     }; | ||||
| 
 | ||||
|     scrollLink.onLayoutCreated = function() { | ||||
|         $(".preview-container").scroll(function() { | ||||
|         $(".preview-container").bind("keydown click focus mousewheel", function() { | ||||
|             isScrollPreview = true; | ||||
|             isScrollEditor = false; | ||||
|             runScrollLink(); | ||||
|         }); | ||||
|         $("#wmd-input").scroll(function() { | ||||
|         $("#wmd-input").bind("keydown click focus mousewheel", function() { | ||||
|             isScrollEditor = true; | ||||
|             isScrollPreview = false; | ||||
|             runScrollLink(); | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     scrollLink.onEditorConfigure = function(editor) { | ||||
|         lastPreviewScrollTop = 0; | ||||
|         editor.getConverter().hooks.chain("postConversion", function(text) { | ||||
|             // To avoid losing scrolling position before elements are fully loaded
 | ||||
|             // To avoid losing scrolling position before elements are fully
 | ||||
|             // loaded
 | ||||
|             $("#wmd-preview").height($("#wmd-preview").height()); | ||||
|             return text; | ||||
|         }); | ||||
| @ -183,11 +194,8 @@ define([ | ||||
|     scrollLink.onPreviewFinished = function() { | ||||
|         // Now set the correct height
 | ||||
|         $("#wmd-preview").height("auto"); | ||||
|         _.defer(function() { | ||||
|             // Modify scroll position of the preview not the editor
 | ||||
|             lastEditorScrollTop = -10; | ||||
|             buildSections(); | ||||
|         }); | ||||
|         isScrollEditor = true; | ||||
|         buildSections(); | ||||
|     }; | ||||
| 
 | ||||
|     return scrollLink; | ||||
|  | ||||
| @ -11,10 +11,16 @@ define([ | ||||
| 
 | ||||
|     var fileMgr = {}; | ||||
| 
 | ||||
|     // Defines a file descriptor in the file system (fileDesc objects)
 | ||||
|     // Defines a file descriptor (fileDesc objects)
 | ||||
|     function FileDescriptor(fileIndex, title, syncLocations, publishLocations) { | ||||
|         this.fileIndex = fileIndex; | ||||
|         this._title = title; | ||||
|         this._editorScrollTop = parseInt(localStorage[fileIndex + ".editorScrollTop"]) || 0; | ||||
|         this._editorStart = parseInt(localStorage[fileIndex + ".editorStart"]) || 0; | ||||
|         this._editorEnd = parseInt(localStorage[fileIndex + ".editorEnd"]) || 0; | ||||
|         this._previewScrollTop = parseInt(localStorage[fileIndex + ".previewScrollTop"]) || 0; | ||||
|         this.syncLocations = syncLocations || {}; | ||||
|         this.publishLocations = publishLocations || {}; | ||||
|         this.__defineGetter__("title", function() { | ||||
|             return this._title; | ||||
|         }); | ||||
| @ -30,12 +36,38 @@ define([ | ||||
|             localStorage[this.fileIndex + ".content"] = content; | ||||
|             extensionMgr.onContentChanged(this); | ||||
|         }); | ||||
|         this.syncLocations = syncLocations || {}; | ||||
|         this.publishLocations = publishLocations || {}; | ||||
|         this.__defineGetter__("editorScrollTop", function() { | ||||
|             return this._editorScrollTop; | ||||
|         }); | ||||
|         this.__defineSetter__("editorScrollTop", function(editorScrollTop) { | ||||
|             this._editorScrollTop = editorScrollTop; | ||||
|             localStorage[this.fileIndex + ".editorScrollTop"] = editorScrollTop; | ||||
|         }); | ||||
|         this.__defineGetter__("editorStart", function() { | ||||
|             return this._editorStart; | ||||
|         }); | ||||
|         this.__defineSetter__("editorStart", function(editorStart) { | ||||
|             this._editorStart = editorStart; | ||||
|             localStorage[this.fileIndex + ".editorStart"] = editorStart; | ||||
|         }); | ||||
|         this.__defineGetter__("editorEnd", function() { | ||||
|             return this._editorEnd; | ||||
|         }); | ||||
|         this.__defineSetter__("editorEnd", function(editorEnd) { | ||||
|             this._editorEnd = editorEnd; | ||||
|             localStorage[this.fileIndex + ".editorEnd"] = editorEnd; | ||||
|         }); | ||||
|         this.__defineGetter__("previewScrollTop", function() { | ||||
|             return this._previewScrollTop; | ||||
|         }); | ||||
|         this.__defineSetter__("previewScrollTop", function(previewScrollTop) { | ||||
|             this._previewScrollTop = previewScrollTop; | ||||
|             localStorage[this.fileIndex + ".previewScrollTop"] = previewScrollTop; | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     // Load file descriptors from localStorage
 | ||||
|     _.chain(localStorage["file.list"].split(";")).compact().each(function(fileIndex) { | ||||
|     // Retrieve file descriptors from localStorage and populate fileSystem
 | ||||
|     _.each(utils.retrieveIndexArray("file.list"), function(fileIndex) { | ||||
|         fileSystem[fileIndex] = new FileDescriptor(fileIndex, localStorage[fileIndex + ".title"]); | ||||
|     }); | ||||
| 
 | ||||
| @ -57,7 +89,6 @@ define([ | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     // Caution: this function recreates the editor (reset undo operations)
 | ||||
|     fileMgr.selectFile = function(fileDesc) { | ||||
|         fileDesc = fileDesc || fileMgr.getCurrentFile(); | ||||
| 
 | ||||
| @ -92,12 +123,8 @@ define([ | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Recreate the editor
 | ||||
|         $("#wmd-input").val(fileDesc.content); | ||||
|         core.createEditor(function() { | ||||
|             // Callback to save content when textarea changes
 | ||||
|             fileMgr.saveFile(); | ||||
|         }); | ||||
|         // Refresh the editor
 | ||||
|         core.createEditor(fileDesc); | ||||
|     }; | ||||
| 
 | ||||
|     fileMgr.createFile = function(title, content, syncLocations, isTemporary) { | ||||
| @ -137,7 +164,7 @@ define([ | ||||
| 
 | ||||
|         // Add the index to the file list
 | ||||
|         if(!isTemporary) { | ||||
|             localStorage["file.list"] += fileIndex + ";"; | ||||
|             utils.appendIndexToArray("file.list", fileIndex); | ||||
|             fileSystem[fileIndex] = fileDesc; | ||||
|             extensionMgr.onFileCreated(fileDesc); | ||||
|         } | ||||
| @ -148,7 +175,7 @@ define([ | ||||
|         fileDesc = fileDesc || fileMgr.getCurrentFile(); | ||||
| 
 | ||||
|         // Remove the index from the file list
 | ||||
|         localStorage["file.list"] = localStorage["file.list"].replace(";" + fileDesc.fileIndex + ";", ";"); | ||||
|         utils.removeIndexFromArray("file.list", fileDesc.fileIndex); | ||||
|         delete fileSystem[fileDesc.fileIndex]; | ||||
|          | ||||
|         if(fileMgr.isCurrentFile(fileDesc) === true) { | ||||
| @ -160,12 +187,12 @@ define([ | ||||
| 
 | ||||
|         // Remove synchronized locations
 | ||||
|         _.each(fileDesc.syncLocations, function(syncAttributes) { | ||||
|             fileMgr.removeSync(syncAttributes, true); | ||||
|             fileMgr.removeSync(syncAttributes); | ||||
|         }); | ||||
| 
 | ||||
|         // Remove publish locations
 | ||||
|         _.each(fileDesc.publishLocations, function(publishAttributes) { | ||||
|             fileMgr.removePublish(publishAttributes, true); | ||||
|             fileMgr.removePublish(publishAttributes); | ||||
|         }); | ||||
| 
 | ||||
|         localStorage.removeItem(fileDesc.fileIndex + ".title"); | ||||
| @ -176,32 +203,24 @@ define([ | ||||
|         extensionMgr.onFileDeleted(fileDesc); | ||||
|     }; | ||||
| 
 | ||||
|     // Save current file in localStorage
 | ||||
|     fileMgr.saveFile = function() { | ||||
|         var fileDesc = fileMgr.getCurrentFile(); | ||||
|         fileDesc.content = $("#wmd-input").val(); | ||||
|     }; | ||||
| 
 | ||||
|     // Add a synchronized location to a file
 | ||||
|     fileMgr.addSync = function(fileDesc, syncAttributes) { | ||||
|         localStorage[fileDesc.fileIndex + ".sync"] += syncAttributes.syncIndex + ";"; | ||||
|         utils.appendIndexToArray(fileDesc.fileIndex + ".sync", syncAttributes.syncIndex); | ||||
|         fileDesc.syncLocations[syncAttributes.syncIndex] = syncAttributes; | ||||
|         // addSync is only used for export, not for import
 | ||||
|         extensionMgr.onSyncExportSuccess(fileDesc, syncAttributes); | ||||
|     }; | ||||
| 
 | ||||
|     // Remove a synchronized location
 | ||||
|     fileMgr.removeSync = function(syncAttributes, skipExtensions) { | ||||
|     fileMgr.removeSync = function(syncAttributes) { | ||||
|         var fileDesc = fileMgr.getFileFromSyncIndex(syncAttributes.syncIndex); | ||||
|         if(fileDesc !== undefined) { | ||||
|             localStorage[fileDesc.fileIndex + ".sync"] = localStorage[fileDesc.fileIndex + ".sync"].replace(";" + syncAttributes.syncIndex + ";", ";"); | ||||
|         } | ||||
|         // Remove sync attributes
 | ||||
|         localStorage.removeItem(syncAttributes.syncIndex); | ||||
|         delete fileDesc.syncLocations[syncAttributes.syncIndex]; | ||||
|         if(!skipExtensions) { | ||||
|             utils.removeIndexFromArray(fileDesc.fileIndex + ".sync", syncAttributes.syncIndex); | ||||
|             delete fileDesc.syncLocations[syncAttributes.syncIndex]; | ||||
|             extensionMgr.onSyncRemoved(fileDesc, syncAttributes); | ||||
|         } | ||||
|         // Remove sync attributes from localStorage
 | ||||
|         localStorage.removeItem(syncAttributes.syncIndex); | ||||
|     }; | ||||
| 
 | ||||
|     // Get the file descriptor associated to a syncIndex
 | ||||
| @ -228,23 +247,21 @@ define([ | ||||
| 
 | ||||
|     // Add a publishIndex (publish location) to a file
 | ||||
|     fileMgr.addPublish = function(fileDesc, publishAttributes) { | ||||
|         localStorage[fileDesc.fileIndex + ".publish"] += publishAttributes.publishIndex + ";"; | ||||
|         utils.appendIndexToArray(fileDesc.fileIndex + ".publish", publishAttributes.publishIndex); | ||||
|         fileDesc.publishLocations[publishAttributes.publishIndex] = publishAttributes; | ||||
|         extensionMgr.onNewPublishSuccess(fileDesc, publishAttributes); | ||||
|     }; | ||||
| 
 | ||||
|     // Remove a publishIndex (publish location)
 | ||||
|     fileMgr.removePublish = function(publishAttributes, skipExtensions) { | ||||
|     fileMgr.removePublish = function(publishAttributes) { | ||||
|         var fileDesc = fileMgr.getFileFromPublishIndex(publishAttributes.publishIndex); | ||||
|         if(fileDesc !== undefined) { | ||||
|             localStorage[fileDesc.fileIndex + ".publish"] = localStorage[fileDesc.fileIndex + ".publish"].replace(";" + publishAttributes.publishIndex + ";", ";"); | ||||
|         } | ||||
|         // Remove publish attributes
 | ||||
|         localStorage.removeItem(publishAttributes.publishIndex); | ||||
|         delete fileDesc.publishLocations[publishAttributes.publishIndex]; | ||||
|         if(!skipExtensions) { | ||||
|             utils.removeIndexFromArray(fileDesc.fileIndex + ".publish", publishAttributes.publishIndex); | ||||
|             delete fileDesc.publishLocations[publishAttributes.publishIndex]; | ||||
|             extensionMgr.onPublishRemoved(fileDesc, publishAttributes); | ||||
|         } | ||||
|         // Remove publish attributes from localStorage
 | ||||
|         localStorage.removeItem(publishAttributes.publishIndex); | ||||
|     }; | ||||
| 
 | ||||
|     // Get the file descriptor associated to a publishIndex
 | ||||
|  | ||||
| @ -362,7 +362,7 @@ define([ | ||||
|                     task.retry(new Error(errorMsg), 1); | ||||
|                     return; | ||||
|                 } | ||||
|                 else if(error.code <= 0) { | ||||
|                 else if(error.code === 0 || error.code === -1) { | ||||
|                     connected = false; | ||||
|                     authenticated = false; | ||||
|                     core.setOffline(); | ||||
|  | ||||
| @ -111,14 +111,13 @@ | ||||
|                                                   * its own image insertion dialog, this hook should return true, and the callback should be called with the chosen | ||||
|                                                   * image url (or null if the user cancelled). If this hook returns false, the default dialog will be used. | ||||
|                                                   */ | ||||
|         hooks.addFalse("insertLinkDialog"); // benweet
 | ||||
|         hooks.addFalse("insertLinkDialog"); | ||||
| 
 | ||||
|         this.getConverter = function () { return markdownConverter; } | ||||
| 
 | ||||
|         var that = this, | ||||
|             panels; | ||||
| 
 | ||||
|         // benweet
 | ||||
|         var undoManager; | ||||
|         this.run = function (previewWrapper) { | ||||
|             if (panels) | ||||
| @ -126,7 +125,7 @@ | ||||
| 
 | ||||
|             panels = new PanelCollection(idPostfix); | ||||
|             var commandManager = new CommandManager(hooks, getString); | ||||
|             var previewManager = new PreviewManager(markdownConverter, panels, function () { hooks.onPreviewRefresh(); }, previewWrapper); // benweet
 | ||||
|             var previewManager = new PreviewManager(markdownConverter, panels, function () { hooks.onPreviewRefresh(); }, previewWrapper); | ||||
|             var uiManager; | ||||
| 
 | ||||
|             if (!/\?noundo/.test(doc.location.href)) { | ||||
| @ -147,13 +146,9 @@ | ||||
| 
 | ||||
|             var forceRefresh = that.refreshPreview = function () { previewManager.refresh(true); }; | ||||
| 
 | ||||
|             forceRefresh(); | ||||
|         }; | ||||
|          | ||||
|         // benweet
 | ||||
|         this.restart = function() { | ||||
|             undoManager.reinit(); | ||||
|             that.refreshPreview(); | ||||
|             //Not necessary
 | ||||
|             //forceRefresh();
 | ||||
|             return undoManager; | ||||
|         }; | ||||
| 
 | ||||
|     } | ||||
| @ -681,18 +676,21 @@ | ||||
|         var init = function () { | ||||
|             setEventHandlers(); | ||||
|             refreshState(true); | ||||
|             saveState(); | ||||
|             //Not necessary
 | ||||
|             //saveState();
 | ||||
|         }; | ||||
|          | ||||
|         // benweet
 | ||||
|         this.reinit = function() { | ||||
|         this.reinit = function(content, start, end, scrollTop) { | ||||
|             undoStack = []; | ||||
|             stackPtr = 0; | ||||
|             mode = "none"; | ||||
|             lastState = undefined; | ||||
|             timer = undefined; | ||||
|             inputStateObj = undefined; | ||||
|             refreshState(); | ||||
|             inputStateObj.text = content; | ||||
|             inputStateObj.start = start; | ||||
|             inputStateObj.end = end; | ||||
|             inputStateObj.scrollTop = scrollTop; | ||||
|             inputStateObj.setInputAreaSelection(); | ||||
|             saveState(); | ||||
|         }; | ||||
| @ -842,7 +840,7 @@ | ||||
|         this.init(); | ||||
|     }; | ||||
| 
 | ||||
|     function PreviewManager(converter, panels, previewRefreshCallback, previewWrapper) { // benweet
 | ||||
|     function PreviewManager(converter, panels, previewRefreshCallback, previewWrapper) { | ||||
| 
 | ||||
|         var managerObj = this; | ||||
|         var timeout; | ||||
| @ -908,7 +906,7 @@ | ||||
| 
 | ||||
|             pushPreviewHtml(text); | ||||
|         }; | ||||
|         if(previewWrapper !== undefined) { // benweet
 | ||||
|         if(previewWrapper !== undefined) { | ||||
|         	makePreviewHtml = previewWrapper(makePreviewHtml); | ||||
|         } | ||||
| 
 | ||||
| @ -1030,7 +1028,8 @@ | ||||
|         var init = function () { | ||||
| 
 | ||||
|             setupEvents(panels.input, applyTimeout); | ||||
|             makePreviewHtml(); | ||||
|             //Not necessary
 | ||||
|             //makePreviewHtml();
 | ||||
| 
 | ||||
|             if (panels.preview) { | ||||
|                 panels.preview.scrollTop = 0; | ||||
| @ -1437,12 +1436,12 @@ | ||||
|                         return false; | ||||
|                     } | ||||
|                 } | ||||
|                 button.className = button.className.replace(/ disabled/g, ""); // benweet
 | ||||
|                 button.className = button.className.replace(/ disabled/g, ""); | ||||
|             } | ||||
|             else { | ||||
|                 image.style.backgroundPosition = button.XShift + " " + disabledYShift; | ||||
|                 button.onmouseover = button.onmouseout = button.onclick = function () { }; | ||||
|                 button.className += " disabled"; // benweet
 | ||||
|                 button.className += " disabled"; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -1807,7 +1806,7 @@ | ||||
|                     ui.prompt(this.getString("imagedialog"), imageDefaultText, linkEnteredCallback); | ||||
|             } | ||||
|             else { | ||||
|                 if (!this.hooks.insertLinkDialog(linkEnteredCallback)) // benweet
 | ||||
|                 if (!this.hooks.insertLinkDialog(linkEnteredCallback)) | ||||
|                 	ui.prompt(this.getString("linkdialog"), linkDefaultText, linkEnteredCallback); | ||||
|             } | ||||
|             return true; | ||||
|  | ||||
| @ -24,7 +24,7 @@ | ||||
|         } | ||||
|       } | ||||
|       return -1; | ||||
|     } | ||||
|     }; | ||||
|   } | ||||
| 
 | ||||
|   function trim(str) { | ||||
| @ -113,21 +113,17 @@ | ||||
| 
 | ||||
|   // Duplicated from PageDown converter
 | ||||
|   function unescapeSpecialChars(text) { | ||||
|     //
 | ||||
|     // Swap back in all the special characters we've hidden.
 | ||||
|     //
 | ||||
|     text = text.replace(/~E(\d+)E/g, | ||||
|         function (wholeMatch, m1) { | ||||
|             var charCodeToReplace = parseInt(m1); | ||||
|             return String.fromCharCode(charCodeToReplace); | ||||
|         } | ||||
|     ); | ||||
|     text = text.replace(/~E(\d+)E/g, function(wholeMatch, m1) { | ||||
| 			var charCodeToReplace = parseInt(m1); | ||||
| 			return String.fromCharCode(charCodeToReplace); | ||||
| 		}); | ||||
|     return text; | ||||
|   } | ||||
| 
 | ||||
|   /****************************************************************** | ||||
|    * Markdown.Extra                                                 * | ||||
|    *****************************************************************/ | ||||
|   /***************************************************************************** | ||||
| 	 * Markdown.Extra * | ||||
| 	 ****************************************************************************/ | ||||
| 
 | ||||
|   Markdown.Extra = function() { | ||||
|     // For converting internal markdown (in tables for instance).
 | ||||
| @ -159,36 +155,47 @@ | ||||
|     var extra = new Markdown.Extra(); | ||||
|     var postNormalizationTransformations = []; | ||||
|     var preBlockGamutTransformations = []; | ||||
|     var postConversionTransformations = ["unHashExtraBlocks"]; | ||||
| 
 | ||||
|     options = options || {}; | ||||
|     options.extensions = options.extensions || ["all"]; | ||||
|     if (contains(options.extensions, "all")) | ||||
|     if (contains(options.extensions, "all")) { | ||||
|     	options.extensions = ["tables", "fenced_code_gfm", "def_list", "attr_list"]; | ||||
|     if (contains(options.extensions, "tables")) | ||||
|         preBlockGamutTransformations.push("tables"); | ||||
|     if (contains(options.extensions, "fenced_code_gfm")) | ||||
|     } | ||||
|     if (contains(options.extensions, "attr_list")) { | ||||
|     	postNormalizationTransformations.push("hashFcbAttributeBlocks"); | ||||
|     	preBlockGamutTransformations.push("hashHeaderAttributeBlocks"); | ||||
|     	postConversionTransformations.push("applyAttributeBlocks"); | ||||
|       extra.attributeBlocks = true; | ||||
|     } | ||||
|     if (contains(options.extensions, "tables")) { | ||||
|     	preBlockGamutTransformations.push("tables"); | ||||
|     } | ||||
|     if (contains(options.extensions, "fenced_code_gfm")) { | ||||
|     	postNormalizationTransformations.push("fencedCodeBlocks"); | ||||
|     if (contains(options.extensions, "def_list")) | ||||
|         preBlockGamutTransformations.push("definitionLists"); | ||||
|     if (contains(options.extensions, "attr_list")) | ||||
|         extra.attributeBlocks = true; | ||||
|      | ||||
|     } | ||||
|     if (contains(options.extensions, "def_list")) { | ||||
|       preBlockGamutTransformations.push("definitionLists"); | ||||
|     } | ||||
|      | ||||
|     converter.hooks.chain("postNormalization", function(text) { | ||||
|         return extra.doTransform(postNormalizationTransformations, text); | ||||
|       return extra.doTransform(postNormalizationTransformations, text) + '\n'; | ||||
|     }); | ||||
| 
 | ||||
|     // preBlockGamut also gives us access to a hook so we can run the
 | ||||
|     // block gamut recursively, however we don't need it at this point
 | ||||
|     converter.hooks.chain("preBlockGamut", function(text, blockGamutHookCallback) { | ||||
|     	// Keep a reference to the block gamut callback to run recursively
 | ||||
|       extra.blockGamutHookCallback = blockGamutHookCallback; | ||||
|       return extra.doConversion(preBlockGamutTransformations, text); | ||||
|       text = processEscapes(text); | ||||
|       return extra.doTransform(preBlockGamutTransformations, text) + '\n'; | ||||
|     }); | ||||
| 
 | ||||
|     // Keep a reference to the hook chain running before finishConversion to apply on hashed extra blocks
 | ||||
|     // Keep a reference to the hook chain running before doPostConversion to apply on hashed extra blocks
 | ||||
|   	extra.previousPostConversion = converter.hooks.postConversion; | ||||
|     converter.hooks.chain("postConversion", function(text) { | ||||
|       return extra.finishConversion(text); | ||||
|       text = extra.doTransform(postConversionTransformations, text); | ||||
|       // Clear state vars that may use unnecessary memory
 | ||||
|       this.hashBlocks = []; | ||||
|       return text; | ||||
|     }); | ||||
| 
 | ||||
|     if ("highlighter" in options) { | ||||
| @ -208,35 +215,9 @@ | ||||
| 
 | ||||
|   // Do transformations
 | ||||
|   Markdown.Extra.prototype.doTransform = function(transformations, text) { | ||||
| 	  if (this.attributeBlocks) | ||||
| 	    text = this.hashFcbAttributeBlocks(text); | ||||
| 
 | ||||
| 	  for(var i = 0; i < transformations.length; i++) | ||||
| 		  text = this[transformations[i]](text); | ||||
| 	   | ||||
| 	  return text + '\n'; | ||||
|   }; | ||||
| 
 | ||||
|   // Setup state vars, do conversion
 | ||||
|   Markdown.Extra.prototype.doConversion = function(transformations, text) { | ||||
|     text = processEscapes(text); | ||||
| 
 | ||||
|     if (this.attributeBlocks) | ||||
|       text = this.hashHeaderAttributeBlocks(text); | ||||
| 
 | ||||
|     return this.doTransform(transformations, text); | ||||
|   }; | ||||
|    | ||||
|   // Clear state vars that may use unnecessary memory. Unhash blocks we
 | ||||
|   // stored, apply attribute blocks if necessary, and return converted text.
 | ||||
|   Markdown.Extra.prototype.finishConversion = function(text) { | ||||
|     text = this.unHashExtraBlocks(text); | ||||
| 
 | ||||
|     if (this.attributeBlocks) | ||||
|       text = this.applyAttributeBlocks(text); | ||||
| 
 | ||||
|     this.hashBlocks = []; | ||||
|     return text; | ||||
| 	  return text; | ||||
|   }; | ||||
| 
 | ||||
|   // Return a placeholder containing a key, which is the block's index in the
 | ||||
| @ -466,6 +447,9 @@ | ||||
|       code = code.replace(/&/g, "&"); | ||||
|       code = code.replace(/</g, "<"); | ||||
|       code = code.replace(/>/g, ">"); | ||||
|       // These were escaped by PageDown before postNormalization 
 | ||||
|       code = code.replace(/~D/g, "$$"); | ||||
|       code = code.replace(/~T/g, "~"); | ||||
|       return code; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										117
									
								
								js/libs/jquery.mousewheel.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								js/libs/jquery.mousewheel.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,117 @@ | ||||
| /*! Copyright (c) 2013 Brandon Aaron (http://brandonaaron.net) | ||||
|  * Licensed under the MIT License (LICENSE.txt). | ||||
|  * | ||||
|  * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 | ||||
|  * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 | ||||
|  * Thanks to: Seamus Leahy for adding deltaX and deltaY | ||||
|  * | ||||
|  * Version: 3.1.3 | ||||
|  * | ||||
|  * Requires: 1.2.2+ | ||||
|  */ | ||||
| 
 | ||||
| (function (factory) { | ||||
|     if ( typeof define === 'function' && define.amd ) { | ||||
|         // AMD. Register as an anonymous module.
 | ||||
|         define(['jquery'], factory); | ||||
|     } else if (typeof exports === 'object') { | ||||
|         // Node/CommonJS style for Browserify
 | ||||
|         module.exports = factory; | ||||
|     } else { | ||||
|         // Browser globals
 | ||||
|         factory(jQuery); | ||||
|     } | ||||
| }(function ($) { | ||||
| 
 | ||||
|     var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll']; | ||||
|     var toBind = 'onwheel' in document || document.documentMode >= 9 ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll']; | ||||
|     var lowestDelta, lowestDeltaXY; | ||||
| 
 | ||||
|     if ( $.event.fixHooks ) { | ||||
|         for ( var i = toFix.length; i; ) { | ||||
|             $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     $.event.special.mousewheel = { | ||||
|         setup: function() { | ||||
|             if ( this.addEventListener ) { | ||||
|                 for ( var i = toBind.length; i; ) { | ||||
|                     this.addEventListener( toBind[--i], handler, false ); | ||||
|                 } | ||||
|             } else { | ||||
|                 this.onmousewheel = handler; | ||||
|             } | ||||
|         }, | ||||
| 
 | ||||
|         teardown: function() { | ||||
|             if ( this.removeEventListener ) { | ||||
|                 for ( var i = toBind.length; i; ) { | ||||
|                     this.removeEventListener( toBind[--i], handler, false ); | ||||
|                 } | ||||
|             } else { | ||||
|                 this.onmousewheel = null; | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     $.fn.extend({ | ||||
|         mousewheel: function(fn) { | ||||
|             return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel"); | ||||
|         }, | ||||
| 
 | ||||
|         unmousewheel: function(fn) { | ||||
|             return this.unbind("mousewheel", fn); | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
| 
 | ||||
|     function handler(event) { | ||||
|         var orgEvent = event || window.event, | ||||
|             args = [].slice.call(arguments, 1), | ||||
|             delta = 0, | ||||
|             deltaX = 0, | ||||
|             deltaY = 0, | ||||
|             absDelta = 0, | ||||
|             absDeltaXY = 0, | ||||
|             fn; | ||||
|         event = $.event.fix(orgEvent); | ||||
|         event.type = "mousewheel"; | ||||
| 
 | ||||
|         // Old school scrollwheel delta
 | ||||
|         if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta; } | ||||
|         if ( orgEvent.detail )     { delta = orgEvent.detail * -1; } | ||||
| 
 | ||||
|         // New school wheel delta (wheel event)
 | ||||
|         if ( orgEvent.deltaY ) { | ||||
|             deltaY = orgEvent.deltaY * -1; | ||||
|             delta  = deltaY; | ||||
|         } | ||||
|         if ( orgEvent.deltaX ) { | ||||
|             deltaX = orgEvent.deltaX; | ||||
|             delta  = deltaX * -1; | ||||
|         } | ||||
| 
 | ||||
|         // Webkit
 | ||||
|         if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY; } | ||||
|         if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = orgEvent.wheelDeltaX * -1; } | ||||
| 
 | ||||
|         // Look for lowest delta to normalize the delta values
 | ||||
|         absDelta = Math.abs(delta); | ||||
|         if ( !lowestDelta || absDelta < lowestDelta ) { lowestDelta = absDelta; } | ||||
|         absDeltaXY = Math.max(Math.abs(deltaY), Math.abs(deltaX)); | ||||
|         if ( !lowestDeltaXY || absDeltaXY < lowestDeltaXY ) { lowestDeltaXY = absDeltaXY; } | ||||
| 
 | ||||
|         // Get a whole value for the deltas
 | ||||
|         fn = delta > 0 ? 'floor' : 'ceil'; | ||||
|         delta  = Math[fn](delta / lowestDelta); | ||||
|         deltaX = Math[fn](deltaX / lowestDeltaXY); | ||||
|         deltaY = Math[fn](deltaY / lowestDeltaXY); | ||||
| 
 | ||||
|         // Add event and delta to the front of the arguments
 | ||||
|         args.unshift(event, delta, deltaX, deltaY); | ||||
| 
 | ||||
|         return ($.event.dispatch || $.event.handle).apply(this, args); | ||||
|     } | ||||
| 
 | ||||
| })); | ||||
| @ -26,6 +26,9 @@ requirejs.config({ | ||||
|         'libs/jquery.waitforimages': [ | ||||
|             'jquery' | ||||
|         ], | ||||
|         'libs/jquery.mousewheel': [ | ||||
|             'jquery' | ||||
|         ], | ||||
|         'libs/layout': [ | ||||
|             'libs/jquery-ui' | ||||
|         ], | ||||
|  | ||||
| @ -244,12 +244,11 @@ define([ | ||||
|     }; | ||||
| 
 | ||||
|     core.onReady(function() { | ||||
|         var state = localStorage[PROVIDER_GDRIVE + ".state"]; | ||||
|         var state = utils.retrieveIgnoreError(PROVIDER_GDRIVE + ".state"); | ||||
|         if(state === undefined) { | ||||
|             return; | ||||
|         } | ||||
|         localStorage.removeItem(PROVIDER_GDRIVE + ".state"); | ||||
|         state = JSON.parse(state); | ||||
|         if(state.action == "create") { | ||||
|             googleHelper.upload(undefined, state.folderId, GDRIVE_DEFAULT_FILE_TITLE, settings.defaultContent, undefined, function(error, file) { | ||||
|                 if(error) { | ||||
|  | ||||
| @ -28,6 +28,7 @@ define([ | ||||
| 
 | ||||
|     var importImageCallback = undefined; | ||||
|     var imageDoc = undefined; | ||||
|     var importImagePreferences = utils.retrieveIgnoreError(PROVIDER_GPLUS + ".importImagePreferences"); | ||||
|     gplusProvider.importImage = function(callback) { | ||||
|         importImageCallback = callback; | ||||
|         googleHelper.picker(function(error, docs) { | ||||
| @ -46,9 +47,7 @@ define([ | ||||
|             utils.setInputValue("#input-import-image-title", imageDoc.name); | ||||
| 
 | ||||
|             // Load preferences
 | ||||
|             var serializedPreferences = localStorage[PROVIDER_GPLUS + ".importImagePreferences"]; | ||||
|             if(serializedPreferences) { | ||||
|                 var importImagePreferences = JSON.parse(serializedPreferences); | ||||
|             if(importImagePreferences) { | ||||
|                 utils.setInputValue("#input-import-image-size", importImagePreferences.size); | ||||
|             } | ||||
| 
 | ||||
| @ -67,7 +66,7 @@ define([ | ||||
|             importImageCallback(undefined, image); | ||||
| 
 | ||||
|             // Store import preferences for next time
 | ||||
|             var importImagePreferences = {}; | ||||
|             importImagePreferences = {}; | ||||
|             if(size) { | ||||
|                 importImagePreferences.size = size; | ||||
|             } | ||||
|  | ||||
| @ -30,13 +30,22 @@ define([ | ||||
| 
 | ||||
|     // Retrieve publish locations from localStorage
 | ||||
|     _.each(fileSystem, function(fileDesc) { | ||||
|         _.chain(localStorage[fileDesc.fileIndex + ".publish"].split(";")).compact().each(function(publishIndex) { | ||||
|             var publishAttributes = JSON.parse(localStorage[publishIndex]); | ||||
|             // Store publishIndex
 | ||||
|             publishAttributes.publishIndex = publishIndex; | ||||
|             // Replace provider ID by provider module in attributes
 | ||||
|             publishAttributes.provider = providerMap[publishAttributes.provider]; | ||||
|             fileDesc.publishLocations[publishIndex] = publishAttributes; | ||||
|         _.each(utils.retrieveIndexArray(fileDesc.fileIndex + ".publish"), function(publishIndex) { | ||||
|             try { | ||||
|                 var publishAttributes = JSON.parse(localStorage[publishIndex]); | ||||
|                 // Store publishIndex
 | ||||
|                 publishAttributes.publishIndex = publishIndex; | ||||
|                 // Replace provider ID by provider module in attributes
 | ||||
|                 publishAttributes.provider = providerMap[publishAttributes.provider]; | ||||
|                 fileDesc.publishLocations[publishIndex] = publishAttributes; | ||||
|             } | ||||
|             catch(e) { | ||||
|                 // localStorage can be corrupted
 | ||||
|                 extensionMgr.onError(e); | ||||
|                 // Remove publish location
 | ||||
|                 utils.removeIndexFromArray(fileDesc.fileIndex + ".publish", publishIndex); | ||||
|                 localStorage.removeItem(publishIndex); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| 
 | ||||
| @ -151,9 +160,8 @@ define([ | ||||
|         $("input:radio[name=radio-publish-format][value=" + defaultPublishFormat + "]").prop("checked", true); | ||||
| 
 | ||||
|         // Load preferences
 | ||||
|         var serializedPreferences = localStorage[provider.providerId + ".publishPreferences"]; | ||||
|         if(serializedPreferences) { | ||||
|             var publishPreferences = JSON.parse(serializedPreferences); | ||||
|         var publishPreferences = utils.retrieveIgnoreError(provider.providerId + ".publishPreferences"); | ||||
|         if(publishPreferences) { | ||||
|             _.each(provider.publishPreferencesInputIds, function(inputId) { | ||||
|                 utils.setInputValue("#input-publish-" + inputId, publishPreferences[inputId]); | ||||
|             }); | ||||
| @ -195,18 +203,6 @@ define([ | ||||
|         localStorage[provider.providerId + ".publishPreferences"] = JSON.stringify(publishPreferences); | ||||
|     } | ||||
| 
 | ||||
|     // Retrieve file's publish locations from localStorage
 | ||||
|     publisher.populatePublishLocations = function(fileDesc) { | ||||
|         _.chain(localStorage[fileDesc.fileIndex + ".publish"].split(";")).compact().each(function(publishIndex) { | ||||
|             var publishAttributes = JSON.parse(localStorage[publishIndex]); | ||||
|             // Store publishIndex
 | ||||
|             publishAttributes.publishIndex = publishIndex; | ||||
|             // Replace provider ID by provider module in attributes
 | ||||
|             publishAttributes.provider = providerMap[publishAttributes.provider]; | ||||
|             fileDesc.publishLocations[publishIndex] = publishAttributes; | ||||
|         }); | ||||
|     }; | ||||
| 
 | ||||
|     core.onReady(function() { | ||||
|         // Add every provider
 | ||||
|         var publishMenu = $("#publish-menu"); | ||||
|  | ||||
| @ -26,9 +26,12 @@ define([ | ||||
|         extensionSettings: {} | ||||
|     }; | ||||
| 
 | ||||
|     if(_.has(localStorage, "settings")) { | ||||
|     try { | ||||
|         _.extend(settings, JSON.parse(localStorage.settings)); | ||||
|     } | ||||
|     catch(e) { | ||||
|         // Ignore parsing error
 | ||||
|     } | ||||
| 
 | ||||
|     return settings; | ||||
| }); | ||||
| @ -1,13 +1,10 @@ | ||||
| // Setup an empty localStorage or upgrade an existing one
 | ||||
| define([ | ||||
|     "underscore" | ||||
| ], function(_) { | ||||
|     "underscore", | ||||
|     "utils" | ||||
| ], function(_, utils) { | ||||
| 
 | ||||
|     // Create the file system if not exist
 | ||||
|     if(localStorage["file.list"] === undefined) { | ||||
|         localStorage["file.list"] = ";"; | ||||
|     } | ||||
|     var fileIndexList = _.compact(localStorage["file.list"].split(";")); | ||||
|     var fileIndexList = utils.retrieveIndexArray("file.list"); | ||||
| 
 | ||||
|     // localStorage versioning
 | ||||
|     var version = localStorage["version"]; | ||||
| @ -22,7 +19,7 @@ define([ | ||||
| 
 | ||||
|         _.each(fileIndexList, function(fileIndex) { | ||||
|             localStorage[fileIndex + ".publish"] = ";"; | ||||
|             var syncIndexList = _.compact(localStorage[fileIndex + ".sync"].split(";")); | ||||
|             var syncIndexList = utils.retrieveIndexArray(fileIndex + ".sync"); | ||||
|             _.each(syncIndexList, function(syncIndex) { | ||||
|                 localStorage[syncIndex + ".contentCRC"] = "0"; | ||||
|                 // We store title CRC only for Google Drive synchronization
 | ||||
| @ -52,7 +49,7 @@ define([ | ||||
|         var SYNC_PROVIDER_GDRIVE = "sync." + PROVIDER_GDRIVE + "."; | ||||
|         var SYNC_PROVIDER_DROPBOX = "sync." + PROVIDER_DROPBOX + "."; | ||||
|         _.each(fileIndexList, function(fileIndex) { | ||||
|             var syncIndexList = _.compact(localStorage[fileIndex + ".sync"].split(";")); | ||||
|             var syncIndexList = utils.retrieveIndexArray(fileIndex + ".sync"); | ||||
|             _.each(syncIndexList, function(syncIndex) { | ||||
|                 var syncAttributes = {}; | ||||
|                 if(syncIndex.indexOf(SYNC_PROVIDER_GDRIVE) === 0) { | ||||
| @ -85,7 +82,7 @@ define([ | ||||
|                 localStorage.removeItem(fileIndex + ".title"); | ||||
|                 localStorage.removeItem(fileIndex + ".publish"); | ||||
|                 localStorage.removeItem(fileIndex + ".content"); | ||||
|                 localStorage["file.list"] = localStorage["file.list"].replace(";" + fileIndex + ";", ";"); | ||||
|                 utils.removeIndexFromArray("file.list", fileIndex); | ||||
|             } | ||||
|         }); | ||||
|         version = "v3"; | ||||
| @ -110,7 +107,7 @@ define([ | ||||
|     // Upgrade from v5 to v6
 | ||||
|     if(version == "v5") { | ||||
|         _.each(fileIndexList, function(fileIndex) { | ||||
|             var publishIndexList = _.compact(localStorage[fileIndex + ".publish"].split(";")); | ||||
|             var publishIndexList = utils.retrieveIndexArray(fileIndex + ".publish"); | ||||
|             _.each(publishIndexList, function(publishIndex) { | ||||
|                 var publishAttributes = JSON.parse(localStorage[publishIndex]); | ||||
|                 if(publishAttributes.provider == "gdrive") { | ||||
|  | ||||
| @ -22,13 +22,22 @@ define([ | ||||
| 
 | ||||
|     // Retrieve sync locations from localStorage
 | ||||
|     _.each(fileSystem, function(fileDesc) { | ||||
|         _.chain(localStorage[fileDesc.fileIndex + ".sync"].split(";")).compact().each(function(syncIndex) { | ||||
|             var syncAttributes = JSON.parse(localStorage[syncIndex]); | ||||
|             // Store syncIndex
 | ||||
|             syncAttributes.syncIndex = syncIndex; | ||||
|             // Replace provider ID by provider module in attributes
 | ||||
|             syncAttributes.provider = providerMap[syncAttributes.provider]; | ||||
|             fileDesc.syncLocations[syncIndex] = syncAttributes; | ||||
|         _.each(utils.retrieveIndexArray(fileDesc.fileIndex + ".sync"), function(syncIndex) { | ||||
|             try { | ||||
|                 var syncAttributes = JSON.parse(localStorage[syncIndex]); | ||||
|                 // Store syncIndex
 | ||||
|                 syncAttributes.syncIndex = syncIndex; | ||||
|                 // Replace provider ID by provider module in attributes
 | ||||
|                 syncAttributes.provider = providerMap[syncAttributes.provider]; | ||||
|                 fileDesc.syncLocations[syncIndex] = syncAttributes; | ||||
|             } | ||||
|             catch(e) { | ||||
|                 // localStorage can be corrupted
 | ||||
|                 extensionMgr.onError(e); | ||||
|                 // Remove sync location
 | ||||
|                 utils.removeIndexFromArray(fileDesc.fileIndex + ".sync", syncIndex); | ||||
|                 localStorage.removeItem(syncIndex); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
| 
 | ||||
| @ -191,9 +200,8 @@ define([ | ||||
|         utils.resetModalInputs(); | ||||
| 
 | ||||
|         // Load preferences
 | ||||
|         var serializedPreferences = localStorage[provider.providerId + ".exportPreferences"]; | ||||
|         if(serializedPreferences) { | ||||
|             var exportPreferences = JSON.parse(serializedPreferences); | ||||
|         var exportPreferences = utils.retrieveIgnoreError(provider.providerId + ".exportPreferences"); | ||||
|         if(exportPreferences) { | ||||
|             _.each(provider.exportPreferencesInputIds, function(inputId) { | ||||
|                 utils.setInputValue("#input-sync-export-" + inputId, exportPreferences[inputId]); | ||||
|             }); | ||||
|  | ||||
							
								
								
									
										33
									
								
								js/utils.js
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								js/utils.js
									
									
									
									
									
								
							| @ -196,7 +196,7 @@ define([ | ||||
|     }; | ||||
|     utils.updateCurrentTime(); | ||||
| 
 | ||||
|     // Serialize sync/publish attributes and store it in the fileStorage
 | ||||
|     // Serialize sync/publish attributes and store it in the localStorage
 | ||||
|     utils.storeAttributes = function(attributes) { | ||||
|         var storeIndex = attributes.syncIndex || attributes.publishIndex; | ||||
|         // Don't store sync/publish index
 | ||||
| @ -206,6 +206,37 @@ define([ | ||||
|         localStorage[storeIndex] = JSON.stringify(attributes); | ||||
|     }; | ||||
|      | ||||
|     // Retrieve/parse an index array from localStorage
 | ||||
|     utils.retrieveIndexArray = function(storeIndex) { | ||||
|         try { | ||||
|             return _.compact(localStorage[storeIndex].split(";")); | ||||
|         } | ||||
|         catch(e) { | ||||
|             localStorage[storeIndex] = ";"; | ||||
|             return []; | ||||
|         } | ||||
|     }; | ||||
|      | ||||
|     // Append an index to an array in localStorage
 | ||||
|     utils.appendIndexToArray = function(storeIndex, index) { | ||||
|         localStorage[storeIndex] += index + ";"; | ||||
|     }; | ||||
|      | ||||
|     // Remove an index from an array in localStorage
 | ||||
|     utils.removeIndexFromArray = function(storeIndex, index) { | ||||
|         localStorage[storeIndex] = localStorage[storeIndex].replace(";" + index + ";", ";"); | ||||
|     }; | ||||
| 
 | ||||
|     // Retrieve/parse an object from localStorage. Returns undefined if error.
 | ||||
|     utils.retrieveIgnoreError = function(storeIndex) { | ||||
|         try { | ||||
|             return JSON.parse(localStorage[storeIndex]); | ||||
|         } | ||||
|         catch(e) { | ||||
|             return undefined; | ||||
|         } | ||||
|     }; | ||||
|      | ||||
|     // Base64 conversion
 | ||||
|     utils.encodeBase64 = function(str) { | ||||
|         if(str.length === 0) { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 benweet
						benweet