ZeroClipboard.js 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539
  1. /*!
  2. * ZeroClipboard
  3. * The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface.
  4. * Copyright (c) 2014 Jon Rohan, James M. Greene
  5. * Licensed MIT
  6. * http://zeroclipboard.org/
  7. * v2.0.0-beta.5
  8. */
  9. ;(function (window) {
  10. 'use strict'
  11. var _currentElement
  12. var _flashState = {
  13. bridge: null,
  14. version: '0.0.0',
  15. pluginType: 'unknown',
  16. disabled: null,
  17. outdated: null,
  18. unavailable: null,
  19. deactivated: null,
  20. overdue: null,
  21. ready: null,
  22. }
  23. var _clipData = {}
  24. var _clipDataFormatMap = null
  25. var _clientIdCounter = 0
  26. var _clientMeta = {}
  27. var _elementIdCounter = 0
  28. var _elementMeta = {}
  29. var _swfPath = (function () {
  30. var i,
  31. jsDir,
  32. tmpJsPath,
  33. jsPath,
  34. swfPath = 'ZeroClipboard.swf'
  35. if (!(document.currentScript && (jsPath = document.currentScript.src))) {
  36. var scripts = document.getElementsByTagName('script')
  37. if ('readyState' in scripts[0]) {
  38. for (i = scripts.length; i--; ) {
  39. if (
  40. scripts[i].readyState === 'interactive' &&
  41. (jsPath = scripts[i].src)
  42. ) {
  43. break
  44. }
  45. }
  46. } else if (document.readyState === 'loading') {
  47. jsPath = scripts[scripts.length - 1].src
  48. } else {
  49. for (i = scripts.length; i--; ) {
  50. tmpJsPath = scripts[i].src
  51. if (!tmpJsPath) {
  52. jsDir = null
  53. break
  54. }
  55. tmpJsPath = tmpJsPath.split('#')[0].split('?')[0]
  56. tmpJsPath = tmpJsPath.slice(0, tmpJsPath.lastIndexOf('/') + 1)
  57. if (jsDir == null) {
  58. jsDir = tmpJsPath
  59. } else if (jsDir !== tmpJsPath) {
  60. jsDir = null
  61. break
  62. }
  63. }
  64. if (jsDir !== null) {
  65. jsPath = jsDir
  66. }
  67. }
  68. }
  69. if (jsPath) {
  70. jsPath = jsPath.split('#')[0].split('?')[0]
  71. swfPath = jsPath.slice(0, jsPath.lastIndexOf('/') + 1) + swfPath
  72. }
  73. return swfPath
  74. })()
  75. var _camelizeCssPropName = (function () {
  76. var matcherRegex = /\-([a-z])/g,
  77. replacerFn = function (match, group) {
  78. return group.toUpperCase()
  79. }
  80. return function (prop) {
  81. return prop.replace(matcherRegex, replacerFn)
  82. }
  83. })()
  84. var _getStyle = function (el, prop) {
  85. var value, camelProp, tagName
  86. if (window.getComputedStyle) {
  87. value = window.getComputedStyle(el, null).getPropertyValue(prop)
  88. } else {
  89. camelProp = _camelizeCssPropName(prop)
  90. if (el.currentStyle) {
  91. value = el.currentStyle[camelProp]
  92. } else {
  93. value = el.style[camelProp]
  94. }
  95. }
  96. if (prop === 'cursor') {
  97. if (!value || value === 'auto') {
  98. tagName = el.tagName.toLowerCase()
  99. if (tagName === 'a') {
  100. return 'pointer'
  101. }
  102. }
  103. }
  104. return value
  105. }
  106. var _elementMouseOver = function (event) {
  107. if (!event) {
  108. event = window.event
  109. }
  110. var target
  111. if (this !== window) {
  112. target = this
  113. } else if (event.target) {
  114. target = event.target
  115. } else if (event.srcElement) {
  116. target = event.srcElement
  117. }
  118. ZeroClipboard.activate(target)
  119. }
  120. var _addEventHandler = function (element, method, func) {
  121. if (!element || element.nodeType !== 1) {
  122. return
  123. }
  124. if (element.addEventListener) {
  125. element.addEventListener(method, func, false)
  126. } else if (element.attachEvent) {
  127. element.attachEvent('on' + method, func)
  128. }
  129. }
  130. var _removeEventHandler = function (element, method, func) {
  131. if (!element || element.nodeType !== 1) {
  132. return
  133. }
  134. if (element.removeEventListener) {
  135. element.removeEventListener(method, func, false)
  136. } else if (element.detachEvent) {
  137. element.detachEvent('on' + method, func)
  138. }
  139. }
  140. var _addClass = function (element, value) {
  141. if (!element || element.nodeType !== 1) {
  142. return element
  143. }
  144. if (element.classList) {
  145. if (!element.classList.contains(value)) {
  146. element.classList.add(value)
  147. }
  148. return element
  149. }
  150. if (value && typeof value === 'string') {
  151. var classNames = (value || '').split(/\s+/)
  152. if (element.nodeType === 1) {
  153. if (!element.className) {
  154. element.className = value
  155. } else {
  156. var className = ' ' + element.className + ' ',
  157. setClass = element.className
  158. for (var c = 0, cl = classNames.length; c < cl; c++) {
  159. if (className.indexOf(' ' + classNames[c] + ' ') < 0) {
  160. setClass += ' ' + classNames[c]
  161. }
  162. }
  163. element.className = setClass.replace(/^\s+|\s+$/g, '')
  164. }
  165. }
  166. }
  167. return element
  168. }
  169. var _removeClass = function (element, value) {
  170. if (!element || element.nodeType !== 1) {
  171. return element
  172. }
  173. if (element.classList) {
  174. if (element.classList.contains(value)) {
  175. element.classList.remove(value)
  176. }
  177. return element
  178. }
  179. if ((value && typeof value === 'string') || value === undefined) {
  180. var classNames = (value || '').split(/\s+/)
  181. if (element.nodeType === 1 && element.className) {
  182. if (value) {
  183. var className = (' ' + element.className + ' ').replace(
  184. /[\n\t]/g,
  185. ' '
  186. )
  187. for (var c = 0, cl = classNames.length; c < cl; c++) {
  188. className = className.replace(' ' + classNames[c] + ' ', ' ')
  189. }
  190. element.className = className.replace(/^\s+|\s+$/g, '')
  191. } else {
  192. element.className = ''
  193. }
  194. }
  195. }
  196. return element
  197. }
  198. var _getZoomFactor = function () {
  199. var rect,
  200. physicalWidth,
  201. logicalWidth,
  202. zoomFactor = 1
  203. if (typeof document.body.getBoundingClientRect === 'function') {
  204. rect = document.body.getBoundingClientRect()
  205. physicalWidth = rect.right - rect.left
  206. logicalWidth = document.body.offsetWidth
  207. zoomFactor = Math.round((physicalWidth / logicalWidth) * 100) / 100
  208. }
  209. return zoomFactor
  210. }
  211. var _getDOMObjectPosition = function (obj, defaultZIndex) {
  212. var info = {
  213. left: 0,
  214. top: 0,
  215. width: 0,
  216. height: 0,
  217. zIndex: _getSafeZIndex(defaultZIndex) - 1,
  218. }
  219. if (obj.getBoundingClientRect) {
  220. var rect = obj.getBoundingClientRect()
  221. var pageXOffset, pageYOffset, zoomFactor
  222. if ('pageXOffset' in window && 'pageYOffset' in window) {
  223. pageXOffset = window.pageXOffset
  224. pageYOffset = window.pageYOffset
  225. } else {
  226. zoomFactor = _getZoomFactor()
  227. pageXOffset = Math.round(
  228. document.documentElement.scrollLeft / zoomFactor
  229. )
  230. pageYOffset = Math.round(
  231. document.documentElement.scrollTop / zoomFactor
  232. )
  233. }
  234. var leftBorderWidth = document.documentElement.clientLeft || 0
  235. var topBorderWidth = document.documentElement.clientTop || 0
  236. info.left = rect.left + pageXOffset - leftBorderWidth
  237. info.top = rect.top + pageYOffset - topBorderWidth
  238. info.width = 'width' in rect ? rect.width : rect.right - rect.left
  239. info.height = 'height' in rect ? rect.height : rect.bottom - rect.top
  240. }
  241. return info
  242. }
  243. var _cacheBust = function (path, options) {
  244. var cacheBust = options == null || (options && options.cacheBust === true)
  245. if (cacheBust) {
  246. return (
  247. (path.indexOf('?') === -1 ? '?' : '&') +
  248. 'noCache=' +
  249. new Date().getTime()
  250. )
  251. } else {
  252. return ''
  253. }
  254. }
  255. var _vars = function (options) {
  256. var i,
  257. len,
  258. domain,
  259. domains,
  260. str = '',
  261. trustedOriginsExpanded = []
  262. if (options.trustedDomains) {
  263. if (typeof options.trustedDomains === 'string') {
  264. domains = [options.trustedDomains]
  265. } else if (
  266. typeof options.trustedDomains === 'object' &&
  267. 'length' in options.trustedDomains
  268. ) {
  269. domains = options.trustedDomains
  270. }
  271. }
  272. if (domains && domains.length) {
  273. for (i = 0, len = domains.length; i < len; i++) {
  274. if (
  275. domains.hasOwnProperty(i) &&
  276. domains[i] &&
  277. typeof domains[i] === 'string'
  278. ) {
  279. domain = _extractDomain(domains[i])
  280. if (!domain) {
  281. continue
  282. }
  283. if (domain === '*') {
  284. trustedOriginsExpanded = [domain]
  285. break
  286. }
  287. trustedOriginsExpanded.push.apply(trustedOriginsExpanded, [
  288. domain,
  289. '//' + domain,
  290. window.location.protocol + '//' + domain,
  291. ])
  292. }
  293. }
  294. }
  295. if (trustedOriginsExpanded.length) {
  296. str +=
  297. 'trustedOrigins=' + encodeURIComponent(trustedOriginsExpanded.join(','))
  298. }
  299. if (options.forceEnhancedClipboard === true) {
  300. str += (str ? '&' : '') + 'forceEnhancedClipboard=true'
  301. }
  302. return str
  303. }
  304. var _inArray = function (elem, array, fromIndex) {
  305. if (typeof array.indexOf === 'function') {
  306. return array.indexOf(elem, fromIndex)
  307. }
  308. var i,
  309. len = array.length
  310. if (typeof fromIndex === 'undefined') {
  311. fromIndex = 0
  312. } else if (fromIndex < 0) {
  313. fromIndex = len + fromIndex
  314. }
  315. for (i = fromIndex; i < len; i++) {
  316. if (array.hasOwnProperty(i) && array[i] === elem) {
  317. return i
  318. }
  319. }
  320. return -1
  321. }
  322. var _prepClip = function (elements) {
  323. if (typeof elements === 'string') {
  324. throw new TypeError("ZeroClipboard doesn't accept query strings.")
  325. }
  326. return typeof elements.length !== 'number' ? [elements] : elements
  327. }
  328. var _dispatchCallback = function (func, context, args, async) {
  329. if (async) {
  330. window.setTimeout(function () {
  331. func.apply(context, args)
  332. }, 0)
  333. } else {
  334. func.apply(context, args)
  335. }
  336. }
  337. var _getSafeZIndex = function (val) {
  338. var zIndex, tmp
  339. if (val) {
  340. if (typeof val === 'number' && val > 0) {
  341. zIndex = val
  342. } else if (
  343. typeof val === 'string' &&
  344. (tmp = parseInt(val, 10)) &&
  345. !isNaN(tmp) &&
  346. tmp > 0
  347. ) {
  348. zIndex = tmp
  349. }
  350. }
  351. if (!zIndex) {
  352. if (
  353. typeof _globalConfig.zIndex === 'number' &&
  354. _globalConfig.zIndex > 0
  355. ) {
  356. zIndex = _globalConfig.zIndex
  357. } else if (
  358. typeof _globalConfig.zIndex === 'string' &&
  359. (tmp = parseInt(_globalConfig.zIndex, 10)) &&
  360. !isNaN(tmp) &&
  361. tmp > 0
  362. ) {
  363. zIndex = tmp
  364. }
  365. }
  366. return zIndex || 0
  367. }
  368. var _extend = function () {
  369. var i,
  370. len,
  371. arg,
  372. prop,
  373. src,
  374. copy,
  375. target = arguments[0] || {}
  376. for (i = 1, len = arguments.length; i < len; i++) {
  377. if ((arg = arguments[i]) != null) {
  378. for (prop in arg) {
  379. if (arg.hasOwnProperty(prop)) {
  380. src = target[prop]
  381. copy = arg[prop]
  382. if (target === copy) {
  383. continue
  384. }
  385. if (copy !== undefined) {
  386. target[prop] = copy
  387. }
  388. }
  389. }
  390. }
  391. }
  392. return target
  393. }
  394. var _extractDomain = function (originOrUrl) {
  395. if (originOrUrl == null || originOrUrl === '') {
  396. return null
  397. }
  398. originOrUrl = originOrUrl.replace(/^\s+|\s+$/g, '')
  399. if (originOrUrl === '') {
  400. return null
  401. }
  402. var protocolIndex = originOrUrl.indexOf('//')
  403. originOrUrl =
  404. protocolIndex === -1 ? originOrUrl : originOrUrl.slice(protocolIndex + 2)
  405. var pathIndex = originOrUrl.indexOf('/')
  406. originOrUrl =
  407. pathIndex === -1
  408. ? originOrUrl
  409. : protocolIndex === -1 || pathIndex === 0
  410. ? null
  411. : originOrUrl.slice(0, pathIndex)
  412. if (originOrUrl && originOrUrl.slice(-4).toLowerCase() === '.swf') {
  413. return null
  414. }
  415. return originOrUrl || null
  416. }
  417. var _determineScriptAccess = (function () {
  418. var _extractAllDomains = function (origins, resultsArray) {
  419. var i, len, tmp
  420. if (origins == null || resultsArray[0] === '*') {
  421. return
  422. }
  423. if (typeof origins === 'string') {
  424. origins = [origins]
  425. }
  426. if (
  427. !(typeof origins === 'object' && typeof origins.length === 'number')
  428. ) {
  429. return
  430. }
  431. for (i = 0, len = origins.length; i < len; i++) {
  432. if (origins.hasOwnProperty(i) && (tmp = _extractDomain(origins[i]))) {
  433. if (tmp === '*') {
  434. resultsArray.length = 0
  435. resultsArray.push('*')
  436. break
  437. }
  438. if (_inArray(tmp, resultsArray) === -1) {
  439. resultsArray.push(tmp)
  440. }
  441. }
  442. }
  443. }
  444. return function (currentDomain, configOptions) {
  445. var swfDomain = _extractDomain(configOptions.swfPath)
  446. if (swfDomain === null) {
  447. swfDomain = currentDomain
  448. }
  449. var trustedDomains = []
  450. _extractAllDomains(configOptions.trustedOrigins, trustedDomains)
  451. _extractAllDomains(configOptions.trustedDomains, trustedDomains)
  452. var len = trustedDomains.length
  453. if (len > 0) {
  454. if (len === 1 && trustedDomains[0] === '*') {
  455. return 'always'
  456. }
  457. if (_inArray(currentDomain, trustedDomains) !== -1) {
  458. if (len === 1 && currentDomain === swfDomain) {
  459. return 'sameDomain'
  460. }
  461. return 'always'
  462. }
  463. }
  464. return 'never'
  465. }
  466. })()
  467. var _objectKeys = function (obj) {
  468. if (obj == null) {
  469. return []
  470. }
  471. if (Object.keys) {
  472. return Object.keys(obj)
  473. }
  474. var keys = []
  475. for (var prop in obj) {
  476. if (obj.hasOwnProperty(prop)) {
  477. keys.push(prop)
  478. }
  479. }
  480. return keys
  481. }
  482. var _deleteOwnProperties = function (obj) {
  483. if (obj) {
  484. for (var prop in obj) {
  485. if (obj.hasOwnProperty(prop)) {
  486. delete obj[prop]
  487. }
  488. }
  489. }
  490. return obj
  491. }
  492. var _safeActiveElement = function () {
  493. try {
  494. return document.activeElement
  495. } catch (err) {}
  496. return null
  497. }
  498. var _pick = function (obj, keys) {
  499. var newObj = {}
  500. for (var i = 0, len = keys.length; i < len; i++) {
  501. if (keys[i] in obj) {
  502. newObj[keys[i]] = obj[keys[i]]
  503. }
  504. }
  505. return newObj
  506. }
  507. var _omit = function (obj, keys) {
  508. var newObj = {}
  509. for (var prop in obj) {
  510. if (_inArray(prop, keys) === -1) {
  511. newObj[prop] = obj[prop]
  512. }
  513. }
  514. return newObj
  515. }
  516. var _mapClipDataToFlash = function (clipData) {
  517. var newClipData = {},
  518. formatMap = {}
  519. if (!(typeof clipData === 'object' && clipData)) {
  520. return
  521. }
  522. for (var dataFormat in clipData) {
  523. if (
  524. dataFormat &&
  525. clipData.hasOwnProperty(dataFormat) &&
  526. typeof clipData[dataFormat] === 'string' &&
  527. clipData[dataFormat]
  528. ) {
  529. switch (dataFormat.toLowerCase()) {
  530. case 'text/plain':
  531. case 'text':
  532. case 'air:text':
  533. case 'flash:text':
  534. newClipData.text = clipData[dataFormat]
  535. formatMap.text = dataFormat
  536. break
  537. case 'text/html':
  538. case 'html':
  539. case 'air:html':
  540. case 'flash:html':
  541. newClipData.html = clipData[dataFormat]
  542. formatMap.html = dataFormat
  543. break
  544. case 'application/rtf':
  545. case 'text/rtf':
  546. case 'rtf':
  547. case 'richtext':
  548. case 'air:rtf':
  549. case 'flash:rtf':
  550. newClipData.rtf = clipData[dataFormat]
  551. formatMap.rtf = dataFormat
  552. break
  553. default:
  554. break
  555. }
  556. }
  557. }
  558. return {
  559. data: newClipData,
  560. formatMap: formatMap,
  561. }
  562. }
  563. var _mapClipResultsFromFlash = function (clipResults, formatMap) {
  564. if (
  565. !(
  566. typeof clipResults === 'object' &&
  567. clipResults &&
  568. typeof formatMap === 'object' &&
  569. formatMap
  570. )
  571. ) {
  572. return clipResults
  573. }
  574. var newResults = {}
  575. for (var prop in clipResults) {
  576. if (clipResults.hasOwnProperty(prop)) {
  577. if (prop !== 'success' && prop !== 'data') {
  578. newResults[prop] = clipResults[prop]
  579. continue
  580. }
  581. newResults[prop] = {}
  582. var tmpHash = clipResults[prop]
  583. for (var dataFormat in tmpHash) {
  584. if (
  585. dataFormat &&
  586. tmpHash.hasOwnProperty(dataFormat) &&
  587. formatMap.hasOwnProperty(dataFormat)
  588. ) {
  589. newResults[prop][formatMap[dataFormat]] = tmpHash[dataFormat]
  590. }
  591. }
  592. }
  593. }
  594. return newResults
  595. }
  596. var _args = (function (arraySlice) {
  597. return function (args) {
  598. return arraySlice.call(args, 0)
  599. }
  600. })(window.Array.prototype.slice)
  601. var _detectFlashSupport = function () {
  602. var plugin,
  603. ax,
  604. mimeType,
  605. hasFlash = false,
  606. isActiveX = false,
  607. isPPAPI = false,
  608. flashVersion = ''
  609. function parseFlashVersion(desc) {
  610. var matches = desc.match(/[\d]+/g)
  611. matches.length = 3
  612. return matches.join('.')
  613. }
  614. function isPepperFlash(flashPlayerFileName) {
  615. return (
  616. !!flashPlayerFileName &&
  617. (flashPlayerFileName = flashPlayerFileName.toLowerCase()) &&
  618. (/^(pepflashplayer\.dll|libpepflashplayer\.so|pepperflashplayer\.plugin)$/.test(
  619. flashPlayerFileName
  620. ) ||
  621. flashPlayerFileName.slice(-13) === 'chrome.plugin')
  622. )
  623. }
  624. function inspectPlugin(plugin) {
  625. if (plugin) {
  626. hasFlash = true
  627. if (plugin.version) {
  628. flashVersion = parseFlashVersion(plugin.version)
  629. }
  630. if (!flashVersion && plugin.description) {
  631. flashVersion = parseFlashVersion(plugin.description)
  632. }
  633. if (plugin.filename) {
  634. isPPAPI = isPepperFlash(plugin.filename)
  635. }
  636. }
  637. }
  638. if (navigator.plugins && navigator.plugins.length) {
  639. plugin = navigator.plugins['Shockwave Flash']
  640. inspectPlugin(plugin)
  641. if (navigator.plugins['Shockwave Flash 2.0']) {
  642. hasFlash = true
  643. flashVersion = '2.0.0.11'
  644. }
  645. } else if (navigator.mimeTypes && navigator.mimeTypes.length) {
  646. mimeType = navigator.mimeTypes['application/x-shockwave-flash']
  647. plugin = mimeType && mimeType.enabledPlugin
  648. inspectPlugin(plugin)
  649. } else if (typeof ActiveXObject !== 'undefined') {
  650. isActiveX = true
  651. try {
  652. ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.7')
  653. hasFlash = true
  654. flashVersion = parseFlashVersion(ax.GetVariable('$version'))
  655. } catch (e1) {
  656. try {
  657. ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.6')
  658. hasFlash = true
  659. flashVersion = '6.0.21'
  660. } catch (e2) {
  661. try {
  662. ax = new ActiveXObject('ShockwaveFlash.ShockwaveFlash')
  663. hasFlash = true
  664. flashVersion = parseFlashVersion(ax.GetVariable('$version'))
  665. } catch (e3) {
  666. isActiveX = false
  667. }
  668. }
  669. }
  670. }
  671. _flashState.disabled = hasFlash !== true
  672. _flashState.outdated = flashVersion && parseFloat(flashVersion) < 11
  673. _flashState.version = flashVersion || '0.0.0'
  674. _flashState.pluginType = isPPAPI
  675. ? 'pepper'
  676. : isActiveX
  677. ? 'activex'
  678. : hasFlash
  679. ? 'netscape'
  680. : 'unknown'
  681. }
  682. _detectFlashSupport()
  683. var ZeroClipboard = function (elements) {
  684. if (!(this instanceof ZeroClipboard)) {
  685. return new ZeroClipboard(elements)
  686. }
  687. this.id = '' + _clientIdCounter++
  688. _clientMeta[this.id] = {
  689. instance: this,
  690. elements: [],
  691. handlers: {},
  692. }
  693. if (elements) {
  694. this.clip(elements)
  695. }
  696. if (typeof _flashState.ready !== 'boolean') {
  697. _flashState.ready = false
  698. }
  699. if (!ZeroClipboard.isFlashUnusable() && _flashState.bridge === null) {
  700. var _client = this
  701. var maxWait = _globalConfig.flashLoadTimeout
  702. if (typeof maxWait === 'number' && maxWait >= 0) {
  703. setTimeout(function () {
  704. if (typeof _flashState.deactivated !== 'boolean') {
  705. _flashState.deactivated = true
  706. }
  707. if (_flashState.deactivated === true) {
  708. ZeroClipboard.emit({
  709. type: 'error',
  710. name: 'flash-deactivated',
  711. client: _client,
  712. })
  713. }
  714. }, maxWait)
  715. }
  716. _flashState.overdue = false
  717. _bridge()
  718. }
  719. }
  720. ZeroClipboard.prototype.setText = function (text) {
  721. ZeroClipboard.setData('text/plain', text)
  722. return this
  723. }
  724. ZeroClipboard.prototype.setHtml = function (html) {
  725. ZeroClipboard.setData('text/html', html)
  726. return this
  727. }
  728. ZeroClipboard.prototype.setRichText = function (richText) {
  729. ZeroClipboard.setData('application/rtf', richText)
  730. return this
  731. }
  732. ZeroClipboard.prototype.setData = function () {
  733. ZeroClipboard.setData.apply(ZeroClipboard, _args(arguments))
  734. return this
  735. }
  736. ZeroClipboard.prototype.clearData = function () {
  737. ZeroClipboard.clearData.apply(ZeroClipboard, _args(arguments))
  738. return this
  739. }
  740. ZeroClipboard.prototype.setSize = function (width, height) {
  741. _setSize(width, height)
  742. return this
  743. }
  744. var _setHandCursor = function (enabled) {
  745. if (
  746. _flashState.ready === true &&
  747. _flashState.bridge &&
  748. typeof _flashState.bridge.setHandCursor === 'function'
  749. ) {
  750. _flashState.bridge.setHandCursor(enabled)
  751. } else {
  752. _flashState.ready = false
  753. }
  754. }
  755. ZeroClipboard.prototype.destroy = function () {
  756. this.unclip()
  757. this.off()
  758. delete _clientMeta[this.id]
  759. }
  760. var _getAllClients = function () {
  761. var i,
  762. len,
  763. client,
  764. clients = [],
  765. clientIds = _objectKeys(_clientMeta)
  766. for (i = 0, len = clientIds.length; i < len; i++) {
  767. client = _clientMeta[clientIds[i]].instance
  768. if (client && client instanceof ZeroClipboard) {
  769. clients.push(client)
  770. }
  771. }
  772. return clients
  773. }
  774. ZeroClipboard.version = '2.0.0-beta.5'
  775. var _globalConfig = {
  776. swfPath: _swfPath,
  777. trustedDomains: window.location.host ? [window.location.host] : [],
  778. cacheBust: true,
  779. forceHandCursor: false,
  780. forceEnhancedClipboard: false,
  781. zIndex: 999999999,
  782. debug: false,
  783. title: null,
  784. autoActivate: true,
  785. flashLoadTimeout: 3e4,
  786. }
  787. ZeroClipboard.isFlashUnusable = function () {
  788. return !!(
  789. _flashState.disabled ||
  790. _flashState.outdated ||
  791. _flashState.unavailable ||
  792. _flashState.deactivated
  793. )
  794. }
  795. ZeroClipboard.config = function (options) {
  796. if (typeof options === 'object' && options !== null) {
  797. _extend(_globalConfig, options)
  798. }
  799. if (typeof options === 'string' && options) {
  800. if (_globalConfig.hasOwnProperty(options)) {
  801. return _globalConfig[options]
  802. }
  803. return
  804. }
  805. var copy = {}
  806. for (var prop in _globalConfig) {
  807. if (_globalConfig.hasOwnProperty(prop)) {
  808. if (
  809. typeof _globalConfig[prop] === 'object' &&
  810. _globalConfig[prop] !== null
  811. ) {
  812. if ('length' in _globalConfig[prop]) {
  813. copy[prop] = _globalConfig[prop].slice(0)
  814. } else {
  815. copy[prop] = _extend({}, _globalConfig[prop])
  816. }
  817. } else {
  818. copy[prop] = _globalConfig[prop]
  819. }
  820. }
  821. }
  822. return copy
  823. }
  824. ZeroClipboard.destroy = function () {
  825. ZeroClipboard.deactivate()
  826. for (var clientId in _clientMeta) {
  827. if (_clientMeta.hasOwnProperty(clientId) && _clientMeta[clientId]) {
  828. var client = _clientMeta[clientId].instance
  829. if (client && typeof client.destroy === 'function') {
  830. client.destroy()
  831. }
  832. }
  833. }
  834. var flashBridge = _flashState.bridge
  835. if (flashBridge) {
  836. var htmlBridge = _getHtmlBridge(flashBridge)
  837. if (htmlBridge) {
  838. if (
  839. _flashState.pluginType === 'activex' &&
  840. 'readyState' in flashBridge
  841. ) {
  842. flashBridge.style.display = 'none'
  843. ;(function removeSwfFromIE() {
  844. if (flashBridge.readyState === 4) {
  845. for (var prop in flashBridge) {
  846. if (typeof flashBridge[prop] === 'function') {
  847. flashBridge[prop] = null
  848. }
  849. }
  850. flashBridge.parentNode.removeChild(flashBridge)
  851. if (htmlBridge.parentNode) {
  852. htmlBridge.parentNode.removeChild(htmlBridge)
  853. }
  854. } else {
  855. setTimeout(removeSwfFromIE, 10)
  856. }
  857. })()
  858. } else {
  859. flashBridge.parentNode.removeChild(flashBridge)
  860. if (htmlBridge.parentNode) {
  861. htmlBridge.parentNode.removeChild(htmlBridge)
  862. }
  863. }
  864. }
  865. _flashState.ready = null
  866. _flashState.bridge = null
  867. _flashState.deactivated = null
  868. }
  869. ZeroClipboard.clearData()
  870. }
  871. ZeroClipboard.activate = function (element) {
  872. if (_currentElement) {
  873. _removeClass(_currentElement, _globalConfig.hoverClass)
  874. _removeClass(_currentElement, _globalConfig.activeClass)
  875. }
  876. _currentElement = element
  877. _addClass(element, _globalConfig.hoverClass)
  878. _reposition()
  879. var newTitle = _globalConfig.title || element.getAttribute('title')
  880. if (newTitle) {
  881. var htmlBridge = _getHtmlBridge(_flashState.bridge)
  882. if (htmlBridge) {
  883. htmlBridge.setAttribute('title', newTitle)
  884. }
  885. }
  886. var useHandCursor =
  887. _globalConfig.forceHandCursor === true ||
  888. _getStyle(element, 'cursor') === 'pointer'
  889. _setHandCursor(useHandCursor)
  890. }
  891. ZeroClipboard.deactivate = function () {
  892. var htmlBridge = _getHtmlBridge(_flashState.bridge)
  893. if (htmlBridge) {
  894. htmlBridge.removeAttribute('title')
  895. htmlBridge.style.left = '0px'
  896. htmlBridge.style.top = '-9999px'
  897. _setSize(1, 1)
  898. }
  899. if (_currentElement) {
  900. _removeClass(_currentElement, _globalConfig.hoverClass)
  901. _removeClass(_currentElement, _globalConfig.activeClass)
  902. _currentElement = null
  903. }
  904. }
  905. ZeroClipboard.state = function () {
  906. return {
  907. browser: _pick(window.navigator, ['userAgent', 'platform', 'appName']),
  908. flash: _omit(_flashState, ['bridge']),
  909. zeroclipboard: {
  910. version: ZeroClipboard.version,
  911. config: ZeroClipboard.config(),
  912. },
  913. }
  914. }
  915. ZeroClipboard.setData = function (format, data) {
  916. var dataObj
  917. if (typeof format === 'object' && format && typeof data === 'undefined') {
  918. dataObj = format
  919. ZeroClipboard.clearData()
  920. } else if (typeof format === 'string' && format) {
  921. dataObj = {}
  922. dataObj[format] = data
  923. } else {
  924. return
  925. }
  926. for (var dataFormat in dataObj) {
  927. if (
  928. dataFormat &&
  929. dataObj.hasOwnProperty(dataFormat) &&
  930. typeof dataObj[dataFormat] === 'string' &&
  931. dataObj[dataFormat]
  932. ) {
  933. _clipData[dataFormat] = dataObj[dataFormat]
  934. }
  935. }
  936. }
  937. ZeroClipboard.clearData = function (format) {
  938. if (typeof format === 'undefined') {
  939. _deleteOwnProperties(_clipData)
  940. _clipDataFormatMap = null
  941. } else if (typeof format === 'string' && _clipData.hasOwnProperty(format)) {
  942. delete _clipData[format]
  943. }
  944. }
  945. var _bridge = function () {
  946. var flashBridge, len
  947. var container = document.getElementById('global-zeroclipboard-html-bridge')
  948. if (!container) {
  949. var allowScriptAccess = _determineScriptAccess(
  950. window.location.host,
  951. _globalConfig
  952. )
  953. var allowNetworking = allowScriptAccess === 'never' ? 'none' : 'all'
  954. var flashvars = _vars(_globalConfig)
  955. var swfUrl =
  956. _globalConfig.swfPath + _cacheBust(_globalConfig.swfPath, _globalConfig)
  957. container = _createHtmlBridge()
  958. var divToBeReplaced = document.createElement('div')
  959. container.appendChild(divToBeReplaced)
  960. document.body.appendChild(container)
  961. var tmpDiv = document.createElement('div')
  962. var oldIE = _flashState.pluginType === 'activex'
  963. tmpDiv.innerHTML =
  964. '<object id="global-zeroclipboard-flash-bridge" name="global-zeroclipboard-flash-bridge" ' +
  965. 'width="100%" height="100%" ' +
  966. (oldIE
  967. ? 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"'
  968. : 'type="application/x-shockwave-flash" data="' + swfUrl + '"') +
  969. '>' +
  970. (oldIE ? '<param name="movie" value="' + swfUrl + '"/>' : '') +
  971. '<param name="allowScriptAccess" value="' +
  972. allowScriptAccess +
  973. '"/>' +
  974. '<param name="allowNetworking" value="' +
  975. allowNetworking +
  976. '"/>' +
  977. '<param name="menu" value="false"/>' +
  978. '<param name="wmode" value="transparent"/>' +
  979. '<param name="flashvars" value="' +
  980. flashvars +
  981. '"/>' +
  982. '</object>'
  983. flashBridge = tmpDiv.firstChild
  984. tmpDiv = null
  985. flashBridge.ZeroClipboard = ZeroClipboard
  986. container.replaceChild(flashBridge, divToBeReplaced)
  987. }
  988. if (!flashBridge) {
  989. flashBridge = document['global-zeroclipboard-flash-bridge']
  990. if (flashBridge && (len = flashBridge.length)) {
  991. flashBridge = flashBridge[len - 1]
  992. }
  993. if (!flashBridge) {
  994. flashBridge = container.firstChild
  995. }
  996. }
  997. _flashState.bridge = flashBridge || null
  998. }
  999. var _createHtmlBridge = function () {
  1000. var container = document.createElement('div')
  1001. container.id = 'global-zeroclipboard-html-bridge'
  1002. container.className = 'global-zeroclipboard-container'
  1003. container.style.position = 'absolute'
  1004. container.style.left = '0px'
  1005. container.style.top = '-9999px'
  1006. container.style.width = '1px'
  1007. container.style.height = '1px'
  1008. container.style.zIndex = '' + _getSafeZIndex(_globalConfig.zIndex)
  1009. return container
  1010. }
  1011. var _getHtmlBridge = function (flashBridge) {
  1012. var htmlBridge = flashBridge && flashBridge.parentNode
  1013. while (
  1014. htmlBridge &&
  1015. htmlBridge.nodeName === 'OBJECT' &&
  1016. htmlBridge.parentNode
  1017. ) {
  1018. htmlBridge = htmlBridge.parentNode
  1019. }
  1020. return htmlBridge || null
  1021. }
  1022. var _reposition = function () {
  1023. if (_currentElement) {
  1024. var pos = _getDOMObjectPosition(_currentElement, _globalConfig.zIndex)
  1025. var htmlBridge = _getHtmlBridge(_flashState.bridge)
  1026. if (htmlBridge) {
  1027. htmlBridge.style.top = pos.top + 'px'
  1028. htmlBridge.style.left = pos.left + 'px'
  1029. htmlBridge.style.width = pos.width + 'px'
  1030. htmlBridge.style.height = pos.height + 'px'
  1031. htmlBridge.style.zIndex = pos.zIndex + 1
  1032. }
  1033. _setSize(pos.width, pos.height)
  1034. }
  1035. }
  1036. var _setSize = function (width, height) {
  1037. var htmlBridge = _getHtmlBridge(_flashState.bridge)
  1038. if (htmlBridge) {
  1039. htmlBridge.style.width = width + 'px'
  1040. htmlBridge.style.height = height + 'px'
  1041. }
  1042. }
  1043. ZeroClipboard.emit = function (event) {
  1044. var eventType,
  1045. eventObj,
  1046. performCallbackAsync,
  1047. clients,
  1048. i,
  1049. len,
  1050. eventCopy,
  1051. returnVal,
  1052. tmp
  1053. if (typeof event === 'string' && event) {
  1054. eventType = event
  1055. }
  1056. if (
  1057. typeof event === 'object' &&
  1058. event &&
  1059. typeof event.type === 'string' &&
  1060. event.type
  1061. ) {
  1062. eventType = event.type
  1063. eventObj = event
  1064. }
  1065. if (!eventType) {
  1066. return
  1067. }
  1068. event = _createEvent(eventType, eventObj)
  1069. _preprocessEvent(event)
  1070. if (event.type === 'ready' && _flashState.overdue === true) {
  1071. return ZeroClipboard.emit({
  1072. type: 'error',
  1073. name: 'flash-overdue',
  1074. })
  1075. }
  1076. performCallbackAsync = !/^(before)?copy$/.test(event.type)
  1077. if (event.client) {
  1078. _dispatchClientCallbacks.call(event.client, event, performCallbackAsync)
  1079. } else {
  1080. clients =
  1081. event.target &&
  1082. event.target !== window &&
  1083. _globalConfig.autoActivate === true
  1084. ? _getAllClientsClippedToElement(event.target)
  1085. : _getAllClients()
  1086. for (i = 0, len = clients.length; i < len; i++) {
  1087. eventCopy = _extend({}, event, {
  1088. client: clients[i],
  1089. })
  1090. _dispatchClientCallbacks.call(
  1091. clients[i],
  1092. eventCopy,
  1093. performCallbackAsync
  1094. )
  1095. }
  1096. }
  1097. if (event.type === 'copy') {
  1098. tmp = _mapClipDataToFlash(_clipData)
  1099. returnVal = tmp.data
  1100. _clipDataFormatMap = tmp.formatMap
  1101. }
  1102. return returnVal
  1103. }
  1104. var _dispatchClientCallbacks = function (event, async) {
  1105. var handlers =
  1106. _clientMeta[this.id] && _clientMeta[this.id].handlers[event.type]
  1107. if (handlers && handlers.length) {
  1108. var i,
  1109. len,
  1110. func,
  1111. context,
  1112. originalContext = this
  1113. for (i = 0, len = handlers.length; i < len; i++) {
  1114. func = handlers[i]
  1115. context = originalContext
  1116. if (typeof func === 'string' && typeof window[func] === 'function') {
  1117. func = window[func]
  1118. }
  1119. if (
  1120. typeof func === 'object' &&
  1121. func &&
  1122. typeof func.handleEvent === 'function'
  1123. ) {
  1124. context = func
  1125. func = func.handleEvent
  1126. }
  1127. if (typeof func === 'function') {
  1128. _dispatchCallback(func, context, [event], async)
  1129. }
  1130. }
  1131. }
  1132. return this
  1133. }
  1134. var _eventMessages = {
  1135. ready: 'Flash communication is established',
  1136. error: {
  1137. 'flash-disabled': 'Flash is disabled or not installed',
  1138. 'flash-outdated': 'Flash is too outdated to support ZeroClipboard',
  1139. 'flash-unavailable':
  1140. 'Flash is unable to communicate bidirectionally with JavaScript',
  1141. 'flash-deactivated':
  1142. 'Flash is too outdated for your browser and/or is configured as click-to-activate',
  1143. 'flash-overdue':
  1144. 'Flash communication was established but NOT within the acceptable time limit',
  1145. },
  1146. }
  1147. var _createEvent = function (eventType, event) {
  1148. if (!(eventType || (event && event.type))) {
  1149. return
  1150. }
  1151. event = event || {}
  1152. eventType = (eventType || event.type).toLowerCase()
  1153. _extend(event, {
  1154. type: eventType,
  1155. target: event.target || _currentElement || null,
  1156. relatedTarget: event.relatedTarget || null,
  1157. currentTarget: (_flashState && _flashState.bridge) || null,
  1158. })
  1159. var msg = _eventMessages[event.type]
  1160. if (event.type === 'error' && event.name && msg) {
  1161. msg = msg[event.name]
  1162. }
  1163. if (msg) {
  1164. event.message = msg
  1165. }
  1166. if (event.type === 'ready') {
  1167. _extend(event, {
  1168. target: null,
  1169. version: _flashState.version,
  1170. })
  1171. }
  1172. if (event.type === 'error') {
  1173. event.target = null
  1174. if (
  1175. /^flash-(outdated|unavailable|deactivated|overdue)$/.test(event.name)
  1176. ) {
  1177. _extend(event, {
  1178. version: _flashState.version,
  1179. minimumVersion: '11.0.0',
  1180. })
  1181. }
  1182. }
  1183. if (event.type === 'copy') {
  1184. event.clipboardData = {
  1185. setData: ZeroClipboard.setData,
  1186. clearData: ZeroClipboard.clearData,
  1187. }
  1188. }
  1189. if (event.type === 'aftercopy') {
  1190. event = _mapClipResultsFromFlash(event, _clipDataFormatMap)
  1191. }
  1192. if (event.target && !event.relatedTarget) {
  1193. event.relatedTarget = _getRelatedTarget(event.target)
  1194. }
  1195. return event
  1196. }
  1197. var _getRelatedTarget = function (targetEl) {
  1198. var relatedTargetId =
  1199. targetEl &&
  1200. targetEl.getAttribute &&
  1201. targetEl.getAttribute('data-clipboard-target')
  1202. return relatedTargetId ? document.getElementById(relatedTargetId) : null
  1203. }
  1204. var _preprocessEvent = function (event) {
  1205. var element = event.target || _currentElement
  1206. switch (event.type) {
  1207. case 'error':
  1208. if (
  1209. _inArray(event.name, [
  1210. 'flash-disabled',
  1211. 'flash-outdated',
  1212. 'flash-deactivated',
  1213. 'flash-overdue',
  1214. ])
  1215. ) {
  1216. _extend(_flashState, {
  1217. disabled: event.name === 'flash-disabled',
  1218. outdated: event.name === 'flash-outdated',
  1219. unavailable: event.name === 'flash-unavailable',
  1220. deactivated: event.name === 'flash-deactivated',
  1221. overdue: event.name === 'flash-overdue',
  1222. ready: false,
  1223. })
  1224. }
  1225. break
  1226. case 'ready':
  1227. var wasDeactivated = _flashState.deactivated === true
  1228. _extend(_flashState, {
  1229. disabled: false,
  1230. outdated: false,
  1231. unavailable: false,
  1232. deactivated: false,
  1233. overdue: wasDeactivated,
  1234. ready: !wasDeactivated,
  1235. })
  1236. break
  1237. case 'copy':
  1238. var textContent,
  1239. htmlContent,
  1240. targetEl = event.relatedTarget
  1241. if (
  1242. !(_clipData['text/html'] || _clipData['text/plain']) &&
  1243. targetEl &&
  1244. (htmlContent =
  1245. targetEl.value || targetEl.outerHTML || targetEl.innerHTML) &&
  1246. (textContent =
  1247. targetEl.value || targetEl.textContent || targetEl.innerText)
  1248. ) {
  1249. event.clipboardData.clearData()
  1250. event.clipboardData.setData('text/plain', textContent)
  1251. if (htmlContent !== textContent) {
  1252. event.clipboardData.setData('text/html', htmlContent)
  1253. }
  1254. } else if (
  1255. !_clipData['text/plain'] &&
  1256. event.target &&
  1257. (textContent = event.target.getAttribute('data-clipboard-text'))
  1258. ) {
  1259. event.clipboardData.clearData()
  1260. event.clipboardData.setData('text/plain', textContent)
  1261. }
  1262. break
  1263. case 'aftercopy':
  1264. ZeroClipboard.clearData()
  1265. if (element && element !== _safeActiveElement() && element.focus) {
  1266. element.focus()
  1267. }
  1268. break
  1269. case 'mouseover':
  1270. _addClass(element, _globalConfig.hoverClass)
  1271. break
  1272. case 'mouseout':
  1273. if (_globalConfig.autoActivate === true) {
  1274. ZeroClipboard.deactivate()
  1275. }
  1276. break
  1277. case 'mousedown':
  1278. _addClass(element, _globalConfig.activeClass)
  1279. break
  1280. case 'mouseup':
  1281. _removeClass(element, _globalConfig.activeClass)
  1282. break
  1283. }
  1284. }
  1285. ZeroClipboard.prototype.on = function (eventName, func) {
  1286. var i,
  1287. len,
  1288. events,
  1289. added = {},
  1290. handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers
  1291. if (typeof eventName === 'string' && eventName) {
  1292. events = eventName.toLowerCase().split(/\s+/)
  1293. } else if (
  1294. typeof eventName === 'object' &&
  1295. eventName &&
  1296. typeof func === 'undefined'
  1297. ) {
  1298. for (i in eventName) {
  1299. if (
  1300. eventName.hasOwnProperty(i) &&
  1301. typeof i === 'string' &&
  1302. i &&
  1303. typeof eventName[i] === 'function'
  1304. ) {
  1305. this.on(i, eventName[i])
  1306. }
  1307. }
  1308. }
  1309. if (events && events.length) {
  1310. for (i = 0, len = events.length; i < len; i++) {
  1311. eventName = events[i].replace(/^on/, '')
  1312. added[eventName] = true
  1313. if (!handlers[eventName]) {
  1314. handlers[eventName] = []
  1315. }
  1316. handlers[eventName].push(func)
  1317. }
  1318. if (added.ready && _flashState.ready) {
  1319. ZeroClipboard.emit({
  1320. type: 'ready',
  1321. client: this,
  1322. })
  1323. }
  1324. if (added.error) {
  1325. var errorTypes = [
  1326. 'disabled',
  1327. 'outdated',
  1328. 'unavailable',
  1329. 'deactivated',
  1330. 'overdue',
  1331. ]
  1332. for (i = 0, len = errorTypes.length; i < len; i++) {
  1333. if (_flashState[errorTypes[i]]) {
  1334. ZeroClipboard.emit({
  1335. type: 'error',
  1336. name: 'flash-' + errorTypes[i],
  1337. client: this,
  1338. })
  1339. break
  1340. }
  1341. }
  1342. }
  1343. }
  1344. return this
  1345. }
  1346. ZeroClipboard.prototype.off = function (eventName, func) {
  1347. var i,
  1348. len,
  1349. foundIndex,
  1350. events,
  1351. perEventHandlers,
  1352. handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers
  1353. if (arguments.length === 0) {
  1354. events = _objectKeys(handlers)
  1355. } else if (typeof eventName === 'string' && eventName) {
  1356. events = eventName.split(/\s+/)
  1357. } else if (
  1358. typeof eventName === 'object' &&
  1359. eventName &&
  1360. typeof func === 'undefined'
  1361. ) {
  1362. for (i in eventName) {
  1363. if (
  1364. eventName.hasOwnProperty(i) &&
  1365. typeof i === 'string' &&
  1366. i &&
  1367. typeof eventName[i] === 'function'
  1368. ) {
  1369. this.off(i, eventName[i])
  1370. }
  1371. }
  1372. }
  1373. if (events && events.length) {
  1374. for (i = 0, len = events.length; i < len; i++) {
  1375. eventName = events[i].toLowerCase().replace(/^on/, '')
  1376. perEventHandlers = handlers[eventName]
  1377. if (perEventHandlers && perEventHandlers.length) {
  1378. if (func) {
  1379. foundIndex = _inArray(func, perEventHandlers)
  1380. while (foundIndex !== -1) {
  1381. perEventHandlers.splice(foundIndex, 1)
  1382. foundIndex = _inArray(func, perEventHandlers, foundIndex)
  1383. }
  1384. } else {
  1385. handlers[eventName].length = 0
  1386. }
  1387. }
  1388. }
  1389. }
  1390. return this
  1391. }
  1392. ZeroClipboard.prototype.handlers = function (eventName) {
  1393. var prop,
  1394. copy = null,
  1395. handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers
  1396. if (handlers) {
  1397. if (typeof eventName === 'string' && eventName) {
  1398. return handlers[eventName] ? handlers[eventName].slice(0) : null
  1399. }
  1400. copy = {}
  1401. for (prop in handlers) {
  1402. if (handlers.hasOwnProperty(prop) && handlers[prop]) {
  1403. copy[prop] = handlers[prop].slice(0)
  1404. }
  1405. }
  1406. }
  1407. return copy
  1408. }
  1409. ZeroClipboard.prototype.clip = function (elements) {
  1410. elements = _prepClip(elements)
  1411. for (var i = 0; i < elements.length; i++) {
  1412. if (
  1413. elements.hasOwnProperty(i) &&
  1414. elements[i] &&
  1415. elements[i].nodeType === 1
  1416. ) {
  1417. if (!elements[i].zcClippingId) {
  1418. elements[i].zcClippingId = 'zcClippingId_' + _elementIdCounter++
  1419. _elementMeta[elements[i].zcClippingId] = [this.id]
  1420. if (_globalConfig.autoActivate === true) {
  1421. _addEventHandler(elements[i], 'mouseover', _elementMouseOver)
  1422. }
  1423. } else if (
  1424. _inArray(this.id, _elementMeta[elements[i].zcClippingId]) === -1
  1425. ) {
  1426. _elementMeta[elements[i].zcClippingId].push(this.id)
  1427. }
  1428. var clippedElements = _clientMeta[this.id].elements
  1429. if (_inArray(elements[i], clippedElements) === -1) {
  1430. clippedElements.push(elements[i])
  1431. }
  1432. }
  1433. }
  1434. return this
  1435. }
  1436. ZeroClipboard.prototype.unclip = function (elements) {
  1437. var meta = _clientMeta[this.id]
  1438. if (!meta) {
  1439. return this
  1440. }
  1441. var clippedElements = meta.elements
  1442. var arrayIndex
  1443. if (typeof elements === 'undefined') {
  1444. elements = clippedElements.slice(0)
  1445. } else {
  1446. elements = _prepClip(elements)
  1447. }
  1448. for (var i = elements.length; i--; ) {
  1449. if (
  1450. elements.hasOwnProperty(i) &&
  1451. elements[i] &&
  1452. elements[i].nodeType === 1
  1453. ) {
  1454. arrayIndex = 0
  1455. while (
  1456. (arrayIndex = _inArray(elements[i], clippedElements, arrayIndex)) !==
  1457. -1
  1458. ) {
  1459. clippedElements.splice(arrayIndex, 1)
  1460. }
  1461. var clientIds = _elementMeta[elements[i].zcClippingId]
  1462. if (clientIds) {
  1463. arrayIndex = 0
  1464. while (
  1465. (arrayIndex = _inArray(this.id, clientIds, arrayIndex)) !== -1
  1466. ) {
  1467. clientIds.splice(arrayIndex, 1)
  1468. }
  1469. if (clientIds.length === 0) {
  1470. if (_globalConfig.autoActivate === true) {
  1471. _removeEventHandler(elements[i], 'mouseover', _elementMouseOver)
  1472. }
  1473. delete elements[i].zcClippingId
  1474. }
  1475. }
  1476. }
  1477. }
  1478. return this
  1479. }
  1480. ZeroClipboard.prototype.elements = function () {
  1481. var meta = _clientMeta[this.id]
  1482. return meta && meta.elements ? meta.elements.slice(0) : []
  1483. }
  1484. var _getAllClientsClippedToElement = function (element) {
  1485. var elementMetaId,
  1486. clientIds,
  1487. i,
  1488. len,
  1489. client,
  1490. clients = []
  1491. if (
  1492. element &&
  1493. element.nodeType === 1 &&
  1494. (elementMetaId = element.zcClippingId) &&
  1495. _elementMeta.hasOwnProperty(elementMetaId)
  1496. ) {
  1497. clientIds = _elementMeta[elementMetaId]
  1498. if (clientIds && clientIds.length) {
  1499. for (i = 0, len = clientIds.length; i < len; i++) {
  1500. client = _clientMeta[clientIds[i]].instance
  1501. if (client && client instanceof ZeroClipboard) {
  1502. clients.push(client)
  1503. }
  1504. }
  1505. }
  1506. }
  1507. return clients
  1508. }
  1509. _globalConfig.hoverClass = 'zeroclipboard-is-hover'
  1510. _globalConfig.activeClass = 'zeroclipboard-is-active'
  1511. if (typeof define === 'function' && define.amd) {
  1512. define(function () {
  1513. return ZeroClipboard
  1514. })
  1515. } else if (
  1516. typeof module === 'object' &&
  1517. module &&
  1518. typeof module.exports === 'object' &&
  1519. module.exports
  1520. ) {
  1521. module.exports = ZeroClipboard
  1522. } else {
  1523. window.ZeroClipboard = ZeroClipboard
  1524. }
  1525. })(
  1526. (function () {
  1527. return this
  1528. })()
  1529. )