diff --git a/.gitignore b/.gitignore
index 4895fd2..de467b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
.DS_Store
-_gitignore/
\ No newline at end of file
+_gitignore/
+node_modules/
\ No newline at end of file
diff --git a/faq.html b/faq.html
index 7ca20d1..246fe87 100644
--- a/faq.html
+++ b/faq.html
@@ -177,7 +177,7 @@
- Streaming remote files also requires the Content-Range header in the server's response. Most production-ready servers support this header, but Python's SimpleHTTPServer does not. If you need a quick and easy server, spark will do the trick: $ ./spark
+ Streaming remote files also requires the Content-Range header in the server's response. Most production-ready servers support this header, but Python's SimpleHTTPServer does not. If you need a quick and easy server, Caddy will do the trick: $ caddy
Can I pause and resume parsing?
diff --git a/resources/js/papaparse.js b/resources/js/papaparse.js
index 94faad6..5d09354 100644
--- a/resources/js/papaparse.js
+++ b/resources/js/papaparse.js
@@ -1,13 +1,15 @@
/*!
Papa Parse
- v4.1.2 - PRE-RELEASE
+ v4.1.2
https://github.com/mholt/PapaParse
*/
(function(global)
{
"use strict";
- var IS_WORKER = (!global.document && !!global.postMessage), LOADED_SYNC = false, AUTO_SCRIPT_PATH;
+ var IS_WORKER = !global.document && !!global.postMessage,
+ IS_PAPA_WORKER = IS_WORKER && /(\?|&)papaworker(=|&|$)/.test(global.location.search),
+ LOADED_SYNC = false, AUTO_SCRIPT_PATH;
var workers = {}, workerIdCounter = 0;
var Papa = {};
@@ -19,7 +21,7 @@
Papa.UNIT_SEP = String.fromCharCode(31);
Papa.BYTE_ORDER_MARK = "\ufeff";
Papa.BAD_DELIMITERS = ["\r", "\n", "\"", Papa.BYTE_ORDER_MARK];
- Papa.WORKERS_SUPPORTED = !!global.Worker;
+ Papa.WORKERS_SUPPORTED = !IS_WORKER && !!global.Worker;
Papa.SCRIPT_PATH = null; // Must be set by your code if you use workers and this lib is loaded asynchronously
// Configurable chunk sizes for local and remote files, respectively
@@ -145,7 +147,7 @@
}
- if (IS_WORKER)
+ if (IS_PAPA_WORKER)
{
global.onmessage = workerThreadReceivedMessage;
}
@@ -223,9 +225,15 @@
var _fields = [];
// Default configuration
- var _quotes = false; // whether to surround every datum with quotes
- var _delimiter = ","; // delimiting character
- var _newline = "\r\n"; // newline character(s)
+
+ /** whether to surround every datum with quotes */
+ var _quotes = false;
+
+ /** delimiting character */
+ var _delimiter = ",";
+
+ /** newline character(s) */
+ var _newline = "\r\n";
unpackConfig();
@@ -283,7 +291,7 @@
}
- // Turns an object's keys into an array
+ /** Turns an object's keys into an array */
function objectKeys(obj)
{
if (typeof obj !== 'object')
@@ -294,7 +302,7 @@
return keys;
}
- // The double for loop that iterates the data and writes out a CSV string including header row
+ /** The double for loop that iterates the data and writes out a CSV string including header row */
function serialize(fields, data)
{
var csv = "";
@@ -340,7 +348,7 @@
return csv;
}
- // Encloses a value around quotes if needed (makes a value safe for CSV insertion)
+ /** Encloses a value around quotes if needed (makes a value safe for CSV insertion) */
function safe(str, col)
{
if (typeof str === "undefined" || str === null)
@@ -367,7 +375,7 @@
}
}
- // ChunkStreamer is the base prototype for various streamer implementations.
+ /** ChunkStreamer is the base prototype for various streamer implementations. */
function ChunkStreamer(config)
{
this._handle = null;
@@ -420,7 +428,7 @@
var finishedIncludingPreview = this._finished || (this._config.preview && this._rowCount >= this._config.preview);
- if (IS_WORKER)
+ if (IS_PAPA_WORKER)
{
global.postMessage({
results: results,
@@ -456,7 +464,7 @@
{
if (isFunction(this._config.error))
this._config.error(error);
- else if (IS_WORKER && this._config.error)
+ else if (IS_PAPA_WORKER && this._config.error)
{
global.postMessage({
workerId: Papa.WORKER_ID,
@@ -721,9 +729,11 @@
};
}
- // Parses input. Most users won't need, and shouldn't mess with, the baseIndex
- // and ignoreLastRow parameters. They are used by streamers (wrapper functions)
- // when an input comes in multiple chunks, like from a file.
+ /**
+ * Parses input. Most users won't need, and shouldn't mess with, the baseIndex
+ * and ignoreLastRow parameters. They are used by streamers (wrapper functions)
+ * when an input comes in multiple chunks, like from a file.
+ */
this.parse = function(input, baseIndex, ignoreLastRow)
{
if (!_config.newline)
@@ -905,7 +915,8 @@
}
}
- avgFieldCount /= preview.data.length;
+ if (preview.data.length > 0)
+ avgFieldCount /= preview.data.length;
if ((typeof bestDelta === 'undefined' || delta < bestDelta)
&& avgFieldCount > 1.99)
@@ -963,7 +974,7 @@
- // The core parser implements speedy and correct CSV parsing
+ /** The core parser implements speedy and correct CSV parsing */
function Parser(config)
{
// Unpack the config object
@@ -1185,13 +1196,15 @@
lastCursor = cursor;
}
- // Appends the remaining input from cursor to the end into
- // row, saves the row, calls step, and returns the results.
+ /**
+ * Appends the remaining input from cursor to the end into
+ * row, saves the row, calls step, and returns the results.
+ */
function finish(value)
{
if (ignoreLastRow)
return returnable();
- if (!value)
+ if (typeof value === 'undefined')
value = input.substr(cursor);
row.push(value);
cursor = inputLen; // important in case parsing is paused
@@ -1201,10 +1214,12 @@
return returnable();
}
- // Appends the current row to the results. It sets the cursor
- // to newCursor and finds the nextNewline. The caller should
- // take care to execute user's step function and check for
- // preview and end parsing if necessary.
+ /**
+ * Appends the current row to the results. It sets the cursor
+ * to newCursor and finds the nextNewline. The caller should
+ * take care to execute user's step function and check for
+ * preview and end parsing if necessary.
+ */
function saveRow(newCursor)
{
cursor = newCursor;
@@ -1213,7 +1228,7 @@
nextNewline = input.indexOf(newline, cursor);
}
- // Returns an object with the results, errors, and meta.
+ /** Returns an object with the results, errors, and meta. */
function returnable(stopped)
{
return {
@@ -1229,7 +1244,7 @@
};
}
- // Executes the user's step function and resets data & errors.
+ /** Executes the user's step function and resets data & errors. */
function doStep()
{
step(returnable());
@@ -1237,13 +1252,13 @@
}
};
- // Sets the abort flag
+ /** Sets the abort flag */
this.abort = function()
{
aborted = true;
};
- // Gets the cursor position
+ /** Gets the cursor position */
this.getCharIndex = function()
{
return cursor;
@@ -1268,14 +1283,17 @@
'Script path cannot be determined automatically when Papa Parse is loaded asynchronously. ' +
'You need to set Papa.SCRIPT_PATH manually.'
);
- var w = new global.Worker(Papa.SCRIPT_PATH || AUTO_SCRIPT_PATH);
+ var workerUrl = Papa.SCRIPT_PATH || AUTO_SCRIPT_PATH;
+ // Append "papaworker" to the search string to tell papaparse that this is our worker.
+ workerUrl += (workerUrl.indexOf('?') !== -1 ? '&' : '?') + 'papaworker';
+ var w = new global.Worker(workerUrl);
w.onmessage = mainThreadReceivedMessage;
w.id = workerIdCounter++;
workers[w.id] = w;
return w;
}
- // Callback when main thread receives a message
+ /** Callback when main thread receives a message */
function mainThreadReceivedMessage(e)
{
var msg = e.data;
@@ -1334,7 +1352,7 @@
throw "Not implemented.";
}
- // Callback when worker thread receives a message
+ /** Callback when worker thread receives a message */
function workerThreadReceivedMessage(e)
{
var msg = e.data;
@@ -1362,7 +1380,7 @@
}
}
- // Makes a deep copy of an array or object (mostly)
+ /** Makes a deep copy of an array or object (mostly) */
function copy(obj)
{
if (typeof obj !== 'object')
@@ -1382,4 +1400,4 @@
{
return typeof func === 'function';
}
-})(typeof window !== 'undefined' ? window : this);
\ No newline at end of file
+})(typeof window !== 'undefined' ? window : this);