ZeroClipboard.js 43 KB

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