diff --git a/packages/webapp/css_detect.css b/packages/webapp/css_detect.css deleted file mode 100644 index fa54606703..0000000000 --- a/packages/webapp/css_detect.css +++ /dev/null @@ -1,3 +0,0 @@ -._meteor_detect_css { - width: 0px; -} \ No newline at end of file diff --git a/packages/webapp/package.js b/packages/webapp/package.js index a8f9d66e66..fab6a96434 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -22,5 +22,4 @@ Package.on_use(function (api) { api.export(['WebApp'], 'client'); api.add_files('webapp_server.js', 'server'); api.add_files('webapp_client.js', 'client'); - api.add_files('css_detect.css', 'client'); }); diff --git a/packages/webapp/webapp_client.js b/packages/webapp/webapp_client.js index 09a0eb44e2..2a8a577532 100644 --- a/packages/webapp/webapp_client.js +++ b/packages/webapp/webapp_client.js @@ -3,9 +3,9 @@ WebApp = { _isCssLoaded: function () { return _.find(document.styleSheets, function (sheet) { if (sheet.cssText && !sheet.cssRules) // IE8 - return sheet.cssText.match(/_meteor_detect_css/); - return _.find(sheet.cssRules, function (rule) { - return rule.selectorText === '._meteor_detect_css'; + return !sheet.cssText.match(/meteor-css-not-found-error/); + return !_.find(sheet.cssRules, function (rule) { + return rule.selectorText === '.meteor-css-not-found-error'; }); }); } diff --git a/packages/webapp/webapp_server.js b/packages/webapp/webapp_server.js index e5ee0053a6..1e60ddeb63 100644 --- a/packages/webapp/webapp_server.js +++ b/packages/webapp/webapp_server.js @@ -397,7 +397,6 @@ var runWebAppServer = function () { // in `about:config` (it is on by default in FF 24). if (info.sourceMapUrl) res.setHeader('X-SourceMap', info.sourceMapUrl); - send(req, path.join(clientDir, info.path)) .maxage(maxAge) .hidden(true) // if we specified a dotfile in the manifest, serve it @@ -445,8 +444,17 @@ var runWebAppServer = function () { var request = WebApp.categorizeRequest(req); + if (request.url.query && request.url.query['meteor_css_resource']) { + // In this case, we're requesting a CSS resource in the meteor-specific + // way, but we don't have it. Serve a static css file that indicates that + // we didn't have it, so we can detect that and refresh. + headers['Content-Type'] = 'text/css; charset=utf-8'; + res.writeHead(200, headers); + res.write(".meteor-css-not-found-error { width: 0px;}"); + res.end(); + return undefined; + } res.writeHead(200, headers); - var requestSpecificHtml = htmlAttributes(boilerplateHtml, request); res.write(requestSpecificHtml); res.end(); diff --git a/tools/bundler.js b/tools/bundler.js index 9d93ddd75f..b0c3f1c841 100644 --- a/tools/bundler.js +++ b/tools/bundler.js @@ -313,15 +313,18 @@ _.extend(File.prototype, { return self.contents().length; }, - // Set the URL of this file to "/". suffix will - // typically be used to pick a reasonable extension. Also set - // cacheable to true, since the file's name is now derived from its - // contents. - setUrlToHash: function (suffix) { + // Set the URL (and target path) of this file to "/". suffix + // will typically be used to pick a reasonable extension. Also set cacheable + // to true, since the file's name is now derived from its contents. + + // Also allow a special second suffix that will *only* be postpended to the + // url, useful for query parameters. + setUrlToHash: function (fileAndUrlSuffix, urlSuffix) { var self = this; - self.url = "/" + self.hash() + suffix; + urlSuffix = urlSuffix || ""; + self.url = "/" + self.hash() + fileAndUrlSuffix + urlSuffix; self.cacheable = true; - self.targetPath = self.hash() + suffix; + self.targetPath = self.hash() + fileAndUrlSuffix; }, // Append "?" to the URL and mark the file as cacheable. @@ -766,7 +769,7 @@ _.extend(ClientTarget.prototype, { allCss = minifiers.CleanCSSProcess(allCss); self.css = [new File({ data: new Buffer(allCss, 'utf8') })]; - self.css[0].setUrlToHash(".css"); + self.css[0].setUrlToHash(".css", "?meteor_css_resource=true"); }, // XXX Instead of packaging the boilerplate in the client program, the