video.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  1. /**
  2. * Created by JetBrains PhpStorm.
  3. * User: taoqili
  4. * Date: 12-2-20
  5. * Time: 上午11:19
  6. * To change this template use File | Settings | File Templates.
  7. */
  8. ;(function () {
  9. var video = {},
  10. uploadVideoList = [],
  11. isModifyUploadVideo = false,
  12. uploadFile
  13. window.onload = function () {
  14. $focus($G('videoUrl'))
  15. initTabs()
  16. initVideo()
  17. initUpload()
  18. }
  19. /* 初始化tab标签 */
  20. function initTabs() {
  21. var tabs = $G('tabHeads').children
  22. for (var i = 0; i < tabs.length; i++) {
  23. domUtils.on(tabs[i], 'click', function (e) {
  24. var j,
  25. bodyId,
  26. target = e.target || e.srcElement
  27. for (j = 0; j < tabs.length; j++) {
  28. bodyId = tabs[j].getAttribute('data-content-id')
  29. if (tabs[j] == target) {
  30. domUtils.addClass(tabs[j], 'focus')
  31. domUtils.addClass($G(bodyId), 'focus')
  32. } else {
  33. domUtils.removeClasses(tabs[j], 'focus')
  34. domUtils.removeClasses($G(bodyId), 'focus')
  35. }
  36. }
  37. })
  38. }
  39. }
  40. function initVideo() {
  41. createAlignButton(['videoFloat', 'upload_alignment'])
  42. addUrlChangeListener($G('videoUrl'))
  43. addOkListener()
  44. //编辑视频时初始化相关信息
  45. ;(function () {
  46. var img = editor.selection.getRange().getClosedNode(),
  47. url
  48. if (img && img.className) {
  49. var hasFakedClass = img.className == 'edui-faked-video',
  50. hasUploadClass = img.className.indexOf('edui-upload-video') != -1
  51. if (hasFakedClass || hasUploadClass) {
  52. $G('videoUrl').value = url = img.getAttribute('_url')
  53. $G('videoWidth').value = img.width
  54. $G('videoHeight').value = img.height
  55. var align = domUtils.getComputedStyle(img, 'float'),
  56. parentAlign = domUtils.getComputedStyle(
  57. img.parentNode,
  58. 'text-align'
  59. )
  60. updateAlignButton(parentAlign === 'center' ? 'center' : align)
  61. }
  62. if (hasUploadClass) {
  63. isModifyUploadVideo = true
  64. }
  65. }
  66. createPreviewVideo(url)
  67. })()
  68. }
  69. /**
  70. * 监听确认和取消两个按钮事件,用户执行插入或者清空正在播放的视频实例操作
  71. */
  72. function addOkListener() {
  73. dialog.onok = function () {
  74. $G('preview').innerHTML = ''
  75. var currentTab = findFocus('tabHeads', 'tabSrc')
  76. switch (currentTab) {
  77. case 'video':
  78. return insertSingle()
  79. break
  80. case 'videoSearch':
  81. return insertSearch('searchList')
  82. break
  83. case 'upload':
  84. return insertUpload()
  85. break
  86. }
  87. }
  88. dialog.oncancel = function () {
  89. $G('preview').innerHTML = ''
  90. }
  91. }
  92. /**
  93. * 依据传入的align值更新按钮信息
  94. * @param align
  95. */
  96. function updateAlignButton(align) {
  97. var aligns = $G('videoFloat').children
  98. for (var i = 0, ci; (ci = aligns[i++]); ) {
  99. if (ci.getAttribute('name') == align) {
  100. if (ci.className != 'focus') {
  101. ci.className = 'focus'
  102. }
  103. } else {
  104. if (ci.className == 'focus') {
  105. ci.className = ''
  106. }
  107. }
  108. }
  109. }
  110. /**
  111. * 将单个视频信息插入编辑器中
  112. */
  113. function insertSingle() {
  114. var width = $G('videoWidth'),
  115. height = $G('videoHeight'),
  116. url = $G('videoUrl').value,
  117. align = findFocus('videoFloat', 'name')
  118. if (!url) return false
  119. if (!checkNum([width, height])) return false
  120. editor.execCommand(
  121. 'insertvideo',
  122. {
  123. url: convert_url(url),
  124. width: width.value,
  125. height: height.value,
  126. align: align
  127. },
  128. isModifyUploadVideo ? 'upload' : null
  129. )
  130. }
  131. /**
  132. * 将元素id下的所有代表视频的图片插入编辑器中
  133. * @param id
  134. */
  135. function insertSearch(id) {
  136. var imgs = domUtils.getElementsByTagName($G(id), 'img'),
  137. videoObjs = []
  138. for (var i = 0, img; (img = imgs[i++]); ) {
  139. if (img.getAttribute('selected')) {
  140. videoObjs.push({
  141. url: img.getAttribute('ue_video_url'),
  142. width: 420,
  143. height: 280,
  144. align: 'none'
  145. })
  146. }
  147. }
  148. editor.execCommand('insertvideo', videoObjs)
  149. }
  150. /**
  151. * 找到id下具有focus类的节点并返回该节点下的某个属性
  152. * @param id
  153. * @param returnProperty
  154. */
  155. function findFocus(id, returnProperty) {
  156. var tabs = $G(id).children,
  157. property
  158. for (var i = 0, ci; (ci = tabs[i++]); ) {
  159. if (ci.className == 'focus') {
  160. property = ci.getAttribute(returnProperty)
  161. break
  162. }
  163. }
  164. return property
  165. }
  166. function convert_url(url) {
  167. if (!url) return ''
  168. url = utils
  169. .trim(url)
  170. .replace(
  171. /v\.youku\.com\/v_show\/id_([\w\-=]+)\.html/i,
  172. 'player.youku.com/player.php/sid/$1/v.swf'
  173. )
  174. .replace(
  175. /(www\.)?youtube\.com\/watch\?v=([\w\-]+)/i,
  176. 'www.youtube.com/v/$2'
  177. )
  178. .replace(/youtu.be\/(\w+)$/i, 'www.youtube.com/v/$1')
  179. .replace(
  180. /v\.ku6\.com\/.+\/([\w\.]+)\.html.*$/i,
  181. 'player.ku6.com/refer/$1/v.swf'
  182. )
  183. .replace(
  184. /www\.56\.com\/u\d+\/v_([\w\-]+)\.html/i,
  185. 'player.56.com/v_$1.swf'
  186. )
  187. .replace(
  188. /www.56.com\/w\d+\/play_album\-aid\-\d+_vid\-([^.]+)\.html/i,
  189. 'player.56.com/v_$1.swf'
  190. )
  191. .replace(
  192. /v\.pps\.tv\/play_([\w]+)\.html.*$/i,
  193. 'player.pps.tv/player/sid/$1/v.swf'
  194. )
  195. .replace(
  196. /www\.letv\.com\/ptv\/vplay\/([\d]+)\.html.*$/i,
  197. 'i7.imgs.letv.com/player/swfPlayer.swf?id=$1&autoplay=0'
  198. )
  199. .replace(
  200. /www\.tudou\.com\/programs\/view\/([\w\-]+)\/?/i,
  201. 'www.tudou.com/v/$1'
  202. )
  203. .replace(
  204. /v\.qq\.com\/cover\/[\w]+\/[\w]+\/([\w]+)\.html/i,
  205. 'static.video.qq.com/TPout.swf?vid=$1'
  206. )
  207. .replace(
  208. /v\.qq\.com\/.+[\?\&]vid=([^&]+).*$/i,
  209. 'static.video.qq.com/TPout.swf?vid=$1'
  210. )
  211. .replace(
  212. /my\.tv\.sohu\.com\/[\w]+\/[\d]+\/([\d]+)\.shtml.*$/i,
  213. 'share.vrs.sohu.com/my/v.swf&id=$1'
  214. )
  215. return url
  216. }
  217. /**
  218. * 检测传入的所有input框中输入的长宽是否是正数
  219. * @param nodes input框集合,
  220. */
  221. function checkNum(nodes) {
  222. for (var i = 0, ci; (ci = nodes[i++]); ) {
  223. var value = ci.value
  224. if (!isNumber(value) && value) {
  225. alert(lang.numError)
  226. ci.value = ''
  227. ci.focus()
  228. return false
  229. }
  230. }
  231. return true
  232. }
  233. /**
  234. * 数字判断
  235. * @param value
  236. */
  237. function isNumber(value) {
  238. return /(0|^[1-9]\d*$)/.test(value)
  239. }
  240. /**
  241. * 创建图片浮动选择按钮
  242. * @param ids
  243. */
  244. function createAlignButton(ids) {
  245. for (var i = 0, ci; (ci = ids[i++]); ) {
  246. var floatContainer = $G(ci),
  247. nameMaps = {
  248. none: lang['default'],
  249. left: lang.floatLeft,
  250. right: lang.floatRight,
  251. center: lang.block
  252. }
  253. for (var j in nameMaps) {
  254. var div = document.createElement('div')
  255. div.setAttribute('name', j)
  256. if (j == 'none') div.className = 'focus'
  257. div.style.cssText = 'background:url(images/' + j + '_focus.jpg);'
  258. div.setAttribute('title', nameMaps[j])
  259. floatContainer.appendChild(div)
  260. }
  261. switchSelect(ci)
  262. }
  263. }
  264. /**
  265. * 选择切换
  266. * @param selectParentId
  267. */
  268. function switchSelect(selectParentId) {
  269. var selects = $G(selectParentId).children
  270. for (var i = 0, ci; (ci = selects[i++]); ) {
  271. domUtils.on(ci, 'click', function () {
  272. for (var j = 0, cj; (cj = selects[j++]); ) {
  273. cj.className = ''
  274. cj.removeAttribute && cj.removeAttribute('class')
  275. }
  276. this.className = 'focus'
  277. })
  278. }
  279. }
  280. /**
  281. * 监听url改变事件
  282. * @param url
  283. */
  284. function addUrlChangeListener(url) {
  285. if (browser.ie) {
  286. url.onpropertychange = function () {
  287. createPreviewVideo(this.value)
  288. }
  289. } else {
  290. url.addEventListener(
  291. 'input',
  292. function () {
  293. createPreviewVideo(this.value)
  294. },
  295. false
  296. )
  297. }
  298. }
  299. /**
  300. * 根据url生成视频预览
  301. * @param url
  302. */
  303. function createPreviewVideo(url) {
  304. if (!url) return
  305. var conUrl = convert_url(url)
  306. conUrl = utils.unhtmlForUrl(conUrl)
  307. $G('preview').innerHTML =
  308. '<div class="previewMsg"><span>' +
  309. lang.urlError +
  310. '</span></div>' +
  311. '<embed class="previewVideo" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"' +
  312. ' src="' +
  313. conUrl +
  314. '"' +
  315. ' width="' +
  316. 420 +
  317. '"' +
  318. ' height="' +
  319. 280 +
  320. '"' +
  321. ' wmode="transparent" play="true" loop="false" menu="false" allowscriptaccess="never" allowfullscreen="true" >' +
  322. '</embed>'
  323. }
  324. /* 插入上传视频 */
  325. function insertUpload() {
  326. var videoObjs = [],
  327. uploadDir = editor.getOpt('videoUrlPrefix'),
  328. width = parseInt($G('upload_width').value, 10) || 420,
  329. height = parseInt($G('upload_height').value, 10) || 280,
  330. align = findFocus('upload_alignment', 'name') || 'none'
  331. for (var key in uploadVideoList) {
  332. var file = uploadVideoList[key]
  333. videoObjs.push({
  334. url: file.url,
  335. width: width,
  336. height: height,
  337. align: align
  338. })
  339. }
  340. var count = uploadFile.getQueueCount()
  341. if (count) {
  342. $('.info', '#queueList').html(
  343. '<span style="color:red;">' +
  344. '还有2个未上传文件'.replace(/[\d]/, count) +
  345. '</span>'
  346. )
  347. return false
  348. } else {
  349. editor.execCommand('insertvideo', videoObjs, 'upload')
  350. }
  351. }
  352. /*初始化上传标签*/
  353. function initUpload() {
  354. uploadFile = new UploadFile('queueList')
  355. }
  356. /* 上传附件 */
  357. function UploadFile(target) {
  358. this.$wrap = target.constructor == String ? $('#' + target) : $(target)
  359. this.init()
  360. }
  361. UploadFile.prototype = {
  362. init: function () {
  363. this.fileList = []
  364. this.initContainer()
  365. this.initUploader()
  366. },
  367. initContainer: function () {
  368. this.$queue = this.$wrap.find('.filelist')
  369. },
  370. /* 初始化容器 */
  371. initUploader: function () {
  372. var _this = this,
  373. $ = jQuery, // just in case. Make sure it's not an other libaray.
  374. $wrap = _this.$wrap,
  375. // 图片容器
  376. $queue = $wrap.find('.filelist'),
  377. // 状态栏,包括进度和控制按钮
  378. $statusBar = $wrap.find('.statusBar'),
  379. // 文件总体选择信息。
  380. $info = $statusBar.find('.info'),
  381. // 上传按钮
  382. $upload = $wrap.find('.uploadBtn'),
  383. // 上传按钮
  384. $filePickerBtn = $wrap.find('.filePickerBtn'),
  385. // 上传按钮
  386. $filePickerBlock = $wrap.find('.filePickerBlock'),
  387. // 没选择文件之前的内容。
  388. $placeHolder = $wrap.find('.placeholder'),
  389. // 总体进度条
  390. $progress = $statusBar.find('.progress').hide(),
  391. // 添加的文件数量
  392. fileCount = 0,
  393. // 添加的文件总大小
  394. fileSize = 0,
  395. // 优化retina, 在retina下这个值是2
  396. ratio = window.devicePixelRatio || 1,
  397. // 缩略图大小
  398. thumbnailWidth = 113 * ratio,
  399. thumbnailHeight = 113 * ratio,
  400. // 可能有pedding, ready, uploading, confirm, done.
  401. state = '',
  402. // 所有文件的进度信息,key为file id
  403. percentages = {},
  404. supportTransition = (function () {
  405. var s = document.createElement('p').style,
  406. r =
  407. 'transition' in s ||
  408. 'WebkitTransition' in s ||
  409. 'MozTransition' in s ||
  410. 'msTransition' in s ||
  411. 'OTransition' in s
  412. s = null
  413. return r
  414. })(),
  415. // WebUploader实例
  416. uploader,
  417. actionUrl = editor.getActionUrl(editor.getOpt('videoActionName')),
  418. fileMaxSize = editor.getOpt('videoMaxSize'),
  419. acceptExtensions = (editor.getOpt('videoAllowFiles') || [])
  420. .join('')
  421. .replace(/\./g, ',')
  422. .replace(/^[,]/, '')
  423. if (!WebUploader.Uploader.support()) {
  424. $('#filePickerReady')
  425. .after($('<div>').html(lang.errorNotSupport))
  426. .hide()
  427. return
  428. } else if (!editor.getOpt('videoActionName')) {
  429. $('#filePickerReady')
  430. .after($('<div>').html(lang.errorLoadConfig))
  431. .hide()
  432. return
  433. }
  434. uploader = _this.uploader = WebUploader.create({
  435. pick: {
  436. id: '#filePickerReady',
  437. label: lang.uploadSelectFile
  438. },
  439. swf: '../../third-party/webuploader/Uploader.swf',
  440. server: actionUrl,
  441. fileVal: editor.getOpt('videoFieldName'),
  442. duplicate: true,
  443. fileSingleSizeLimit: fileMaxSize,
  444. compress: false
  445. })
  446. uploader.addButton({
  447. id: '#filePickerBlock'
  448. })
  449. uploader.addButton({
  450. id: '#filePickerBtn',
  451. label: lang.uploadAddFile
  452. })
  453. setState('pedding')
  454. // 当有文件添加进来时执行,负责view的创建
  455. function addFile(file) {
  456. var $li = $(
  457. '<li id="' +
  458. file.id +
  459. '">' +
  460. '<p class="title">' +
  461. file.name +
  462. '</p>' +
  463. '<p class="imgWrap"></p>' +
  464. '<p class="progress"><span></span></p>' +
  465. '</li>'
  466. ),
  467. $btns = $(
  468. '<div class="file-panel">' +
  469. '<span class="cancel">' +
  470. lang.uploadDelete +
  471. '</span>' +
  472. '<span class="rotateRight">' +
  473. lang.uploadTurnRight +
  474. '</span>' +
  475. '<span class="rotateLeft">' +
  476. lang.uploadTurnLeft +
  477. '</span></div>'
  478. ).appendTo($li),
  479. $prgress = $li.find('p.progress span'),
  480. $wrap = $li.find('p.imgWrap'),
  481. $info = $('<p class="error"></p>').hide().appendTo($li),
  482. showError = function (code) {
  483. switch (code) {
  484. case 'exceed_size':
  485. text = lang.errorExceedSize
  486. break
  487. case 'interrupt':
  488. text = lang.errorInterrupt
  489. break
  490. case 'http':
  491. text = lang.errorHttp
  492. break
  493. case 'not_allow_type':
  494. text = lang.errorFileType
  495. break
  496. default:
  497. text = lang.errorUploadRetry
  498. break
  499. }
  500. $info.text(text).show()
  501. }
  502. if (file.getStatus() === 'invalid') {
  503. showError(file.statusText)
  504. } else {
  505. $wrap.text(lang.uploadPreview)
  506. if (
  507. '|png|jpg|jpeg|bmp|gif|'.indexOf(
  508. '|' + file.ext.toLowerCase() + '|'
  509. ) == -1
  510. ) {
  511. $wrap
  512. .empty()
  513. .addClass('notimage')
  514. .append(
  515. '<i class="file-preview file-type-' +
  516. file.ext.toLowerCase() +
  517. '"></i>' +
  518. '<span class="file-title">' +
  519. file.name +
  520. '</span>'
  521. )
  522. } else {
  523. if (browser.ie && browser.version <= 7) {
  524. $wrap.text(lang.uploadNoPreview)
  525. } else {
  526. uploader.makeThumb(
  527. file,
  528. function (error, src) {
  529. if (
  530. error ||
  531. !src ||
  532. (/^data:/.test(src) && browser.ie && browser.version <= 7)
  533. ) {
  534. $wrap.text(lang.uploadNoPreview)
  535. } else {
  536. var $img = $('<img src="' + src + '">')
  537. $wrap.empty().append($img)
  538. $img.on('error', function () {
  539. $wrap.text(lang.uploadNoPreview)
  540. })
  541. }
  542. },
  543. thumbnailWidth,
  544. thumbnailHeight
  545. )
  546. }
  547. }
  548. percentages[file.id] = [file.size, 0]
  549. file.rotation = 0
  550. /* 检查文件格式 */
  551. if (
  552. !file.ext ||
  553. acceptExtensions.indexOf(file.ext.toLowerCase()) == -1
  554. ) {
  555. showError('not_allow_type')
  556. uploader.removeFile(file)
  557. }
  558. }
  559. file.on('statuschange', function (cur, prev) {
  560. if (prev === 'progress') {
  561. $prgress.hide().width(0)
  562. } else if (prev === 'queued') {
  563. $li.off('mouseenter mouseleave')
  564. $btns.remove()
  565. }
  566. // 成功
  567. if (cur === 'error' || cur === 'invalid') {
  568. showError(file.statusText)
  569. percentages[file.id][1] = 1
  570. } else if (cur === 'interrupt') {
  571. showError('interrupt')
  572. } else if (cur === 'queued') {
  573. percentages[file.id][1] = 0
  574. } else if (cur === 'progress') {
  575. $info.hide()
  576. $prgress.css('display', 'block')
  577. } else if (cur === 'complete') {
  578. }
  579. $li.removeClass('state-' + prev).addClass('state-' + cur)
  580. })
  581. $li.on('mouseenter', function () {
  582. $btns.stop().animate({ height: 30 })
  583. })
  584. $li.on('mouseleave', function () {
  585. $btns.stop().animate({ height: 0 })
  586. })
  587. $btns.on('click', 'span', function () {
  588. var index = $(this).index(),
  589. deg
  590. switch (index) {
  591. case 0:
  592. uploader.removeFile(file)
  593. return
  594. case 1:
  595. file.rotation += 90
  596. break
  597. case 2:
  598. file.rotation -= 90
  599. break
  600. }
  601. if (supportTransition) {
  602. deg = 'rotate(' + file.rotation + 'deg)'
  603. $wrap.css({
  604. '-webkit-transform': deg,
  605. '-mos-transform': deg,
  606. '-o-transform': deg,
  607. transform: deg
  608. })
  609. } else {
  610. $wrap.css(
  611. 'filter',
  612. 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' +
  613. (~~(((file.rotation / 90) % 4) + 4) % 4) +
  614. ')'
  615. )
  616. }
  617. })
  618. $li.insertBefore($filePickerBlock)
  619. }
  620. // 负责view的销毁
  621. function removeFile(file) {
  622. var $li = $('#' + file.id)
  623. delete percentages[file.id]
  624. updateTotalProgress()
  625. $li.off().find('.file-panel').off().end().remove()
  626. }
  627. function updateTotalProgress() {
  628. var loaded = 0,
  629. total = 0,
  630. spans = $progress.children(),
  631. percent
  632. $.each(percentages, function (k, v) {
  633. total += v[0]
  634. loaded += v[0] * v[1]
  635. })
  636. percent = total ? loaded / total : 0
  637. spans.eq(0).text(Math.round(percent * 100) + '%')
  638. spans.eq(1).css('width', Math.round(percent * 100) + '%')
  639. updateStatus()
  640. }
  641. function setState(val, files) {
  642. if (val != state) {
  643. var stats = uploader.getStats()
  644. $upload.removeClass('state-' + state)
  645. $upload.addClass('state-' + val)
  646. switch (val) {
  647. /* 未选择文件 */
  648. case 'pedding':
  649. $queue.addClass('element-invisible')
  650. $statusBar.addClass('element-invisible')
  651. $placeHolder.removeClass('element-invisible')
  652. $progress.hide()
  653. $info.hide()
  654. uploader.refresh()
  655. break
  656. /* 可以开始上传 */
  657. case 'ready':
  658. $placeHolder.addClass('element-invisible')
  659. $queue.removeClass('element-invisible')
  660. $statusBar.removeClass('element-invisible')
  661. $progress.hide()
  662. $info.show()
  663. $upload.text(lang.uploadStart)
  664. uploader.refresh()
  665. break
  666. /* 上传中 */
  667. case 'uploading':
  668. $progress.show()
  669. $info.hide()
  670. $upload.text(lang.uploadPause)
  671. break
  672. /* 暂停上传 */
  673. case 'paused':
  674. $progress.show()
  675. $info.hide()
  676. $upload.text(lang.uploadContinue)
  677. break
  678. case 'confirm':
  679. $progress.show()
  680. $info.hide()
  681. $upload.text(lang.uploadStart)
  682. stats = uploader.getStats()
  683. if (stats.successNum && !stats.uploadFailNum) {
  684. setState('finish')
  685. return
  686. }
  687. break
  688. case 'finish':
  689. $progress.hide()
  690. $info.show()
  691. if (stats.uploadFailNum) {
  692. $upload.text(lang.uploadRetry)
  693. } else {
  694. $upload.text(lang.uploadStart)
  695. }
  696. break
  697. }
  698. state = val
  699. updateStatus()
  700. }
  701. if (!_this.getQueueCount()) {
  702. $upload.addClass('disabled')
  703. } else {
  704. $upload.removeClass('disabled')
  705. }
  706. }
  707. function updateStatus() {
  708. var text = '',
  709. stats
  710. if (state === 'ready') {
  711. text = lang.updateStatusReady
  712. .replace('_', fileCount)
  713. .replace('_KB', WebUploader.formatSize(fileSize))
  714. } else if (state === 'confirm') {
  715. stats = uploader.getStats()
  716. if (stats.uploadFailNum) {
  717. text = lang.updateStatusConfirm
  718. .replace('_', stats.successNum)
  719. .replace('_', stats.successNum)
  720. }
  721. } else {
  722. stats = uploader.getStats()
  723. text = lang.updateStatusFinish
  724. .replace('_', fileCount)
  725. .replace('_KB', WebUploader.formatSize(fileSize))
  726. .replace('_', stats.successNum)
  727. if (stats.uploadFailNum) {
  728. text += lang.updateStatusError.replace('_', stats.uploadFailNum)
  729. }
  730. }
  731. $info.html(text)
  732. }
  733. uploader.on('fileQueued', function (file) {
  734. fileCount++
  735. fileSize += file.size
  736. if (fileCount === 1) {
  737. $placeHolder.addClass('element-invisible')
  738. $statusBar.show()
  739. }
  740. addFile(file)
  741. })
  742. uploader.on('fileDequeued', function (file) {
  743. fileCount--
  744. fileSize -= file.size
  745. removeFile(file)
  746. updateTotalProgress()
  747. })
  748. uploader.on('filesQueued', function (file) {
  749. if (
  750. !uploader.isInProgress() &&
  751. (state == 'pedding' ||
  752. state == 'finish' ||
  753. state == 'confirm' ||
  754. state == 'ready')
  755. ) {
  756. setState('ready')
  757. }
  758. updateTotalProgress()
  759. })
  760. uploader.on('all', function (type, files) {
  761. switch (type) {
  762. case 'uploadFinished':
  763. setState('confirm', files)
  764. break
  765. case 'startUpload':
  766. /* 添加额外的GET参数 */
  767. var params =
  768. utils.serializeParam(editor.queryCommandValue('serverparam')) ||
  769. '',
  770. url = utils.formatUrl(
  771. actionUrl +
  772. (actionUrl.indexOf('?') == -1 ? '?' : '&') +
  773. 'encode=utf-8&' +
  774. params
  775. )
  776. uploader.option('server', url)
  777. setState('uploading', files)
  778. break
  779. case 'stopUpload':
  780. setState('paused', files)
  781. break
  782. }
  783. })
  784. uploader.on('uploadBeforeSend', function (file, data, header) {
  785. //这里可以通过data对象添加POST参数
  786. header['X_Requested_With'] = 'XMLHttpRequest'
  787. // HaoChuan9421
  788. if (
  789. editor.options.headers &&
  790. Object.prototype.toString.apply(editor.options.headers) ===
  791. '[object Object]'
  792. ) {
  793. for (var key in editor.options.headers) {
  794. header[key] = editor.options.headers[key]
  795. }
  796. }
  797. })
  798. uploader.on('uploadProgress', function (file, percentage) {
  799. var $li = $('#' + file.id),
  800. $percent = $li.find('.progress span')
  801. $percent.css('width', percentage * 100 + '%')
  802. percentages[file.id][1] = percentage
  803. updateTotalProgress()
  804. })
  805. uploader.on('uploadSuccess', function (file, ret) {
  806. var $file = $('#' + file.id)
  807. try {
  808. var responseText = ret.data
  809. if (ret.code == 200) {
  810. uploadVideoList.push({
  811. url: responseText.url,
  812. type: responseText.type,
  813. original: responseText.original
  814. })
  815. $file.append('<span class="success"></span>')
  816. } else {
  817. $file.find('.error').text(json.state).show()
  818. }
  819. } catch (e) {
  820. $file.find('.error').text(lang.errorServerUpload).show()
  821. }
  822. })
  823. uploader.on('uploadError', function (file, code) {})
  824. uploader.on('error', function (code, file) {
  825. if (code == 'Q_TYPE_DENIED' || code == 'F_EXCEED_SIZE') {
  826. addFile(file)
  827. }
  828. })
  829. uploader.on('uploadComplete', function (file, ret) {})
  830. $upload.on('click', function () {
  831. if ($(this).hasClass('disabled')) {
  832. return false
  833. }
  834. if (state === 'ready') {
  835. uploader.upload()
  836. } else if (state === 'paused') {
  837. uploader.upload()
  838. } else if (state === 'uploading') {
  839. uploader.stop()
  840. }
  841. })
  842. $upload.addClass('state-' + state)
  843. updateTotalProgress()
  844. },
  845. getQueueCount: function () {
  846. var file,
  847. i,
  848. status,
  849. readyFile = 0,
  850. files = this.uploader.getFiles()
  851. for (i = 0; (file = files[i++]); ) {
  852. status = file.getStatus()
  853. if (status == 'queued' || status == 'uploading' || status == 'progress')
  854. readyFile++
  855. }
  856. return readyFile
  857. },
  858. refresh: function () {
  859. this.uploader.refresh()
  860. }
  861. }
  862. })()