mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge branch 'master-redesign' into master-redesign-templates-and-blog
This commit is contained in:
commit
5093820a5f
18 changed files with 372 additions and 67 deletions
|
@ -16,9 +16,9 @@ module.exports = AuthenticationController =
|
|||
if !isAllowed
|
||||
logger.log email:email, "too many login requests"
|
||||
res.statusCode = 429
|
||||
return res.send
|
||||
return res.send
|
||||
message:
|
||||
text: 'This account has had too many login requests, <br> please wait 2 minutes before trying to log in again',
|
||||
text: 'This account has had too many login requests. Please wait 2 minutes before trying to log in again',
|
||||
type: 'error'
|
||||
AuthenticationManager.authenticate email: email, password, (error, user) ->
|
||||
return next(error) if error?
|
||||
|
@ -100,7 +100,7 @@ module.exports = AuthenticationController =
|
|||
callback()
|
||||
|
||||
_establishUserSession: (req, user, callback = (error) ->) ->
|
||||
lightUser =
|
||||
lightUser =
|
||||
_id: user._id
|
||||
first_name: user.first_name
|
||||
last_name: user.last_name
|
||||
|
@ -110,7 +110,3 @@ module.exports = AuthenticationController =
|
|||
req.session.user = lightUser
|
||||
req.session.justLoggedIn = true
|
||||
req.session.save callback
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
aside#file-tree(ng-controller="FileTreeController")
|
||||
.toolbar.toolbar-small(ng-if="permissions.write")
|
||||
.toolbar.toolbar-small.toolbar-alt(ng-if="permissions.write")
|
||||
a(
|
||||
href,
|
||||
ng-click="openNewDocModal()",
|
||||
|
@ -40,7 +40,7 @@ aside#file-tree(ng-controller="FileTreeController")
|
|||
i.fa.fa-trash-o
|
||||
|
||||
.file-tree-inner(
|
||||
ng-if="rootFolder",
|
||||
ng-if="rootFolder",
|
||||
ng-controller="FileTreeRootFolderController",
|
||||
ng-class="{ 'no-toolbar': !permissions.write }"
|
||||
)
|
||||
|
@ -284,7 +284,7 @@ script(type='text/ng-template', id='entityListItemTemplate')
|
|||
permissions="permissions",
|
||||
ng-repeat="child in entity.children | orderBy:[orderByFoldersFirst, 'name']"
|
||||
)
|
||||
|
||||
|
||||
script(type='text/ng-template', id='newDocModalTemplate')
|
||||
.modal-header
|
||||
h3 New File
|
||||
|
|
|
@ -80,22 +80,41 @@ div#trackChanges(ng-show="ui.view == 'track-changes'")
|
|||
i.fa.fa-spin.fa-refresh
|
||||
| Loading...
|
||||
|
||||
.diff.full-size(ng-controller="TrackChangesDiffController")
|
||||
.diff-editor.hide-ace-cursor(
|
||||
ace-editor="track-changes",
|
||||
ng-show="!!trackChanges.diff && !trackChanges.diff.loading && !trackChanges.diff.deleted && !trackChanges.diff.error",
|
||||
theme="settings.theme",
|
||||
font-size="settings.fontSize",
|
||||
text="trackChanges.diff.text",
|
||||
highlights="trackChanges.diff.highlights",
|
||||
read-only="true",
|
||||
resize-on="layout:main:resize"
|
||||
.diff-panel.full-size(ng-controller="TrackChangesDiffController")
|
||||
.diff(
|
||||
ng-show="!!trackChanges.diff && !trackChanges.diff.loading && !trackChanges.diff.deleted && !trackChanges.diff.error"
|
||||
)
|
||||
.toolbar.toolbar-alt
|
||||
span.name
|
||||
| <strong>{{trackChanges.diff.highlights.length}} </strong>
|
||||
ng-pluralize(
|
||||
count="trackChanges.diff.highlights.length",
|
||||
when="{\
|
||||
'one': 'change',\
|
||||
'other': 'changes'\
|
||||
}"
|
||||
)
|
||||
| in <strong>{{trackChanges.diff.doc.name}}</strong>
|
||||
.toolbar-right
|
||||
a.btn.btn-danger.btn-sm(
|
||||
href,
|
||||
ng-click="openRestoreDiffModal()"
|
||||
) Restore to before these changes
|
||||
.diff-editor.hide-ace-cursor(
|
||||
ace-editor="track-changes",
|
||||
theme="settings.theme",
|
||||
font-size="settings.fontSize",
|
||||
text="trackChanges.diff.text",
|
||||
highlights="trackChanges.diff.highlights",
|
||||
read-only="true",
|
||||
resize-on="layout:main:resize",
|
||||
navigate-highlights="true"
|
||||
)
|
||||
.diff-deleted.text-centered(
|
||||
ng-show="trackChanges.diff.deleted"
|
||||
)
|
||||
p.text-serif {{ trackChanges.diff.doc.name }} has been deleted.
|
||||
p
|
||||
p
|
||||
a.btn.btn-primary.btn-lg(
|
||||
href,
|
||||
ng-click="restoreDeletedDoc()"
|
||||
|
@ -104,4 +123,26 @@ div#trackChanges(ng-show="ui.view == 'track-changes'")
|
|||
i.fa.fa-spin.fa-refresh
|
||||
| Loading...
|
||||
.error-panel(ng-show="trackChanges.diff.error")
|
||||
.alert.alert-danger Sorry, something went wrong :(
|
||||
.alert.alert-danger Sorry, something went wrong :(
|
||||
|
||||
script(type="text/ng-template", id="trackChangesRestoreDiffModalTemplate")
|
||||
.modal-header
|
||||
button.close(
|
||||
type="button"
|
||||
data-dismiss="modal"
|
||||
ng-click="cancel()"
|
||||
) ×
|
||||
h3 Restore {{diff.doc.name}}
|
||||
.modal-body.modal-body-share
|
||||
p Are you sure you want to restore <strong>{{diff.doc.name}}</strong> to before the changes on {{diff.start_ts | formatDate}}?
|
||||
.modal-footer
|
||||
button.btn.btn-default(
|
||||
ng-click="cancel()",
|
||||
ng-disabled="state.inflight"
|
||||
) Cancel
|
||||
button.btn.btn-danger(
|
||||
ng-click="restore()",
|
||||
ng-disabled="state.inflight"
|
||||
)
|
||||
span(ng-show="!state.inflight") Restore
|
||||
span(ng-show="state.inflight") Restoring...
|
||||
|
|
|
@ -35,7 +35,9 @@ block content
|
|||
| Required
|
||||
.actions
|
||||
button.btn-primary.btn(
|
||||
type='submit'
|
||||
ng-disabled="loginForm.$invalid"
|
||||
) Login
|
||||
type='submit',
|
||||
ng-disabled="loginForm.inflight"
|
||||
)
|
||||
span(ng-show="!loginForm.inflight") Login
|
||||
span(ng-show="loginForm.inflight") Logging in...
|
||||
a.pull-right(href='/user/password/reset') Forgot your password?
|
||||
|
|
|
@ -10,7 +10,7 @@ block content
|
|||
div Join ShareLaTeX to view this project
|
||||
else if newTemplateData.templateName !== undefined
|
||||
h1 Please register to edit the '#{newTemplateData.templateName}' template
|
||||
div Already have a ShareLaTeX account?
|
||||
div Already have a ShareLaTeX account?
|
||||
a(href="/login") Login here
|
||||
|
||||
.row
|
||||
|
@ -18,12 +18,12 @@ block content
|
|||
.card
|
||||
.page-header
|
||||
h1 Register
|
||||
form(async-form="register", name="registerForm", action="/register", novalidate, ng-cloak)
|
||||
form(async-form="register", name="registerForm", action="/register", ng-cloak)
|
||||
input(name='_csrf', type='hidden', value=csrfToken)
|
||||
input(name='redir', type='hidden', value=redir)
|
||||
form-messages(for="registerForm")
|
||||
.form-group
|
||||
label(for='email') Email
|
||||
label(for='email') Email
|
||||
input.form-control(
|
||||
type='email',
|
||||
name='email',
|
||||
|
@ -36,7 +36,7 @@ block content
|
|||
span.small.text-primary(ng-show="registerForm.email.$invalid && registerForm.email.$dirty")
|
||||
| Must be an email address
|
||||
.form-group
|
||||
label(for='password') Password
|
||||
label(for='password') Password
|
||||
input.form-control(
|
||||
type='password',
|
||||
name='password',
|
||||
|
@ -49,6 +49,7 @@ block content
|
|||
.actions
|
||||
button.btn-primary.btn(
|
||||
type='submit'
|
||||
ng-disabled="register.$invalid"
|
||||
) Register
|
||||
|
||||
ng-disabled="registerForm.inflight"
|
||||
)
|
||||
span(ng-show="!registerForm.inflight") Register
|
||||
span(ng-show="registerForm.inflight") Registering...
|
||||
|
|
|
@ -7,6 +7,7 @@ define [
|
|||
formName = attrs.asyncForm
|
||||
|
||||
scope[attrs.name].response = response = {}
|
||||
scope[attrs.name].inflight = false
|
||||
|
||||
element.on "submit", (e) ->
|
||||
e.preventDefault()
|
||||
|
@ -15,9 +16,12 @@ define [
|
|||
for data in element.serializeArray()
|
||||
formData[data.name] = data.value
|
||||
|
||||
scope[attrs.name].inflight = true
|
||||
|
||||
$http
|
||||
.post(element.attr('action'), formData)
|
||||
.success (data, status, headers, config) ->
|
||||
scope[attrs.name].inflight = false
|
||||
response.success = true
|
||||
response.error = false
|
||||
|
||||
|
@ -33,12 +37,13 @@ define [
|
|||
ga('send', 'event', formName, 'failure', data.message)
|
||||
else
|
||||
ga('send', 'event', formName, 'success')
|
||||
|
||||
|
||||
.error (data, status, headers, config) ->
|
||||
scope[attrs.name].inflight = false
|
||||
response.success = false
|
||||
response.error = true
|
||||
response.message =
|
||||
text: data.message or "Something went wrong talking to the server :(. Please try again."
|
||||
text: data.message?.text or "Something went wrong talking to the server :(. Please try again."
|
||||
type: 'error'
|
||||
ga('send', 'event', formName, 'failure', data.message)
|
||||
}
|
||||
|
@ -60,4 +65,4 @@ define [
|
|||
form: "=for"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
define [
|
||||
"base"
|
||||
"ace/ace"
|
||||
"ace/ext-searchbox"
|
||||
"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"
|
||||
], (App, Ace, UndoManager, AutoCompleteManager, SpellCheckManager, HighlightsManager, CursorPositionManager) ->
|
||||
], (App, Ace, SearchBox, UndoManager, AutoCompleteManager, SpellCheckManager, HighlightsManager, CursorPositionManager) ->
|
||||
EditSession = require('ace/edit_session').EditSession
|
||||
|
||||
App.directive "aceEditor", ["$timeout", ($timeout) ->
|
||||
App.directive "aceEditor", ["$timeout", "$compile", "$rootScope", ($timeout, $compile, $rootScope) ->
|
||||
monkeyPatchSearch($rootScope, $compile)
|
||||
|
||||
return {
|
||||
scope: {
|
||||
theme: "="
|
||||
|
@ -24,6 +27,7 @@ define [
|
|||
readOnly: "="
|
||||
gotoLine: "="
|
||||
annotations: "="
|
||||
navigateHighlights: "="
|
||||
}
|
||||
link: (scope, element, attrs) ->
|
||||
# Don't freak out if we're already in an apply callback
|
||||
|
@ -57,6 +61,20 @@ define [
|
|||
editor.commands.removeCommand "showSettingsMenu"
|
||||
editor.commands.removeCommand "foldall"
|
||||
|
||||
# Trigger search AND replace on CMD+F
|
||||
editor.commands.addCommand
|
||||
name: "find",
|
||||
bindKey: win: "Ctrl-F", mac: "Command-F"
|
||||
exec: (editor) ->
|
||||
Ace.require("ace/ext/searchbox").Search(editor, true)
|
||||
readOnly: true
|
||||
editor.commands.removeCommand "replace"
|
||||
|
||||
# Make '/' work for search in vim mode.
|
||||
editor.showCommandLine = (arg) =>
|
||||
if arg == "/"
|
||||
Ace.require("ace/ext/searchbox").Search(editor, true)
|
||||
|
||||
if attrs.resizeOn?
|
||||
for event in attrs.resizeOn.split(",")
|
||||
scope.$on event, () ->
|
||||
|
@ -95,7 +113,7 @@ define [
|
|||
|
||||
scope.$watch "annotations", (annotations) ->
|
||||
if annotations?
|
||||
session = editor.getSession()
|
||||
session = editor.getSession()
|
||||
session.setAnnotations annotations
|
||||
|
||||
scope.$watch "readOnly", (value) ->
|
||||
|
@ -107,11 +125,11 @@ define [
|
|||
session.setMode("ace/mode/latex")
|
||||
session.setAnnotations scope.annotations
|
||||
|
||||
emitChange = () ->
|
||||
emitChange = () ->
|
||||
scope.$emit "#{scope.name}:change"
|
||||
|
||||
attachToAce = (sharejs_doc) ->
|
||||
lines = sharejs_doc.getSnapshot().split("\n")
|
||||
lines = sharejs_doc.getSnapshot().split("\n")
|
||||
editor.setSession(new EditSession(lines))
|
||||
resetSession()
|
||||
session = editor.getSession()
|
||||
|
@ -149,7 +167,7 @@ define [
|
|||
>Dismiss</a>
|
||||
</div>
|
||||
<div class="ace-editor-body"></div>
|
||||
<div
|
||||
<div
|
||||
id="spellCheckMenu"
|
||||
class="dropdown context-menu"
|
||||
ng-show="spellingMenu.open"
|
||||
|
@ -180,7 +198,71 @@ define [
|
|||
>
|
||||
{{ annotationLabel.text }}
|
||||
</div>
|
||||
|
||||
<a
|
||||
href
|
||||
class="highlights-before-label btn btn-info btn-xs"
|
||||
ng-show="updateLabels.highlightsBefore > 0"
|
||||
ng-click="gotoHighlightAbove()"
|
||||
>
|
||||
<i class="fa fa-fw fa-arrow-up"></i>
|
||||
{{ updateLabels.highlightsBefore }} more update{{ updateLabels.highlightsBefore > 1 && "" || "s" }} above
|
||||
</a>
|
||||
|
||||
<a
|
||||
href
|
||||
class="highlights-after-label btn btn-info btn-xs"
|
||||
ng-show="updateLabels.highlightsAfter > 0"
|
||||
ng-click="gotoHighlightBelow()"
|
||||
>
|
||||
<i class="fa fa-fw fa-arrow-down"></i>
|
||||
{{ updateLabels.highlightsAfter }} more update{{ updateLabels.highlightsAfter > 1 && "" || "s" }} below
|
||||
|
||||
</a>
|
||||
</div>
|
||||
"""
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
monkeyPatchSearch = ($rootScope, $compile) ->
|
||||
SearchBox = Ace.require("ace/ext/searchbox").SearchBox
|
||||
searchHtml = """
|
||||
<div class="ace_search right">
|
||||
<a href type="button" action="hide" class="ace_searchbtn_close">
|
||||
<i class="fa fa-fw fa-times"></i>
|
||||
</a>
|
||||
<div class="ace_search_form">
|
||||
<input class="ace_search_field form-control input-sm" placeholder="Search for" spellcheck="false"></input>
|
||||
<div class="btn-group">
|
||||
<button type="button" action="findNext" class="ace_searchbtn next btn btn-default btn-sm">
|
||||
<i class="fa fa-chevron-down fa-fw"></i>
|
||||
</button>
|
||||
<button type="button" action="findPrev" class="ace_searchbtn prev btn btn-default btn-sm">
|
||||
<i class="fa fa-chevron-up fa-fw"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ace_replace_form">
|
||||
<input class="ace_search_field form-control input-sm" placeholder="Replace with" spellcheck="false"></input>
|
||||
<div class="btn-group">
|
||||
<button type="button" action="replaceAndFindNext" class="ace_replacebtn btn btn-default btn-sm">Replace</button>
|
||||
<button type="button" action="replaceAll" class="ace_replacebtn btn btn-default btn-sm">All</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ace_search_options">
|
||||
<div class="btn-group">
|
||||
<span action="toggleRegexpMode" class="btn btn-default btn-sm" tooltip-placement="bottom" tooltip-append-to-body="true" tooltip="RegExp Search">.*</span>
|
||||
<span action="toggleCaseSensitive" class="btn btn-default btn-sm" tooltip-placement="bottom" tooltip-append-to-body="true" tooltip="CaseSensitive Search">Aa</span>
|
||||
<span action="toggleWholeWords" class="btn btn-default btn-sm" tooltip-placement="bottom" tooltip-append-to-body="true" tooltip="Whole Word Search">"..."</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
|
||||
# Remove Ace CSS
|
||||
$("#ace_searchbox").remove()
|
||||
|
||||
$init = SearchBox::$init
|
||||
SearchBox::$init = () ->
|
||||
@element = $compile(searchHtml)($rootScope.$new())[0];
|
||||
$init.apply(@)
|
||||
|
|
|
@ -86,16 +86,17 @@ define [
|
|||
|
||||
Autocomplete::_insertMatch.call this, data
|
||||
|
||||
# Overwrite this to set autoInsert = false
|
||||
# Overwrite this to set autoInsert = false and set font size
|
||||
Autocomplete.startCommand = {
|
||||
name: "startAutocomplete",
|
||||
exec: (editor) ->
|
||||
exec: (editor) =>
|
||||
if (!editor.completer)
|
||||
editor.completer = new Autocomplete()
|
||||
editor.completer.autoInsert = false
|
||||
editor.completer.autoSelect = true
|
||||
editor.completer.showPopup(editor)
|
||||
editor.completer.cancelContextMenu()
|
||||
$(editor.completer.popup.container).css({'font-size': @$scope.fontSize + 'px'})
|
||||
bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,11 @@ define [
|
|||
text: ""
|
||||
}
|
||||
|
||||
@$scope.updateLabels = {
|
||||
updatesAbove: 0
|
||||
updatesBelow: 0
|
||||
}
|
||||
|
||||
@$scope.$watch "highlights", (value) =>
|
||||
@redrawAnnotations()
|
||||
|
||||
|
@ -29,9 +34,30 @@ define [
|
|||
e.position = position
|
||||
@showAnnotationLabels(position)
|
||||
|
||||
@editor.on "changeSession", () =>
|
||||
onChangeScrollTop = () =>
|
||||
@updateShowMoreLabels()
|
||||
|
||||
@editor.getSession().on "changeScrollTop", onChangeScrollTop
|
||||
|
||||
@$scope.$watch "text", () =>
|
||||
if @$scope.navigateHighlights
|
||||
setTimeout () =>
|
||||
@scrollToFirstHighlight()
|
||||
, 0
|
||||
|
||||
@editor.on "changeSession", (e) =>
|
||||
e.oldSession?.off "changeScrollTop", onChangeScrollTop
|
||||
e.session.on "changeScrollTop", onChangeScrollTop
|
||||
@redrawAnnotations()
|
||||
|
||||
@$scope.gotoHighlightBelow = () =>
|
||||
return if !@firstHiddenHighlightAfter?
|
||||
@editor.scrollToLine(@firstHiddenHighlightAfter.end.row, true, false)
|
||||
|
||||
@$scope.gotoHighlightAbove = () =>
|
||||
return if !@lastHiddenHighlightBefore?
|
||||
@editor.scrollToLine(@lastHiddenHighlightBefore.start.row, true, false)
|
||||
|
||||
redrawAnnotations: () ->
|
||||
@_clearMarkers()
|
||||
@_clearLabels()
|
||||
|
@ -71,6 +97,8 @@ define [
|
|||
}
|
||||
@_drawStrikeThrough(annotation, colorScheme)
|
||||
|
||||
@updateShowMoreLabels()
|
||||
|
||||
showAnnotationLabels: (position) ->
|
||||
labelToShow = null
|
||||
for label in @labels or []
|
||||
|
@ -127,6 +155,39 @@ define [
|
|||
text: labelToShow.text
|
||||
}
|
||||
|
||||
updateShowMoreLabels: () ->
|
||||
return if !@$scope.navigateHighlights
|
||||
setTimeout () =>
|
||||
firstRow = @editor.getFirstVisibleRow()
|
||||
lastRow = @editor.getLastVisibleRow()
|
||||
highlightsBefore = 0
|
||||
highlightsAfter = 0
|
||||
@lastHiddenHighlightBefore = null
|
||||
@firstHiddenHighlightAfter = null
|
||||
for annotation in @$scope.highlights or []
|
||||
range = annotation.highlight or annotation.strikeThrough
|
||||
continue if !range?
|
||||
if range.start.row < firstRow
|
||||
highlightsBefore += 1
|
||||
@lastHiddenHighlightBefore = range
|
||||
if range.end.row > lastRow
|
||||
highlightsAfter += 1
|
||||
@firstHiddenHighlightAfter ||= range
|
||||
|
||||
@$scope.$apply =>
|
||||
@$scope.updateLabels = {
|
||||
highlightsBefore: highlightsBefore
|
||||
highlightsAfter: highlightsAfter
|
||||
}
|
||||
, 100
|
||||
|
||||
scrollToFirstHighlight: () ->
|
||||
for annotation in @$scope.highlights or []
|
||||
range = annotation.highlight or annotation.strikeThrough
|
||||
continue if !range?
|
||||
@editor.scrollToLine(range.start.row, true, false)
|
||||
break
|
||||
|
||||
_clearMarkers: () ->
|
||||
for marker_id in @markerIds
|
||||
@editor.getSession().removeMarker(marker_id)
|
||||
|
@ -177,9 +238,9 @@ define [
|
|||
new Range(
|
||||
annotation.strikeThrough.start.row, annotation.strikeThrough.start.column,
|
||||
annotation.strikeThrough.end.row, annotation.strikeThrough.end.column + 1
|
||||
),
|
||||
),
|
||||
"annotation strike-through-foreground",
|
||||
true,
|
||||
true,
|
||||
"""
|
||||
height: #{Math.round(lineHeight/2) + 2}px;
|
||||
border-bottom: 2px solid #{colorScheme.strikeThroughForegroundColor};
|
||||
|
@ -223,4 +284,4 @@ define [
|
|||
r = parseInt(r, 10)
|
||||
g = parseInt(g, 10)
|
||||
b = parseInt(b, 10)
|
||||
return r + g + b < 3 * 128
|
||||
return r + g + b < 3 * 128
|
||||
|
|
|
@ -81,7 +81,7 @@ define [
|
|||
reloadDiff: () ->
|
||||
diff = @$scope.trackChanges.diff
|
||||
{updates, doc} = @$scope.trackChanges.selection
|
||||
{fromV, toV} = @_calculateRangeFromSelection()
|
||||
{fromV, toV, start_ts, end_ts} = @_calculateRangeFromSelection()
|
||||
|
||||
return if !doc?
|
||||
|
||||
|
@ -91,10 +91,12 @@ define [
|
|||
diff.toV == toV
|
||||
|
||||
@$scope.trackChanges.diff = diff = {
|
||||
fromV: fromV
|
||||
toV: toV
|
||||
doc: doc
|
||||
error: false
|
||||
fromV: fromV
|
||||
toV: toV
|
||||
start_ts: start_ts
|
||||
end_ts: end_ts
|
||||
doc: doc
|
||||
error: false
|
||||
}
|
||||
|
||||
if !doc.deleted
|
||||
|
@ -117,10 +119,12 @@ define [
|
|||
diff.deleted = true
|
||||
|
||||
restoreDeletedDoc: (doc) ->
|
||||
@ide.$http.post "/project/#{@$scope.project_id}/doc/#{doc.id}/restore", {
|
||||
name: doc.name
|
||||
_csrf: window.csrfToken
|
||||
}
|
||||
url = "/project/#{@$scope.project_id}/doc/#{doc.id}/restore"
|
||||
@ide.$http.post(url, name: doc.name, _csrf: window.csrfToken)
|
||||
|
||||
restoreDiff: (diff) ->
|
||||
url = "/project/#{@$scope.project_id}/doc/#{diff.doc.id}/version/#{diff.fromV}/restore"
|
||||
@ide.$http.post(url, _csrf: window.csrfToken)
|
||||
|
||||
_parseDiff: (diff) ->
|
||||
row = 0
|
||||
|
|
|
@ -1,9 +1,34 @@
|
|||
define [
|
||||
"base"
|
||||
], (App) ->
|
||||
App.controller "TrackChangesDiffController", ["$scope", "ide", ($scope, ide) ->
|
||||
App.controller "TrackChangesDiffController", ($scope, $modal, ide) ->
|
||||
$scope.restoreDeletedDoc = () ->
|
||||
ide.trackChangesManager.restoreDeletedDoc(
|
||||
$scope.trackChanges.diff.doc
|
||||
)
|
||||
]
|
||||
|
||||
$scope.openRestoreDiffModal = () ->
|
||||
$modal.open {
|
||||
templateUrl: "trackChangesRestoreDiffModalTemplate"
|
||||
controller: "TrackChangesRestoreDiffModalController"
|
||||
resolve:
|
||||
diff: () -> $scope.trackChanges.diff
|
||||
}
|
||||
|
||||
App.controller "TrackChangesRestoreDiffModalController", ($scope, $modalInstance, diff, ide) ->
|
||||
$scope.state =
|
||||
inflight: false
|
||||
|
||||
$scope.diff = diff
|
||||
|
||||
$scope.restore = () ->
|
||||
$scope.state.inflight = true
|
||||
ide.trackChangesManager
|
||||
.restoreDiff(diff)
|
||||
.success () ->
|
||||
$scope.state.inflight = false
|
||||
$modalInstance.close()
|
||||
ide.editorManager.openDoc(diff.doc)
|
||||
|
||||
$scope.cancel = () ->
|
||||
$modalInstance.dismiss()
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
@import "./editor/share.less";
|
||||
@import "./editor/chat.less";
|
||||
@import "./editor/binary-file.less";
|
||||
@import "./editor/search.less";
|
||||
|
||||
.full-size {
|
||||
position: absolute;
|
||||
|
@ -152,6 +153,16 @@
|
|||
position: absolute;
|
||||
z-index: 2;
|
||||
}
|
||||
.highlights-before-label {
|
||||
position: absolute;
|
||||
top: @line-height-computed / 2;
|
||||
right: @line-height-computed;
|
||||
}
|
||||
.highlights-after-label {
|
||||
position: absolute;
|
||||
bottom: @line-height-computed / 2;
|
||||
right: @line-height-computed;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-layout-resizer {
|
||||
|
@ -197,4 +208,3 @@
|
|||
position: fixed;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
|
||||
aside#file-tree {
|
||||
background-color: #fafafa;
|
||||
|
||||
.file-tree-inner {
|
||||
position: absolute;
|
||||
top: 32px;
|
||||
|
@ -93,4 +91,4 @@ aside#file-tree {
|
|||
ul.droppable-hover {
|
||||
background-color: @file-tree-droppable-background-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,10 +127,10 @@
|
|||
}
|
||||
|
||||
.synctex-controls {
|
||||
padding: 68px 2px 0;
|
||||
top: 68px;
|
||||
padding: 0px 2px;
|
||||
.btn-xs {
|
||||
line-height: 1.3;
|
||||
padding: 0 2px 0;
|
||||
}
|
||||
}
|
||||
|
57
services/web/public/stylesheets/app/editor/search.less
Normal file
57
services/web/public/stylesheets/app/editor/search.less
Normal file
|
@ -0,0 +1,57 @@
|
|||
.ace_search {
|
||||
background-color: @gray-lightest;
|
||||
border: 1px solid @toolbar-border-color;
|
||||
border-top: 0 none;
|
||||
width: 350px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
z-index: 99;
|
||||
white-space: normal;
|
||||
padding: @line-height-computed / 4;
|
||||
|
||||
font-family: @font-family-sans-serif;
|
||||
|
||||
a, button {
|
||||
i {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
.ace_searchbtn_close {
|
||||
position: absolute;
|
||||
top: 6px;
|
||||
right: 12px;
|
||||
color: @gray;
|
||||
&:hover {
|
||||
color: @gray-dark;
|
||||
}
|
||||
}
|
||||
|
||||
.ace_search_form, .ace_replace_form {
|
||||
margin-bottom: @line-height-computed / 4;
|
||||
input {
|
||||
width: 210px;
|
||||
display: inline-block;
|
||||
}
|
||||
.btn-group {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.ace_nomatch {
|
||||
input {
|
||||
border-color: @red;
|
||||
}
|
||||
}
|
||||
}
|
||||
.ace_search.left {
|
||||
border-left: 0 none;
|
||||
border-radius: 0px 0px @border-radius-base 0px;
|
||||
left: 0;
|
||||
}
|
||||
.ace_search.right {
|
||||
border-radius: 0px 0px 0px @border-radius-base;
|
||||
border-right: 0 none;
|
||||
right: 0;
|
||||
}
|
|
@ -84,4 +84,8 @@
|
|||
padding: 4px 10px 5px;
|
||||
}
|
||||
}
|
||||
|
||||
&.toolbar-alt {
|
||||
background-color: #fafafa;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,8 +29,25 @@
|
|||
}
|
||||
}
|
||||
|
||||
.diff {
|
||||
.diff-panel {
|
||||
.full-size;
|
||||
margin-right: @changesListWidth;
|
||||
}
|
||||
|
||||
.diff {
|
||||
.full-size;
|
||||
.toolbar {
|
||||
padding: 3px;
|
||||
.name {
|
||||
float: left;
|
||||
padding: 3px @line-height-computed / 4;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
.diff-editor {
|
||||
.full-size;
|
||||
top: 40px;
|
||||
}
|
||||
.hide-ace-cursor {
|
||||
.ace_active-line, .ace_cursor-layer, .ace_gutter-active-line {
|
||||
display: none;
|
||||
|
@ -245,4 +262,4 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -505,6 +505,7 @@
|
|||
&:focus,
|
||||
&:active,
|
||||
&.active,
|
||||
&.checked,
|
||||
.open .dropdown-toggle& {
|
||||
color: @color;
|
||||
background-color: darken(@background, 8%);
|
||||
|
|
Loading…
Reference in a new issue