Authored by 陈轩

returns 首页

  1 +/**
  2 + * 个人中心-地址管理
  3 + */
  4 +
1 -'use strict';  
2 /** 1 /**
3 * 个人中心 退换货 2 * 个人中心 退换货
4 * @author 陈轩 <xuan.chen@yoho.cn> 3 * @author 陈轩 <xuan.chen@yoho.cn>
5 */ 4 */
  5 +'use strict';
  6 +
  7 +const cookie = global.yoho.cookie;
  8 +const logger = global.yoho.logger;
  9 +
  10 +const returnsModel = require('../models/returns');
6 11
7 /* 12 /*
8 我的退换货-列表页 13 我的退换货-列表页
9 */ 14 */
10 -exports.returnsListAction = (req, res, next) => {  
11 -  
12 -}  
  15 +exports.index = (req, res, next) => {
  16 + const uid = cookie.getUid(req);
  17 + const page = req.query.page;
  18 +
  19 + returnsModel.getReturnsList(uid, page /* ,limit=10*/)
  20 + .then(data => {
  21 + const viewData = Object.assign({
  22 + module: 'home',
  23 + page: 'returns',
  24 + meReturnsPage: true
  25 + }, data);
  26 + res.render('returns/returns', viewData);
  27 + })
  28 + .catch(next);
  29 +};
  1 +/**
  2 + * 个人中心 退换货
  3 + * @author chenxuan <xuan.chen@yoho.cn>
  4 + */
  5 +
  6 +'use strict';
  7 +
  8 +const path = require('path');
  9 +const Promise = require('bluebird');
  10 +const _ = require('lodash');
  11 +
  12 +// 使用 product中的分页逻辑
  13 +const pagerPath = path.join(global.appRoot, '/apps/product/models/public-handler.js');
  14 +const pager = require(pagerPath).handlePagerData;
  15 +
  16 +const co = Promise.coroutine;
  17 +const api = global.yoho.API;
  18 +const helpers = global.yoho.helpers;
  19 +
  20 +// 常量
  21 +const REFUND = 1; // 退货
  22 +const EXCHANGE = 2; // 换货
  23 +const TRUE = 'Y';
  24 +const RETURNS_EMPTY = '您没有退/换货订单';
  25 +const REFUND_URI = '/home/returns/refundDetail';
  26 +const EXCHANGE_URI = '/home/returns/exchangeDetail';
  27 +
  28 +// 处理订单商品的数据
  29 +function getGoodsData(goods) {
  30 + const arr = [];
  31 +
  32 + goods.forEach(good=> {
  33 + const obj = {};
  34 + const cnAlphabet = good.cn_alphabet || '';
  35 +
  36 + obj.href = helpers.getUrlBySkc(good.product_id, good.goods_id, cnAlphabet);
  37 + obj.thumb = helpers.image(good.goods_image, 60, 60);
  38 + obj.name = good.product_name;
  39 + obj.color = good.color_name;
  40 + obj.size = good.size_name;
  41 +
  42 + arr.push(obj);
  43 + });
  44 +
  45 + return arr;
  46 +}
  47 +
  48 +/**
  49 + * 退换货列表页数据
  50 + * @param {string} uid 用户 uid
  51 + * @param {Number} page 当前页数
  52 + * @param {Number} limit 每页最大条数
  53 + * @return {Object} Promise
  54 + */
  55 +exports.getReturnsList = co(function*(uid, page, limit) {
  56 + page = Number.parseInt(page) || 1;
  57 + limit = Number.parseInt(limit) || 10;
  58 +
  59 + const obj = {
  60 + orders: [],
  61 + pager: {}
  62 + };
  63 + let response = yield api.post('', {
  64 + method: 'app.refund.getList',
  65 + data: { uid: uid, page: page, limit: limit }
  66 + });
  67 + let repData = response.data;
  68 +
  69 +
  70 + // 处理数据
  71 + if (response.code === 200 && repData && repData.list.length) {
  72 + obj.pager = pager(repData.total, {
  73 + page: page,
  74 + limit: limit
  75 + });
  76 +
  77 + repData.list.forEach(item => {
  78 + const t = {};
  79 +
  80 + t.returnId = item.id;
  81 + t.orderNum = item.order_code;
  82 + t.orderTime = item.oreder_create_time.replace('-', '/');
  83 + t.returnTime = item.create_time;
  84 + t.returnStatus = item.status_name;
  85 +
  86 +
  87 + const canCancel = item.canCancel === TRUE;
  88 + let isChange, uri;
  89 +
  90 + switch (item.refund_type) {
  91 + case REFUND:
  92 + isChange = false;
  93 + uri = REFUND_URI;
  94 + break;
  95 + case EXCHANGE:
  96 + isChange = true;
  97 + uri = EXCHANGE_URI;
  98 + break;
  99 + default:
  100 + }
  101 +
  102 + t.isChange = isChange;
  103 + t.canCancelUrl = helpers.urlFormat(uri);
  104 + t.moreHref = helpers.urlFormat(uri, {id: item.id});
  105 + t.goods = getGoodsData(item.goods);
  106 +
  107 + obj.orders.push(t);
  108 + });
  109 + } else {
  110 + obj.empty = RETURNS_EMPTY;
  111 + }
  112 +
  113 + return obj;
  114 +});
@@ -103,6 +103,10 @@ router.get('/consult', consultController.index); @@ -103,6 +103,10 @@ router.get('/consult', consultController.index);
103 // 我的退/换货 103 // 我的退/换货
104 router.get('/returns', returnsController.index); 104 router.get('/returns', returnsController.index);
105 105
  106 +// // 地址管理
  107 +// router.get('address', addressController.index);
  108 +// router.get('address/area', addressController.area);
  109 +
106 router.get('/index', [getCommonHeader, getHomeNav], Index.index); 110 router.get('/index', [getCommonHeader, getHomeNav], Index.index);
107 111
108 module.exports = router; 112 module.exports = router;
1 -{{> layout/header}}  
2 <div class="returns-me-page me-page yoho-page clearfix"> 1 <div class="returns-me-page me-page yoho-page clearfix">
3 - {{# returns}}  
4 - {{> path}}  
5 -  
6 - {{> navigation}}  
7 -  
8 - <div class="me-main">  
9 - <div class="returns block">  
10 - <h2 class="title"></h2>  
11 -  
12 - <div class="me-orders">  
13 - <p class="order-table-header table-header clearfix">  
14 - <span class="info">商品信息</span>  
15 - <span class="time">申请时间</span>  
16 - <span class="return-type">退/换货</span>  
17 - <span class="return-status">状态</span>  
18 - <span class="operation">操作</span>  
19 - </p>  
20 -  
21 - {{#if orders.empty}}  
22 - {{#with orders}}  
23 - {{> empty}}  
24 - {{/with}}  
25 - {{^}}  
26 - {{# orders}}  
27 - <div class="order">  
28 - <p class="order-title">  
29 - 订单编号:{{orderNum}}  
30 - <span class="right">下单时间:{{orderTime}}</span>  
31 - </p>  
32 - <div class="order-wrap">  
33 - <ul>  
34 - {{# goods}}  
35 - <li>  
36 - <div class="info clearfix">  
37 - <a class="thumb-wrap" href="{{href}}">  
38 - <img class="thumb" src="{{thumb}}">  
39 - </a>  
40 - <div class="text-info">  
41 - <a class="name" href="{{href}}" title="{{name}}">{{name}}</a>  
42 - <span class="color-size"> 2 + {{> path}} {{> navigation}}
  3 + <div class="me-main">
  4 + <div class="returns block">
  5 + <h2 class="title"></h2>
  6 + <div class="me-orders">
  7 + <p class="order-table-header table-header clearfix">
  8 + <span class="info">商品信息</span>
  9 + <span class="time">申请时间</span>
  10 + <span class="return-type">退/换货</span>
  11 + <span class="return-status">状态</span>
  12 + <span class="operation">操作</span>
  13 + </p>
  14 + {{#if orders.length}}
  15 + {{#each orders}}
  16 + <div class="order">
  17 + <p class="order-title">
  18 + 订单编号:{{orderNum}}
  19 + <span class="right">下单时间:{{orderTime}}</span>
  20 + </p>
  21 + <div class="order-wrap">
  22 + <ul>
  23 + {{#each goods}}
  24 + <li>
  25 + <div class="info clearfix">
  26 + <a class="thumb-wrap" href="{{href}}">
  27 + <img class="thumb" src="{{thumb}}">
  28 + </a>
  29 + <div class="text-info">
  30 + <a class="name" href="{{href}}" title="{{name}}">{{name}}</a>
  31 + <span class="color-size">
43 {{#if color}} 32 {{#if color}}
44 颜色:{{color}}&nbsp;&nbsp; 33 颜色:{{color}}&nbsp;&nbsp;
45 {{/if}} 34 {{/if}}
@@ -48,37 +37,34 @@ @@ -48,37 +37,34 @@
48 尺码:{{size}} 37 尺码:{{size}}
49 {{/if}} 38 {{/if}}
50 </span> 39 </span>
51 - </div>  
52 </div> 40 </div>
53 - </li>  
54 - {{/ goods}}  
55 - </ul>  
56 -  
57 - <div class="time">{{returnTime}}</div>  
58 - <div class="return-type">  
59 - {{#if isChange}}  
60 - 换货  
61 - {{^}}  
62 - 退货  
63 - {{/if}}  
64 - </div>  
65 - <div class="return-status">  
66 - {{returnStatus}}  
67 - </div>  
68 - <div class="operation">  
69 - <a class="op-item" href="{{moreHref}}" target="_blank">查看详情</a>  
70 - </div> 41 + </div>
  42 + </li>
  43 + {{/each}}
  44 + </ul>
  45 + <div class="time">{{returnTime}}</div>
  46 + <div class="return-type">
  47 + {{#if isChange}}换货{{else}}退货{{/if}}
  48 + </div>
  49 + <div class="return-status">
  50 + {{returnStatus}}
  51 + </div>
  52 + <div class="operation">
  53 + <a class="op-item" href="{{moreHref}}" target="_blank">查看详情</a>
71 </div> 54 </div>
72 </div> 55 </div>
73 - {{/ orders}}  
74 - {{/if}}  
75 - </div>  
76 -  
77 - {{> pager}} 56 + </div>
  57 + {{/each}}
  58 + {{#with ../pager}}
  59 + {{> common/foot-pager footPager=this}}
  60 + {{/with}}
  61 + {{else}}
  62 + {{#with orders}}
  63 + {{> empty}}
  64 + {{/with}}
  65 + {{/if}}
78 </div> 66 </div>
79 -  
80 - {{> help-us}}  
81 </div> 67 </div>
82 - {{/ returns}} 68 + {{> help-us}}
  69 + </div>
83 </div> 70 </div>
84 -{{> layout/footer}}  
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 * @date: 2016/02/24 4 * @date: 2016/02/24
5 */ 5 */
6 6
7 -var $ = require('yoho.jquery'), 7 +var $ = require('yoho-jquery'),
8 dialog = require('../common/dialog'), 8 dialog = require('../common/dialog'),
9 Alert = dialog.Alert; 9 Alert = dialog.Alert;
10 10
@@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
3 * @author: yyqing<yanqing.yang@yoho.cn> 3 * @author: yyqing<yanqing.yang@yoho.cn>
4 * @date: 2016/2/29 4 * @date: 2016/2/29
5 */ 5 */
6 -var $ = require('yoho.jquery'), 6 +var $ = require('yoho-jquery'),
7 Addr = require('./common-address'); 7 Addr = require('./common-address');
8 8
9 var $goodsTable = $('#goods-table'), 9 var $goodsTable = $('#goods-table'),
@@ -27,7 +27,7 @@ var $exchange = $('.exchange-detail'), @@ -27,7 +27,7 @@ var $exchange = $('.exchange-detail'),
27 var $submitBox = $('.submit-box'), 27 var $submitBox = $('.submit-box'),
28 $waitPoint = $submitBox.find('.wait-gif span'); 28 $waitPoint = $submitBox.find('.wait-gif span');
29 29
30 -var pageType = 0, // 0-换货 1-退货 30 +var pageType = 0, // 0-换货 1-退货
31 orderCode = $('#order-code').val(), 31 orderCode = $('#order-code').val(),
32 defaultArea = $exchange.find('input[name="hide-area"]').val(), 32 defaultArea = $exchange.find('input[name="hide-area"]').val(),
33 defaultPhone = $hidePhone.val(), 33 defaultPhone = $hidePhone.val(),
@@ -36,7 +36,7 @@ var pageType = 0, // 0-换货 1-退货 @@ -36,7 +36,7 @@ var pageType = 0, // 0-换货 1-退货
36 colorSize = {}, 36 colorSize = {},
37 timer; 37 timer;
38 38
39 -require('../../plugin/jquery.qupload'); 39 +require('../plugins/jquery.qupload');
40 40
41 if (defaultPhone) { 41 if (defaultPhone) {
42 $hidePhone.remove(); 42 $hidePhone.remove();
@@ -401,7 +401,7 @@ function loadWaiting(status) { @@ -401,7 +401,7 @@ function loadWaiting(status) {
401 $('.save-btn').click(function() { 401 $('.save-btn').click(function() {
402 var url, data; 402 var url, data;
403 403
404 - verifyTip = ''; // 初始化提示语 404 + verifyTip = ''; // 初始化提示语
405 if (pageType) { 405 if (pageType) {
406 url = '/home/returns/saveRefund'; 406 url = '/home/returns/saveRefund';
407 data = packRefundInfo(); 407 data = packRefundInfo();
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 * @date: 2016/2/26 4 * @date: 2016/2/26
5 */ 5 */
6 6
7 -var $ = require('yoho.jquery'); 7 +var $ = require('yoho-jquery');
8 8
9 var $returnState = $('.visual-return-state li'), 9 var $returnState = $('.visual-return-state li'),
10 $detail = $('.detail-container'), 10 $detail = $('.detail-container'),
  1 +/**
  2 + * upload plugin
  3 + *
  4 + */
  5 +var $ = require('yoho-jquery');
  6 +var SWFUpload = require('./swfupload.queue').SWFUpload;
  7 +
  8 +var file_upload_limit = 6;
  9 +$.fn.extend({
  10 + qupload: function(options) {
  11 + writeProgressHtml();
  12 + initSwfUpload($(this).attr('id'), options);
  13 + }
  14 +});
  15 +
  16 +var hasProgreeHtml = 0;
  17 +
  18 +// 创建进度条的html
  19 +function writeProgressHtml() {
  20 + if (hasProgreeHtml == 0) // 一个页面只创建一次
  21 + {
  22 + $('body')
  23 + .append(
  24 + '<div id="progressDialog" style="display: none;width:370px;height:80px !important;"><div style="padding:10px 20px;"><span id="curUploadStatus">图片上传中……请稍等</span><div id="progress"></div></div></div>');
  25 + hasProgreeHtml = 1;
  26 + }
  27 +}
  28 +
  29 +function setUploadStatus(uploadNum, totalUploadNum) {
  30 + $('#uploadNum').html(uploadNum);
  31 + $('#totalUploadNum').html(totalUploadNum);
  32 +}
  33 +
  34 +// 初始化swf
  35 +function initSwfUpload(btnId, options) {
  36 + // 上传成功的回调函数
  37 + var uploadSuccessCallBack = null;
  38 + if (options.uploadSuccessed != undefined) {
  39 + uploadSuccessCallBack = options.uploadSuccessed;
  40 + }
  41 +
  42 + // 上传的key
  43 + var uploadKeyValue = '';
  44 + if (options.uploadKey != undefined) {
  45 + uploadKeyValue = options.uploadKey;
  46 + }
  47 +
  48 + // 上传之前可以做的操作参数
  49 + var preUploadCallBack = null;
  50 + if (options.preupload != undefined) {
  51 + preUploadCallBack = options.preupload;
  52 + }
  53 +
  54 + // 弹出层ID
  55 + var progressDivId = 'progressDialog';
  56 +
  57 + // 进度条ID
  58 + var progressTargetId = 'progress';
  59 +
  60 + // 共有多少张需要上传
  61 + var totalUploadNum = 0;
  62 +
  63 + // 当前已经上传的张数
  64 + var curUploadedNum = 0;
  65 +
  66 + this.options = options;
  67 +
  68 + var numTest = 0;
  69 +
  70 + var errmsg_box = this.options.errmsg_box;
  71 +
  72 + // 设置默认值函数
  73 + function setDefaultValue(optionName, optionValue) {
  74 + this.options[optionName] = options[optionName] == undefined ? optionValue
  75 + : options[optionName];
  76 + }
  77 +
  78 + setDefaultValue('flash_url',
  79 + 'http://static.yohobuy.com/admin/js/swfupload/swfupload.swf');
  80 + setDefaultValue('upload_url', 'http://upload.yohobuy.com');
  81 + setDefaultValue('file_post_name', 'Filedata');
  82 + setDefaultValue('file_size_limit', '2 MB');
  83 + setDefaultValue('file_types', '*.*');
  84 + setDefaultValue('file_types_description', 'All Files');
  85 + setDefaultValue('file_upload_limit', file_upload_limit);
  86 + setDefaultValue('file_queue_limit', 0);
  87 + setDefaultValue('button_image_url',
  88 + 'http://static.yohobuy.com/admin/images/btn_swfupload.png');
  89 + setDefaultValue('button_width', '104');
  90 + setDefaultValue('button_height', '20');
  91 + setDefaultValue('button_text', '<span class="btn_upload_xzzp">选择本地照片</span>');
  92 + setDefaultValue('button_text_style', '.btn_upload_xzzp{color:#ffffff}');
  93 + setDefaultValue('button_text_left_padding', 24);
  94 + setDefaultValue('button_text_top_padding', 0);
  95 + setDefaultValue('button_window_mode', 'TRANSPARENT');
  96 + setDefaultValue('button_cursor', '-2');
  97 +
  98 + var settings = {
  99 + flash_url: this.options.flash_url,
  100 + upload_url: this.options.upload_url,
  101 + file_post_name: this.options.file_post_name,
  102 +
  103 + // post_params: {"PHPSESSID" : "<?php echo session_id(); ?>"},
  104 + file_size_limit: this.options.file_size_limit,
  105 + file_types: this.options.file_types,
  106 + file_types_description: this.options.file_types_description,
  107 + file_upload_limit: this.options.file_upload_limit,
  108 + file_queue_limit: this.options.file_queue_limit,
  109 + prevent_swf_caching: false,
  110 + preserve_relative_urls: false,
  111 + custom_settings: {
  112 +
  113 + },
  114 + debug: false,
  115 +
  116 + // Button settings
  117 + button_image_url: this.options.button_image_url,
  118 + button_width: this.options.button_width,
  119 + button_height: this.options.button_height,
  120 + button_placeholder_id: btnId,
  121 + button_text: this.options.button_text,
  122 + button_text_style: this.options.button_text_style,
  123 + button_text_left_padding: this.options.button_text_left_padding,
  124 + button_text_top_padding: this.options.button_text_top_padding,
  125 + button_window_mode: this.options.button_window_mode,
  126 + button_cursor: this.options.button_cursor,
  127 +
  128 + // The event handler functions are defined in handlers.js
  129 + file_dialog_start_handler: fileDialogStart,
  130 + file_queued_handler: fileQueued,
  131 + file_queue_error_handler: fileQueueError,
  132 + file_dialog_complete_handler: fileDialogComplete,
  133 + upload_start_handler: uploadStart,
  134 + upload_progress_handler: uploadProgress,
  135 + upload_error_handler: uploadError,
  136 + upload_success_handler: uploadSuccess,
  137 + upload_complete_handler: uploadComplete,
  138 + queue_complete_handler: queueComplete,
  139 + button_action: this.options.button_action
  140 + };
  141 +
  142 + var swfu = new SWFUpload(settings);
  143 +
  144 + function fileQueued(file) {
  145 + try {
  146 +
  147 + } catch (ex) {
  148 + this.debug(ex);
  149 + }
  150 +
  151 + }
  152 +
  153 + function fileQueueError(file, errorCode, message) {
  154 + var errmsg;
  155 + try {
  156 + if (errorCode === SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED) {
  157 + alert('您尝试上传太多文件.\n'
  158 + + (message === 0 ? '您已达到上传限制.' : '您最多还可以 '
  159 + + (message > 1 ? '上传 ' + message + '文件.'
  160 + : '一个文件.')));
  161 + return;
  162 + }
  163 +
  164 + // var progress = new FileProgress(file,
  165 + // this.customSettings.progressTarget);
  166 + // progress.setError();
  167 + // progress.toggleCancel(false);
  168 + switch (errorCode) {
  169 +
  170 + case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
  171 + // progress.setStatus("File is too big.");
  172 +
  173 + errmsg = '文件超过' + settings.file_size_limit / 1024 + 'M';
  174 + alert(errmsg);
  175 + this.debug('Error Code: File too big, File name: '
  176 + + file.name + ', File size: ' + file.size
  177 + + ', Message: ' + message);
  178 + break;
  179 + case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
  180 + // progress.setStatus("Cannot upload Zero Byte files.");
  181 + alert('请上传有内容的文件!');
  182 + this.debug('Error Code: Zero byte file, File name: '
  183 + + file.name + ', File size: ' + file.size
  184 + + ', Message: ' + message);
  185 + break;
  186 + case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
  187 + alert('请上传指定类型的文件!');
  188 + this.debug('Error Code: Invalid File Type, File name: '
  189 + + file.name + ', File size: ' + file.size
  190 + + ', Message: ' + message);
  191 + break;
  192 + default:
  193 + if (file !== null) {
  194 + // progress.setStatus("Unhandled Error");
  195 + }
  196 + alert('上传文件失败,请稍后在试!');
  197 + this.debug('Error Code: ' + errorCode + ', File name: '
  198 + + file.name + ', File size: ' + file.size
  199 + + ', Message: ' + message);
  200 + break;
  201 + }
  202 + } catch (ex) {
  203 + this.debug(ex);
  204 + }
  205 + }
  206 +
  207 + function fileDialogStart() {
  208 + if (preUploadCallBack != null) {
  209 + preUploadCallBack();
  210 + }
  211 + }
  212 +
  213 + // 选择文件完成
  214 + function fileDialogComplete(numFilesSelected, numFilesQueued) {
  215 + try {
  216 +
  217 + if (numFilesSelected > 0) {
  218 + // document.getElementById(this.customSettings.cancelButtonId).disabled
  219 + // = false;
  220 + totalUploadNum = numFilesSelected;
  221 + curUploadedNum = 1;
  222 + setUploadStatus(curUploadedNum, totalUploadNum);
  223 + this.startUpload();
  224 + }
  225 +
  226 + } catch (ex) {
  227 + this.debug(ex);
  228 + }
  229 + }
  230 +
  231 + // 开始上传
  232 + function uploadStart(file) {
  233 + this.addPostParam('_key', uploadKeyValue);
  234 +
  235 + // $('#' + progressDivId).dialog();
  236 + }
  237 +
  238 + // 上传进度
  239 + function uploadProgress(file, bytesLoaded, bytesTotal) {
  240 + // $('#uploadData').html(bytesLoaded + "/" + bytesTotal);
  241 + // $('#uploadData').html( $('#uploadData').html() + ' - ' + bytesLoaded
  242 + // + '+' + ',' + bytesTotal );
  243 + var percent = Math.ceil((bytesLoaded / bytesTotal) * 100);
  244 +
  245 + // $("#progress").progressbar({
  246 + // value : percent
  247 + // });
  248 + }
  249 +
  250 + // 上传成功
  251 + function uploadSuccess(file, serverData) {
  252 + curUploadedNum++;
  253 + setUploadStatus(curUploadedNum, totalUploadNum);
  254 + if (uploadSuccessCallBack != null) {
  255 + uploadSuccessCallBack(serverData);
  256 + }
  257 + }
  258 +
  259 + // 上传出错
  260 + function uploadError(file, errorCode, message) {
  261 +
  262 + try {
  263 + if (errorCode === SWFUpload.QUEUE_ERROR.QUEUE_LIMIT_EXCEEDED) {
  264 + alert('您尝试上传太多文件.\n'
  265 + + (message === 0 ? '您已达到上传限制.' : '您最多还可以 '
  266 + + (message > 1 ? '上传 ' + message + '文件.'
  267 + : '一个文件.')));
  268 + return;
  269 + }
  270 + switch (errorCode) {
  271 +
  272 + case SWFUpload.QUEUE_ERROR.FILE_EXCEEDS_SIZE_LIMIT:
  273 + alert('Error Code: 文件太大。 文件名为: ' + file.name + ', 大小为: '
  274 + + file.size + ', Message: ' + message);
  275 + break;
  276 + case SWFUpload.QUEUE_ERROR.ZERO_BYTE_FILE:
  277 +
  278 + alert('Error Code: 文件为0, 文件名为: ' + file.name + ', 大小为: '
  279 + + file.size + ', Message: ' + message);
  280 + break;
  281 + case SWFUpload.QUEUE_ERROR.INVALID_FILETYPE:
  282 + alert('Error Code: 文件类型不合要求, 文件名为: ' + file.name + ', 大小为: '
  283 + + file.size + ', Message: ' + message);
  284 + break;
  285 + default:
  286 + if (file !== null) {
  287 +
  288 + }
  289 + alert('上传出错' + 'Error Code: ' + errorCode + ', File name: '
  290 + + file.name + ', File size: ' + file.size
  291 + + ', Message: ' + message);
  292 + break;
  293 + }
  294 + } catch (ex) {
  295 + this.debug(ex);
  296 + }
  297 + }
  298 +
  299 + // 上传完成
  300 + function uploadComplete(file) {
  301 + // $('#' + progressDivId).dialog('close');
  302 + }
  303 +
  304 + // This event comes from the Queue Plugin
  305 + function queueComplete(numFilesUploaded) {
  306 +
  307 + }
  308 +}
  309 +
  310 +window.SWFUpload = SWFUpload;
  1 +/**
  2 + * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com
  3 + *
  4 + * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/
  5 + *
  6 + * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilz锟絥 and Mammon Media and is released under the MIT License:
  7 + * http://www.opensource.org/licenses/mit-license.php
  8 + *
  9 + * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License:
  10 + * http://www.opensource.org/licenses/mit-license.php
  11 + *
  12 + */
  13 +
  14 +
  15 +/* ******************* */
  16 +/* Constructor & Init */
  17 +/* ******************* */
  18 +var SWFUpload;
  19 +
  20 +if (SWFUpload == undefined) {
  21 + SWFUpload = function(settings) {
  22 + this.initSWFUpload(settings);
  23 + };
  24 +}
  25 +
  26 +SWFUpload.prototype.initSWFUpload = function(settings) {
  27 + try {
  28 + this.customSettings = {}; // A container where developers can place their own settings associated with this instance.
  29 + this.settings = settings;
  30 + this.eventQueue = [];
  31 + this.movieName = 'SWFUpload_' + SWFUpload.movieCount++;
  32 + this.movieElement = null;
  33 +
  34 +
  35 + // Setup global control tracking
  36 + SWFUpload.instances[this.movieName] = this;
  37 +
  38 + // Load the settings. Load the Flash movie.
  39 + this.initSettings();
  40 + this.loadFlash();
  41 + this.displayDebugInfo();
  42 + } catch (ex) {
  43 + delete SWFUpload.instances[this.movieName];
  44 + throw ex;
  45 + }
  46 +};
  47 +
  48 +/* *************** */
  49 +/* Static Members */
  50 +/* *************** */
  51 +SWFUpload.instances = {};
  52 +SWFUpload.movieCount = 0;
  53 +SWFUpload.version = '2.2.0 2009-03-25';
  54 +SWFUpload.QUEUE_ERROR = {
  55 + QUEUE_LIMIT_EXCEEDED: -100,
  56 + FILE_EXCEEDS_SIZE_LIMIT: -110,
  57 + ZERO_BYTE_FILE: -120,
  58 + INVALID_FILETYPE: -130
  59 +};
  60 +SWFUpload.UPLOAD_ERROR = {
  61 + HTTP_ERROR: -200,
  62 + MISSING_UPLOAD_URL: -210,
  63 + IO_ERROR: -220,
  64 + SECURITY_ERROR: -230,
  65 + UPLOAD_LIMIT_EXCEEDED: -240,
  66 + UPLOAD_FAILED: -250,
  67 + SPECIFIED_FILE_ID_NOT_FOUND: -260,
  68 + FILE_VALIDATION_FAILED: -270,
  69 + FILE_CANCELLED: -280,
  70 + UPLOAD_STOPPED: -290
  71 +};
  72 +SWFUpload.FILE_STATUS = {
  73 + QUEUED: -1,
  74 + IN_PROGRESS: -2,
  75 + ERROR: -3,
  76 + COMPLETE: -4,
  77 + CANCELLED: -5
  78 +};
  79 +SWFUpload.BUTTON_ACTION = {
  80 + SELECT_FILE: -100,
  81 + SELECT_FILES: -110,
  82 + START_UPLOAD: -120
  83 +};
  84 +SWFUpload.CURSOR = {
  85 + ARROW: -1,
  86 + HAND: -2
  87 +};
  88 +SWFUpload.WINDOW_MODE = {
  89 + WINDOW: 'window',
  90 + TRANSPARENT: 'transparent',
  91 + OPAQUE: 'opaque'
  92 +};
  93 +
  94 +// Private: takes a URL, determines if it is relative and converts to an absolute URL
  95 +// using the current site. Only processes the URL if it can, otherwise returns the URL untouched
  96 +SWFUpload.completeURL = function(url) {
  97 + if (typeof(url) !== 'string' || url.match(/^https?:\/\//i) || url.match(/^\//)) {
  98 + return url;
  99 + }
  100 +
  101 + var currentURL = window.location.protocol + '//' + window.location.hostname + (window.location.port ? ':' + window.location.port : '');
  102 +
  103 + var indexSlash = window.location.pathname.lastIndexOf('/');
  104 + if (indexSlash <= 0) {
  105 + path = '/';
  106 + } else {
  107 + path = window.location.pathname.substr(0, indexSlash) + '/';
  108 + }
  109 +
  110 + return /* currentURL +*/ path + url;
  111 +
  112 +};
  113 +
  114 +
  115 +/* ******************** */
  116 +/* Instance Members */
  117 +/* ******************** */
  118 +
  119 +// Private: initSettings ensures that all the
  120 +// settings are set, getting a default value if one was not assigned.
  121 +SWFUpload.prototype.initSettings = function() {
  122 + this.ensureDefault = function(settingName, defaultValue) {
  123 + this.settings[settingName] = (this.settings[settingName] == undefined) ? defaultValue : this.settings[settingName];
  124 + };
  125 +
  126 + // Upload backend settings
  127 + this.ensureDefault('upload_url', '');
  128 + this.ensureDefault('preserve_relative_urls', false);
  129 + this.ensureDefault('file_post_name', 'Filedata');
  130 + this.ensureDefault('post_params', {});
  131 + this.ensureDefault('use_query_string', false);
  132 + this.ensureDefault('requeue_on_error', false);
  133 + this.ensureDefault('http_success', []);
  134 + this.ensureDefault('assume_success_timeout', 0);
  135 +
  136 + // File Settings
  137 + this.ensureDefault('file_types', '*.*');
  138 + this.ensureDefault('file_types_description', 'All Files');
  139 + this.ensureDefault('file_size_limit', 0); // Default zero means "unlimited"
  140 + this.ensureDefault('file_upload_limit', 0);
  141 + this.ensureDefault('file_queue_limit', 0);
  142 +
  143 + // Flash Settings
  144 + this.ensureDefault('flash_url', 'swfupload.swf');
  145 + this.ensureDefault('prevent_swf_caching', true);
  146 +
  147 + // Button Settings
  148 + this.ensureDefault('button_image_url', '');
  149 + this.ensureDefault('button_width', 1);
  150 + this.ensureDefault('button_height', 1);
  151 + this.ensureDefault('button_text', '');
  152 + this.ensureDefault('button_text_style', 'color: #000000; font-size: 16pt;');
  153 + this.ensureDefault('button_text_top_padding', 0);
  154 + this.ensureDefault('button_text_left_padding', 0);
  155 + this.ensureDefault('button_action', SWFUpload.BUTTON_ACTION.SELECT_FILES);
  156 + this.ensureDefault('button_disabled', false);
  157 + this.ensureDefault('button_placeholder_id', '');
  158 + this.ensureDefault('button_placeholder', null);
  159 + this.ensureDefault('button_cursor', SWFUpload.CURSOR.ARROW);
  160 + this.ensureDefault('button_window_mode', SWFUpload.WINDOW_MODE.WINDOW);
  161 +
  162 + // Debug Settings
  163 + this.ensureDefault('debug', false);
  164 + this.settings.debug_enabled = this.settings.debug; // Here to maintain v2 API
  165 +
  166 + // Event Handlers
  167 + this.settings.return_upload_start_handler = this.returnUploadStart;
  168 + this.ensureDefault('swfupload_loaded_handler', null);
  169 + this.ensureDefault('file_dialog_start_handler', null);
  170 + this.ensureDefault('file_queued_handler', null);
  171 + this.ensureDefault('file_queue_error_handler', null);
  172 + this.ensureDefault('file_dialog_complete_handler', null);
  173 +
  174 + this.ensureDefault('upload_start_handler', null);
  175 + this.ensureDefault('upload_progress_handler', null);
  176 + this.ensureDefault('upload_error_handler', null);
  177 + this.ensureDefault('upload_success_handler', null);
  178 + this.ensureDefault('upload_complete_handler', null);
  179 +
  180 + this.ensureDefault('debug_handler', this.debugMessage);
  181 +
  182 + this.ensureDefault('custom_settings', {});
  183 +
  184 + // Other settings
  185 + this.customSettings = this.settings.custom_settings;
  186 +
  187 + // Update the flash url if needed
  188 + if (!!this.settings.prevent_swf_caching) {
  189 + this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf('?') < 0 ? '?' : '&') + 'preventswfcaching=' + new Date().getTime();
  190 + }
  191 +
  192 + if (!this.settings.preserve_relative_urls) {
  193 + // this.settings.flash_url = SWFUpload.completeURL(this.settings.flash_url); // Don't need to do this one since flash doesn't look at it
  194 + this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url);
  195 + if (this.settings.button_image_url) {
  196 + this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url);
  197 + }
  198 + }
  199 +
  200 + delete this.ensureDefault;
  201 +};
  202 +
  203 +// Private: loadFlash replaces the button_placeholder element with the flash movie.
  204 +SWFUpload.prototype.loadFlash = function() {
  205 + var targetElement, tempParent;
  206 +
  207 + // Make sure an element with the ID we are going to use doesn't already exist
  208 + if (document.getElementById(this.movieName) !== null) {
  209 + throw 'ID ' + this.movieName + ' is already in use. The Flash Object could not be added';
  210 + }
  211 +
  212 + // Get the element where we will be placing the flash movie
  213 + targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder;
  214 +
  215 + if (targetElement == undefined) {
  216 + throw 'Could not find the placeholder element: ' + this.settings.button_placeholder_id;
  217 + }
  218 +
  219 + // Append the container and load the flash
  220 + tempParent = document.createElement('div');
  221 + tempParent.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers)
  222 + targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement);
  223 +
  224 + // Fix IE Flash/Form bug
  225 + if (window[this.movieName] == undefined) {
  226 + window[this.movieName] = this.getMovieElement();
  227 + }
  228 +
  229 +};
  230 +
  231 +// Private: getFlashHTML generates the object tag needed to embed the flash in to the document
  232 +SWFUpload.prototype.getFlashHTML = function() {
  233 + // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay
  234 + return ['<object id="', this.movieName, '" type="application/x-shockwave-flash" data="', this.settings.flash_url, '" width="', this.settings.button_width, '" height="', this.settings.button_height, '" class="swfupload">',
  235 + '<param name="wmode" value="', this.settings.button_window_mode, '" />',
  236 + '<param name="movie" value="', this.settings.flash_url, '" />',
  237 + '<param name="quality" value="high" />',
  238 + '<param name="menu" value="false" />',
  239 + '<param name="allowScriptAccess" value="always" />',
  240 + '<param name="flashvars" value="' + this.getFlashVars() + '" />',
  241 + '</object>'].join('');
  242 +};
  243 +
  244 +// Private: getFlashVars builds the parameter string that will be passed
  245 +// to flash in the flashvars param.
  246 +SWFUpload.prototype.getFlashVars = function() {
  247 + // Build a string from the post param object
  248 + var paramString = this.buildParamString();
  249 + var httpSuccessString = this.settings.http_success.join(',');
  250 +
  251 + // Build the parameter string
  252 + return ['movieName=', encodeURIComponent(this.movieName),
  253 + '&amp;uploadURL=', encodeURIComponent(this.settings.upload_url),
  254 + '&amp;useQueryString=', encodeURIComponent(this.settings.use_query_string),
  255 + '&amp;requeueOnError=', encodeURIComponent(this.settings.requeue_on_error),
  256 + '&amp;httpSuccess=', encodeURIComponent(httpSuccessString),
  257 + '&amp;assumeSuccessTimeout=', encodeURIComponent(this.settings.assume_success_timeout),
  258 + '&amp;params=', encodeURIComponent(paramString),
  259 + '&amp;filePostName=', encodeURIComponent(this.settings.file_post_name),
  260 + '&amp;fileTypes=', encodeURIComponent(this.settings.file_types),
  261 + '&amp;fileTypesDescription=', encodeURIComponent(this.settings.file_types_description),
  262 + '&amp;fileSizeLimit=', encodeURIComponent(this.settings.file_size_limit),
  263 + '&amp;fileUploadLimit=', encodeURIComponent(this.settings.file_upload_limit),
  264 + '&amp;fileQueueLimit=', encodeURIComponent(this.settings.file_queue_limit),
  265 + '&amp;debugEnabled=', encodeURIComponent(this.settings.debug_enabled),
  266 + '&amp;buttonImageURL=', encodeURIComponent(this.settings.button_image_url),
  267 + '&amp;buttonWidth=', encodeURIComponent(this.settings.button_width),
  268 + '&amp;buttonHeight=', encodeURIComponent(this.settings.button_height),
  269 + '&amp;buttonText=', encodeURIComponent(this.settings.button_text),
  270 + '&amp;buttonTextTopPadding=', encodeURIComponent(this.settings.button_text_top_padding),
  271 + '&amp;buttonTextLeftPadding=', encodeURIComponent(this.settings.button_text_left_padding),
  272 + '&amp;buttonTextStyle=', encodeURIComponent(this.settings.button_text_style),
  273 + '&amp;buttonAction=', encodeURIComponent(this.settings.button_action),
  274 + '&amp;buttonDisabled=', encodeURIComponent(this.settings.button_disabled),
  275 + '&amp;buttonCursor=', encodeURIComponent(this.settings.button_cursor)
  276 + ].join('');
  277 +};
  278 +
  279 +// Public: getMovieElement retrieves the DOM reference to the Flash element added by SWFUpload
  280 +// The element is cached after the first lookup
  281 +SWFUpload.prototype.getMovieElement = function() {
  282 + if (this.movieElement == undefined) {
  283 + this.movieElement = document.getElementById(this.movieName);
  284 + }
  285 +
  286 + if (this.movieElement === null) {
  287 + throw 'Could not find Flash element';
  288 + }
  289 +
  290 + return this.movieElement;
  291 +};
  292 +
  293 +// Private: buildParamString takes the name/value pairs in the post_params setting object
  294 +// and joins them up in to a string formatted "name=value&amp;name=value"
  295 +SWFUpload.prototype.buildParamString = function() {
  296 + var postParams = this.settings.post_params;
  297 + var paramStringPairs = [];
  298 +
  299 + if (typeof(postParams) === 'object') {
  300 + for (var name in postParams) {
  301 + if (postParams.hasOwnProperty(name)) {
  302 + paramStringPairs.push(encodeURIComponent(name.toString()) + '=' + encodeURIComponent(postParams[name].toString()));
  303 + }
  304 + }
  305 + }
  306 +
  307 + return paramStringPairs.join('&amp;');
  308 +};
  309 +
  310 +// Public: Used to remove a SWFUpload instance from the page. This method strives to remove
  311 +// all references to the SWF, and other objects so memory is properly freed.
  312 +// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state.
  313 +// Credits: Major improvements provided by steffen
  314 +SWFUpload.prototype.destroy = function() {
  315 + try {
  316 + // Make sure Flash is done before we try to remove it
  317 + this.cancelUpload(null, false);
  318 +
  319 +
  320 + // Remove the SWFUpload DOM nodes
  321 + var movieElement = null;
  322 + movieElement = this.getMovieElement();
  323 +
  324 + if (movieElement && typeof(movieElement.CallFunction) === 'unknown') { // We only want to do this in IE
  325 + // Loop through all the movie's properties and remove all function references (DOM/JS IE 6/7 memory leak workaround)
  326 + for (var i in movieElement) {
  327 + try {
  328 + if (typeof(movieElement[i]) === 'function') {
  329 + movieElement[i] = null;
  330 + }
  331 + } catch (ex1) {}
  332 + }
  333 +
  334 + // Remove the Movie Element from the page
  335 + try {
  336 + movieElement.parentNode.removeChild(movieElement);
  337 + } catch (ex) {}
  338 + }
  339 +
  340 + // Remove IE form fix reference
  341 + window[this.movieName] = null;
  342 +
  343 + // Destroy other references
  344 + SWFUpload.instances[this.movieName] = null;
  345 + delete SWFUpload.instances[this.movieName];
  346 +
  347 + this.movieElement = null;
  348 + this.settings = null;
  349 + this.customSettings = null;
  350 + this.eventQueue = null;
  351 + this.movieName = null;
  352 +
  353 +
  354 + return true;
  355 + } catch (ex2) {
  356 + return false;
  357 + }
  358 +};
  359 +
  360 +
  361 +// Public: displayDebugInfo prints out settings and configuration
  362 +// information about this SWFUpload instance.
  363 +// This function (and any references to it) can be deleted when placing
  364 +// SWFUpload in production.
  365 +SWFUpload.prototype.displayDebugInfo = function() {
  366 + this.debug(
  367 + [
  368 + '---SWFUpload Instance Info---\n',
  369 + 'Version: ', SWFUpload.version, '\n',
  370 + 'Movie Name: ', this.movieName, '\n',
  371 + 'Settings:\n',
  372 + '\t', 'upload_url: ', this.settings.upload_url, '\n',
  373 + '\t', 'flash_url: ', this.settings.flash_url, '\n',
  374 + '\t', 'use_query_string: ', this.settings.use_query_string.toString(), '\n',
  375 + '\t', 'requeue_on_error: ', this.settings.requeue_on_error.toString(), '\n',
  376 + '\t', 'http_success: ', this.settings.http_success.join(', '), '\n',
  377 + '\t', 'assume_success_timeout: ', this.settings.assume_success_timeout, '\n',
  378 + '\t', 'file_post_name: ', this.settings.file_post_name, '\n',
  379 + '\t', 'post_params: ', this.settings.post_params.toString(), '\n',
  380 + '\t', 'file_types: ', this.settings.file_types, '\n',
  381 + '\t', 'file_types_description: ', this.settings.file_types_description, '\n',
  382 + '\t', 'file_size_limit: ', this.settings.file_size_limit, '\n',
  383 + '\t', 'file_upload_limit: ', this.settings.file_upload_limit, '\n',
  384 + '\t', 'file_queue_limit: ', this.settings.file_queue_limit, '\n',
  385 + '\t', 'debug: ', this.settings.debug.toString(), '\n',
  386 +
  387 + '\t', 'prevent_swf_caching: ', this.settings.prevent_swf_caching.toString(), '\n',
  388 +
  389 + '\t', 'button_placeholder_id: ', this.settings.button_placeholder_id.toString(), '\n',
  390 + '\t', 'button_placeholder: ', (this.settings.button_placeholder ? 'Set' : 'Not Set'), '\n',
  391 + '\t', 'button_image_url: ', this.settings.button_image_url.toString(), '\n',
  392 + '\t', 'button_width: ', this.settings.button_width.toString(), '\n',
  393 + '\t', 'button_height: ', this.settings.button_height.toString(), '\n',
  394 + '\t', 'button_text: ', this.settings.button_text.toString(), '\n',
  395 + '\t', 'button_text_style: ', this.settings.button_text_style.toString(), '\n',
  396 + '\t', 'button_text_top_padding: ', this.settings.button_text_top_padding.toString(), '\n',
  397 + '\t', 'button_text_left_padding: ', this.settings.button_text_left_padding.toString(), '\n',
  398 + '\t', 'button_action: ', this.settings.button_action.toString(), '\n',
  399 + '\t', 'button_disabled: ', this.settings.button_disabled.toString(), '\n',
  400 +
  401 + '\t', 'custom_settings: ', this.settings.custom_settings.toString(), '\n',
  402 + 'Event Handlers:\n',
  403 + '\t', 'swfupload_loaded_handler assigned: ', (typeof this.settings.swfupload_loaded_handler === 'function').toString(), '\n',
  404 + '\t', 'file_dialog_start_handler assigned: ', (typeof this.settings.file_dialog_start_handler === 'function').toString(), '\n',
  405 + '\t', 'file_queued_handler assigned: ', (typeof this.settings.file_queued_handler === 'function').toString(), '\n',
  406 + '\t', 'file_queue_error_handler assigned: ', (typeof this.settings.file_queue_error_handler === 'function').toString(), '\n',
  407 + '\t', 'upload_start_handler assigned: ', (typeof this.settings.upload_start_handler === 'function').toString(), '\n',
  408 + '\t', 'upload_progress_handler assigned: ', (typeof this.settings.upload_progress_handler === 'function').toString(), '\n',
  409 + '\t', 'upload_error_handler assigned: ', (typeof this.settings.upload_error_handler === 'function').toString(), '\n',
  410 + '\t', 'upload_success_handler assigned: ', (typeof this.settings.upload_success_handler === 'function').toString(), '\n',
  411 + '\t', 'upload_complete_handler assigned: ', (typeof this.settings.upload_complete_handler === 'function').toString(), '\n',
  412 + '\t', 'debug_handler assigned: ', (typeof this.settings.debug_handler === 'function').toString(), '\n'
  413 + ].join('')
  414 + );
  415 +};
  416 +
  417 +/* Note: addSetting and getSetting are no longer used by SWFUpload but are included
  418 + the maintain v2 API compatibility
  419 +*/
  420 +// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used.
  421 +SWFUpload.prototype.addSetting = function(name, value, default_value) {
  422 + if (value == undefined) {
  423 + return (this.settings[name] = default_value);
  424 + } else {
  425 + return (this.settings[name] = value);
  426 + }
  427 +};
  428 +
  429 +// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found.
  430 +SWFUpload.prototype.getSetting = function(name) {
  431 + if (this.settings[name] != undefined) {
  432 + return this.settings[name];
  433 + }
  434 +
  435 + return '';
  436 +};
  437 +
  438 +
  439 +
  440 +// Private: callFlash handles function calls made to the Flash element.
  441 +// Calls are made with a setTimeout for some functions to work around
  442 +// bugs in the ExternalInterface library.
  443 +SWFUpload.prototype.callFlash = function(functionName, argumentArray) {
  444 + argumentArray = argumentArray || [];
  445 +
  446 + var movieElement = this.getMovieElement();
  447 + var returnValue, returnString;
  448 +
  449 + // Flash's method if calling ExternalInterface methods (code adapted from MooTools).
  450 + try {
  451 + returnString = movieElement.CallFunction('<invoke name="' + functionName + '" returntype="javascript">' + __flash__argumentsToXML(argumentArray, 0) + '</invoke>');
  452 + returnValue = eval(returnString);
  453 + } catch (ex) {
  454 + throw 'Call to ' + functionName + ' failed';
  455 + }
  456 +
  457 + // Unescape file post param values
  458 + if (returnValue != undefined && typeof returnValue.post === 'object') {
  459 + returnValue = this.unescapeFilePostParams(returnValue);
  460 + }
  461 +
  462 + return returnValue;
  463 +};
  464 +
  465 +/* *****************************
  466 + -- Flash control methods --
  467 + Your UI should use these
  468 + to operate SWFUpload
  469 + ***************************** */
  470 +
  471 +// WARNING: this function does not work in Flash Player 10
  472 +// Public: selectFile causes a File Selection Dialog window to appear. This
  473 +// dialog only allows 1 file to be selected.
  474 +SWFUpload.prototype.selectFile = function() {
  475 + this.callFlash('SelectFile');
  476 +};
  477 +
  478 +// WARNING: this function does not work in Flash Player 10
  479 +// Public: selectFiles causes a File Selection Dialog window to appear/ This
  480 +// dialog allows the user to select any number of files
  481 +// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names.
  482 +// If the selection name length is too long the dialog will fail in an unpredictable manner. There is no work-around
  483 +// for this bug.
  484 +SWFUpload.prototype.selectFiles = function() {
  485 + this.callFlash('SelectFiles');
  486 +};
  487 +
  488 +
  489 +// Public: startUpload starts uploading the first file in the queue unless
  490 +// the optional parameter 'fileID' specifies the ID
  491 +SWFUpload.prototype.startUpload = function(fileID) {
  492 + this.callFlash('StartUpload', [fileID]);
  493 +};
  494 +
  495 +// Public: cancelUpload cancels any queued file. The fileID parameter may be the file ID or index.
  496 +// If you do not specify a fileID the current uploading file or first file in the queue is cancelled.
  497 +// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter.
  498 +SWFUpload.prototype.cancelUpload = function(fileID, triggerErrorEvent) {
  499 + if (triggerErrorEvent !== false) {
  500 + triggerErrorEvent = true;
  501 + }
  502 + this.callFlash('CancelUpload', [fileID, triggerErrorEvent]);
  503 +};
  504 +
  505 +// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue.
  506 +// If nothing is currently uploading then nothing happens.
  507 +SWFUpload.prototype.stopUpload = function() {
  508 + this.callFlash('StopUpload');
  509 +};
  510 +
  511 +/* ************************
  512 + * Settings methods
  513 + * These methods change the SWFUpload settings.
  514 + * SWFUpload settings should not be changed directly on the settings object
  515 + * since many of the settings need to be passed to Flash in order to take
  516 + * effect.
  517 + * *********************** */
  518 +
  519 +// Public: getStats gets the file statistics object.
  520 +SWFUpload.prototype.getStats = function() {
  521 + return this.callFlash('GetStats');
  522 +};
  523 +
  524 +// Public: setStats changes the SWFUpload statistics. You shouldn't need to
  525 +// change the statistics but you can. Changing the statistics does not
  526 +// affect SWFUpload accept for the successful_uploads count which is used
  527 +// by the upload_limit setting to determine how many files the user may upload.
  528 +SWFUpload.prototype.setStats = function(statsObject) {
  529 + this.callFlash('SetStats', [statsObject]);
  530 +};
  531 +
  532 +// Public: getFile retrieves a File object by ID or Index. If the file is
  533 +// not found then 'null' is returned.
  534 +SWFUpload.prototype.getFile = function(fileID) {
  535 + if (typeof(fileID) === 'number') {
  536 + return this.callFlash('GetFileByIndex', [fileID]);
  537 + } else {
  538 + return this.callFlash('GetFile', [fileID]);
  539 + }
  540 +};
  541 +
  542 +// Public: addFileParam sets a name/value pair that will be posted with the
  543 +// file specified by the Files ID. If the name already exists then the
  544 +// exiting value will be overwritten.
  545 +SWFUpload.prototype.addFileParam = function(fileID, name, value) {
  546 + return this.callFlash('AddFileParam', [fileID, name, value]);
  547 +};
  548 +
  549 +// Public: removeFileParam removes a previously set (by addFileParam) name/value
  550 +// pair from the specified file.
  551 +SWFUpload.prototype.removeFileParam = function(fileID, name) {
  552 + this.callFlash('RemoveFileParam', [fileID, name]);
  553 +};
  554 +
  555 +// Public: setUploadUrl changes the upload_url setting.
  556 +SWFUpload.prototype.setUploadURL = function(url) {
  557 + this.settings.upload_url = url.toString();
  558 + this.callFlash('SetUploadURL', [url]);
  559 +};
  560 +
  561 +// Public: setPostParams changes the post_params setting
  562 +SWFUpload.prototype.setPostParams = function(paramsObject) {
  563 + this.settings.post_params = paramsObject;
  564 + this.callFlash('SetPostParams', [paramsObject]);
  565 +};
  566 +
  567 +// Public: addPostParam adds post name/value pair. Each name can have only one value.
  568 +SWFUpload.prototype.addPostParam = function(name, value) {
  569 + this.settings.post_params[name] = value;
  570 + this.callFlash('SetPostParams', [this.settings.post_params]);
  571 +};
  572 +
  573 +// Public: removePostParam deletes post name/value pair.
  574 +SWFUpload.prototype.removePostParam = function(name) {
  575 + delete this.settings.post_params[name];
  576 + this.callFlash('SetPostParams', [this.settings.post_params]);
  577 +};
  578 +
  579 +// Public: setFileTypes changes the file_types setting and the file_types_description setting
  580 +SWFUpload.prototype.setFileTypes = function(types, description) {
  581 + this.settings.file_types = types;
  582 + this.settings.file_types_description = description;
  583 + this.callFlash('SetFileTypes', [types, description]);
  584 +};
  585 +
  586 +// Public: setFileSizeLimit changes the file_size_limit setting
  587 +SWFUpload.prototype.setFileSizeLimit = function(fileSizeLimit) {
  588 + this.settings.file_size_limit = fileSizeLimit;
  589 + this.callFlash('SetFileSizeLimit', [fileSizeLimit]);
  590 +};
  591 +
  592 +// Public: setFileUploadLimit changes the file_upload_limit setting
  593 +SWFUpload.prototype.setFileUploadLimit = function(fileUploadLimit) {
  594 + this.settings.file_upload_limit = fileUploadLimit;
  595 + this.callFlash('SetFileUploadLimit', [fileUploadLimit]);
  596 +};
  597 +
  598 +// Public: setFileQueueLimit changes the file_queue_limit setting
  599 +SWFUpload.prototype.setFileQueueLimit = function(fileQueueLimit) {
  600 + this.settings.file_queue_limit = fileQueueLimit;
  601 + this.callFlash('SetFileQueueLimit', [fileQueueLimit]);
  602 +};
  603 +
  604 +// Public: setFilePostName changes the file_post_name setting
  605 +SWFUpload.prototype.setFilePostName = function(filePostName) {
  606 + this.settings.file_post_name = filePostName;
  607 + this.callFlash('SetFilePostName', [filePostName]);
  608 +};
  609 +
  610 +// Public: setUseQueryString changes the use_query_string setting
  611 +SWFUpload.prototype.setUseQueryString = function(useQueryString) {
  612 + this.settings.use_query_string = useQueryString;
  613 + this.callFlash('SetUseQueryString', [useQueryString]);
  614 +};
  615 +
  616 +// Public: setRequeueOnError changes the requeue_on_error setting
  617 +SWFUpload.prototype.setRequeueOnError = function(requeueOnError) {
  618 + this.settings.requeue_on_error = requeueOnError;
  619 + this.callFlash('SetRequeueOnError', [requeueOnError]);
  620 +};
  621 +
  622 +// Public: setHTTPSuccess changes the http_success setting
  623 +SWFUpload.prototype.setHTTPSuccess = function(http_status_codes) {
  624 + if (typeof http_status_codes === 'string') {
  625 + http_status_codes = http_status_codes.replace(' ', '').split(',');
  626 + }
  627 +
  628 + this.settings.http_success = http_status_codes;
  629 + this.callFlash('SetHTTPSuccess', [http_status_codes]);
  630 +};
  631 +
  632 +// Public: setHTTPSuccess changes the http_success setting
  633 +SWFUpload.prototype.setAssumeSuccessTimeout = function(timeout_seconds) {
  634 + this.settings.assume_success_timeout = timeout_seconds;
  635 + this.callFlash('SetAssumeSuccessTimeout', [timeout_seconds]);
  636 +};
  637 +
  638 +// Public: setDebugEnabled changes the debug_enabled setting
  639 +SWFUpload.prototype.setDebugEnabled = function(debugEnabled) {
  640 + this.settings.debug_enabled = debugEnabled;
  641 + this.callFlash('SetDebugEnabled', [debugEnabled]);
  642 +};
  643 +
  644 +// Public: setButtonImageURL loads a button image sprite
  645 +SWFUpload.prototype.setButtonImageURL = function(buttonImageURL) {
  646 + if (buttonImageURL == undefined) {
  647 + buttonImageURL = '';
  648 + }
  649 +
  650 + this.settings.button_image_url = buttonImageURL;
  651 + this.callFlash('SetButtonImageURL', [buttonImageURL]);
  652 +};
  653 +
  654 +// Public: setButtonDimensions resizes the Flash Movie and button
  655 +SWFUpload.prototype.setButtonDimensions = function(width, height) {
  656 + this.settings.button_width = width;
  657 + this.settings.button_height = height;
  658 +
  659 + var movie = this.getMovieElement();
  660 + if (movie != undefined) {
  661 + movie.style.width = width + 'px';
  662 + movie.style.height = height + 'px';
  663 + }
  664 +
  665 + this.callFlash('SetButtonDimensions', [width, height]);
  666 +};
  667 +
  668 +// Public: setButtonText Changes the text overlaid on the button
  669 +SWFUpload.prototype.setButtonText = function(html) {
  670 + this.settings.button_text = html;
  671 + this.callFlash('SetButtonText', [html]);
  672 +};
  673 +
  674 +// Public: setButtonTextPadding changes the top and left padding of the text overlay
  675 +SWFUpload.prototype.setButtonTextPadding = function(left, top) {
  676 + this.settings.button_text_top_padding = top;
  677 + this.settings.button_text_left_padding = left;
  678 + this.callFlash('SetButtonTextPadding', [left, top]);
  679 +};
  680 +
  681 +// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button
  682 +SWFUpload.prototype.setButtonTextStyle = function(css) {
  683 + this.settings.button_text_style = css;
  684 + this.callFlash('SetButtonTextStyle', [css]);
  685 +};
  686 +
  687 +// Public: setButtonDisabled disables/enables the button
  688 +SWFUpload.prototype.setButtonDisabled = function(isDisabled) {
  689 + this.settings.button_disabled = isDisabled;
  690 + this.callFlash('SetButtonDisabled', [isDisabled]);
  691 +};
  692 +
  693 +// Public: setButtonAction sets the action that occurs when the button is clicked
  694 +SWFUpload.prototype.setButtonAction = function(buttonAction) {
  695 + this.settings.button_action = buttonAction;
  696 + this.callFlash('SetButtonAction', [buttonAction]);
  697 +};
  698 +
  699 +// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button
  700 +SWFUpload.prototype.setButtonCursor = function(cursor) {
  701 + this.settings.button_cursor = cursor;
  702 + this.callFlash('SetButtonCursor', [cursor]);
  703 +};
  704 +
  705 +/* *******************************
  706 + Flash Event Interfaces
  707 + These functions are used by Flash to trigger the various
  708 + events.
  709 +
  710 + All these functions a Private.
  711 +
  712 + Because the ExternalInterface library is buggy the event calls
  713 + are added to a queue and the queue then executed by a setTimeout.
  714 + This ensures that events are executed in a determinate order and that
  715 + the ExternalInterface bugs are avoided.
  716 +******************************* */
  717 +
  718 +SWFUpload.prototype.queueEvent = function(handlerName, argumentArray) {
  719 + // Warning: Don't call this.debug inside here or you'll create an infinite loop
  720 +
  721 + if (argumentArray == undefined) {
  722 + argumentArray = [];
  723 + } else if (!(argumentArray instanceof Array)) {
  724 + argumentArray = [argumentArray];
  725 + }
  726 +
  727 + var self = this;
  728 + if (typeof this.settings[handlerName] === 'function') {
  729 + // Queue the event
  730 + this.eventQueue.push(function() {
  731 + this.settings[handlerName].apply(this, argumentArray);
  732 + });
  733 +
  734 + // Execute the next queued event
  735 + setTimeout(function() {
  736 + self.executeNextEvent();
  737 + }, 0);
  738 +
  739 + } else if (this.settings[handlerName] !== null) {
  740 + throw 'Event handler ' + handlerName + ' is unknown or is not a function';
  741 + }
  742 +};
  743 +
  744 +// Private: Causes the next event in the queue to be executed. Since events are queued using a setTimeout
  745 +// we must queue them in order to garentee that they are executed in order.
  746 +SWFUpload.prototype.executeNextEvent = function() {
  747 + // Warning: Don't call this.debug inside here or you'll create an infinite loop
  748 +
  749 + var f = this.eventQueue ? this.eventQueue.shift() : null;
  750 + if (typeof(f) === 'function') {
  751 + f.apply(this);
  752 + }
  753 +};
  754 +
  755 +// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have
  756 +// properties that contain characters that are not valid for JavaScript identifiers. To work around this
  757 +// the Flash Component escapes the parameter names and we must unescape again before passing them along.
  758 +SWFUpload.prototype.unescapeFilePostParams = function(file) {
  759 + var reg = /[$]([0-9a-f]{4})/i;
  760 + var unescapedPost = {};
  761 + var uk;
  762 +
  763 + if (file != undefined) {
  764 + for (var k in file.post) {
  765 + if (file.post.hasOwnProperty(k)) {
  766 + uk = k;
  767 + var match;
  768 + while ((match = reg.exec(uk)) !== null) {
  769 + uk = uk.replace(match[0], String.fromCharCode(parseInt('0x' + match[1], 16)));
  770 + }
  771 + unescapedPost[uk] = file.post[k];
  772 + }
  773 + }
  774 +
  775 + file.post = unescapedPost;
  776 + }
  777 +
  778 + return file;
  779 +};
  780 +
  781 +// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working)
  782 +SWFUpload.prototype.testExternalInterface = function() {
  783 + try {
  784 + return this.callFlash('TestExternalInterface');
  785 + } catch (ex) {
  786 + return false;
  787 + }
  788 +};
  789 +
  790 +// Private: This event is called by Flash when it has finished loading. Don't modify this.
  791 +// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded.
  792 +SWFUpload.prototype.flashReady = function() {
  793 + // Check that the movie element is loaded correctly with its ExternalInterface methods defined
  794 + var movieElement = this.getMovieElement();
  795 +
  796 + if (!movieElement) {
  797 + this.debug('Flash called back ready but the flash movie can\'t be found.');
  798 + return;
  799 + }
  800 +
  801 + this.cleanUp(movieElement);
  802 +
  803 + this.queueEvent('swfupload_loaded_handler');
  804 +};
  805 +
  806 +// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE.
  807 +// This function is called by Flash each time the ExternalInterface functions are created.
  808 +SWFUpload.prototype.cleanUp = function(movieElement) {
  809 + // Pro-actively unhook all the Flash functions
  810 + try {
  811 + if (this.movieElement && typeof(movieElement.CallFunction) === 'unknown') { // We only want to do this in IE
  812 + this.debug('Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)');
  813 + for (var key in movieElement) {
  814 + try {
  815 + if (typeof(movieElement[key]) === 'function') {
  816 + movieElement[key] = null;
  817 + }
  818 + } catch (ex) {
  819 + }
  820 + }
  821 + }
  822 + } catch (ex1) {
  823 +
  824 + }
  825 +
  826 + // Fix Flashes own cleanup code so if the SWFMovie was removed from the page
  827 + // it doesn't display errors.
  828 + window['__flash__removeCallback'] = function(instance, name) {
  829 + try {
  830 + if (instance) {
  831 + instance[name] = null;
  832 + }
  833 + } catch (flashEx) {
  834 +
  835 + }
  836 + };
  837 +
  838 +};
  839 +
  840 +
  841 +/* This is a chance to do something before the browse window opens */
  842 +SWFUpload.prototype.fileDialogStart = function() {
  843 + this.queueEvent('file_dialog_start_handler');
  844 +};
  845 +
  846 +
  847 +/* Called when a file is successfully added to the queue. */
  848 +SWFUpload.prototype.fileQueued = function(file) {
  849 + file = this.unescapeFilePostParams(file);
  850 + this.queueEvent('file_queued_handler', file);
  851 +};
  852 +
  853 +
  854 +/* Handle errors that occur when an attempt to queue a file fails. */
  855 +SWFUpload.prototype.fileQueueError = function(file, errorCode, message) {
  856 + file = this.unescapeFilePostParams(file);
  857 + this.queueEvent('file_queue_error_handler', [file, errorCode, message]);
  858 +};
  859 +
  860 +/* Called after the file dialog has closed and the selected files have been queued.
  861 + You could call startUpload here if you want the queued files to begin uploading immediately. */
  862 +SWFUpload.prototype.fileDialogComplete = function(numFilesSelected, numFilesQueued, numFilesInQueue) {
  863 + this.queueEvent('file_dialog_complete_handler', [numFilesSelected, numFilesQueued, numFilesInQueue]);
  864 +};
  865 +
  866 +SWFUpload.prototype.uploadStart = function(file) {
  867 + file = this.unescapeFilePostParams(file);
  868 + this.queueEvent('return_upload_start_handler', file);
  869 +};
  870 +
  871 +SWFUpload.prototype.returnUploadStart = function(file) {
  872 + var returnValue;
  873 + if (typeof this.settings.upload_start_handler === 'function') {
  874 + file = this.unescapeFilePostParams(file);
  875 + returnValue = this.settings.upload_start_handler.call(this, file);
  876 + } else if (this.settings.upload_start_handler != undefined) {
  877 + throw 'upload_start_handler must be a function';
  878 + }
  879 +
  880 + // Convert undefined to true so if nothing is returned from the upload_start_handler it is
  881 + // interpretted as 'true'.
  882 + if (returnValue === undefined) {
  883 + returnValue = true;
  884 + }
  885 +
  886 + returnValue = !!returnValue;
  887 +
  888 + this.callFlash('ReturnUploadStart', [returnValue]);
  889 +};
  890 +
  891 +
  892 +
  893 +SWFUpload.prototype.uploadProgress = function(file, bytesComplete, bytesTotal) {
  894 + file = this.unescapeFilePostParams(file);
  895 + this.queueEvent('upload_progress_handler', [file, bytesComplete, bytesTotal]);
  896 +};
  897 +
  898 +SWFUpload.prototype.uploadError = function(file, errorCode, message) {
  899 + file = this.unescapeFilePostParams(file);
  900 + this.queueEvent('upload_error_handler', [file, errorCode, message]);
  901 +};
  902 +
  903 +SWFUpload.prototype.uploadSuccess = function(file, serverData, responseReceived) {
  904 + file = this.unescapeFilePostParams(file);
  905 + this.queueEvent('upload_success_handler', [file, serverData, responseReceived]);
  906 +};
  907 +
  908 +SWFUpload.prototype.uploadComplete = function(file) {
  909 + file = this.unescapeFilePostParams(file);
  910 + this.queueEvent('upload_complete_handler', file);
  911 +};
  912 +
  913 +/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the
  914 + internal debug console. You can override this event and have messages written where you want. */
  915 +SWFUpload.prototype.debug = function(message) {
  916 + this.queueEvent('debug_handler', message);
  917 +};
  918 +
  919 +
  920 +/* **********************************
  921 + Debug Console
  922 + The debug console is a self contained, in page location
  923 + for debug message to be sent. The Debug Console adds
  924 + itself to the body if necessary.
  925 +
  926 + The console is automatically scrolled as messages appear.
  927 +
  928 + If you are using your own debug handler or when you deploy to production and
  929 + have debug disabled you can remove these functions to reduce the file size
  930 + and complexity.
  931 +********************************** */
  932 +
  933 +// Private: debugMessage is the default debug_handler. If you want to print debug messages
  934 +// call the debug() function. When overriding the function your own function should
  935 +// check to see if the debug setting is true before outputting debug information.
  936 +SWFUpload.prototype.debugMessage = function(message) {
  937 + if (this.settings.debug) {
  938 + var exceptionMessage, exceptionValues = [];
  939 +
  940 + // Check for an exception object and print it nicely
  941 + if (typeof message === 'object' && typeof message.name === 'string' && typeof message.message === 'string') {
  942 + for (var key in message) {
  943 + if (message.hasOwnProperty(key)) {
  944 + exceptionValues.push(key + ': ' + message[key]);
  945 + }
  946 + }
  947 + exceptionMessage = exceptionValues.join('\n') || '';
  948 + exceptionValues = exceptionMessage.split('\n');
  949 + exceptionMessage = 'EXCEPTION: ' + exceptionValues.join('\nEXCEPTION: ');
  950 + SWFUpload.Console.writeLine(exceptionMessage);
  951 + } else {
  952 + SWFUpload.Console.writeLine(message);
  953 + }
  954 + }
  955 +};
  956 +
  957 +SWFUpload.Console = {};
  958 +SWFUpload.Console.writeLine = function(message) {
  959 + var console, documentForm;
  960 +
  961 + try {
  962 + console = document.getElementById('SWFUpload_Console');
  963 +
  964 + if (!console) {
  965 + documentForm = document.createElement('form');
  966 + document.getElementsByTagName('body')[0].appendChild(documentForm);
  967 +
  968 + console = document.createElement('textarea');
  969 + console.id = 'SWFUpload_Console';
  970 + console.style.fontFamily = 'monospace';
  971 + console.setAttribute('wrap', 'off');
  972 + console.wrap = 'off';
  973 + console.style.overflow = 'auto';
  974 + console.style.width = '700px';
  975 + console.style.height = '350px';
  976 + console.style.margin = '5px';
  977 + documentForm.appendChild(console);
  978 + }
  979 +
  980 + console.value += message + '\n';
  981 +
  982 + console.scrollTop = console.scrollHeight - console.clientHeight;
  983 + } catch (ex) {
  984 + alert('Exception: ' + ex.name + ' Message: ' + ex.message);
  985 + }
  986 +};
  987 +
  988 +exports.SWFUpload = SWFUpload;
  1 +/*
  2 + Queue Plug-in
  3 +
  4 + Features:
  5 + *Adds a cancelQueue() method for cancelling the entire queue.
  6 + *All queued files are uploaded when startUpload() is called.
  7 + *If false is returned from uploadComplete then the queue upload is stopped.
  8 + If false is not returned (strict comparison) then the queue upload is continued.
  9 + *Adds a QueueComplete event that is fired when all the queued files have finished uploading.
  10 + Set the event handler with the queue_complete_handler setting.
  11 +
  12 + */
  13 +var SWFUpload = require('./swfupload').SWFUpload;
  14 +
  15 +if (typeof(SWFUpload) === 'function') {
  16 + SWFUpload.queue = {};
  17 +
  18 + SWFUpload.prototype.initSettings = (function(oldInitSettings) {
  19 + return function() {
  20 + if (typeof(oldInitSettings) === 'function') {
  21 + oldInitSettings.call(this);
  22 + }
  23 +
  24 + this.queueSettings = {};
  25 +
  26 + this.queueSettings.queue_cancelled_flag = false;
  27 + this.queueSettings.queue_upload_count = 0;
  28 +
  29 + this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler;
  30 + this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler;
  31 + this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler;
  32 + this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler;
  33 +
  34 + this.settings.queue_complete_handler = this.settings.queue_complete_handler || null;
  35 + };
  36 + })(SWFUpload.prototype.initSettings);
  37 +
  38 + SWFUpload.prototype.startUpload = function(fileID) {
  39 + this.queueSettings.queue_cancelled_flag = false;
  40 + this.callFlash('StartUpload', [fileID]);
  41 + };
  42 +
  43 + SWFUpload.prototype.cancelQueue = function() {
  44 + this.queueSettings.queue_cancelled_flag = true;
  45 + this.stopUpload();
  46 +
  47 + var stats = this.getStats();
  48 + while (stats.files_queued > 0) {
  49 + this.cancelUpload();
  50 + stats = this.getStats();
  51 + }
  52 + };
  53 +
  54 + SWFUpload.queue.uploadStartHandler = function(file) {
  55 + var returnValue;
  56 + if (typeof(this.queueSettings.user_upload_start_handler) === 'function') {
  57 + returnValue = this.queueSettings.user_upload_start_handler.call(this, file);
  58 + }
  59 +
  60 + // To prevent upload a real "FALSE" value must be returned, otherwise default to a real "TRUE" value.
  61 + returnValue = (returnValue === false) ? false : true;
  62 +
  63 + this.queueSettings.queue_cancelled_flag = !returnValue;
  64 +
  65 + return returnValue;
  66 + };
  67 +
  68 + SWFUpload.queue.uploadCompleteHandler = function(file) {
  69 + var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler;
  70 + var continueUpload;
  71 +
  72 + if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) {
  73 + this.queueSettings.queue_upload_count++;
  74 + }
  75 +
  76 + if (typeof(user_upload_complete_handler) === 'function') {
  77 + continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true;
  78 + } else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) {
  79 + // If the file was stopped and re-queued don't restart the upload
  80 + continueUpload = false;
  81 + } else {
  82 + continueUpload = true;
  83 + }
  84 +
  85 + if (continueUpload) {
  86 + var stats = this.getStats();
  87 + if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) {
  88 + this.startUpload();
  89 + } else if (this.queueSettings.queue_cancelled_flag === false) {
  90 + this.queueEvent('queue_complete_handler', [this.queueSettings.queue_upload_count]);
  91 + this.queueSettings.queue_upload_count = 0;
  92 + } else {
  93 + this.queueSettings.queue_cancelled_flag = false;
  94 + this.queueSettings.queue_upload_count = 0;
  95 + }
  96 + }
  97 + };
  98 +}
  99 +
  100 +exports.SWFUpload = SWFUpload;
@@ -255,6 +255,7 @@ @@ -255,6 +255,7 @@
255 @import "qrcode"; 255 @import "qrcode";
256 @import "comment"; 256 @import "comment";
257 @import "consult"; 257 @import "consult";
  258 +@import "returns";
258 259
259 /* 260 /*
260 @import "red-envelopes"; 261 @import "red-envelopes";
@@ -262,7 +263,6 @@ @@ -262,7 +263,6 @@
262 @import "currency"; 263 @import "currency";
263 @import "favorite"; 264 @import "favorite";
264 @import "user-info"; 265 @import "user-info";
265 -@import "returns";  
266 @import "returns-detail"; 266 @import "returns-detail";
267 @import "returns-apply"; 267 @import "returns-apply";
268 @import "returns-save"; 268 @import "returns-save";
1 .returns-me-page { 1 .returns-me-page {
2 -  
3 .returns .title { 2 .returns .title {
4 - background-image: resolve(/home/returns.png); 3 + background-image: resolve(img/home/returns.png);
5 } 4 }
6 -  
7 .time, 5 .time,
8 .return-status, 6 .return-status,
9 .operation { 7 .operation {
10 width: 100px; 8 width: 100px;
11 border-left: 1px solid #e6e6e6; 9 border-left: 1px solid #e6e6e6;
12 } 10 }
13 -  
14 .return-type { 11 .return-type {
15 width: 80px; 12 width: 80px;
16 border-left: 1px solid #e6e6e6; 13 border-left: 1px solid #e6e6e6;
17 } 14 }
18 -  
19 .order-table-header { 15 .order-table-header {
20 padding: 0; 16 padding: 0;
21 margin: 10px; 17 margin: 10px;
22 border: 1px #e6e6e6 solid; 18 border: 1px #e6e6e6 solid;
23 -  
24 > span { 19 > span {
25 text-align: center; 20 text-align: center;
26 border-left: none; 21 border-left: none;
27 } 22 }
28 -  
29 .info { 23 .info {
30 width: 384px; 24 width: 384px;
31 padding-left: 10px; 25 padding-left: 10px;
32 text-align: left; 26 text-align: left;
33 } 27 }
34 -  
35 } 28 }
36 -  
37 .order-wrap { 29 .order-wrap {
38 -  
39 li { 30 li {
40 border-top: none; 31 border-top: none;
41 -  
42 .info { 32 .info {
43 width: 384px; 33 width: 384px;
44 padding: 5px 0 5px 10px; 34 padding: 5px 0 5px 10px;
45 } 35 }
46 -  
47 .text-info { 36 .text-info {
48 width: 300px; 37 width: 300px;
49 right: 0; 38 right: 0;
50 bottom: 15px; 39 bottom: 15px;
51 -  
52 .name { 40 .name {
53 max-width: 300px; 41 max-width: 300px;
54 } 42 }
55 -  
56 .name:hover { 43 .name:hover {
57 text-decoration: underline; 44 text-decoration: underline;
58 } 45 }
59 } 46 }
60 } 47 }
61 } 48 }
62 -  
63 -}  
  49 +}
  1 +'use strict';
  2 +let Promise = require('bluebird');
  3 +let co = Promise.coroutine;
  4 +
  5 +
  6 +co(function*() {
  7 + let a = yield Promise.reject(3);
  8 + console.log('here');
  9 + a = 4;
  10 + return a;
  11 +})().then(a=>console.log(a))
  12 +.catch(a=>console.log(a));