mirror of
https://github.com/overleaf/overleaf.git
synced 2025-03-15 08:23:08 +00:00
Merge branch 'master' into pr-toggle-comment-keybinding-windows
This commit is contained in:
commit
6a8499f515
17 changed files with 186 additions and 90 deletions
|
@ -3,14 +3,22 @@ request = require("request")
|
||||||
logger = require("logger-sharelatex")
|
logger = require("logger-sharelatex")
|
||||||
|
|
||||||
oneSecond = 1000
|
oneSecond = 1000
|
||||||
|
|
||||||
|
makeRequest = (opts, callback)->
|
||||||
|
if !settings.apis.notifications?.url?
|
||||||
|
return callback()
|
||||||
|
else
|
||||||
|
request(opts, callback)
|
||||||
|
|
||||||
module.exports =
|
module.exports =
|
||||||
|
|
||||||
getUserNotifications: (user_id, callback)->
|
getUserNotifications: (user_id, callback)->
|
||||||
opts =
|
opts =
|
||||||
uri: "#{settings.apis.notifications.url}/user/#{user_id}"
|
uri: "#{settings.apis.notifications?.url}/user/#{user_id}"
|
||||||
json: true
|
json: true
|
||||||
timeout: oneSecond
|
timeout: oneSecond
|
||||||
request.get opts, (err, res, unreadNotifications)->
|
method: "GET"
|
||||||
|
request opts, (err, res, unreadNotifications)->
|
||||||
statusCode = if res? then res.statusCode else 500
|
statusCode = if res? then res.statusCode else 500
|
||||||
if err? or statusCode != 200
|
if err? or statusCode != 200
|
||||||
e = new Error("something went wrong getting notifications, #{err}, #{statusCode}")
|
e = new Error("something went wrong getting notifications, #{err}, #{statusCode}")
|
||||||
|
@ -23,30 +31,33 @@ module.exports =
|
||||||
|
|
||||||
createNotification: (user_id, key, templateKey, messageOpts, callback)->
|
createNotification: (user_id, key, templateKey, messageOpts, callback)->
|
||||||
opts =
|
opts =
|
||||||
uri: "#{settings.apis.notifications.url}/user/#{user_id}"
|
uri: "#{settings.apis.notifications?.url}/user/#{user_id}"
|
||||||
timeout: oneSecond
|
timeout: oneSecond
|
||||||
|
method:"POST"
|
||||||
json: {
|
json: {
|
||||||
key:key
|
key:key
|
||||||
messageOpts:messageOpts
|
messageOpts:messageOpts
|
||||||
templateKey:templateKey
|
templateKey:templateKey
|
||||||
}
|
}
|
||||||
logger.log opts:opts, "creating notification for user"
|
logger.log opts:opts, "creating notification for user"
|
||||||
request.post opts, callback
|
request opts, callback
|
||||||
|
|
||||||
markAsReadWithKey: (user_id, key, callback)->
|
markAsReadWithKey: (user_id, key, callback)->
|
||||||
opts =
|
opts =
|
||||||
uri: "#{settings.apis.notifications.url}/user/#{user_id}"
|
uri: "#{settings.apis.notifications?.url}/user/#{user_id}"
|
||||||
|
method: "DELETE"
|
||||||
timeout: oneSecond
|
timeout: oneSecond
|
||||||
json: {
|
json: {
|
||||||
key:key
|
key:key
|
||||||
}
|
}
|
||||||
logger.log user_id:user_id, key:key, "sending mark notification as read with key to notifications api"
|
logger.log user_id:user_id, key:key, "sending mark notification as read with key to notifications api"
|
||||||
request.del opts, callback
|
request opts, callback
|
||||||
|
|
||||||
|
|
||||||
markAsRead: (user_id, notification_id, callback)->
|
markAsRead: (user_id, notification_id, callback)->
|
||||||
opts =
|
opts =
|
||||||
uri: "#{settings.apis.notifications.url}/user/#{user_id}/notification/#{notification_id}"
|
method: "DELETE"
|
||||||
|
uri: "#{settings.apis.notifications?.url}/user/#{user_id}/notification/#{notification_id}"
|
||||||
timeout:oneSecond
|
timeout:oneSecond
|
||||||
logger.log user_id:user_id, notification_id:notification_id, "sending mark notification as read to notifications api"
|
logger.log user_id:user_id, notification_id:notification_id, "sending mark notification as read to notifications api"
|
||||||
request.del opts, callback
|
request opts, callback
|
||||||
|
|
|
@ -15,7 +15,7 @@ module.exports = ReferencesController =
|
||||||
return res.sendStatus 400
|
return res.sendStatus 400
|
||||||
logger.log {projectId, docIds: docIds}, "index references for project"
|
logger.log {projectId, docIds: docIds}, "index references for project"
|
||||||
ReferencesHandler.index projectId, docIds, (err, data) ->
|
ReferencesHandler.index projectId, docIds, (err, data) ->
|
||||||
if err
|
if err?
|
||||||
logger.err {err, projectId}, "error indexing all references"
|
logger.err {err, projectId}, "error indexing all references"
|
||||||
return res.sendStatus 500
|
return res.sendStatus 500
|
||||||
ReferencesController._handleIndexResponse(req, res, projectId, shouldBroadcast, data)
|
ReferencesController._handleIndexResponse(req, res, projectId, shouldBroadcast, data)
|
||||||
|
@ -25,13 +25,15 @@ module.exports = ReferencesController =
|
||||||
shouldBroadcast = req.body.shouldBroadcast
|
shouldBroadcast = req.body.shouldBroadcast
|
||||||
logger.log {projectId}, "index all references for project"
|
logger.log {projectId}, "index all references for project"
|
||||||
ReferencesHandler.indexAll projectId, (err, data) ->
|
ReferencesHandler.indexAll projectId, (err, data) ->
|
||||||
if err
|
if err?
|
||||||
logger.err {err, projectId}, "error indexing all references"
|
logger.err {err, projectId}, "error indexing all references"
|
||||||
return res.sendStatus 500
|
return res.sendStatus 500
|
||||||
ReferencesController._handleIndexResponse(req, res, projectId, shouldBroadcast, data)
|
ReferencesController._handleIndexResponse(req, res, projectId, shouldBroadcast, data)
|
||||||
|
|
||||||
_handleIndexResponse: (req, res, projectId, shouldBroadcast, data) ->
|
_handleIndexResponse: (req, res, projectId, shouldBroadcast, data) ->
|
||||||
if shouldBroadcast
|
if !data? or !data.keys?
|
||||||
|
return res.send()
|
||||||
|
else if shouldBroadcast
|
||||||
logger.log {projectId}, "emitting new references keys to connected clients"
|
logger.log {projectId}, "emitting new references keys to connected clients"
|
||||||
EditorRealTimeController.emitToRoom projectId, 'references:keys:updated', data.keys
|
EditorRealTimeController.emitToRoom projectId, 'references:keys:updated', data.keys
|
||||||
return res.json data
|
return res.json data
|
||||||
|
|
|
@ -66,6 +66,8 @@ module.exports = ReferencesHandler =
|
||||||
ReferencesHandler._doIndexOperation(projectId, project, docIds, [], callback)
|
ReferencesHandler._doIndexOperation(projectId, project, docIds, [], callback)
|
||||||
|
|
||||||
_doIndexOperation: (projectId, project, docIds, fileIds, callback) ->
|
_doIndexOperation: (projectId, project, docIds, fileIds, callback) ->
|
||||||
|
if !settings.apis?.references?.url?
|
||||||
|
return callback()
|
||||||
ReferencesHandler._isFullIndex project, (err, isFullIndex) ->
|
ReferencesHandler._isFullIndex project, (err, isFullIndex) ->
|
||||||
if err
|
if err
|
||||||
logger.err {err, projectId}, "error checking whether to do full index"
|
logger.err {err, projectId}, "error checking whether to do full index"
|
||||||
|
|
|
@ -39,6 +39,13 @@ module.exports = WikiController =
|
||||||
if pageData.content?.length > 280
|
if pageData.content?.length > 280
|
||||||
if _.include(other_lngs, req.lng)
|
if _.include(other_lngs, req.lng)
|
||||||
pageData.title = pageData.title.slice(0, pageData.title.length - (req.lng.length+1) )
|
pageData.title = pageData.title.slice(0, pageData.title.length - (req.lng.length+1) )
|
||||||
|
|
||||||
|
if pageData.title?.toLowerCase()?.indexOf("kb") == 0
|
||||||
|
pageData.title = pageData.title.slice(3)
|
||||||
|
|
||||||
|
if pageData.title?.toLowerCase()?.indexOf("errors") == 0
|
||||||
|
pageData.title = pageData.title.slice(7)
|
||||||
|
|
||||||
WikiController._renderPage(pageData, contents, res)
|
WikiController._renderPage(pageData, contents, res)
|
||||||
else
|
else
|
||||||
WikiController._getPageContent page, (error, pageData) ->
|
WikiController._getPageContent page, (error, pageData) ->
|
||||||
|
|
|
@ -106,7 +106,10 @@ div.full-size.pdf(ng-controller="PdfController")
|
||||||
span(ng-show="entry.file") {{ entry.file }}
|
span(ng-show="entry.file") {{ entry.file }}
|
||||||
span(ng-show="entry.line") , line {{ entry.line }}
|
span(ng-show="entry.line") , line {{ entry.line }}
|
||||||
p.entry-message(ng-show="entry.message") {{ entry.message }}
|
p.entry-message(ng-show="entry.message") {{ entry.message }}
|
||||||
.card.card-hint(ng-if="entry.humanReadableHint")
|
.card.card-hint(
|
||||||
|
ng-if="entry.humanReadableHint"
|
||||||
|
stop-propagation="click"
|
||||||
|
)
|
||||||
figure.card-hint-icon-container
|
figure.card-hint-icon-container
|
||||||
i.fa.fa-lightbulb-o(aria-hidden="true")
|
i.fa.fa-lightbulb-o(aria-hidden="true")
|
||||||
p.card-hint-text(ng-show="entry.humanReadableHint", ng-bind-html="entry.humanReadableHint")
|
p.card-hint-text(ng-show="entry.humanReadableHint", ng-bind-html="entry.humanReadableHint")
|
||||||
|
@ -122,14 +125,16 @@ div.full-size.pdf(ng-controller="PdfController")
|
||||||
label.card-hint-feedback-label #{translate("log_hint_feedback_label")}
|
label.card-hint-feedback-label #{translate("log_hint_feedback_label")}
|
||||||
a.card-hint-feedback-positive(
|
a.card-hint-feedback-positive(
|
||||||
ng-click="feedbackSent = true;"
|
ng-click="feedbackSent = true;"
|
||||||
|
href
|
||||||
) #{translate("answer_yes")}
|
) #{translate("answer_yes")}
|
||||||
span /
|
span /
|
||||||
a.card-hint-feedback-negative(
|
a.card-hint-feedback-negative(
|
||||||
ng-click="feedbackSent = true;"
|
ng-click="feedbackSent = true;"
|
||||||
|
href
|
||||||
) #{translate("answer_no")}
|
) #{translate("answer_no")}
|
||||||
.card-hint-feedback(ng-show="feedbackSent")
|
.card-hint-feedback(ng-show="feedbackSent")
|
||||||
label.card-hint-feedback-label #{translate("log_hint_feedback_gratitude")}
|
label.card-hint-feedback-label #{translate("log_hint_feedback_gratitude")}
|
||||||
p.entry-content(ng-show="entry.content") {{ entry.content }}
|
p.entry-content(ng-show="entry.content") {{ entry.content.trim() }}
|
||||||
|
|
||||||
p
|
p
|
||||||
.pull-right
|
.pull-right
|
||||||
|
|
|
@ -94,18 +94,7 @@
|
||||||
- if (showUserDetailsArea)
|
- if (showUserDetailsArea)
|
||||||
span(ng-controller="LeftHandMenuPromoController", ng-cloak)
|
span(ng-controller="LeftHandMenuPromoController", ng-cloak)
|
||||||
|
|
||||||
.row-spaced(ng-if="showDatajoy")
|
.row-spaced#userProfileInformation(ng-if="hasProjects")
|
||||||
hr
|
|
||||||
.card.card-thin
|
|
||||||
p.text-center.small
|
|
||||||
| <strong>Python</strong> or <strong>R</strong> user?
|
|
||||||
p.text-center.small
|
|
||||||
a(href="https://www.getdatajoy.com/", target="_blank").btn.btn-info.btn-small Try DataJoy
|
|
||||||
p.text-center.small(style="font-size: 0.8em")
|
|
||||||
a(href="https://www.getdatajoy.com/", target="_blank") DataJoy
|
|
||||||
| is a new online Python and R editor from ShareLaTeX.
|
|
||||||
|
|
||||||
.row-spaced#userProfileInformation(ng-if="hasProjects && !showDatajoy")
|
|
||||||
div(ng-controller="UserProfileController")
|
div(ng-controller="UserProfileController")
|
||||||
hr(ng-show="percentComplete < 100")
|
hr(ng-show="percentComplete < 100")
|
||||||
.text-centered.user-profile(ng-show="percentComplete < 100")
|
.text-centered.user-profile(ng-show="percentComplete < 100")
|
||||||
|
|
|
@ -104,10 +104,10 @@ module.exports = settings =
|
||||||
url: "http://localhost:3036"
|
url: "http://localhost:3036"
|
||||||
sixpack:
|
sixpack:
|
||||||
url: ""
|
url: ""
|
||||||
references:
|
# references:
|
||||||
url: "http://localhost:3040"
|
# url: "http://localhost:3040"
|
||||||
notifications:
|
# notifications:
|
||||||
url: "http://localhost:3042"
|
# url: "http://localhost:3042"
|
||||||
|
|
||||||
templates:
|
templates:
|
||||||
user_id: process.env.TEMPLATES_USER_ID or "5395eb7aad1f29a88756c7f2"
|
user_id: process.env.TEMPLATES_USER_ID or "5395eb7aad1f29a88756c7f2"
|
||||||
|
|
|
@ -2,7 +2,7 @@ define [
|
||||||
"base"
|
"base"
|
||||||
"libs/moment-2.9.0"
|
"libs/moment-2.9.0"
|
||||||
], (App, moment) ->
|
], (App, moment) ->
|
||||||
moment.updateLocale "en", calendar:
|
moment.locale "en", calendar:
|
||||||
lastDay : '[Yesterday]'
|
lastDay : '[Yesterday]'
|
||||||
sameDay : '[Today]'
|
sameDay : '[Today]'
|
||||||
nextDay : '[Tomorrow]'
|
nextDay : '[Tomorrow]'
|
||||||
|
|
|
@ -1,43 +1,91 @@
|
||||||
define -> [
|
define -> [
|
||||||
# regexToMatch: /Too many }'s/
|
regexToMatch: /Misplaced alignment tab character \&/
|
||||||
# extraInfoURL: ""
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:Misplaced_alignment_tab_character_%26"
|
||||||
# humanReadableHint: """
|
humanReadableHint: """
|
||||||
# The reason LaTeX thinks there are too many }'s here is that the opening curly brace is missing after the <tt>\\date</tt> control sequence and before the word December, so the closing curly brace is seen as one too many (which it is!).
|
You have placed an alignment tab character '&' in the wrong place. If you want to align something, you must write it inside an align environment such as \\begin{align} \u2026 \\end{align}, \\begin{tabular} \u2026 \\end{tabular}, etc. If you want to write an ampersand '&' in text, you must write \\& instead.
|
||||||
# """
|
"""
|
||||||
# ,
|
,
|
||||||
# regexToMatch: /Undefined control sequence/
|
regexToMatch: /Extra alignment tab has been changed to \\cr/
|
||||||
# extraInfoURL: "/learn/Errors:Undefined_control_sequence."
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:Extra_alignment_tab_has_been_changed_to_%5Ccr"
|
||||||
# humanReadableHint: """
|
humanReadableHint: """
|
||||||
# In this example, LaTeX is complaining that it has no such command ("control sequence") as <tt>\\dtae</tt>. Obviously it's been mistyped, but only a human can detect that fact: all LaTeX knows is that <tt>\\dtae</tt> is not a command it knows about: it's undefined.
|
You have written too many alignment tabs in a table, causing one of them to be turned into a line break. Make sure you have specified the correct number of columns in your <a target=\"_blank\" href=\"https://www.sharelatex.com/learn/Tables\">table</a>.
|
||||||
# """
|
"""
|
||||||
# ,
|
,
|
||||||
# regexToMatch: /Missing \$ inserted/
|
regexToMatch: /Display math should end with \$\$/
|
||||||
# extraInfoURL: "/learn/Errors:Missing_$_inserted"
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:Display_math_should_end_with_$$."
|
||||||
# humanReadableHint: """
|
humanReadableHint: """
|
||||||
# A character that can only be used in the mathematics was inserted in normal text. If you intended to use mathematics mode, then use <tt>$...$</tt> or <tt>\\begin{math}...\\end{math}</tt> or use the 'quick math mode': <tt>\\ensuremath{...}</tt>.
|
You have forgotten a $ sign at the end of 'display math' mode. When writing in display math mode, you must always math write inside $$ \u2026 $$. Check that the number of $s match around each math expression.
|
||||||
# """
|
"""
|
||||||
# ,
|
,
|
||||||
# regexToMatch: /Runaway argument/
|
regexToMatch: /Missing [{$] inserted./
|
||||||
# extraInfoURL: "/learn/Errors:Undefined_control_sequence."
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:Missing_$_inserted"
|
||||||
# humanReadableHint: """
|
humanReadableHint: """
|
||||||
# In this error, the closing curly brace has been omitted from the date. It's the opposite of the error of too many }'s, and it results in <tt>\\maketitle</tt> trying to format the title page while LaTeX is still expecting more text for the date!
|
Check that your $'s match around math expressions. If they do, then you've probably used a symbol in normal text that needs to be in math mode. Symbols such as subscripts ( _ ), integrals ( \\int ), Greek letters ( \\alpha, \\beta, \\delta ), and modifiers (\\vec{x}, \\tilde{x} ) must be written in math mode. See the full list <a target=\"_blank\" href=\"https://www.sharelatex.com/learn/Errors:Missing_$_inserted\">here</a>.
|
||||||
# """
|
"""
|
||||||
# ,
|
,
|
||||||
# regexToMatch: /Underfull \\hbox/
|
regexToMatch: /(undefined )?[rR]eference(s)?.+(undefined)?/
|
||||||
# extraInfoURL: "/learn/Errors:Underfull_%5Chbox"
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:There_were_undefined_references."
|
||||||
# humanReadableHint: """
|
humanReadableHint: """
|
||||||
# This is a warning that LaTeX cannot stretch the line wide enough to fit, without making the spacing bigger than its currently permitted maximum. The badness (0-10,000) indicates how severe this is (here you can probably ignore a badness of 1394).
|
You have referenced something which has not yet been labelled. If you have labelled it already, make sure that what is written inside \\ref{...} is the same as what is written inside \\label{...}.
|
||||||
# """
|
"""
|
||||||
# ,
|
,
|
||||||
# regexToMatch: /Overfull \\hbox/
|
regexToMatch: /Citation .+ on page .+ undefined on input line .+/
|
||||||
# extraInfoURL: ""
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:Citation_XXX_on_page_XXX_undefined_on_input_line_XXX."
|
||||||
# humanReadableHint: """
|
humanReadableHint: """
|
||||||
# An overfull \\hbox means that there is a hyphenation or justification problem: moving the last word on the line to the next line would make the spaces in the line wider than the current limit; keeping the word on the line would make the spaces smaller than the current limit, so the word is left on the line, but with the minimum allowed space between words, and which makes the line go over the edge.
|
You have cited something which is not included in your bibliography. Make sure that the citation (\\cite{...}) has a corresponding key in your bibliography, and that both are spelled the same way.
|
||||||
# """
|
"""
|
||||||
# ,
|
,
|
||||||
# regexToMatch: /LaTeX Error: File .* not found/
|
regexToMatch: /(Label .+)? multiply[ -]defined( labels)?/
|
||||||
# extraInfoURL: "/learn/Errors:missing_package"
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:There_were_multiply-defined_labels."
|
||||||
# humanReadableHint: """
|
humanReadableHint: """
|
||||||
# When you use the <tt>\\usepackage</tt> command to request LaTeX to use a certain package, it will look for a file with the specified name and the filetype <tt>.sty</tt>. In this case the user has mistyped the name of the paralist package, so it's easy to fix.
|
You have used the same label more than once. Check that each \\label{...} labels only one item.
|
||||||
# """
|
"""
|
||||||
|
,
|
||||||
|
regexToMatch: /`!?h' float specifier changed to `!?ht'/
|
||||||
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:%60!h%27_float_specifier_changed_to_%60!ht%27."
|
||||||
|
humanReadableHint: """
|
||||||
|
The float specifier 'h' is too strict of a demand for LaTeX to place your float in a nice way here. Try relaxing it by using 'ht', or even 'htbp' if necessary. If you want to try keep the float here anyway, check out the <a target=\"_blank\" href=\"https://www.sharelatex.com/learn/Positioning_of_Figures\">float package</a>.
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
regexToMatch: /No positions in optional float specifier/
|
||||||
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:No_positions_in_optional_float_specifier."
|
||||||
|
humanReadableHint: """
|
||||||
|
You have forgotten to include a float specifier, which tells LaTeX where to position your figure. Find out more about float specifiers <a target=\"_blank\" href=\"https://www.sharelatex.com/learn/Positioning_of_Figures\">here</a>.
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
regexToMatch: /Undefined control sequence/
|
||||||
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:Undefined_control_sequence."
|
||||||
|
humanReadableHint: """
|
||||||
|
The compiler is having trouble understanding a command you have used. Check that the command is spelled correctly. If the command is part of a package, make sure you have included the package in your preamble using \\usepackage{...}.
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
regexToMatch: /File .+ not found/
|
||||||
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:File_XXX_not_found_on_input_line_XXX."
|
||||||
|
humanReadableHint: """
|
||||||
|
The compiler cannot find the file you want to include. Make sure that you have <a target=\"_blank\" href=\"https://www.sharelatex.com/learn/Including_images_in_ShareLaTeX\">uploaded the file</a> and <a target=\"_blank\" href=\"https://www.sharelatex.com/learn/Errors:File_XXX_not_found_on_input_line_XXX.\">specified the file location correctly</a>.
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
regexToMatch: /LaTeX Error: Unknown graphics extension: \..+/
|
||||||
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:LaTeX_Error:_Unknown_graphics_extension:_.gif."
|
||||||
|
humanReadableHint: """
|
||||||
|
The compiler does not recognise the file type of one of your images. Make sure you are using a <a target=\"_blank\" href=\"https://www.sharelatex.com/learn/Errors:LaTeX_Error:_Unknown_graphics_extension:_.gif.\">supported image format</a> for your choice of compiler, and check that there are no periods (.) in the name of your image.
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
regexToMatch: /LaTeX Error: Unknown float option `H'/
|
||||||
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:LaTeX_Error:_Unknown_float_option_%60H%27."
|
||||||
|
humanReadableHint: """
|
||||||
|
The compiler isn't recognizing the float option 'H'. Include \\usepackage{float} in your preamble to fix this.
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
regexToMatch: /LaTeX Error: Unknown float option `.+'/
|
||||||
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:LaTeX_Error:_Unknown_float_option_%60H%27."
|
||||||
|
humanReadableHint: """
|
||||||
|
You have used a float specifier which the compiler does not understand. You can learn more about the different float options available for placing figures <a target=\"_blank\" href=\"https://www.sharelatex.com/learn/Positioning_of_Figures\">here</a>.
|
||||||
|
"""
|
||||||
|
,
|
||||||
|
regexToMatch: /LaTeX Error: \\math.+ allowed only in math mode/
|
||||||
|
extraInfoURL: "https://www.sharelatex.com/learn/Errors:LaTeX_Error:_%5Cmathrm_allowed_only_in_math_mode."
|
||||||
|
humanReadableHint: """
|
||||||
|
You have used a font command which is only available in math mode. To use this command, you must be in maths mode (E.g. $ \u2026 $ or \\begin{math} \u2026 \\end{math}). If you want to use it outside of math mode, use the text version instead: \\textrm, \\textit, etc.
|
||||||
|
"""
|
||||||
]
|
]
|
||||||
|
|
|
@ -156,7 +156,7 @@ define [
|
||||||
method:"GET"
|
method:"GET"
|
||||||
params:
|
params:
|
||||||
clsiserverid:ide.clsiServerId
|
clsiserverid:ide.clsiServerId
|
||||||
if file.url? # FIXME clean this up when we have file.urls out consistently
|
if file?.url? # FIXME clean this up when we have file.urls out consistently
|
||||||
opts.url = file.url
|
opts.url = file.url
|
||||||
else if file?.build?
|
else if file?.build?
|
||||||
opts.url = "/project/#{$scope.project_id}/build/#{file.build}/output/#{name}"
|
opts.url = "/project/#{$scope.project_id}/build/#{file.build}/output/#{name}"
|
||||||
|
|
|
@ -4,12 +4,14 @@ define [
|
||||||
App.controller 'WordCountModalController', ($scope, $modalInstance, ide, $http) ->
|
App.controller 'WordCountModalController', ($scope, $modalInstance, ide, $http) ->
|
||||||
$scope.status =
|
$scope.status =
|
||||||
loading:true
|
loading:true
|
||||||
|
|
||||||
|
perUserCompile = window.location?.search?.match(/isolated=true/)? or undefined
|
||||||
opts =
|
opts =
|
||||||
url:"/project/#{ide.project_id}/wordcount"
|
url:"/project/#{ide.project_id}/wordcount"
|
||||||
method:"GET"
|
method:"GET"
|
||||||
params:
|
params:
|
||||||
clsiserverid:ide.clsiServerId
|
clsiserverid:ide.clsiServerId
|
||||||
|
isolated: perUserCompile
|
||||||
$http opts
|
$http opts
|
||||||
.success (data) ->
|
.success (data) ->
|
||||||
$scope.status.loading = false
|
$scope.status.loading = false
|
||||||
|
|
|
@ -3,8 +3,7 @@ define [
|
||||||
], (App) ->
|
], (App) ->
|
||||||
|
|
||||||
App.controller 'LeftHandMenuPromoController', ($scope) ->
|
App.controller 'LeftHandMenuPromoController', ($scope) ->
|
||||||
|
|
||||||
$scope.showDatajoy = Math.random() < 0.5
|
|
||||||
$scope.hasProjects = window.data.projects.length > 0
|
$scope.hasProjects = window.data.projects.length > 0
|
||||||
$scope.userHasSubscription = window.userHasSubscription
|
$scope.userHasSubscription = window.userHasSubscription
|
||||||
$scope.randomView = _.shuffle(["default", "dropbox", "github"])[0]
|
$scope.randomView = _.shuffle(["default", "dropbox", "github"])[0]
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -181,6 +181,8 @@
|
||||||
|
|
||||||
.card-hint:extend(.card-thin) {
|
.card-hint:extend(.card-thin) {
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
|
padding-bottom: 7px;
|
||||||
|
cursor: default;
|
||||||
|
|
||||||
&-icon-container {
|
&-icon-container {
|
||||||
background: currentColor;
|
background: currentColor;
|
||||||
|
@ -217,6 +219,10 @@
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-text {
|
||||||
|
min-height: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
&-feedback-label {
|
&-feedback-label {
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
margin-right: 0.5em;
|
margin-right: 0.5em;
|
||||||
|
@ -230,7 +236,8 @@
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&-actions a {
|
&-actions a,
|
||||||
|
&-text a {
|
||||||
.alert-danger & {
|
.alert-danger & {
|
||||||
color: @alert-danger-text;
|
color: @alert-danger-text;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,10 +12,7 @@ describe 'NotificationsHandler', ->
|
||||||
notificationUrl = "notification.sharelatex.testing"
|
notificationUrl = "notification.sharelatex.testing"
|
||||||
|
|
||||||
beforeEach ->
|
beforeEach ->
|
||||||
@request =
|
@request = sinon.stub().callsArgWith(1)
|
||||||
post: sinon.stub().callsArgWith(1)
|
|
||||||
del: sinon.stub().callsArgWith(1)
|
|
||||||
get: sinon.stub()
|
|
||||||
@handler = SandboxedModule.require modulePath, requires:
|
@handler = SandboxedModule.require modulePath, requires:
|
||||||
"settings-sharelatex": apis:{notifications:{url:notificationUrl}}
|
"settings-sharelatex": apis:{notifications:{url:notificationUrl}}
|
||||||
"request":@request
|
"request":@request
|
||||||
|
@ -26,18 +23,19 @@ describe 'NotificationsHandler', ->
|
||||||
describe "getUserNotifications", ->
|
describe "getUserNotifications", ->
|
||||||
it 'should get unread notifications', (done)->
|
it 'should get unread notifications', (done)->
|
||||||
stubbedNotifications = [{_id: notification_id, user_id: user_id}]
|
stubbedNotifications = [{_id: notification_id, user_id: user_id}]
|
||||||
@request.get.callsArgWith(1, null, {statusCode:200}, stubbedNotifications)
|
@request.callsArgWith(1, null, {statusCode:200}, stubbedNotifications)
|
||||||
@handler.getUserNotifications user_id, (err, unreadNotifications)=>
|
@handler.getUserNotifications user_id, (err, unreadNotifications)=>
|
||||||
stubbedNotifications.should.deep.equal unreadNotifications
|
stubbedNotifications.should.deep.equal unreadNotifications
|
||||||
getOpts =
|
getOpts =
|
||||||
uri: "#{notificationUrl}/user/#{user_id}"
|
uri: "#{notificationUrl}/user/#{user_id}"
|
||||||
json:true
|
json:true
|
||||||
timeout:1000
|
timeout:1000
|
||||||
@request.get.calledWith(getOpts).should.equal true
|
method: "GET"
|
||||||
|
@request.calledWith(getOpts).should.equal true
|
||||||
done()
|
done()
|
||||||
|
|
||||||
it 'should return empty arrays if there are no notifications', ->
|
it 'should return empty arrays if there are no notifications', ->
|
||||||
@request.get.callsArgWith(1, null, {statusCode:200}, null)
|
@request.callsArgWith(1, null, {statusCode:200}, null)
|
||||||
@handler.getUserNotifications user_id, (err, unreadNotifications)=>
|
@handler.getUserNotifications user_id, (err, unreadNotifications)=>
|
||||||
unreadNotifications.length.should.equal 0
|
unreadNotifications.length.should.equal 0
|
||||||
|
|
||||||
|
@ -52,7 +50,8 @@ describe 'NotificationsHandler', ->
|
||||||
json:
|
json:
|
||||||
key:@key
|
key:@key
|
||||||
timeout:1000
|
timeout:1000
|
||||||
@request.del.calledWith(opts).should.equal true
|
method: "DELETE"
|
||||||
|
@request.calledWith(opts).should.equal true
|
||||||
done()
|
done()
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,7 +63,7 @@ describe 'NotificationsHandler', ->
|
||||||
|
|
||||||
it "should post the message over", (done)->
|
it "should post the message over", (done)->
|
||||||
@handler.createNotification user_id, @key, @templateKey, @messageOpts, =>
|
@handler.createNotification user_id, @key, @templateKey, @messageOpts, =>
|
||||||
args = @request.post.args[0][0]
|
args = @request.args[0][0]
|
||||||
args.uri.should.equal "#{notificationUrl}/user/#{user_id}"
|
args.uri.should.equal "#{notificationUrl}/user/#{user_id}"
|
||||||
args.timeout.should.equal 1000
|
args.timeout.should.equal 1000
|
||||||
expectedJson = {key:@key, templateKey:@templateKey, messageOpts:@messageOpts}
|
expectedJson = {key:@key, templateKey:@templateKey, messageOpts:@messageOpts}
|
||||||
|
|
|
@ -32,6 +32,7 @@ describe "ReferencesController", ->
|
||||||
shouldBroadcast: false
|
shouldBroadcast: false
|
||||||
@res = new MockResponse()
|
@res = new MockResponse()
|
||||||
@res.json = sinon.stub()
|
@res.json = sinon.stub()
|
||||||
|
@res.send = sinon.stub()
|
||||||
@res.sendStatus = sinon.stub()
|
@res.sendStatus = sinon.stub()
|
||||||
@fakeResponseData =
|
@fakeResponseData =
|
||||||
projectId: @projectId,
|
projectId: @projectId,
|
||||||
|
@ -113,6 +114,30 @@ describe "ReferencesController", ->
|
||||||
@res.json.calledWith(@fakeResponseData).should.equal true
|
@res.json.calledWith(@fakeResponseData).should.equal true
|
||||||
done()
|
done()
|
||||||
|
|
||||||
|
describe 'there is no dataaaaaaa', ->
|
||||||
|
|
||||||
|
beforeEach ->
|
||||||
|
@ReferencesHandler.indexAll.callsArgWith(1)
|
||||||
|
@call = (callback) =>
|
||||||
|
@controller.indexAll @req, @res
|
||||||
|
callback()
|
||||||
|
|
||||||
|
it 'should not call EditorRealTimeController.emitToRoom', (done) ->
|
||||||
|
@call () =>
|
||||||
|
@EditorRealTimeController.emitToRoom.callCount.should.equal 0
|
||||||
|
done()
|
||||||
|
|
||||||
|
it 'should not produce an error', (done) ->
|
||||||
|
@call () =>
|
||||||
|
@res.sendStatus.callCount.should.equal 0
|
||||||
|
@res.sendStatus.calledWith(500).should.equal false
|
||||||
|
@res.sendStatus.calledWith(400).should.equal false
|
||||||
|
done()
|
||||||
|
|
||||||
|
it 'should close the response', (done) ->
|
||||||
|
@call () =>
|
||||||
|
@res.send.called.should.equal true
|
||||||
|
done()
|
||||||
|
|
||||||
describe 'index', ->
|
describe 'index', ->
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue