diff --git a/lib/db/sql_templates.json b/lib/db/sql_templates.json
index 29b3f450..749f8e5f 100644
--- a/lib/db/sql_templates.json
+++ b/lib/db/sql_templates.json
@@ -33,7 +33,7 @@
"getUserForForgotToken": "SELECT `ownership`.*, expires FROM `ownership` INNER JOIN `forgot_tokens` ON `name` = `owner_name` WHERE `token` = ? AND `forgot_tokens`.`expires` >= ?",
"setForgotToken": "INSERT INTO `forgot_tokens` (`owner_name`, `token`, `expires`, `created`) VALUES (?, ?, ?, ?)",
"deleteExpiredForgotToken": "DELETE FROM `forgot_tokens` WHERE `expires` <= ? OR `token`=? OR `owner_name`=?",
- "reportBin": "UPDATE `sandbox` SET `reported`=? WHERE `url`=? AND `revision`=? AND `active`='y'",
+ "reportBin": "UPDATE `sandbox` SET `reported`=?, `active`='n' WHERE `url`=? AND `revision`=? AND `reported` IS NULL",
"updateBinData": "UPDATE `sandbox` SET `:field`=? WHERE `url`=? AND `revision`=?",
"updateOwnersData": "UPDATE `owners` SET `:field`=? WHERE `url`=? AND `revision`=?",
"updateOwnershipData": "UPDATE `ownership` SET `:field`=? WHERE `name`=?",
diff --git a/lib/errors.js b/lib/errors.js
index ff6ed09c..302c7865 100644
--- a/lib/errors.js
+++ b/lib/errors.js
@@ -53,6 +53,14 @@ exports.NotFound = HTTPError.extend({
}
});
+// Creates an error object for handling 404 responses.
+exports.Reported = HTTPError.extend({
+ constructor: function NotFound(message) {
+ HTTPError.call(this, 404, message);
+ }
+});
+
+
exports.BinNotFound = exports.NotFound.extend({
constructor: function BinNotFound(message) {
exports.NotFound.call(this, 404, message);
diff --git a/lib/handlers/bin.js b/lib/handlers/bin.js
index 18f7712f..009546d7 100644
--- a/lib/handlers/bin.js
+++ b/lib/handlers/bin.js
@@ -397,9 +397,9 @@ module.exports = Observable.extend({
return res.redirect(root);
}
return next(new errors.BinNotFound('Could not find bin: ' + req.params.bin));
- } else if (!bin.active) {
+ } else if (!bin.active && bin.reported) {
metrics.increment('bin.404-reported');
- return next(new errors.NotFound('Bin has been reported: ' + req.params.bin));
+ return next(new errors.Reported('Bin has been reported: ' + req.params.bin));
} else {
req.bin = bin;
next();
@@ -807,10 +807,10 @@ module.exports = Observable.extend({
if (!result || err === 401) {
metrics.increment('bin.404');
- return next(new errors.BinNotFound('Could not find bin: ' + req.params.bin));
- } else if (!result.active) {
+ return next(new errors.NotFound('Could not find bin: ' + req.params.bin));
+ } else if (!result.active && result.reported) {
metrics.increment('bin.404-reported');
- return next(new errors.NotFound('Bin has been reported: ' + req.params.bin));
+ return next(new errors.Reported('Bin has been reported: ' + req.params.bin));
} else {
var flag = undefsafe(result, 'metadata.flagged');
if (flag) {
diff --git a/lib/handlers/error.js b/lib/handlers/error.js
index cde01781..4e357f48 100644
--- a/lib/handlers/error.js
+++ b/lib/handlers/error.js
@@ -25,22 +25,25 @@ module.exports = Observable.extend({
if (err instanceof errors.NotFound && req.accepts('html')) {
if (err instanceof errors.BinNotFound) {
- return (new BinHandler(this.sandbox)).notFound(req, res, next);
+ return this.renderErrorPage('error', err, req, res);
+ // return (new BinHandler(this.sandbox)).notFound(req, res, next);
} else {
- return this.renderErrorPage(err, req, res);
+ return this.renderErrorPage('error', err, req, res);
}
+ next(err);
} else if (err instanceof errors.HTTPError) {
- return this.renderError(err, req, res);
+ // return this.renderError(err, req, res);
+ return this.renderErrorPage(err.status, err, req, res);
+ next(err);
}
- next(err);
},
// Fall through handler for when no routes match.
notFound: function (req, res) {
var error = new errors.NotFound('Page Does Not Exist');
if (req.accepts('html') && (req.url.indexOf('/api/') !== 0)) {
- this.renderErrorPage(error, req, res);
+ this.renderErrorPage('404', error, req, res);
} else {
this.renderError(error, req, res);
}
@@ -53,7 +56,7 @@ module.exports = Observable.extend({
this.sendErrorReport(err, req);
if (req.accepts('html')) {
- this.renderErrorPage(err, req, res);
+ this.renderErrorPage('error', err, req, res);
} else {
var error = new errors.HTTPError(500, 'Internal Server Error');
this.renderError(error, req, res);
@@ -74,10 +77,12 @@ module.exports = Observable.extend({
}
},
- renderErrorPage: function (err, req, res) {
+ renderErrorPage: function (view, err, req, res) {
var status = err.status || 500;
- res.status(status).render('error', {
+ var views = ['error', 504, 502];
+
+ res.status(status).render(views.indexOf(view) !== -1 ? view : 'error', {
is_500: status !== 404, // Saves us having many error pages at the mo.
is_404: status === 404,
root: this.helpers.url('', true),
diff --git a/lib/routes.js b/lib/routes.js
index e6cf6551..13f9f185 100644
--- a/lib/routes.js
+++ b/lib/routes.js
@@ -181,7 +181,12 @@ module.exports = function (app) {
});
next();
- }, userHandler.updateLastSeen, binHandler.loadBin);
+ }, userHandler.updateLastSeen, binHandler.loadBin, function (req, res, next) {
+ if (req.bin) {
+ app.emit('bin:loaded', req);
+ }
+ next();
+ });
// track the logged in and logged out numbers
app.get('*', function (req, res, next) {
@@ -555,7 +560,8 @@ module.exports = function (app) {
app.get('/:bin/:rev?/watch', tag('live'), binHandler.getBin);
app.get('/:bin/:rev?/embed', tag('embed'), binHandler.getBin);
- app.post('/:bin/:rev?/report', binHandler.report);
+ // don't expose anymore - reporting goes through github
+ // app.post('/:bin/:rev?/report', binHandler.report);
// Use this handler to check for a user creating/claiming their own bin url.
// We use :url here to prevent loadBin() being called and returning a not
diff --git a/lib/utils.js b/lib/utils.js
index 86d314d6..6d30dcea 100644
--- a/lib/utils.js
+++ b/lib/utils.js
@@ -272,6 +272,6 @@ module.exports = {
return str;
},
binUrlLength: function (req) {
- return undefsafe(req, 'session.user') ? 2 : 7;
+ return undefsafe(req, 'session.user') ? 2 : 11;
},
};
diff --git a/public/css/static-page.css b/public/css/static-page.css
index b4d44da2..cd5dba55 100644
--- a/public/css/static-page.css
+++ b/public/css/static-page.css
@@ -1,63 +1,30 @@
+html {
+ background: rgb(250, 250, 250);
+ min-height: 100%;
+}
+
body {
+ background: #fff;
padding: 0;
margin: 0;
- font-family: sans-serif;
- background: #3FA8C6;
- background: -moz-linear-gradient(top, #3fa8c6 0%, #3fa8c6 0%, #399ab2 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#3fa8c6), color-stop(0%,#3fa8c6), color-stop(100%,#399ab2));
- background: -webkit-linear-gradient(top, #3fa8c6 0%,#3fa8c6 0%,#399ab2 100%);
- background: -o-linear-gradient(top, #3fa8c6 0%,#3fa8c6 0%,#399ab2 100%);
- background: -ms-linear-gradient(top, #3fa8c6 0%,#3fa8c6 0%,#399ab2 100%);
- background: linear-gradient(to bottom, #3fa8c6 0%,#3fa8c6 0%,#399ab2 100%);
- background-color: #399AB2;
- background-repeat: repeat-x;
- color: #fff;
- text-shadow: 0 1px 0 rgba(0,0,0,.3);
+ font-family: 'helvetica neue', sans-serif;
+ font-size: 18px;
+ color: #111111;
line-height: 1.5;
- -webkit-font-smoothing: antialiased;
+ margin: 40px auto;
+ max-width: 660px;
+ border-radius: 10px;
}
-.wrapper {
- width: 50%;
- margin: 0 auto;
-}
-
-h1, h2, h3, h4, h5, h6 {
- letter-spacing: -0.03em;
- font-size: 2em;
-}
-
-a {
- color: white;
- text-decoration: none;
- border-bottom: 1px solid #fff;
- border-bottom: 1px solid rgba(255,255,255,0.7);
- padding-bottom: 0.15em;
- position: relative;
-}
-
-a:after {
- content: '';
- position: absolute;
- height: 1px;
- left: 0;
- right: 0;
- bottom: -2px;
- background: rgba(0,0,0,.1);
-}
-
-a:hover {
- color: #C0E3EC;
+div.wrapper {
+ margin-left: 128px;
+ padding: 10px;
}
h1 {
- text-align: left;
+ letter-spacing: -0.03em;
+ font-size: 2em;
margin: 0.667em 0 0;
- padding-left: 0.5em;
-}
-
-h2 {
- font-size: 1.5em;
}
small {
@@ -67,76 +34,19 @@ small {
font-size: 0.667em;
}
-p em {
- font-style: none;
-}
-
-#welcome {
- position: relative;
- overflow: hidden;
- padding-bottom: 1em;
- padding-left: 20px;
-}
-
-#welcome > div {
- padding-top: 1px;
-}
-
#dave {
+ height: 128px;
float: left;
- margin-top: 3em
- user-drag: none;
- -moz-user-select: none;
- -webkit-user-drag: none;
-}
-
-#welcome > h2 {
- margin-top: 0.5em;
- padding-left: 0.5em;
- margin-bottom: 0;
+ margin-top: 2em;
}
.bubble p {
- line-height: 22px;
+ line-height: 1.4;
}
.bubble {
- background: rgba(255, 255, 255, 0.1);
border-color: rgba(255, 255, 255, 0.1);
-
padding: 0.667em 1em;
- position: relative;
-}
-
-.bubble:after {
- content: "";
- position: absolute;
- width: 0;
- height: 0;
- border-top: 20px solid transparent;
- border-bottom: 20px solid transparent;
- border-right: 20px solid white;
- border-right-color: inherit;
- top: 50px;
- left: -20px;
-}
-
-img {
- z-index: 1;
- -webkit-transition: -webkit-transform 2s ease-in-out;
- -moz-transition: -moz-transform 2s ease-in-out;
- -o-transition: -o-transform 2s ease-in-out;
- -ms-transition: -ms-transform 2s ease-in-out;
- transition: transform 2s ease-in-out;
- position: relative;
-}
-
-img:active {
- -webkit-transform: rotate(1440deg) scale(1.2);
- -moz-transform: rotate(1440deg) scale(1.2);
- -o-transform: rotate(1440deg) scale(1.2);
- -ms-transform: rotate(1440deg) scale(1.2);
- transform: rotate(1440deg) scale(1.2);
}
pre {
@@ -148,50 +58,27 @@ pre {
border-radius: 3px;
}
-@media screen and (max-width: 1200px) {
- .wrapper {
- width: 80%;
- }
-}
-
-@media screen and (max-width: 768px) {
- .wrapper {
+@media screen and (max-width: 660px) {
+ html {
width: auto;
- margin: 0;
- }
- #welcome {
- margin-right: 2.5%;
- }
-}
-
-@media screen and (max-width: 500px) {
- .wrapper {
- text-align: center;
- }
-
- #dave {
- float: none;
- }
-
- #welcome {
- padding: 0 1.5em;
- margin: 0;
+ border-radius: 0;
+ background: #fff;
}
h1 {
- text-align: center;
- margin-bottom: 0;
- padding-left: 0;
- font-size: 1.8em;
+ margin: 0;
}
- #welcome > h2 {
- margin-bottom: 0.667em;
+ body {
+ margin: 10px auto;
+ padding: 10px;
}
- .bubble {
- text-align: center;
- }
- .bubble:after {
+
+ img {
display: none;
}
-}
+
+ div.wrapper {
+ margin-left: 0;
+ }
+}
\ No newline at end of file
diff --git a/public/images/dave.min.svg b/public/images/dave.min.svg
new file mode 100644
index 00000000..a657681f
--- /dev/null
+++ b/public/images/dave.min.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/js/render/edit.js b/public/js/render/edit.js
index f2dbf97a..2bac60a8 100644
--- a/public/js/render/edit.js
+++ b/public/js/render/edit.js
@@ -14,12 +14,12 @@ function jsbinShowEdit(options) {
btn.id = 'edit-with-js-bin';
btn.href = path + (path.slice(-1) === '/' ? '' : '/') + 'edit';
btn.innerHTML = 'Edit in JS Bin
';
- doc.body.appendChild(btn);
+ doc.documentElement.appendChild(btn);
// Style button:
style.setAttribute('rel', 'stylesheet');
style.setAttribute('href', options['static'] + '/css/edit.css');
- doc.getElementsByTagName('head')[0].appendChild(style);
+ doc.documentElement.appendChild(style);
// show / hide button:
diff --git a/views/502.html b/views/502.html
index c18f3117..d87d7057 100644
--- a/views/502.html
+++ b/views/502.html
@@ -6,16 +6,12 @@
- JS Bin isn't available right now. Someone should be working on it, - and you can check the current status on status.jsbin.com, but do feel free to ping @js_bin.
-If you want to add details please add it to the issues page and add any additional information you can to help diagnose this atrocity.
-JS Bin isn't available right now. Someone should be working on it, + and you can check the current status on status.jsbin.com, but do feel free to ping @js_bin.
+If you want to add details please add it to the issues page and add any additional information you can to help diagnose this atrocity.