Skip to content

Commit

Permalink
Improve documentation (code panes, examples)
Browse files Browse the repository at this point in the history
Code panes
==========

The message "Tip : check the source of the page !" wasn't really
friendly and the html source code isn't the best place to display
the code of our examples.

Now, the js fragment and the html fragment are separated from the main
page and are included (using jekyll includes) two times:

- as html or js content, to render the result
- inside jekyll's `highlight` tag to pretty print its content

Using a tab for each block, we keep the page length under control.

Argument and option examples
============================

In the API documentation pages, the return type moved just below the
description and a new line, "since", appeared.

(Almost) all arguments / options now have an example, illustrating (if
possible) what the option does.
For example, `createFolders` in `loadAsync()`: the explanation about
"virtual folders" helps only if you know how a zip file works. The
example will help a lot as it's what people usually see: sub folders or
not sub folders.

Next steps
==========

This commit helps with the options but doesn't lower the learning
curve. The next (documentation) step should be to add more (simple) examples
with real world use cases: with blob urls, canvas, list of promises,
etc.
  • Loading branch information
dduponchel committed Mar 1, 2017
1 parent 5250332 commit b0b10e4
Show file tree
Hide file tree
Showing 50 changed files with 1,280 additions and 676 deletions.
11 changes: 4 additions & 7 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,10 @@ module.exports = function(grunt) {
test: ['./test/helpers/**/*.js', './test/asserts/**/*.js'],
documentation: {
options: {
globals: {
jQuery: false,
JSZip: false,
JSZipUtils: false,
saveAs: false
},
// implied still give false positives in our case
// we include js files with jekyll, jshint can't see all
// variables and we can't declare all of them
undef: false,
// 'implied' still give false positives in our case
strict: false
},
files: {
Expand Down
17 changes: 9 additions & 8 deletions documentation/_layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,20 @@
<meta name="description" content="Create .zip files using Javascript. Provides a simple API to place any content generated by Javascript into a .zip file for your users." />
<title>{{page.title}}</title>

<!--
Any version of jQuery will do (it's just to write some examples), this one
happens to be available in our tests.
-->
<script type="text/javascript" src="{{site.baseurl}}/test/jquery-1.8.3.min.js"></script>

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">

<!-- Optional theme -->
<link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css">

<!-- Latest compiled and minified JavaScript -->
<!-- <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script> -->
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>

<link rel="stylesheet" href="{{site.baseurl}}/documentation/css/pygments.css">
<link rel="stylesheet" href="{{site.baseurl}}/documentation/css/main.css">
Expand All @@ -29,11 +35,6 @@
<script type="text/javascript" src="//stuk.github.io/jszip-utils/dist/jszip-utils-ie.js"></script>
<![endif]-->

<!--
Any version of jQuery will do (it's just to write some examples), this one
happens to be available in our tests.
-->
<script type="text/javascript" src="{{site.baseurl}}/test/jquery-1.8.3.min.js"></script>

<script type="text/javascript" src="{{site.baseurl}}/vendor/FileSaver.js"></script>
</head>
Expand Down Expand Up @@ -88,7 +89,7 @@ <h4>JSZip developers :</h4>
<li><a href="{{site.baseurl}}/documentation/api_jszip/file_name.html">JSZip#file(name)</a></li>
<li><a href="{{site.baseurl}}/documentation/api_jszip/file_regex.html">JSZip#file(regex)</a></li>
<li><a href="{{site.baseurl}}/documentation/api_jszip/file_data.html">JSZip#file(name, data [,options])</a></li>
<li><a href="{{site.baseurl}}/documentation/api_jszip/folder_data.html">JSZip#folder(name)</a></li>
<li><a href="{{site.baseurl}}/documentation/api_jszip/folder_name.html">JSZip#folder(name)</a></li>
<li><a href="{{site.baseurl}}/documentation/api_jszip/folder_regex.html">JSZip#folder(regex)</a></li>
<li><a href="{{site.baseurl}}/documentation/api_jszip/for_each.html">JSZip#forEach(callback)</a></li>
<li><a href="{{site.baseurl}}/documentation/api_jszip/filter.html">JSZip#filter(predicate)</a></li>
Expand All @@ -112,7 +113,7 @@ <h4>JSZip developers :</h4>
<li><a href="{{site.baseurl}}/documentation/api_streamhelper.html">StreamHelper</a>
<ul>
<li><a href="{{site.baseurl}}/documentation/api_streamhelper/on.html">StreamHelper#on(event, callback)</a></li>
<li><a href="{{site.baseurl}}/documentation/api_streamhelper/accumulate.html">StreamHelper#accumulate([updateCallback])</a></li>
<li><a href="{{site.baseurl}}/documentation/api_streamhelper/accumulate.html">StreamHelper#accumulate( [updateCallback])</a></li>
<li><a href="{{site.baseurl}}/documentation/api_streamhelper/resume.html">StreamHelper#resume()</a></li>
<li><a href="{{site.baseurl}}/documentation/api_streamhelper/pause.html">StreamHelper#pause()</a></li>
</ul>
Expand Down
10 changes: 3 additions & 7 deletions documentation/api_jszip/constructor.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,13 @@ layout: default
section: api
---

__Description__ : Create a new JSZip instance.

__Arguments__ : None
Create a new JSZip instance.

__Returns__ : A new JSZip.

__Throws__ : Nothing.

<!-- __Complexity__ : Object creation in **O(1)**. -->
__Since__: v1.0.0

__Example__
## Example

```js
var zip = new JSZip();
Expand Down
252 changes: 207 additions & 45 deletions documentation/api_jszip/file_data.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,15 @@ layout: default
section: api
---

__Description__ : Add (or update) a file to the zip file.
Add (or update) a file to the zip file.
If something goes wrong (the data is not in a supported format for example),
an exception will be propagated when accessing the data.

__Arguments__
__Returns__ : The current JSZip object, for chaining.

__Since__: v1.0.0

## Arguments

name | type | description
--------------------|---------|------------
Expand All @@ -18,57 +24,218 @@ Content of `options` :

name | type | default | description
------------|---------|---------|------------
base64 | boolean | `false` | set to `true` if the data is base64 encoded. For example image data from a `<canvas>` element. Plain text and HTML do not need this option.
binary | boolean | `false` | set to `true` if the data should be treated as raw content, `false` if this is a text. If base64 is used, this defaults to `true`, if the data is not a string, this will be set to `true`.
date | date | the current date | the last modification date.
compression | string | null | If set, specifies compression method to use for this specific file. If not, the default file compression will be used, see [generateAsync(options)]({{site.baseurl}}/documentation/api_jszip/generate_async.html).
compressionOptions | object | `null` | the options to use when compressing the file, see [generate(options)]({{site.baseurl}}/documentation/api_jszip/generate_async.html).
comment | string | null | The comment for this file.
base64 | boolean | `false` | set to `true` if the data is base64 encoded. For example image data from a `<canvas>` element. Plain text and HTML do not need this option. [More](#base64-option).
binary | boolean | `false` | set to `true` if the data should be treated as raw content, `false` if this is a text. If base64 is used, this defaults to `true`, if the data is not a string, this will be set to `true`. [More](#binary-option).
date | date | the current date | the last modification date. [More](#date-option).
compression | string | null | If set, specifies compression method to use for this specific file. If not, the default file compression will be used, see [generateAsync(options)]({{site.baseurl}}/documentation/api_jszip/generate_async.html). [More](#compression-and-compressionoptions-options).
compressionOptions | object | `null` | the options to use when compressing the file, see [generateAsync(options)]({{site.baseurl}}/documentation/api_jszip/generate_async.html). [More](#compression-and-compressionoptions-options).
comment | string | null | The comment for this file. [More](#comment-option).
optimizedBinaryString | boolean | `false` | Set to true if (and only if) the input is a "binary string" and has already been prepared with a 0xFF mask.
createFolders | boolean | `true` | Set to true if folders in the file path should be automatically created, otherwise there will only be virtual folders that represent the path to the file.
unixPermissions | 16 bits number | null | The UNIX permissions of the file, if any.
dosPermissions | 6 bits number | null | The DOS permissions of the file, if any.
dir | boolean | false | Set to true if this is a directory and content should be ignored.
createFolders | boolean | `true` | Set to true if folders in the file path should be automatically created, otherwise there will only be virtual folders that represent the path to the file. [More](#createfolders-option).
unixPermissions | 16 bits number | null | The UNIX permissions of the file, if any. [More](#unixpermissions-and-dospermissions-options).
dosPermissions | 6 bits number | null | The DOS permissions of the file, if any. [More](#unixpermissions-and-dospermissions-options).
dir | boolean | false | Set to true if this is a directory and content should be ignored. [More](#dir-option).

You shouldn't update the data given to this method : it is kept as it so any
### data input

You shouldn't update the data given to this method: it is kept as it so any
update will impact the stored data.

#### About Promise <small>since v3.0.0</small>

__For the permissions__ :
You can use a Promise of content directly to simplify async content handling.
Let's use HTTP calls as examples:

The field `unixPermissions` also accepts a string representing the octal value :
"644", "755", etc. On nodejs you can use the `mode` attribute of
[nodejs' fs.Stats](http://nodejs.org/api/fs.html#fs_class_fs_stats).
```js
/** with promises **/

See also [the platform option of generateAsync()]({{site.baseurl}}/documentation/api_jszip/generate_async.html).
// instead of
$.get("url/to.file.txt") // jQuery v3 returns promises
.then(function (content) {
zip.file("file.txt", content);
})

// you can do
var promise = $.get("url/to.file.txt");
zip.file("file.txt", promise);
```

__About `dir`__ :
```js
/** with callbacks **/

If `dir` is true or if a permission says it's a folder, this entry be flagged
as a folder and the content will be ignored.
// instead of
request('url/to.file.txt', function (error, response, body) {
zip.file("file.txt", body);
});

__About nodejs stream__:
// you can do
var promise = new Promise(function (resolve, reject) {
request('url/to.file.txt', function (error, response, body) {
if (error) {
reject(error);
} else {
resolve(body);
}
});
});
zip.file("file.txt", promise);
```

#### About Blob <small>since v3.0.0</small>

You can use directly [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)
as input, no need to use a `FileReader`.
[File](https://developer.mozilla.org/en-US/docs/Web/API/File) objects are Blobs
so you can use them directly:

```js
// in a change callback of a <input type="file">
var files = evt.target.files;
for (var i = 0; i < files.length; i++) {
var f = files[i];
zip.file(f.name, f);
}
```

#### About nodejs stream <small>since v3.0.0</small>

A stream can't be restarted: if it is used once, it can't be used again (
by [generateAsync()]({{site.baseurl}}/documentation/api_jszip/generate_async.html)
or by [ZipObject methods]({{site.baseurl}}/documentation/api_zipobject.html)).
In that case, the promise/stream (depending on the method called) will get
an error.

__Returns__ : The current JSZip object, for chaining.

__Throws__ : Nothing. (an exception will be propagated if the data is not in
a supported format).
### `base64` option

```js
var zip = new JSZip();
zip.file("hello.txt", "aGVsbG8gd29ybGQK", {base64: true});
```

### `binary` option

```js
var zip = new JSZip();

// here, we have a correct (unicode) string
zip.file("hello.txt", "unicode ♥", {binary: false});

// here, we have a binary string: it can contain binary content, one byte
// per character.
zip.file("hello.txt", "unicode \xE2\x99\xA5", {binary: true});
```

If you use a library that returns a binary string for example, you should use
this option. Otherwise, you will get a corrupted result: JSZip will try to
encode this string with UTF-8 when the content doesn't need to.

### `date` option

```js
zip.file("Xmas.txt", "Ho ho ho !", {
date: new Date("December 25, 2007 00:00:01")
});
```

### `compression` and `compressionOptions` options

See also the same options on [`JSZip#generateAsync()`]({{site.baseurl}}/documentation/api_jszip/generate_async.html#compression-and-compressionoptions-options).

These options will be used when generating a zip file. They let you override
entry per entry the compression / compression options to use.

```js
zip.file("a.png", contentOfA, {
compression: "STORE" // force a compression for this file
});
zip.file("b.txt", contentOfA, {
compression: "DEFLATE",
compressionOptions: {
level: 9 // force a compression and a compression level for this file
}
});

// don't force anything, use the generateAsync options
zip.file("c.txt", contentOfB);

<!--
__Complexity__ : **O(1)** for anything but binary strings.
For binary strings (`data` is a string and `binary` = true), if
`optimizedBinaryString` is not set, the 0xFF mask will be applied giving a
complexity in **O(n)** where n is the size of the added data.
-->
// here:
// - a.png will not be compressed (STORE)
// - b.txt will be compressed at maximum level
// - c.txt will be compressed with the default compression level
zip.generateAsync({
type: "blob",
compression: "DEFLATE"
});
```

__Example__
### `comment` option

```js
zip.file("a.txt", "content", {
comment: "comment of a.txt"
});
```

### `createFolders` option

```js
zip.file("a/b/c/d.txt", "content", {
createFolders: true // default value
});
console.log(zip.files);
// will display:
// - a/
// - a/b/
// - a/b/c/
// - a/b/c/d.txt


zip.file("a/b/c/d.txt", "content", {
createFolders: false
});
console.log(zip.files);
// will display:
// - a/b/c/d.txt
```

### `unixPermissions` and `dosPermissions` options

Each permission will be used for matching [platform option of generateAsync()]({{site.baseurl}}/documentation/api_jszip/generate_async.html):
on `DOS`, use `dosPermissions`, on `UNIX`, use `unixPermissions`.

On nodejs you can use the `mode` attribute of
[nodejs' fs.Stats](http://nodejs.org/api/fs.html#fs_class_fs_stats).

When not set, a default value will be generated:

- `0100664` or `040775` for `UNIX`
- standard file or standard directory for `DOS`

The field `unixPermissions` also accepts a **string** representing the
octal value: "644", "755", etc.

```js
zip.file("script.sh", "#!/bin/bash", {
unixPermissions: "755"
});
```


### `dir` option

If `dir` is true or if a permission says it's a folder, this entry be flagged
as a folder and the content will be ignored.

See also [folder(name)]({{site.baseurl}}/documentation/api_jszip/folder_name.html).

```js
zip.file("folder/", null, {
dir: true
});
```

## Other examples

```js
zip.file("Hello.txt", "Hello World\n");
Expand All @@ -85,17 +252,12 @@ zip.file("folder/file.txt", "file in folder");

zip.file("animals.txt", "dog,platypus\n").file("people.txt", "james,sebastian\n");

// result : Hello.txt, smile.gif, Xmas.txt, animals.txt, people.txt,
// folder/, folder/file.txt
// In the above case, the "folder" folder will not have a 'D'irectory attribute or Method property. The
// folder only exists as part of the path to "file.txt".

zip.file("folder/file.txt", "file in folder", {createFolders: true});
// In this case, the "folder" folder WILL have a 'D'irectory attribute and a Method property of "store".
// It will exist whether or not "file.txt" is present.

zip.file("script.sh", "echo 'hello world'", {
unixPermissions : "755"
});
// when generated with platform:UNIX, the script.sh file will be executable
// result:
// - Hello.txt
// - smile.gif
// - Xmas.txt
// - animals.txt
// - people.txt
// - folder/
// - folder/file.txt
```
Loading

0 comments on commit b0b10e4

Please sign in to comment.