Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
7 changes: 6 additions & 1 deletion Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@ module.exports = function(grunt) {
__filename: undefined,
__dirname: undefined
},
builtins: false
builtins: false,
// ignore the "browser" field of package.json:
// it redirects ./lib/index to the previously
// released dist/jszip.min.js, so the fresh build
// would bundle the old code
browserField: false
},
banner: grunt.file.read("lib/license_header.js").replace(/__VERSION__/, version)
}
Expand Down
32 changes: 27 additions & 5 deletions documentation/api_jszip/folder_name.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: "folder(name)"
title: "folder(name [,options])"
layout: default
section: api
---
Expand All @@ -15,9 +15,29 @@ __Since__: v1.0.0

## Arguments

name | type | description
-----|--------|------------
name | string | the name of the directory.
name | type | description
--------|--------|------------
name | string | the name of the directory.
options | object | the options.

Content of `options` :

name | type | default | description
------------|---------|---------|------------
date | date | the current date | the last modification date.
comment | string | null | The comment for this folder.
createFolders | boolean | `true` | Set to true if folders in the folder path should be automatically created, otherwise there will only be virtual folders that represent the path to the folder.
unixPermissions | 16 bits number | null | The UNIX permissions of the folder, if any.
dosPermissions | 6 bits number | null | The DOS permissions of the folder, if any.

Options such as `unixPermissions`, `dosPermissions`, `date` or `comment` only
apply to the specified folder, not to the automatically created parent
folders: `zip.folder("a/b", options)` behaves like
`zip.folder("a").folder("b", options)`. If the folder already exists, the
options are ignored.

See [file(name, data [,options])]({{site.baseurl}}/documentation/api_jszip/file_data.html)
for the details of these options.

## Examples

Expand All @@ -26,7 +46,9 @@ zip.folder("images");
zip.folder("css").file("style.css", "body {background: #FF0000}");
// or specify an absolute path (using forward slashes)
zip.file("css/font.css", "body {font-family: sans-serif}")
// or create a folder with options
zip.folder("executables", {unixPermissions: "40755"});

// result : images/, css/, css/style.css, css/font.css
// result : images/, css/, css/style.css, css/font.css, executables/
```

20 changes: 19 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,23 @@ declare namespace JSZip {
unixPermissions?: number | string | null;
}

interface JSZipFolderOptions {
/**
* The last modification date, defaults to the current date.
*/
date?: Date;
comment?: string;
/** Set to `true` if folders in the folder path should be automatically created, otherwise there will only be virtual folders that represent the path to the folder. */
createFolders?: boolean;
/** 6 bits number. The DOS permissions of the folder, if any. */
dosPermissions?: number | null;
/**
* 16 bits number. The UNIX permissions of the folder, if any.
* Also accepts a `string` representing the octal value: `"644"`, `"755"`, etc.
*/
unixPermissions?: number | string | null;
}

interface JSZipObjectOptions {
compression: Compression;
}
Expand Down Expand Up @@ -240,9 +257,10 @@ interface JSZip {
* Returns an new JSZip instance with the given folder as root
*
* @param name Name of the folder
* @param options Folder options, only applied to this folder and not to the automatically created sub folders
* @return New JSZip object with the given folder as root or null
*/
folder(name: string): JSZip | null;
folder(name: string, options?: JSZip.JSZipFolderOptions): JSZip | null;

/**
* Returns new JSZip instances with the matching folders as root
Expand Down
16 changes: 11 additions & 5 deletions lib/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,19 +134,23 @@ var forceTrailingSlash = function(path) {
* @param {string} name the folder's name
* @param {boolean=} [createFolders] If true, automatically create sub
* folders. Defaults to false.
* @param {Object=} options the options to use for this folder, only applied
* to this folder and not to the automatically created sub folders.
* @return {Object} the new folder.
*/
var folderAdd = function(name, createFolders) {
var folderAdd = function(name, createFolders, options) {
createFolders = (typeof createFolders !== "undefined") ? createFolders : defaults.createFolders;

name = forceTrailingSlash(name);

// Does this folder already exist?
if (!this.files[name]) {
fileAdd.call(this, name, null, {
dir: true,
var o = utils.extend(options || {}, {
createFolders: createFolders
});
// a folder stays a folder, whatever the options say
o.dir = true;
fileAdd.call(this, name, null, o);
}
return this.files[name];
};
Expand Down Expand Up @@ -244,9 +248,11 @@ var out = {
/**
* Add a directory to the zip file, or search.
* @param {String|RegExp} arg The name of the directory to add, or a regex to search folders.
* @param {Object=} options Folder options, only applied to this folder
* and not to the automatically created sub folders.
* @return {JSZip} an object with the new directory as the root, or an array containing matching folders.
*/
folder: function(arg) {
folder: function(arg, options) {
if (!arg) {
return this;
}
Expand All @@ -259,7 +265,7 @@ var out = {

// else, name is a new folder
var name = this.root + arg;
var newFolder = folderAdd.call(this, name);
var newFolder = folderAdd.call(this, name, undefined, options);

// Allow chaining by returning a new object with this folder as the root
var ret = this.clone();
Expand Down
65 changes: 63 additions & 2 deletions test/asserts/file.js
Original file line number Diff line number Diff line change
Expand Up @@ -636,13 +636,74 @@ QUnit.module("file", function () {
unixPermissions : parseInt("40500", 8)
});

// calling folder() doesn't override it
zip.folder("folder");
// calling folder() doesn't override it, even with options
zip.folder("folder", {
comment : "new comment",
unixPermissions : "40755"
});

assert.equal(zip.files["folder/"].comment, referenceComment, "the folder with options has the correct comment");
assert.equal(zip.files["folder/"].unixPermissions.toString(8), "40500", "the folder with options has the correct UNIX permissions");
});

QUnit.test("folder() accepts options", function (assert) {
var referenceDate = new Date("July 17, 2009 14:36:57");
var zip = new JSZip();
zip.folder("unix", {
comment : "my comment",
date : referenceDate,
unixPermissions : "40755"
});
zip.folder("dos", {
dosPermissions : 16
});

assert.equal(zip.files["unix/"].dir, true, "the folder with options is marked as a folder");
assert.equal(zip.files["unix/"].comment, "my comment", "the folder with options has the correct comment");
assert.equal(zip.files["unix/"].date.getTime(), referenceDate.getTime(), "the folder with options has the correct date");
assert.equal(zip.files["unix/"].unixPermissions.toString(8), "40755", "the folder with options has the correct UNIX permissions");
assert.equal(zip.files["dos/"].dir, true, "the folder with DOS options is marked as a folder");
assert.equal(zip.files["dos/"].dosPermissions, 16, "the folder with options has the correct DOS permissions");
});

QUnit.test("folder() options apply to the folder, not to the created sub folders", function (assert) {
var zip = new JSZip();
zip.folder("0/1/folder", {unixPermissions : "40755"});

assert.equal(zip.files["0/"].unixPermissions, null, "0/ has no UNIX permissions");
assert.equal(zip.files["0/1/"].unixPermissions, null, "0/1/ has no UNIX permissions");
assert.equal(zip.files["0/1/folder/"].unixPermissions.toString(8), "40755", "the folder has the correct UNIX permissions");
});

QUnit.test("nested folder() options work like chained folder() calls", function (assert) {
var nested = new JSZip();
nested.folder("0/1/folder", {unixPermissions : "40755"});
var chained = new JSZip();
chained.folder("0").folder("1").folder("folder", {unixPermissions : "40755"});

["0/", "0/1/", "0/1/folder/"].forEach(function (name) {
assert.equal(
nested.files[name].unixPermissions,
chained.files[name].unixPermissions,
name + " has the same UNIX permissions"
);
});
});

QUnit.test("folder() options survive a reload", function (assert) {
var zip = new JSZip();
zip.folder("folder", {unixPermissions : "40755"});

var done = assert.async();

zip.generateAsync({type:"binarystring", platform:"UNIX"})
.then(JSZip.loadAsync)
.then(function (reloaded) {
assert.equal(reloaded.files["folder/"].unixPermissions.toString(8), "40755", "the folder has the correct UNIX permissions");
done();
})["catch"](JSZipTestUtils.assertNoError);
});

QUnit.test("createFolders works on a file", function (assert) {
var zip = new JSZip();
zip.file("false/0/1/2/file", "content", {createFolders:false, unixPermissions:"644"});
Expand Down