@ -1,13 +1,15 @@
/ * !
/ * !
Papa Parse
Papa Parse
v4 . 1.2 - PRE - RELEASE
v4 . 1.2
https : //github.com/mholt/PapaParse
https : //github.com/mholt/PapaParse
* /
* /
( function ( global )
( function ( global )
{
{
"use strict" ;
"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 workers = { } , workerIdCounter = 0 ;
var Papa = { } ;
var Papa = { } ;
@ -19,7 +21,7 @@
Papa . UNIT _SEP = String . fromCharCode ( 31 ) ;
Papa . UNIT _SEP = String . fromCharCode ( 31 ) ;
Papa . BYTE _ORDER _MARK = "\ufeff" ;
Papa . BYTE _ORDER _MARK = "\ufeff" ;
Papa . BAD _DELIMITERS = [ "\r" , "\n" , "\"" , Papa . BYTE _ORDER _MARK ] ;
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
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
// Configurable chunk sizes for local and remote files, respectively
@ -145,7 +147,7 @@
}
}
if ( IS _WORKER )
if ( IS _PAPA _ WORKER )
{
{
global . onmessage = workerThreadReceivedMessage ;
global . onmessage = workerThreadReceivedMessage ;
}
}
@ -223,9 +225,15 @@
var _fields = [ ] ;
var _fields = [ ] ;
// Default configuration
// Default configuration
var _quotes = false ; // whether to surround every datum with quotes
var _delimiter = "," ; // delimiting character
/** whether to surround every datum with quotes */
var _newline = "\r\n" ; // newline character(s)
var _quotes = false ;
/** delimiting character */
var _delimiter = "," ;
/** newline character(s) */
var _newline = "\r\n" ;
unpackConfig ( ) ;
unpackConfig ( ) ;
@ -283,7 +291,7 @@
}
}
// Turns an object's keys into an array
/** Turns an object's keys into an array */
function objectKeys ( obj )
function objectKeys ( obj )
{
{
if ( typeof obj !== 'object' )
if ( typeof obj !== 'object' )
@ -294,7 +302,7 @@
return keys ;
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 )
function serialize ( fields , data )
{
{
var csv = "" ;
var csv = "" ;
@ -340,7 +348,7 @@
return csv ;
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 )
function safe ( str , col )
{
{
if ( typeof str === "undefined" || str === null )
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 )
function ChunkStreamer ( config )
{
{
this . _handle = null ;
this . _handle = null ;
@ -420,7 +428,7 @@
var finishedIncludingPreview = this . _finished || ( this . _config . preview && this . _rowCount >= this . _config . preview ) ;
var finishedIncludingPreview = this . _finished || ( this . _config . preview && this . _rowCount >= this . _config . preview ) ;
if ( IS _WORKER )
if ( IS _PAPA _ WORKER )
{
{
global . postMessage ( {
global . postMessage ( {
results : results ,
results : results ,
@ -456,7 +464,7 @@
{
{
if ( isFunction ( this . _config . error ) )
if ( isFunction ( this . _config . error ) )
this . _config . error ( error ) ;
this . _config . error ( error ) ;
else if ( IS _WORKER && this . _config . error )
else if ( IS _PAPA _ WORKER && this . _config . error )
{
{
global . postMessage ( {
global . postMessage ( {
workerId : Papa . WORKER _ID ,
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)
* Parses input . Most users won 't need, and shouldn' t mess with , the baseIndex
// when an input comes in multiple chunks, like from a file.
* 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 )
this . parse = function ( input , baseIndex , ignoreLastRow )
{
{
if ( ! _config . newline )
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 )
if ( ( typeof bestDelta === 'undefined' || delta < bestDelta )
&& avgFieldCount > 1.99 )
&& 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 )
function Parser ( config )
{
{
// Unpack the config object
// Unpack the config object
@ -1185,13 +1196,15 @@
lastCursor = cursor ;
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 )
function finish ( value )
{
{
if ( ignoreLastRow )
if ( ignoreLastRow )
return returnable ( ) ;
return returnable ( ) ;
if ( ! value )
if ( typeof value === 'undefined' )
value = input . substr ( cursor ) ;
value = input . substr ( cursor ) ;
row . push ( value ) ;
row . push ( value ) ;
cursor = inputLen ; // important in case parsing is paused
cursor = inputLen ; // important in case parsing is paused
@ -1201,10 +1214,12 @@
return returnable ( ) ;
return returnable ( ) ;
}
}
// Appends the current row to the results. It sets the cursor
/ * *
// to newCursor and finds the nextNewline. The caller should
* Appends the current row to the results . It sets the cursor
// take care to execute user's step function and check for
* to newCursor and finds the nextNewline . The caller should
// preview and end parsing if necessary.
* take care to execute user ' s step function and check for
* preview and end parsing if necessary .
* /
function saveRow ( newCursor )
function saveRow ( newCursor )
{
{
cursor = newCursor ;
cursor = newCursor ;
@ -1213,7 +1228,7 @@
nextNewline = input . indexOf ( newline , cursor ) ;
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 )
function returnable ( stopped )
{
{
return {
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 ( )
function doStep ( )
{
{
step ( returnable ( ) ) ;
step ( returnable ( ) ) ;
@ -1237,13 +1252,13 @@
}
}
} ;
} ;
// Sets the abort flag
/** Sets the abort flag */
this . abort = function ( )
this . abort = function ( )
{
{
aborted = true ;
aborted = true ;
} ;
} ;
// Gets the cursor position
/** Gets the cursor position */
this . getCharIndex = function ( )
this . getCharIndex = function ( )
{
{
return cursor ;
return cursor ;
@ -1268,14 +1283,17 @@
'Script path cannot be determined automatically when Papa Parse is loaded asynchronously. ' +
'Script path cannot be determined automatically when Papa Parse is loaded asynchronously. ' +
'You need to set Papa.SCRIPT_PATH manually.'
'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 . onmessage = mainThreadReceivedMessage ;
w . id = workerIdCounter ++ ;
w . id = workerIdCounter ++ ;
workers [ w . id ] = w ;
workers [ w . id ] = w ;
return w ;
return w ;
}
}
// Callback when main thread receives a message
/** Callback when main thread receives a message */
function mainThreadReceivedMessage ( e )
function mainThreadReceivedMessage ( e )
{
{
var msg = e . data ;
var msg = e . data ;
@ -1334,7 +1352,7 @@
throw "Not implemented." ;
throw "Not implemented." ;
}
}
// Callback when worker thread receives a message
/** Callback when worker thread receives a message */
function workerThreadReceivedMessage ( e )
function workerThreadReceivedMessage ( e )
{
{
var msg = e . data ;
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 )
function copy ( obj )
{
{
if ( typeof obj !== 'object' )
if ( typeof obj !== 'object' )
@ -1382,4 +1400,4 @@
{
{
return typeof func === 'function' ;
return typeof func === 'function' ;
}
}
} ) ( typeof window !== 'undefined' ? window : this ) ;
} ) ( typeof window !== 'undefined' ? window : this ) ;