@ -1,3 +1,6 @@
import { Msg } from "../../foundation/message" ;
import { shortcut , Widget , some , extend } from "@/core" ;
/ * *
* 文件
*
@ -6,27 +9,22 @@
* @ extends BI . Single
* @ abstract
* /
import { shortcut , Widget , some , extend } from "../../../core" ;
import { Msg } from "../../foundation/message" ;
const document = _global . document || { } ;
/ * *
* @ description normalize input . files . create if not present , add item method if not present
* @ param Object generated wrap object
* @ return Object the wrap object itself
* /
const F = ( ( ( item ) => {
return ( input ) => {
const files = input . files || [ input ] ;
if ( ! files . item ) {
files . item = item ;
}
const F = ( item => input => {
const files = input . files || [ input ] ;
if ( ! files . item ) {
files . item = item ;
}
return files ;
} ;
} ) ( ( i ) => {
return this [ i ] ;
} ) ) ;
return files ;
} ) ( i => this [ i ] ) ;
const event = {
@ -37,14 +35,14 @@ const event = {
* @ param Function the callback to associate as event
* @ return Object noswfupload . event
* /
add : document . addEventListener ?
( node , name , callback ) => {
add : document . addEventListener
? ( node , name , callback ) => {
node . addEventListener ( name , callback , false ) ;
return this ;
} :
( node , name , callback ) => {
node . attachEvent ( "on" + name , callback ) ;
}
: ( node , name , callback ) => {
node . attachEvent ( ` on ${ name } ` , callback ) ;
return this ;
} ,
@ -56,14 +54,14 @@ const event = {
* @ param Function the callback associated as event
* @ return Object noswfupload . event
* /
del : document . removeEventListener ?
( node , name , callback ) => {
del : document . removeEventListener
? ( node , name , callback ) => {
node . removeEventListener ( name , callback , false ) ;
return this ;
} :
( node , name , callback ) => {
node . detachEvent ( "on" + name , callback ) ;
}
: ( node , name , callback ) => {
node . detachEvent ( ` on ${ name } ` , callback ) ;
return this ;
} ,
@ -79,34 +77,41 @@ const event = {
event . returnValue = ! ( event . cancelBubble = true ) ;
}
} else {
e . stopPropagation ? e . stopPropagation ( ) : e . cancelBubble = true ;
e . preventDefault ? e . preventDefault ( ) : e . returnValue = false ;
e . stopPropagation ? e . stopPropagation ( ) : ( e . cancelBubble = true ) ;
e . preventDefault ? e . preventDefault ( ) : ( e . returnValue = false ) ;
}
return false ;
} ,
} ;
const sendFile = ( ( ( toString ) => {
const sendFile = ( toString => {
const split = "onabort.onerror.onloadstart.onprogress" . split ( "." ) ,
length = split . length ,
CRLF = "\r\n" ;
let xhr = new XMLHttpRequest ,
let xhr = new XMLHttpRequest ( ) ,
sendFile ;
const multipart = ( boundary , name , file ) => {
return "--" . concat (
boundary , CRLF ,
"Content-Disposition: form-data; name=\"" , name , "\"; filename=\"" , _global . encodeURIComponent ( file . fileName ) , "\"" , CRLF ,
"Content-Type: application/octet-stream" , CRLF ,
const multipart = ( boundary , name , file ) =>
"--" . concat (
boundary ,
CRLF ,
"Content-Disposition: form-data; name=\"" ,
name ,
"\"; filename=\"" ,
_global . encodeURIComponent ( file . fileName ) ,
"\"" ,
CRLF ,
"Content-Type: application/octet-stream" ,
CRLF ,
CRLF ,
file . getAsBinary ( ) , CRLF ,
"--" , boundary , "--" , CRLF
file . getAsBinary ( ) ,
CRLF ,
"--" ,
boundary ,
"--" ,
CRLF
) ;
}
const isFunction = ( Function ) => {
return toString . call ( Function ) === "[object Function]" ;
}
const isFunction = Function => toString . call ( Function ) === "[object Function]" ;
// FireFox 3+, Safari 4 beta (Chrome 2 beta file is buggy and will not work)
if ( xhr . upload || xhr . sendAsBinary ) {
@ -117,31 +122,29 @@ const sendFile = (((toString) => {
handler . onerror ( ) ;
}
return ;
return ;
}
const xhr = new XMLHttpRequest ,
upload = xhr . upload || {
addEventListener ( event , callback ) {
this [ "on" + event ] = callback ;
} ,
} ;
for ( let i = 0 ; i < length ; i ++ ) {
const xhr = new XMLHttpRequest ( ) ,
upload = xhr . upload || {
addEventListener ( event , callback ) {
this [ ` on ${ event } ` ] = callback ;
} ,
} ;
for ( let i = 0 ; i < length ; i ++ ) {
upload . addEventListener (
split [ i ] . substring ( 2 ) ,
// eslint-disable-next-line no-loop-func
( ( ( event ) => {
return ( rpe ) => {
if ( isFunction ( handler [ event ] ) ) {
handler [ event ] ( rpe , xhr ) ;
}
} ;
} ) ( split [ i ] ) ) ,
( event => rpe => {
if ( isFunction ( handler [ event ] ) ) {
handler [ event ] ( rpe , xhr ) ;
}
} ) ( split [ i ] ) ,
false
) ;
}
upload . addEventListener (
"load" ,
( rpe ) => {
rpe => {
if ( handler . onreadystatechange === false ) {
if ( isFunction ( handler . onload ) ) {
handler . onload ( rpe , xhr ) ;
@ -155,15 +158,19 @@ const sendFile = (((toString) => {
} else {
setTimeout ( callback , 15 ) ;
}
}
} ;
setTimeout ( callback , 15 ) ;
}
} ,
false
) ;
xhr . open ( "post" , BI . appendQuery ( handler . url , {
filename : _global . encodeURIComponent ( handler . file . fileName ) ,
} ) , true ) ;
xhr . open (
"post" ,
BI . appendQuery ( handler . url , {
filename : _global . encodeURIComponent ( handler . file . fileName ) ,
} ) ,
true
) ;
if ( ! xhr . upload ) {
const rpe = { loaded : 0 , total : handler . file . fileSize || handler . file . size , simulation : true } ;
rpe . interval = setInterval ( ( ) => {
@ -181,61 +188,61 @@ const sendFile = (((toString) => {
} ;
xhr . onreadystatechange = ( ) => {
switch ( xhr . readyState ) {
case 2 :
case 3 :
if ( rpe . total <= rpe . loaded ) {
rpe . loaded = rpe . total ;
}
upload . onprogress ( rpe ) ;
break ;
case 4 :
clearInterval ( rpe . interval ) ;
rpe . interval = 0 ;
case 2 :
case 3 :
if ( rpe . total <= rpe . loaded ) {
rpe . loaded = rpe . total ;
upload . onprogress ( rpe ) ;
if ( 199 < xhr . status && xhr . status < 400 ) {
upload . onload ( { } ) ;
const attachO = BI . jsonDecode ( xhr . responseText ) ;
attachO . filename = handler . file . fileName ;
if ( handler . file . type . indexOf ( "image" ) !== - 1 ) {
attachO . attach _type = "image" ;
}
handler . attach _array [ current ] = attachO ;
} else {
upload . onerror ( { } ) ;
}
upload . onprogress ( rpe ) ;
break ;
case 4 :
clearInterval ( rpe . interval ) ;
rpe . interval = 0 ;
rpe . loaded = rpe . total ;
upload . onprogress ( rpe ) ;
if ( 199 < xhr . status && xhr . status < 400 ) {
upload . onload ( { } ) ;
const attachO = BI . jsonDecode ( xhr . responseText ) ;
attachO . filename = handler . file . fileName ;
if ( handler . file . type . indexOf ( "image" ) !== - 1 ) {
attachO . attach _type = "image" ;
}
break ;
default :
break ;
handler . attach _array [ current ] = attachO ;
} else {
upload . onerror ( { } ) ;
}
break ;
default :
break ;
}
} ;
upload . onloadstart ( rpe ) ;
} else {
xhr . onreadystatechange = ( ) => {
switch ( xhr . readyState ) {
case 4 :
const attachO = BI . jsonDecode ( xhr . responseText ) ;
if ( handler . file . type . indexOf ( "image" ) !== - 1 ) {
attachO . attach _type = "image" ;
}
attachO . filename = handler . file . fileName ;
if ( handler . maxLength === 1 ) {
handler . attach _array [ 0 ] = attachO ;
// handler.attach_array.push(attachO);
} else {
handler . attach _array [ current ] = attachO ;
}
break ;
default :
break ;
case 4 :
const attachO = BI . jsonDecode ( xhr . responseText ) ;
if ( handler . file . type . indexOf ( "image" ) !== - 1 ) {
attachO . attach _type = "image" ;
}
attachO . filename = handler . file . fileName ;
if ( handler . maxLength === 1 ) {
handler . attach _array [ 0 ] = attachO ;
// handler.attach_array.push(attachO);
} else {
handler . attach _array [ current ] = attachO ;
}
break ;
default :
break ;
}
} ;
if ( isFunction ( upload . onloadstart ) ) {
upload . onloadstart ( ) ;
}
}
const boundary = "AjaxUploadBoundary" + ( new Date ) . getTime ( ) ;
xhr . setRequestHeader ( "Content-Type" , "multipart/form-data; boundary=" + boundary ) ;
const boundary = ` AjaxUploadBoundary ${ new Date ( ) . getTime ( ) } ` ;
xhr . setRequestHeader ( "Content-Type" , ` multipart/form-data; boundary= ${ boundary } ` ) ;
if ( handler . file . getAsBinary ) {
xhr [ xhr . sendAsBinary ? "sendAsBinary" : "send" ] ( multipart ( boundary , handler . name , handler . file ) ) ;
} else {
@ -256,7 +263,10 @@ const sendFile = (((toString) => {
let iframe , form ;
const url = handler . url . concat ( - 1 === handler . url . indexOf ( "?" ) ? "?" : "&" , "AjaxUploadFrame=true" ) ,
rpe = {
loaded : 1 , total : 100 , simulation : true , interval : setInterval ( ( ) => {
loaded : 1 ,
total : 100 ,
simulation : true ,
interval : setInterval ( ( ) => {
if ( rpe . loaded < rpe . total ) {
++ rpe . loaded ;
}
@ -265,56 +275,62 @@ const sendFile = (((toString) => {
}
} , 100 ) ,
} ,
target = [ "AjaxUpload" , ( new Date ) . getTime ( ) , String ( Math . random ( ) ) . substring ( 2 ) ] . join ( "_" ) ;
const onload = ( ) => {
iframe . onreadystatechange = iframe . onload = iframe . onerror = null ;
form . parentNode . removeChild ( form ) ;
form = null ;
clearInterval ( rpe . interval ) ;
// rpe.loaded = rpe.total;
const responseText = ( iframe . contentWindow . document || iframe . contentWindow . contentDocument ) . body . innerHTML ;
try {
const attachO = BI . jsonDecode ( responseText ) ;
if ( handler . file . type . indexOf ( "image" ) !== - 1 ) {
attachO . attach _type = "image" ;
}
target = [ "AjaxUpload" , new Date ( ) . getTime ( ) , String ( Math . random ( ) ) . substring ( 2 ) ] . join ( "_" ) ;
const onload = ( ) => {
iframe . onreadystatechange = iframe . onload = iframe . onerror = null ;
form . parentNode . removeChild ( form ) ;
form = null ;
clearInterval ( rpe . interval ) ;
// rpe.loaded = rpe.total;
const responseText = ( iframe . contentWindow . document || iframe . contentWindow . contentDocument ) . body
. innerHTML ;
try {
const attachO = BI . jsonDecode ( responseText ) ;
if ( handler . file . type . indexOf ( "image" ) !== - 1 ) {
attachO . attach _type = "image" ;
}
// attachO.fileSize = responseText.length;
try {
// decodeURIComponent特殊字符可能有问题, catch一下,保证能正常上传
attachO . filename = _global . decodeURIComponent ( handler . file . fileName ) ;
} catch ( e ) {
attachO . filename = handler . file . fileName ;
}
if ( handler . maxLength === 1 ) {
handler . attach _array [ 0 ] = attachO ;
} else {
handler . attach _array [ current ] = attachO ;
}
// attachO.fileSize = responseText.length;
try {
// decodeURIComponent特殊字符可能有问题, catch一下,保证能正常上传
attachO . filename = _global . decodeURIComponent ( handler . file . fileName ) ;
} catch ( e ) {
if ( isFunction ( handler . onerror ) ) {
handler . onerror ( rpe , event || _global . event ) ;
}
attachO . filename = handler . file . fileName ;
}
if ( handler . maxLength === 1 ) {
handler . attach _array [ 0 ] = attachO ;
} else {
handler . attach _array [ current ] = attachO ;
}
if ( isFunction ( handler . onload ) ) {
handler . onload ( rpe , { responseText : responseText } ) ;
} catch ( e ) {
if ( isFunction ( handler . onerror ) ) {
handler . onerror ( rpe , event || _global . event ) ;
}
}
if ( isFunction ( handler . onload ) ) {
handler . onload ( rpe , { responseText } ) ;
}
} ;
try { // IE < 8 does not accept enctype attribute ...
try {
// IE < 8 does not accept enctype attribute ...
const form = document . createElement ( "<form enctype=\"multipart/form-data\"></form>" ) ,
iframe = handler . iframe || ( handler . iframe = document . createElement ( "<iframe id=\"" + target + "\" name=\"" + target + "\" src=\"" + url + "\"></iframe>" ) ) ;
iframe =
handler . iframe ||
( handler . iframe = document . createElement (
` <iframe id=" ${ target } " name=" ${ target } " src=" ${ url } "></iframe> `
) ) ;
} catch ( e ) {
const form = document . createElement ( "form" ) ,
iframe = handler . iframe || ( handler . iframe = document . createElement ( "iframe" ) ) ;
form . setAttribute ( "enctype" , "multipart/form-data" ) ;
iframe . setAttribute ( "name" , iframe . id = target ) ;
iframe . setAttribute ( "name" , ( iframe . id = target ) ) ;
iframe . setAttribute ( "src" , url ) ;
}
iframe . style . position = "absolute" ;
iframe . style . left = iframe . style . top = "-10000px" ;
iframe . onload = onload ;
iframe . onerror = ( event ) => {
iframe . onerror = event => {
if ( isFunction ( handler . onerror ) ) {
handler . onerror ( rpe , event || _global . event ) ;
}
@ -329,16 +345,17 @@ const sendFile = (((toString) => {
++ rpe . loaded ;
}
handler . onloadprogress ( rpe , {
readyState : {
loading : 2 ,
interactive : 3 ,
loaded : 4 ,
complete : 4 ,
} [ iframe . readyState ] || 1 ,
readyState :
{
loading : 2 ,
interactive : 3 ,
loaded : 4 ,
complete : 4 ,
} [ iframe . readyState ] || 1 ,
} ) ;
}
} ;
form . setAttribute ( "action" , handler . url + "&filename=" + _global . encodeURIComponent ( handler . file . fileName ) ) ;
form . setAttribute ( "action" , ` ${ handler . url } &filename= ${ _global . encodeURIComponent ( handler . file . fileName ) } ` ) ;
form . setAttribute ( "target" , iframe . id ) ;
form . setAttribute ( "method" , "post" ) ;
form . appendChild ( handler . file ) ;
@ -357,17 +374,17 @@ const sendFile = (((toString) => {
xhr = null ;
return sendFile ;
} ) ( Object . prototype . toString ) ) ;
} ) ( Object . prototype . toString ) ;
const sendFiles = ( handler , maxSize , width , height ) => {
const length = handler . files . length ,
onload = handler . onload ,
onloadstart = handler . onloadstart ;
onload = handler . onload ,
onloadstart = handler . onloadstart ;
handler . current = 0 ;
handler . total = 0 ;
handler . sent = 0 ;
while ( handler . current < length ) {
handler . total += ( handler . files [ handler . current ] . fileSize || handler . files [ handler . current ] . size ) ;
handler . total += handler . files [ handler . current ] . fileSize || handler . files [ handler . current ] . size ;
handler . current ++ ;
}
handler . current = 0 ;
@ -375,7 +392,7 @@ const sendFiles = (handler, maxSize, width, height) => {
handler . file = handler . files [ handler . current ] ;
const callback = ( rpe , xhr ) => {
handler . onloadstart = null ;
handler . sent += ( handler . files [ handler . current ] . fileSize || handler . files [ handler . current ] . size ) ;
handler . sent += handler . files [ handler . current ] . fileSize || handler . files [ handler . current ] . size ;
if ( ++ handler . current < length ) {
handler . file = handler . files [ handler . current ] ;
sendFile ( handler , maxSize , width , height ) . onload = callback ;
@ -415,7 +432,7 @@ const sendFiles = (handler, maxSize, width, height) => {
}
return handler ;
}
} ;
const r1 = /\.([^.]+)$/ ; // .png
const r2 = /\/([^/]+)$/ ; // image/png
@ -432,7 +449,7 @@ const fileTypeValidate = (fileName, fileType) => {
}
const mimes = fileType . split ( "," ) ;
if ( mimes [ 0 ] === fileType ) {
mimes = ( fileType + "" ) . split ( ";" ) ;
mimes = ` ${ fileType } ` . split ( ";" ) ;
}
return some ( mimes , ( index , mime ) => {
@ -446,7 +463,7 @@ const fileTypeValidate = (fileName, fileType) => {
return matches [ 1 ] === "*" ? true : fileName . toLowerCase ( ) . indexOf ( matches [ 1 ] ) > - 1 ;
}
} ) ;
}
} ;
@ shortcut ( )
export class File extends Widget {
@ -462,7 +479,7 @@ export class File extends Widget {
const conf = super . _defaultConfig ( ... arguments ) ;
return extend ( conf , {
baseCls : ( conf . baseCls || "" ) + " bi-file display-block" ,
baseCls : ` ${ conf . baseCls || "" } bi-file display-block ` ,
tagName : "input" ,
attributes : {
type : "file" ,
@ -492,7 +509,7 @@ export class File extends Widget {
// create the noswfupload.wrap Object
// wrap.maxSize 文件大小限制
// wrap.maxLength 文件个数限制
const _wrap = this . wrap = this . _wrap ( this . element [ 0 ] , maxSize ) ;
const _wrap = ( this . wrap = this . _wrap ( this . element [ 0 ] , maxSize ) ) ;
// fileType could contain whatever text but filter checks *.{extension}
// if present
@ -586,20 +603,26 @@ export class File extends Widget {
const validateFileType = fileTypeValidate ( value , wrap . fileType ) ;
if ( ! validateFileType ) {
// 文件类型不支持
Msg . toast ( errorText ( {
errorType : 0 ,
file : item ,
} ) || BI . i18nText ( "BI-Upload_File_Type_Error" , wrap . fileType ) , { level : "error" } ) ;
Msg . toast (
errorText ( {
errorType : 0 ,
file : item ,
} ) || BI . i18nText ( "BI-Upload_File_Type_Error" , wrap . fileType ) ,
{ level : "error" }
) ;
this . fireEvent ( File . EVENT _ERROR , {
errorType : 0 ,
file : item ,
} ) ;
} else if ( wrap . maxSize !== - 1 && size && wrap . maxSize < size ) {
// 文件大小不支持
Msg . toast ( errorText ( {
errorType : 1 ,
file : item ,
} ) || BI . i18nText ( "BI-Upload_File_Size_Error" , Math . ceil ( wrap . maxSize / 1024 / 1024 ) ) , { level : "error" } ) ;
Msg . toast (
errorText ( {
errorType : 1 ,
file : item ,
} ) || BI . i18nText ( "BI-Upload_File_Size_Error" , Math . ceil ( wrap . maxSize / 1024 / 1024 ) ) ,
{ level : "error" }
) ;
this . fireEvent ( File . EVENT _ERROR , {
errorType : 1 ,
file : item ,
@ -609,14 +632,15 @@ export class File extends Widget {
}
}
}
wrap . files . length > 0 && this . fireEvent ( File . EVENT _CHANGE , {
files : wrap . files ,
} ) ;
wrap . files . length > 0 &&
this . fireEvent ( File . EVENT _CHANGE , {
files : wrap . files ,
} ) ;
input . value = "" ;
wrap . dom . input . parentNode . replaceChild ( input , wrap . dom . input ) ;
wrap . dom . input = input ;
event . add ( wrap . dom . input , "change" , callback ) ;
}
} ;
event . add ( wrap . dom . input , "change" , callback ) ;
return wrap ;
@ -633,10 +657,9 @@ export class File extends Widget {
// wrap Object
return this . _events ( {
// DOM namespace
dom : {
input : input , // input file
input , // input file
disabled : false , // internal use, checks input file state
} ,
name : input . name , // name to send for each file ($_FILES[{name}] in the server)
@ -655,7 +678,7 @@ export class File extends Widget {
// something like {onload:function(){alert("OK")},onerror:function(){alert("Error")}, etc ...}
upload ( handler ) {
if ( handler ) {
for ( le t key in handler ) {
for ( cons t key in handler ) {
this [ key ] = handler [ key ] ;
}
}