mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-06-10 06:39:01 +02:00
Merge branch 'master' into sk-plans-tidy
This commit is contained in:
@@ -143,7 +143,7 @@ module.exports = UserController =
|
||||
type:'success'
|
||||
text:'Your password has been changed'
|
||||
else
|
||||
logger.log user: user, "current password wrong"
|
||||
logger.log user_id: user_id, "current password wrong"
|
||||
res.send
|
||||
message:
|
||||
type:'error'
|
||||
|
||||
@@ -39,7 +39,7 @@ pathList = [
|
||||
["#{jsPath}ide.js"]
|
||||
["#{jsPath}main.js"]
|
||||
["#{jsPath}libs.js"]
|
||||
["#{jsPath}#{ace}/ace.js","#{jsPath}#{ace}/mode-latex.js", "#{jsPath}#{ace}/snippets/latex.js"]
|
||||
["#{jsPath}#{ace}/ace.js","#{jsPath}#{ace}/mode-latex.js","#{jsPath}#{ace}/worker-latex.js","#{jsPath}#{ace}/snippets/latex.js"]
|
||||
["#{jsPath}libs/#{pdfjs}/pdf.js"]
|
||||
["#{jsPath}libs/#{pdfjs}/pdf.worker.js"]
|
||||
["#{jsPath}libs/#{pdfjs}/compatibility.js"]
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
module.exports =
|
||||
user: (user) ->
|
||||
if !user?
|
||||
return null
|
||||
if !user._id?
|
||||
user = {_id : user}
|
||||
return {
|
||||
@@ -10,6 +12,8 @@ module.exports =
|
||||
}
|
||||
|
||||
project: (project) ->
|
||||
if !project?
|
||||
return null
|
||||
if !project._id?
|
||||
project = {_id: project}
|
||||
return {
|
||||
|
||||
@@ -118,6 +118,9 @@ block requirejs
|
||||
"ace/ext-searchbox": {
|
||||
"deps": ["ace/ace"]
|
||||
},
|
||||
"ace/ext-modelist": {
|
||||
"deps": ["ace/ace"]
|
||||
},
|
||||
"ace/ext-language_tools": {
|
||||
"deps": ["ace/ace"]
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ div.full-size(
|
||||
resize-on="layout:main:resize,layout:pdf:resize",
|
||||
annotations="pdf.logEntryAnnotations[editor.open_doc_id]",
|
||||
read-only="!permissions.write",
|
||||
on-ctrl-enter="recompileViaKey"
|
||||
file-name="editor.open_doc_name",
|
||||
on-ctrl-enter="recompileViaKey",
|
||||
syntax-validation="settings.syntaxValidation"
|
||||
)
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ define [], () ->
|
||||
|
||||
@connected = false
|
||||
@userIsInactive = false
|
||||
@gracefullyReconnecting = false
|
||||
|
||||
@$scope.connection =
|
||||
reconnecting: false
|
||||
@@ -54,6 +55,7 @@ define [], () ->
|
||||
@ide.socket.on "connect", () =>
|
||||
sl_console.log "[socket.io connect] Connected"
|
||||
@connected = true
|
||||
@gracefullyReconnecting = false
|
||||
@ide.pushEvent("connected")
|
||||
|
||||
@$scope.$apply () =>
|
||||
@@ -81,7 +83,7 @@ define [], () ->
|
||||
@$scope.$apply () =>
|
||||
@$scope.connection.reconnecting = false
|
||||
|
||||
if !$scope.connection.forced_disconnect and !@userIsInactive
|
||||
if !$scope.connection.forced_disconnect and !@userIsInactive and !@gracefullyReconnecting
|
||||
@startAutoReconnectCountdown()
|
||||
|
||||
@ide.socket.on 'forceDisconnect', (message) =>
|
||||
@@ -97,7 +99,11 @@ define [], () ->
|
||||
setTimeout () ->
|
||||
location.reload()
|
||||
, 10 * 1000
|
||||
|
||||
|
||||
@ide.socket.on "reconnectGracefully", () =>
|
||||
sl_console.log "Reconnect gracefully"
|
||||
@reconnectGracefully()
|
||||
|
||||
joinProject: () ->
|
||||
sl_console.log "[joinProject] joining..."
|
||||
@ide.socket.emit 'joinProject', {
|
||||
@@ -180,3 +186,24 @@ define [], () ->
|
||||
@$scope.$apply () =>
|
||||
@$scope.connection.inactive_disconnect = true
|
||||
|
||||
RECONNECT_GRACEFULLY_RETRY_INTERVAL: 5000 # ms
|
||||
MAX_RECONNECT_GRACEFULLY_INTERVAL: 60 * 5 * 1000 # 5 minutes
|
||||
reconnectGracefully: () ->
|
||||
@reconnectGracefullyStarted ?= new Date()
|
||||
userIsInactive = (new Date() - @lastUserAction) > @RECONNECT_GRACEFULLY_RETRY_INTERVAL
|
||||
maxIntervalReached = (new Date() - @reconnectGracefullyStarted) > @MAX_RECONNECT_GRACEFULLY_INTERVAL
|
||||
if userIsInactive or maxIntervalReached
|
||||
sl_console.log "[reconnectGracefully] User didn't do anything for last 5 seconds, reconnecting"
|
||||
@_reconnectGracefullyNow()
|
||||
else
|
||||
sl_console.log "[reconnectGracefully] User is working, will try again in 5 seconds"
|
||||
setTimeout () =>
|
||||
@reconnectGracefully()
|
||||
, @RECONNECT_GRACEFULLY_RETRY_INTERVAL
|
||||
|
||||
_reconnectGracefullyNow: () ->
|
||||
@gracefullyReconnecting = true
|
||||
@reconnectGracefullyStarted = null
|
||||
# Clear cookie so we don't go to the same backend server
|
||||
$.cookie("SERVERID", "", { expires: -1, path: "/" })
|
||||
@reconnectImmediately()
|
||||
@@ -8,6 +8,7 @@ define [
|
||||
@$scope.editor = {
|
||||
sharejs_doc: null
|
||||
open_doc_id: null
|
||||
open_doc_name: null
|
||||
opening: true
|
||||
}
|
||||
|
||||
@@ -59,6 +60,7 @@ define [
|
||||
return
|
||||
|
||||
@$scope.editor.open_doc_id = doc.id
|
||||
@$scope.editor.open_doc_name = doc.name
|
||||
|
||||
@ide.localStorage "doc.open_id.#{@$scope.project_id}", doc.id
|
||||
@ide.fileTreeManager.selectEntity(doc)
|
||||
|
||||
@@ -2,14 +2,16 @@ define [
|
||||
"base"
|
||||
"ace/ace"
|
||||
"ace/ext-searchbox"
|
||||
"ace/ext-modelist"
|
||||
"ide/editor/directives/aceEditor/undo/UndoManager"
|
||||
"ide/editor/directives/aceEditor/auto-complete/AutoCompleteManager"
|
||||
"ide/editor/directives/aceEditor/spell-check/SpellCheckManager"
|
||||
"ide/editor/directives/aceEditor/highlights/HighlightsManager"
|
||||
"ide/editor/directives/aceEditor/cursor-position/CursorPositionManager"
|
||||
"ide/editor/directives/aceEditor/track-changes/TrackChangesManager"
|
||||
], (App, Ace, SearchBox, UndoManager, AutoCompleteManager, SpellCheckManager, HighlightsManager, CursorPositionManager, TrackChangesManager) ->
|
||||
], (App, Ace, SearchBox, ModeList, UndoManager, AutoCompleteManager, SpellCheckManager, HighlightsManager, CursorPositionManager, TrackChangesManager) ->
|
||||
EditSession = ace.require('ace/edit_session').EditSession
|
||||
ModeList = ace.require('ace/ext/modelist')
|
||||
|
||||
# set the path for ace workers if using a CDN (from editor.jade)
|
||||
if window.aceWorkerPath != ""
|
||||
@@ -42,7 +44,8 @@ define [
|
||||
text: "="
|
||||
readOnly: "="
|
||||
annotations: "="
|
||||
navigateHighlights: "=",
|
||||
navigateHighlights: "="
|
||||
fileName: "="
|
||||
onCtrlEnter: "="
|
||||
syntaxValidation: "="
|
||||
}
|
||||
@@ -204,11 +207,6 @@ define [
|
||||
|
||||
editor.setOption("scrollPastEnd", true)
|
||||
|
||||
resetSession = () ->
|
||||
session = editor.getSession()
|
||||
session.setUseWrapMode(true)
|
||||
session.setMode("ace/mode/latex")
|
||||
|
||||
updateCount = 0
|
||||
onChange = () ->
|
||||
updateCount++
|
||||
@@ -221,9 +219,18 @@ define [
|
||||
session = editor.getSession()
|
||||
if session?
|
||||
session.destroy()
|
||||
editor.setSession(new EditSession(lines, "ace/mode/latex"))
|
||||
resetSession()
|
||||
|
||||
# see if we can lookup a suitable mode from ace
|
||||
# but fall back to text by default
|
||||
try
|
||||
mode = ModeList.getModeForPath(scope.fileName).mode
|
||||
catch
|
||||
mode = "ace/mode/text"
|
||||
|
||||
editor.setSession(new EditSession(lines, mode))
|
||||
|
||||
session = editor.getSession()
|
||||
session.setUseWrapMode(true)
|
||||
|
||||
doc = session.getDocument()
|
||||
doc.on "change", onChange
|
||||
|
||||
@@ -233,8 +233,16 @@ define [
|
||||
start = aceDelta.start
|
||||
if !start?
|
||||
error = new Error("aceDelta had no start event.")
|
||||
JSONstringifyWithCycles = (o) ->
|
||||
seen = []
|
||||
return JSON.stringify o, (k,v) ->
|
||||
if (typeof v == 'object')
|
||||
if ( !seen.indexOf(v) )
|
||||
return '__cycle__'
|
||||
seen.push(v);
|
||||
return v
|
||||
Raven?.captureException(error, {
|
||||
aceDelta: JSON.stringify(aceDelta)
|
||||
aceDelta: JSONstringifyWithCycles(aceDelta)
|
||||
})
|
||||
throw error
|
||||
linesBefore = docLines.slice(0, start.row)
|
||||
|
||||
@@ -17,8 +17,13 @@ define [
|
||||
# When we join the project:
|
||||
# index all references files
|
||||
# and don't broadcast to all clients
|
||||
@inited = false
|
||||
@$scope.$on 'project:joined', (e) =>
|
||||
@indexAllReferences(false)
|
||||
# We only need to grab the references when the editor first loads,
|
||||
# not on every reconnect
|
||||
if !@inited
|
||||
@inited = true
|
||||
@indexAllReferences(false)
|
||||
|
||||
setTimeout(
|
||||
(self) ->
|
||||
|
||||
@@ -30,7 +30,7 @@ define [
|
||||
|
||||
$scope.$watch "settings.syntaxValidation", (syntaxValidation, oldSyntaxValidation) =>
|
||||
if syntaxValidation != oldSyntaxValidation
|
||||
settings.saveProjectSettings({syntaxValidation: syntaxValidation})
|
||||
settings.saveSettings({syntaxValidation: syntaxValidation})
|
||||
|
||||
$scope.$watch "project.spellCheckLanguage", (language, oldLanguage) =>
|
||||
return if @ignoreUpdates
|
||||
|
||||
@@ -205,128 +205,137 @@ var LatexFoldMode = require("./folding/latex").FoldMode;
|
||||
var Range = require("../range").Range;
|
||||
var WorkerClient = require("ace/worker/worker_client").WorkerClient;
|
||||
|
||||
var createLatexWorker = function (session) {
|
||||
var doc = session.getDocument();
|
||||
var selection = session.getSelection();
|
||||
var cursorAnchor = selection.lead;
|
||||
|
||||
var savedRange = {};
|
||||
var suppressions = [];
|
||||
var hints = [];
|
||||
var changeHandler = null;
|
||||
|
||||
var worker = new WorkerClient(["ace"], "ace/mode/latex_worker", "LatexWorker");
|
||||
worker.attachToDocument(doc);
|
||||
|
||||
doc.on("change", function () {
|
||||
if(changeHandler) {
|
||||
clearTimeout(changeHandler);
|
||||
changeHandler = null;
|
||||
}
|
||||
});
|
||||
|
||||
selection.on("changeCursor", function () {
|
||||
changeHandler = setTimeout(function () {
|
||||
updateMarkers({cursorMoveOnly:true});
|
||||
suppressions = [];
|
||||
changeHandler = null;
|
||||
}, 100);
|
||||
});
|
||||
|
||||
var updateMarkers = function (options) {
|
||||
if (!options) { options = {};};
|
||||
var cursorMoveOnly = options.cursorMoveOnly;
|
||||
var annotations = [];
|
||||
var newRange = {};
|
||||
var cursor = selection.getCursor();
|
||||
suppressions = [];
|
||||
|
||||
for (var i = 0, len = hints.length; i<len; i++) {
|
||||
var hint = hints[i];
|
||||
|
||||
var suppressedChanges = 0;
|
||||
var hintRange = new Range(hint.start_row, hint.start_col, hint.end_row, hint.end_col);
|
||||
|
||||
var cursorInRange = hintRange.insideStart(cursor.row, cursor.column);
|
||||
var cursorAtStart = hintRange.isStart(cursor.row, cursor.column);
|
||||
var cursorAtEnd = hintRange.isEnd(cursor.row, cursor.column);
|
||||
if (hint.suppressIfEditing && (cursorAtStart || cursorAtEnd)) {
|
||||
suppressions.push(hintRange);
|
||||
if (!hint.suppressed) { suppressedChanges++; };
|
||||
hint.suppressed = true;
|
||||
continue;
|
||||
}
|
||||
var isCascadeError = false;
|
||||
for (var j = 0, suplen = suppressions.length; j < suplen; j++) {
|
||||
var badRange = suppressions[j];
|
||||
if (badRange.intersects(hintRange)) {
|
||||
isCascadeError = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(isCascadeError) {
|
||||
if (!hint.suppressed) { suppressedChanges++; };
|
||||
hint.suppressed = true;
|
||||
continue;
|
||||
};
|
||||
|
||||
if (hint.suppressed) { suppressedChanges++; };
|
||||
hint.suppressed = false;
|
||||
|
||||
annotations.push(hint);
|
||||
if (hint.type === "info") {
|
||||
continue;
|
||||
};
|
||||
var key = hintRange.toString() + (cursorInRange ? "+cursor" : "");
|
||||
newRange[key] = {hint: hint, cursorInRange: cursorInRange, range: hintRange};
|
||||
}
|
||||
for (key in newRange) {
|
||||
if (!savedRange[key]) { // doesn't exist in already displayed errors
|
||||
var new_range = newRange[key].range;
|
||||
cursorInRange = newRange[key].cursorInRange;
|
||||
hint = newRange[key].hint;
|
||||
var errorAtStart = (hint.row === hint.start_row && hint.column === hint.start_col);
|
||||
var a = (cursorInRange && !errorAtStart) ? cursorAnchor : doc.createAnchor(new_range.start);
|
||||
var b = (cursorInRange && errorAtStart) ? cursorAnchor : doc.createAnchor(new_range.end);
|
||||
var range = new Range();
|
||||
range.start = a;
|
||||
range.end = b;
|
||||
var cssClass = "ace_error-marker";
|
||||
if (hint.type === "warning") { cssClass = "ace_highlight-marker"; };
|
||||
range.id = session.addMarker(range, cssClass, "text");
|
||||
savedRange[key] = range;
|
||||
}
|
||||
}
|
||||
for (key in savedRange) {
|
||||
if (!newRange[key]) { // no longer present in list of errors to display
|
||||
range = savedRange[key];
|
||||
if (range.start !== cursorAnchor) { range.start.detach(); }
|
||||
if (range.end !== cursorAnchor) { range.end.detach(); }
|
||||
session.removeMarker(range.id);
|
||||
delete savedRange[key];
|
||||
}
|
||||
}
|
||||
if (!cursorMoveOnly || suppressedChanges) {
|
||||
session.setAnnotations(annotations);
|
||||
};
|
||||
|
||||
};
|
||||
worker.on("lint", function(results) {
|
||||
hints = results.data;
|
||||
if (hints.length > 100) {
|
||||
hints = hints.slice(0, 100); // limit to 100 errors
|
||||
};
|
||||
updateMarkers();
|
||||
});
|
||||
worker.on("terminate", function() {
|
||||
for (var key in savedRange) {
|
||||
var range = savedRange[key];
|
||||
range.start.detach();
|
||||
range.end.detach();
|
||||
session.removeMarker(range.id);
|
||||
delete savedRange[key];
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return worker;
|
||||
};
|
||||
|
||||
var Mode = function() {
|
||||
this.HighlightRules = LatexHighlightRules;
|
||||
this.foldingRules = new LatexFoldMode();
|
||||
this.createWorker = function(session) {
|
||||
var doc = session.getDocument();
|
||||
var selection = session.getSelection();
|
||||
|
||||
var savedRange = {};
|
||||
var suppressions = [];
|
||||
var hints = [];
|
||||
var changeHandler = null;
|
||||
|
||||
var worker = new WorkerClient(["ace"], "ace/mode/latex_worker", "LatexWorker");
|
||||
worker.attachToDocument(doc);
|
||||
|
||||
doc.on("change", function () {
|
||||
if(changeHandler) {
|
||||
clearTimeout(changeHandler);
|
||||
changeHandler = null;
|
||||
}
|
||||
});
|
||||
|
||||
selection.on("changeCursor", function () {
|
||||
if(suppressions.length > 0) {
|
||||
changeHandler = setTimeout(function () {
|
||||
updateMarkers();
|
||||
suppressions = [];
|
||||
changeHandler = null;
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
|
||||
var updateMarkers = function () {
|
||||
var annotations = [];
|
||||
var newRange = {};
|
||||
var cursor = selection.getCursor();
|
||||
suppressions = [];
|
||||
|
||||
for (var i = 0; i<hints.length; i++) {
|
||||
var data = hints[i];
|
||||
var start_row = data.start_row;
|
||||
var start_col = data.start_col;
|
||||
var end_row = data.end_row;
|
||||
var end_col = data.end_col;
|
||||
if (data.suppressIfEditing &&
|
||||
((cursor.row === start_row && cursor.column == start_col+1)
|
||||
|| (cursor.row === end_row && (cursor.column+1) == end_col))) {
|
||||
suppressions.push([start_row, start_col, end_row, end_col]);
|
||||
continue;
|
||||
}
|
||||
var suppress = false;
|
||||
for (var j = 0; j < suppressions.length; j++) {
|
||||
var e=suppressions[j];
|
||||
var fromRow=e[0], fromCol=e[1], toRow=e[2], toCol=e[3];
|
||||
if (start_row == fromRow && start_col >= fromCol && start_row === toRow && start_col <= toCol) {
|
||||
suppress = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(suppress) { continue; };
|
||||
|
||||
var key = "(" + start_row + "," + start_col + ")" + ":" + "(" + end_row + "," + end_col + ")";
|
||||
newRange[key] = data;
|
||||
annotations.push(data);
|
||||
}
|
||||
|
||||
var newKeys = Object.keys(newRange);
|
||||
var oldKeys = Object.keys(savedRange);
|
||||
var changes = 0;
|
||||
for (i = 0; i < newKeys.length; i++) {
|
||||
key = newKeys[i];
|
||||
if (!savedRange[key]) {
|
||||
var new_range = newRange[key];
|
||||
var a = doc.createAnchor(new_range.start_row, new_range.start_col);
|
||||
var b = doc.createAnchor(new_range.end_row, new_range.end_col);
|
||||
var range = new Range();
|
||||
range.start = a;
|
||||
range.end = b;
|
||||
range.id = session.addMarker(range, "ace_error-marker", "text");
|
||||
savedRange[key] = range;
|
||||
changes++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < oldKeys.length; i++) {
|
||||
key = oldKeys[i];
|
||||
if (!newRange[key]) {
|
||||
range = savedRange[key];
|
||||
range.start.detach();
|
||||
range.end.detach();
|
||||
session.removeMarker(range.id);
|
||||
delete savedRange[key];
|
||||
changes++;
|
||||
}
|
||||
}
|
||||
|
||||
if (changes>0) {
|
||||
session.setAnnotations(annotations);
|
||||
};
|
||||
};
|
||||
|
||||
worker.on("lint", function(results) {
|
||||
hints = results.data;
|
||||
if (hints.length > 100) {
|
||||
hints = hints.slice(0, 100); // limit to 100 errors
|
||||
};
|
||||
updateMarkers();
|
||||
});
|
||||
|
||||
worker.on("terminate", function() {
|
||||
var oldKeys = Object.keys(savedRange);
|
||||
for (var i = 0; i < oldKeys.length; i++) {
|
||||
var key = oldKeys[i];
|
||||
var range = savedRange[key];
|
||||
session.removeMarker(range.id);
|
||||
delete savedRange[key];
|
||||
}
|
||||
|
||||
});
|
||||
return worker;
|
||||
};
|
||||
this.createWorker = createLatexWorker;
|
||||
};
|
||||
oop.inherits(Mode, TextMode);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -200,6 +200,10 @@ ul.structured-list {
|
||||
.select-item + span, .select-all + span {
|
||||
display: inline-block;
|
||||
padding-left: @line-height-computed * 1.5;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user