Skip to content
This repository has been archived by the owner on Oct 14, 2020. It is now read-only.

Commit

Permalink
initial
Browse files Browse the repository at this point in the history
  • Loading branch information
gpbmike committed Mar 27, 2014
0 parents commit 8b1f59e
Show file tree
Hide file tree
Showing 12 changed files with 527 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,4 @@
bower_components/
node_modules/
dist/
dev/
1 change: 1 addition & 0 deletions .jshintrc
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1 @@
{}
90 changes: 90 additions & 0 deletions api/index.js
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,90 @@
var express = require('express');
var morgan = require('morgan');
var compress = require('compression')();
var bodyParser = require('body-parser');
var UglifyJS = require('uglify-js');
var CleanCSS = require('clean-css');
var hljs = require('highlight.js');
var errorhandler = require('errorhandler');
var api = express();

api.use(morgan('dev'));
// api.use(compress);
api.use(bodyParser({ limit: '1mb' }));
api.use(errorhandler());

/**
* CORS support.
*/

api.all('*', function(req, res, next){
if (!req.get('Origin')) {
return next();
}

// use "*" here to accept any origin
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-Methods', 'GET, POST');
res.set('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');

if ('OPTIONS' === req.method) {
return res.send(200);
}
next();
});


api.post('/', function(req, res){

if (!req.param('code')) {
res.send(404, ':(');
}

var highlighted = hljs.highlightAuto(req.param('code'), ['javascript', 'css']);
var output = { language: highlighted.language };

switch (output.language) {
case 'javascript':
try {
var minified = UglifyJS.minify(req.param('code'), {
fromString: true,
warnings: true,
compress: {
warnings: true
}
});
output.code = minified.code;
output.map = minified.map;
} catch (error) {
delete error.stack;
res.json(500, error);
}
res.send(output);
break;

case 'css':
output.code = new CleanCSS().minify(req.param('code'));
res.send(output);
break;

default:
res.json(500, 'Sorry, we could not figure out what language you are trying to compress.');
}
});

api.post('/:fileName', function (req, res) {
compress(req, res, function (error) {
if (error) {
res.json(error);
}

res.attachment(req.param('fileName'));
res.end(req.param('code'), 'utf8');
});
});

api.all('*', function (req, res) {
res.send(404);
});

api.listen(3001);
116 changes: 116 additions & 0 deletions app/index.html
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,116 @@
<!doctype>
<html>
<head>
<meta charset="utf-8">
<title>Refresh-SF - Online JavaScript and CSS Compressor</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- build:css css/vendor.css -->
<link rel="stylesheet" href="../bower_components/bootstrap/dist/css/bootstrap.min.css">
<!-- endbuild -->
<!-- build:css css/app.css -->
<link rel="stylesheet" href="css/app.css">
<!-- endbuild -->
</head>
<body>

<script type="text/x-handlebars">
<div class="container">
<div class="page-header">
<h1>Online JavaScript/CSS Compressor</h1>
<p class="lead">This is a web interface to compress your JavaScript or CSS. This tool uses <a href="https://github.com/mishoo/UglifyJS2">UglifyJS 2</a> and <a href="https://github.com/GoalSmashers/clean-css">Clean-CSS.</a></p>
</div>
</div>

{{outlet}}

<div class="container" style="text-align: center">
<hr>
<p>Built by <a href="http://twitter.com/gpbmike">@gpbmike</a> with <a href="http://emberjs.com">Ember</a>, <a href="http://getbootstrap.com/">Bootstrap</a>, and <a href="http://gulpjs.com/">gulp.js</a>.</p>
</div>

</script>

<script type="text/x-handlebars" data-template-name="compressor">

<div class="container">

{{#unless output}}
<div class="row">
<div class="col-lg-12">
<div class="form-group">
<h2>Input Code</h2>
{{view App.DragAndDrop value=input class="form-control input" rows="10" placeholder=placeholder disabled=isCompressing}}
</div>
</div>
</div>

{{#if input}}
<div class="col-lg-12">
<div class="row"><button type="button" class="btn btn-primary" {{action "compress"}} {{bind-attr disabled=isCompressing}}>Compress</button></div>
</div>
{{/if}}

{{else}}

<div class="row">
<div class="col-lg-12">
<h2>Compressed {{displayLanguage}}</h2>
{{textarea value=output classBinding=":form-control :alert error:alert-danger:alert-success" rows=10}}
</div>
</div>

<div class="row">

<div class="col-lg-4">
{{#unless error}}
<div class="input-group">
{{input class="form-control" value=filename}}
<span class="input-group-btn">
<button type="button" class="btn btn-primary" {{action "save"}} {{bind-attr disabled=saveDisabled}}>Save As</button>
</span>
</div>
{{/unless}}
</div>

<div class="col-lg-8">
<button type="button" class="btn btn-default pull-right" {{action "clearOutput"}}>Reset</button>
</div>

</div>

{{/unless}}

{{!-- Hidden form used to POST to gzip url for download --}}
<form {{bind-attr action=gzipUrl}} method="post">
{{input name="code" value=output type="hidden"}}
</form>

</div>

</script>

<!-- build:js scripts/vendor.js -->
<script src="../bower_components/jquery/jquery.js"></script>
<script src="../bower_components/handlebars/handlebars.js"></script>

<!-- @if dist=false -->
<script src="../bower_components/ember/ember.js"></script>
<!-- @endif --><!-- @if dist=true -->
<script src="../bower_components/ember/ember.prod.js"></script>
<!-- @endif -->

<script src="../bower_components/filereader.js/filereader.js"></script>
<script src="../bower_components/FileSaver.js/FileSaver.js"></script>
<!-- endbuild -->

<!-- build:js scripts/app.js -->
<script src="../config/environment.js"></script>
<!-- @if dist=false -->
<script src="../config/environments/development.js"></script>
<!-- @endif --><!-- @if dist=true -->
<script src="../config/environments/production.js"></script>
<!-- @endif -->
<script src="scripts/app.js"></script>
<!-- endbuild -->

</body>
120 changes: 120 additions & 0 deletions app/scripts/app.js
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,120 @@
(function () {
'use strict';

var App = Ember.Application.create({
LOG_ACTIVE_GENERATION : true,
LOG_MODULE_RESOLVER : true,
LOG_TRANSITIONS : true,
LOG_TRANSITIONS_INTERNAL: true,
LOG_VIEW_LOOKUPS : true
});

App.Router.map(function() {
this.route('compressor', { path: '/' });
});

App.CompressorRoute = Ember.Route.extend();

App.CompressorController = Ember.Controller.extend({

placeholder: 'To get started, paste your JavaScript or CSS code here, or drag in files from your desktop.',

apiUrl: window.ENV.apiUrl,

gzipUrl: function () {
return this.get('apiUrl') + this.get('filename');
}.property('apiUrl', 'filename'),

saveDisabled: function () {
return !this.get('filename');
}.property('filename'),

displayLanguage: function () {

switch (this.get('language')) {
case 'javascript':
return 'JavaScript';
case 'css':
return 'CSS';
default:
return null;
}

}.property('language'),

compress: function () {
this.set('output', null);
this.set('language', null);
this.set('error', null);

this.set('isCompressing', true);

return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
url: this.get('apiUrl'),
type: 'post',
data: { code: this.get('input') },
dataType: 'json'
}).done(function (data) {
this.set('language', data.language);
this.set('output', data.code);
Ember.run(null, resolve);
}.bind(this)).fail(function (jqXHR) {
this.set('error', true);
this.set('output', JSON.stringify(jqXHR.responseJSON, null, 2));
Ember.run(null, reject);
}.bind(this)).always(function () {
this.set('isCompressing', false);
}.bind(this));
}.bind(this));
},

actions: {
compress: function () {
this.compress().then(function () {

var filename;

if (this.get('language') === 'css') {
filename = 'style.min.css';
} else {
filename = 'app.min.js';
}

this.set('filename', filename);

}.bind(this));
},
save: function () {
var blob = new Blob([this.get('output')], {type: 'text/' + this.get('language') + ';charset=utf-8'});
saveAs(blob, this.get('filename'));
},
saveGzip: function () {
Ember.$('form').trigger('submit');
},
clearOutput: function () {
this.set('output', null);
this.set('language', null);
}
}

});

// Allow users to drop files into textarea from desktop
App.DragAndDrop = Ember.TextArea.extend({
didInsertElement: function () {
this.$().fileReaderJS({
accept: 'text/*',
dragClass: 'dragging',
on: {
load: function (event) {
this.set('value', this.getWithDefault('value', '') + event.target.result);
}.bind(this),
}
});
}
});

window.App = App;

})();
3 changes: 3 additions & 0 deletions app/scss/app.scss
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,3 @@
.form-control.input.dragging {
background-color: #d9edf7;
}
24 changes: 24 additions & 0 deletions bower.json
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "refresh-sf",
"version": "0.0.0",
"authors": [
"Mike Horn <gpbmike@gmail.com>"
],
"license": "MIT",
"private": true,
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"dependencies": {
"ember": "~1.4.0",
"bootstrap": "~3.1.1",
"filereader.js": "bgrins/filereader.js",
"zeroclipboard": "~1.3.5",
"FileSaver.js": "eligrey/FileSaver.js",
"handlebars": "~1.3.0"
}
}
1 change: 1 addition & 0 deletions config/environment.js
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1 @@
window.ENV = {};
1 change: 1 addition & 0 deletions config/environments/development.js
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1 @@
window.ENV.apiUrl = 'http://localhost:3001/';
1 change: 1 addition & 0 deletions config/environments/production.js
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1 @@
window.ENV.apiUrl = 'http://refresh-sf.herokuapp.com/';
Loading

0 comments on commit 8b1f59e

Please sign in to comment.