diff --git a/services/web/app/coffee/infrastructure/ExpressLocals.coffee b/services/web/app/coffee/infrastructure/ExpressLocals.coffee index faba1e4623..8e45f9c7ee 100644 --- a/services/web/app/coffee/infrastructure/ExpressLocals.coffee +++ b/services/web/app/coffee/infrastructure/ExpressLocals.coffee @@ -7,15 +7,19 @@ querystring = require('querystring') SystemMessageManager = require("../Features/SystemMessages/SystemMessageManager") _ = require("underscore") Modules = require "./Modules" +url = require "url" fingerprints = {} Path = require 'path' + + jsPath = if Settings.useMinifiedJs "/minjs/" else "/js/" + logger.log "Generating file fingerprints..." for path in [ "#{jsPath}libs/require.js", @@ -37,7 +41,21 @@ for path in [ fingerprints[path] = hash else logger.log filePath:filePath, "file does not exist for fingerprints" - + +getFingerprint = (path) -> + if fingerprints[path]? + return fingerprints[path] + else + logger.err "No fingerprint for file: #{path}" + return "" + +logger.log "Finished generating file fingerprints" + + +staticFilesBase = "" +if Settings.cdn?.web?.host? + staticFilesBase = Settings.cdn?.web?.host + module.exports = (app, webRouter, apiRouter)-> webRouter.use (req, res, next)-> @@ -46,8 +64,42 @@ module.exports = (app, webRouter, apiRouter)-> webRouter.use (req, res, next)-> res.locals.jsPath = jsPath + res.locals.fullJsPath = url.resolve(staticFilesBase, jsPath) + + imgPath = "/img/" + cssPath = "/stylesheets/" + + res.locals.buildJsPath = (jsFile, opts = {})-> + p = Path.join(jsPath, jsFile) + + doFingerPrint = opts.fingerprint != false + + if !opts.qs? + opts.qs = {} + + if !opts.qs?.fingerprint? and doFingerPrint + opts.qs.fingerprint = getFingerprint(p) + + p = url.resolve(staticFilesBase, p) + qs = querystring.stringify(opts.qs) + + if qs? and qs.length > 0 + p = p + "?" + qs + return p + + + res.locals.buildCssPath = (cssFile)-> + p = Path.join(cssPath, cssFile) + return url.resolve(staticFilesBase, p) + "?fingerprint=" + getFingerprint(p) + + res.locals.buildImgPath = (imgFile)-> + p = Path.join(imgPath, imgFile) + return url.resolve(staticFilesBase, p) + next() + + webRouter.use (req, res, next)-> res.locals.settings = Settings next() @@ -113,12 +165,7 @@ module.exports = (app, webRouter, apiRouter)-> next() webRouter.use (req, res, next)-> - res.locals.fingerprint = (path) -> - if fingerprints[path]? - return fingerprints[path] - else - logger.err "No fingerprint for file: #{path}" - return "" + res.locals.fingerprint = getFingerprint next() webRouter.use (req, res, next)-> diff --git a/services/web/app/views/general/500.jade b/services/web/app/views/general/500.jade index e045a7d457..ef74ed7435 100644 --- a/services/web/app/views/general/500.jade +++ b/services/web/app/views/general/500.jade @@ -3,7 +3,7 @@ html(itemscope, itemtype='http://schema.org/Product') head title Something went wrong link(rel="icon", href="/favicon.ico") - link(rel='stylesheet', href='/stylesheets/style.css') + link(rel='stylesheet', href=buildCssPath('/style.css')) link(href="//netdna.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css",rel="stylesheet") body .content @@ -12,7 +12,7 @@ html(itemscope, itemtype='http://schema.org/Product') .col-md-8.col-md-offset-2.text-center .page-header h2 Oh dear, something went wrong. - p: img(src="/img/lion-sad-128.png", alt="Sad Lion") + p: img(src=buildImgPath("lion-sad-128.png"), alt="Sad Lion") p | Something went wrong with your request, sorry. Our staff are probably looking into this, but if it continues, please contact us at #{settings.adminEmail} p diff --git a/services/web/app/views/layout.jade b/services/web/app/views/layout.jade index efe1691df9..cd284c95e2 100644 --- a/services/web/app/views/layout.jade +++ b/services/web/app/views/layout.jade @@ -15,10 +15,10 @@ html(itemscope, itemtype='http://schema.org/Product') -if (typeof(title) == "undefined") title= 'ShareLaTeX, '+ translate("online_latex_editor") -else - title= translate(title) + ' - ShareLaTeX, '+translate("online_latex_editor") + title= translate(title) + ' - ShareLaTeX, ' + translate("online_latex_editor") link(rel="icon", href="/favicon.ico") - link(rel='stylesheet', href='/stylesheets/style.css?fingerprint='+fingerprint('/stylesheets/style.css')) + link(rel='stylesheet', href=buildCssPath('/style.css')) if settings.i18n.subdomainLang each subdomainDetails in settings.i18n.subdomainLang @@ -124,8 +124,8 @@ html(itemscope, itemtype='http://schema.org/Product') window.csrfToken = "#{csrfToken}"; block scripts - script(src="#{jsPath}libs/jquery-1.11.1.min.js") - script(src="#{jsPath}libs/angular-1.3.15.min.js") + script(src=buildJsPath("libs/jquery-1.11.1.min.js", {fingerprint:false})) + script(src=buildJsPath("libs/angular-1.3.15.min.js", {fingerprint:false})) script. window.sharelatex = { siteUrl: '#{settings.siteUrl}', @@ -194,11 +194,12 @@ html(itemscope, itemtype='http://schema.org/Product') } }; script( - data-main=jsPath+'main.js', - baseurl=jsPath, - src=jsPath+'libs/require.js?fingerprint='+fingerprint(jsPath + 'libs/require.js') + data-main=buildJsPath('main.js', {fingerprint:false}), + baseurl=fullJsPath, + src=buildJsPath('libs/require.js') ) + include contact-us-modal include sentry diff --git a/services/web/app/views/project/editor.jade b/services/web/app/views/project/editor.jade index bcb69597eb..eac92b56df 100644 --- a/services/web/app/views/project/editor.jade +++ b/services/web/app/views/project/editor.jade @@ -100,7 +100,7 @@ block content window.wikiEnabled = #{!!(settings.apis.wiki && settings.apis.wiki.url)}; window.requirejs = { "paths" : { - "mathjax": "/js/libs/mathjax/MathJax.js?config=TeX-AMS_HTML", + "mathjax": "#{buildJsPath('/libs/mathjax/MathJax.js', {qs:{config:'TeX-AMS_HTML', fingerprint:false}})}", "moment": "libs/moment-2.7.0", "libs/pdf": "libs/pdfjs-1.3.91/pdf" }, @@ -129,15 +129,18 @@ block content - var pdfPath = 'libs/pdfjs-1.3.91/pdf.worker.js' - var fingerprintedPath = fingerprint(jsPath+pdfPath) - - var pdfJsWorkerPath = jsPath+pdfPath+'?fingerprint='+fingerprintedPath + - var pdfJsWorkerPath = buildJsPath(pdfPath, {qs:{fingerprint:fingerprintedPath}}) + + script(type='text/javascript'). window.pdfJsWorkerPath = "#{pdfJsWorkerPath}"; script( - data-main=jsPath+"ide.js", - baseurl=jsPath, - data-ace-base=jsPath+'ace', - src=jsPath+'libs/require.js?fingerprint='+fingerprint(jsPath + 'libs/require.js') + data-main=buildJsPath("ide.js", {fingerprint:false}), + baseurl=fullJsPath, + data-ace-base=buildJsPath('ace', {fingerprint:false}), + src=buildJsPath('libs/require.js') ) + diff --git a/services/web/app/views/project/list/side-bar.jade b/services/web/app/views/project/list/side-bar.jade index b3405eb1be..96365c813e 100644 --- a/services/web/app/views/project/list/side-bar.jade +++ b/services/web/app/views/project/list/side-bar.jade @@ -135,7 +135,7 @@ p span Get Dropbox Sync p - img(src="/img/dropbox/simple_logo.png") + img(src=buildImgPath("dropbox/simple_logo.png")) p a(href="/user/subscription/plans", sixpack-convert="left-menu-upgraed-rotation").btn.btn-primary #{translate("upgrade")} p.small.text-centered @@ -148,7 +148,7 @@ p span Get Github Sync p - img(src="/img/github/octocat.jpg") + img(src=buildImgPath("github/octocat.jpg")) p a(href="/user/subscription/plans", sixpack-convert="left-menu-upgraed-rotation").btn.btn-primary #{translate("upgrade")} p.small.text-centered diff --git a/services/web/app/views/sentry.jade b/services/web/app/views/sentry.jade index 9fe5dd3b7d..f339e26cae 100644 --- a/services/web/app/views/sentry.jade +++ b/services/web/app/views/sentry.jade @@ -2,7 +2,7 @@ - if (sentrySrc.match(/^([a-z]+:)?\/\//i)) script(src="#{sentrySrc}") - else - script(src="#{jsPath}libs/#{sentrySrc}") + script(src=buildJsPath("libs/#{sentrySrc}")) - if (typeof(sentrySrc) != "undefined") script(type="text/javascript"). if (typeof(Raven) != "undefined" && Raven.config) { diff --git a/services/web/app/views/subscriptions/edit-billing-details.jade b/services/web/app/views/subscriptions/edit-billing-details.jade index bc47efb4cb..f0b6671bcd 100644 --- a/services/web/app/views/subscriptions/edit-billing-details.jade +++ b/services/web/app/views/subscriptions/edit-billing-details.jade @@ -3,7 +3,7 @@ extends ../layout block content - locals.supressDefaultJs = true script(data-main=jsPath+'main.js', src=jsPath+'libs/require.js', baseurl=jsPath) - script(src=jsPath+'libs/recurly.min.js') + script(src=buildJsPath('libs/recurly.min.js')) .content.content-alt .container diff --git a/services/web/app/views/subscriptions/successful_subscription.jade b/services/web/app/views/subscriptions/successful_subscription.jade index 86b0263238..8413f5e036 100644 --- a/services/web/app/views/subscriptions/successful_subscription.jade +++ b/services/web/app/views/subscriptions/successful_subscription.jade @@ -30,10 +30,10 @@ block content | Henry and James .portraits span.img-circle - img(src="/img/about/henry_oswald.jpg") + img(src=buildImgPath("about/henry_oswald.jpg")) |   span.img-circle - img(src="/img/about/james_allen.jpg") + img(src=buildImgPath("about/james_allen.jpg")) p a.btn.btn-primary(href="/project") < #{translate("back_to_your_projects")} diff --git a/services/web/app/views/translations/translation_message.jade b/services/web/app/views/translations/translation_message.jade index 333139139f..225ad3ea2c 100644 --- a/services/web/app/views/translations/translation_message.jade +++ b/services/web/app/views/translations/translation_message.jade @@ -2,7 +2,7 @@ span(ng-controller="TranslationsPopupController", ng-cloak) .translations-message(ng-hide="hidei18nNotification") a(href=recomendSubdomain.url+currentUrl) !{translate("click_here_to_view_sl_in_lng", {lngName:"" + translate(recomendSubdomain.lngCode) + ""})} - img(src="/img/flags/24/#{recomendSubdomain.lngCode}.png") + img(src=buildImgPath("flags/24/#{recomendSubdomain.lngCode}.png")) button(ng-click="dismiss()").close.pull-right span(aria-hidden="true") × span.sr-only #{translate("close")} \ No newline at end of file diff --git a/services/web/config/settings.defaults.coffee b/services/web/config/settings.defaults.coffee index e98970fa60..e4c565c315 100644 --- a/services/web/config/settings.defaults.coffee +++ b/services/web/config/settings.defaults.coffee @@ -114,6 +114,10 @@ module.exports = settings = showSocialButtons: false showComments: false + # cdn: + # web: + # host:"http://www.sharelatex.dev:3000" + # Where your instance of ShareLaTeX can be found publically. Used in emails # that are sent out, generated links, etc. siteUrl : siteUrl = 'http://localhost:3000' diff --git a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee index dbdd137b57..57b06b3bb1 100644 --- a/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee +++ b/services/web/public/coffee/ide/pdf/controllers/PdfController.coffee @@ -102,6 +102,15 @@ define [ for file in response?.outputFiles fileByPath[file.path] = file + # prepare query string + qs = {} + # add a query string parameter for the compile group + if response.compileGroup? + ide.compileGroup = qs.compileGroup = response.compileGroup + # add a query string parameter for the clsi server id + if response.clsiServerId? + ide.clsiServerId = qs.clsiserverid = response.clsiServerId + if response.status == "timedout" $scope.pdf.view = 'errors' $scope.pdf.timedout = true @@ -133,8 +142,6 @@ define [ $scope.pdf.view = 'pdf' $scope.shouldShowLogs = false - # prepare query string - qs = {} # define the base url. if the pdf file has a build number, pass it to the clsi in the url if fileByPath['output.pdf']?.url? $scope.pdf.url = fileByPath['output.pdf'].url @@ -146,16 +153,8 @@ define [ # check if we need to bust cache (build id is unique so don't need it in that case) if not fileByPath['output.pdf']?.build? qs.cache_bust = "#{Date.now()}" - # add a query string parameter for the compile group - if response.compileGroup? - $scope.pdf.compileGroup = response.compileGroup - qs.compileGroup = "#{$scope.pdf.compileGroup}" - if response.clsiServerId? - qs.clsiserverid = response.clsiServerId - ide.clsiServerId = response.clsiServerId # convert the qs hash into a query string and append it - $scope.pdf.qs = createQueryString qs - $scope.pdf.url += $scope.pdf.qs + $scope.pdf.url += createQueryString qs # Save all downloads as files qs.popupDownload = true $scope.pdf.downloadUrl = "/project/#{$scope.project_id}/output/output.pdf" + createQueryString(qs) @@ -187,6 +186,7 @@ define [ opts = method:"GET" params: + compileGroup:ide.compileGroup clsiserverid:ide.clsiServerId if file?.url? # FIXME clean this up when we have file.urls out consistently opts.url = file.url @@ -194,6 +194,9 @@ define [ opts.url = "/project/#{$scope.project_id}/build/#{file.build}/output/#{name}" else opts.url = "/project/#{$scope.project_id}/output/#{name}" + # check if we need to bust cache (build id is unique so don't need it in that case) + if not file?.build? + opts.params.cache_bust = "#{Date.now()}" return $http(opts) # accumulate the log entries diff --git a/services/web/public/coffee/ide/pdfng/directives/pdfJs.coffee b/services/web/public/coffee/ide/pdfng/directives/pdfJs.coffee index 98361b9ff7..f1c161ffc6 100644 --- a/services/web/public/coffee/ide/pdfng/directives/pdfJs.coffee +++ b/services/web/public/coffee/ide/pdfng/directives/pdfJs.coffee @@ -1,23 +1,14 @@ define [ "base" "ide/pdfng/directives/pdfViewer" - "text!libs/pdfListView/TextLayer.css" - "text!libs/pdfListView/AnnotationsLayer.css" - "text!libs/pdfListView/HighlightsLayer.css" ], ( App pdfViewer - textLayerCss - annotationsLayerCss - highlightsLayerCss + ) -> if PDFJS? PDFJS.workerSrc = window.pdfJsWorkerPath - style = $("