Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #8 - Separate javascript and css from directory.html #9

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 53 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,28 @@ var defaultTemplate = join(__dirname, 'public', 'directory.html');

var defaultStylesheet = join(__dirname, 'public', 'style.css');

/*!
* Stylesheet.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has the wrong comment.

*/

var defaultScript = join(__dirname, 'public', 'script.js');

/**
* Media types and the map for content negotiation.
*/

var mediaTypes = [
'text/css',
'text/html',
'text/javascript',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these from mediaTypes; this array for for content-negoiation on the page itself.

'text/plain',
'application/json'
];

var mediaType = {
'text/css': 'css',
'text/html': 'html',
'text/javascript': 'javascript',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove these; see above.

'text/plain': 'plain',
'application/json': 'json'
};
Expand All @@ -81,7 +91,8 @@ exports = module.exports = function directory(root, options){
, filter = options.filter
, root = normalize(root + sep)
, template = options.template || defaultTemplate
, stylesheet = options.stylesheet || defaultStylesheet;
, stylesheet = options.stylesheet || defaultStylesheet
, script = options.script || defaultScript;

return function directory(req, res, next) {
if ('GET' != req.method && 'HEAD' != req.method) return next();
Expand Down Expand Up @@ -117,9 +128,14 @@ exports = module.exports = function directory(root, options){
// content-negotiation
var type = new Negotiator(req).preferredMediaType(mediaTypes);

// take custom types from the url
// e.g /?text/css
var mediaTypeFromUrl = req.url.replace(/^.+\?/, '');
if (mediaTypes.indexOf(mediaTypeFromUrl) !== -1) type = mediaTypeFromUrl;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be done a different way, because it should not use content-negoiation.


// not acceptable
if (!type) return next(createError(406));
exports[mediaType[type]](req, res, files, next, originalDir, showUp, icons, path, view, template, stylesheet);
exports[mediaType[type]](req, res, files, next, originalDir, showUp, icons, path, view, template, stylesheet, script);
});
});
};
Expand Down Expand Up @@ -152,6 +168,41 @@ exports.html = function(req, res, files, next, dir, showUp, icons, path, view, t
});
};

/**
* Respond with text/css.
*/

exports.css = function (req, res, files, next, dir, showUp, icons, path, view, template, stylesheet){
fs.readFile(stylesheet, 'utf8', function (err, style) {
if (err) return next(err);
stat(path, files, function (err, stats){
if (err) return next(err);
files = files.map(function (file, i){
return { name: file, stat: stats[i] };
});
files.sort(fileSort);
if (showUp) files.unshift({ name: '..' });
var str = style.concat(iconStyle(files, icons));
res.setHeader('Content-Type', 'text/css');
res.setHeader('Content-Length', str.length);
res.end(str);
});
});
};

/**
* Respond with text/javascript.
*/

exports.javascript = function (req, res, files, next, dir, showUp, icons, path, view, template, stylesheet, script){
fs.readFile(script, 'utf8', function (err, script){
if (err) return next(err);
res.setHeader('Content-Type', 'text/javascript');
res.setHeader('Content-Length', script.length);
res.end(script);
});
};

/**
* Respond with application/json.
*/
Expand Down
69 changes: 2 additions & 67 deletions public/directory.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,73 +4,8 @@
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>listing directory {directory}</title>
<style>{style}</style>
<script>
function $(id){
var el = 'string' == typeof id
? document.getElementById(id)
: id;

el.on = function(event, fn){
if ('content loaded' == event) {
event = window.attachEvent ? "load" : "DOMContentLoaded";
}
el.addEventListener
? el.addEventListener(event, fn, false)
: el.attachEvent("on" + event, fn);
};

el.all = function(selector){
return $(el.querySelectorAll(selector));
};

el.each = function(fn){
for (var i = 0, len = el.length; i < len; ++i) {
fn($(el[i]), i);
}
};

el.getClasses = function(){
return this.getAttribute('class').split(/\s+/);
};

el.addClass = function(name){
var classes = this.getAttribute('class');
el.setAttribute('class', classes
? classes + ' ' + name
: name);
};

el.removeClass = function(name){
var classes = this.getClasses().filter(function(curr){
return curr != name;
});
this.setAttribute('class', classes.join(' '));
};

return el;
}

function search() {
var str = $('search').value
, links = $('files').all('a');

links.each(function(link){
var text = link.textContent;

if ('..' == text) return;
if (str.length && ~text.indexOf(str)) {
link.addClass('highlight');
} else {
link.removeClass('highlight');
}
});
}

$(window).on('content loaded', function(){
$('search').on('keyup', search);
});
</script>
<link rel="stylesheet" type="text/css" href="?text/css">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<style>{style}</style> needs to be kept for backwards-compatibility, so if you can figure out a way to keep this and not do the inline styles by default, that'd be awesome. People use their own exports.html that do a replacement on the {style} token currently.

<script src="?text/javascript"></script>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These URLs should probably be ?get=stylesheet and ?get=javascript or some such.

</head>
<body class="directory">
<input id="search" type="text" placeholder="Search" autocomplete="off" />
Expand Down
64 changes: 64 additions & 0 deletions public/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
function $(id){
var el = 'string' == typeof id
? document.getElementById(id)
: id;

el.on = function(event, fn){
if ('content loaded' == event) {
event = window.attachEvent ? "load" : "DOMContentLoaded";
}
el.addEventListener
? el.addEventListener(event, fn, false)
: el.attachEvent("on" + event, fn);
};

el.all = function(selector){
return $(el.querySelectorAll(selector));
};

el.each = function(fn){
for (var i = 0, len = el.length; i < len; ++i) {
fn($(el[i]), i);
}
};

el.getClasses = function(){
return this.getAttribute('class').split(/\s+/);
};

el.addClass = function(name){
var classes = this.getAttribute('class');
el.setAttribute('class', classes
? classes + ' ' + name
: name);
};

el.removeClass = function(name){
var classes = this.getClasses().filter(function(curr){
return curr != name;
});
this.setAttribute('class', classes.join(' '));
};

return el;
}

function search() {
var str = $('search').value
, links = $('files').all('a');

links.each(function(link){
var text = link.textContent;

if ('..' == text) return;
if (str.length && ~text.indexOf(str)) {
link.addClass('highlight');
} else {
link.removeClass('highlight');
}
});
}

$(window).on('content loaded', function(){
$('search').on('keyup', search);
});