t |
Text
\nNot valid!
\n'+P.text()+' |
Text
- ` + - - // Input errors - `Not valid!
-Text
\n " + - -// Input errors -"Not valid!
\nHere’s a comparison of a standard error message. The first one uses the built-in alert-function, while the second is using sweetAlert.
- -alert("Oops... Something went wrong!"); - -- - -
sweetAlert("Oops...", "Something went wrong!", "error");-
Pretty cool huh? SweetAlert automatically centers itself on the page and looks great no matter if you're using a desktop computer, mobile or tablet. It's even highly customizeable, as you can see below!
- - - -In these examples, we're using the shorthand function swal to call sweetAlert.
- -A title with a text under
- -swal("Here's a message!", "It's pretty, isn't it?")-
A success message!
- -swal("Good job!", "You clicked the button!", "success")-
A warning message, with a function attached to the "Confirm"-button...
- -swal({ - title: "Are you sure?", - text: "You will not be able to recover this imaginary file!", - type: "warning", - showCancelButton: true, - confirmButtonColor: "#DD6B55", - confirmButtonText: "Yes, delete it!", - closeOnConfirm: false -}, -function(){ - swal("Deleted!", "Your imaginary file has been deleted.", "success"); -});-
... and by passing a parameter, you can execute something else for "Cancel".
- -swal({ - title: "Are you sure?", - text: "You will not be able to recover this imaginary file!", - type: "warning", - showCancelButton: true, - confirmButtonColor: "#DD6B55", - confirmButtonText: "Yes, delete it!", - cancelButtonText: "No, cancel plx!", - closeOnConfirm: false, - closeOnCancel: false -}, -function(isConfirm){ - if (isConfirm) { - swal("Deleted!", "Your imaginary file has been deleted.", "success"); - } else { - swal("Cancelled", "Your imaginary file is safe :)", "error"); - } -});-
A message with auto close timer
- -swal({ - title: "Auto close alert!", - text: "I will close in 2 seconds.", - timer: 2000, - showConfirmButton: false -});-
A replacement for the "prompt" function
- -swal({ - title: "An input!", - text: "Write something interesting:", - type: "input", - showCancelButton: true, - closeOnConfirm: false, - animation: "slide-from-top", - inputPlaceholder: "Write something" -}, -function(inputValue){ - if (inputValue === false) return false; - - if (inputValue === "") { - swal.showInputError("You need to write something!"); - return false - } - - swal("Nice!", "You wrote: " + inputValue, "success"); -});-
With a loader (for AJAX request for example)
- -swal({ - title: "Ajax request example", - text: "Submit to run ajax request", - type: "info", - showCancelButton: true, - closeOnConfirm: false, - showLoaderOnConfirm: true, -}, -function(){ - setTimeout(function(){ - swal("Ajax request finished!"); - }, 2000); -});-
You can also change the theme of SweetAlert!
- -<link rel="stylesheet" type="text/css" href="dist/sweetalert.css"> - <link rel="stylesheet" type="text/css" href="themes/twitter.css">-
Method 1: Install through bower:
-$ bower install sweetalert-
Method 2: Install through NPM:
-$ npm install sweetalert-
Method 3: Download the sweetAlert CSS and JavaScript files.
- -Download files - -Initialize the plugin by referencing the necessary files:
-<script src="dist/sweetalert.min.js"></script> -<link rel="stylesheet" type="text/css" href="dist/sweetalert.css">-
Call the sweetAlert-function after the page has loaded
-swal({ - title: "Error!", - text: "Here's my error message!", - type: "error", - confirmButtonText: "Cool" -}); --
Here are the keys that you can use if you pass an object into sweetAlert:
- -- - Argument - | -Default value | -- - Description - | -
---|---|---|
title | -null (required) | -The title of the modal. It can either be added to the object under the key "title" or passed as the first parameter of the function. | -
text | -null | -A description for the modal. It can either be added to the object under the key "text" or passed as the second parameter of the function. | -
type | -null | -The type of the modal. SweetAlert comes with 4 built-in types which will show a corresponding icon animation: "warning", "error", "success" and "info". You can also set it as "input" to get a prompt modal. It can either be put in the object under the key "type" or passed as the third parameter of the function. | -
allowEscapeKey | -true | -If set to true, the user can dismiss the modal by pressing the Escape key. | -
customClass | -null | -A custom CSS class for the modal. It can be added to the object under the key "customClass". | -
allowOutsideClick | -false | -If set to true, the user can dismiss the modal by clicking outside it. | -
showCancelButton | -false | -If set to true, a "Cancel"-button will be shown, which the user can click on to dismiss the modal. | -
showConfirmButton | -true | -If set to false, the "OK/Confirm"-button will be hidden. Make sure you set a timer or set allowOutsideClick to true when using this, in order not to annoy the user. | -
confirmButtonText | -"OK" | -Use this to change the text on the "Confirm"-button. If showCancelButton is set as true, the confirm button will automatically show "Confirm" instead of "OK". | -
confirmButtonColor | -"#AEDEF4" | -Use this to change the background color of the "Confirm"-button (must be a HEX value). | -
cancelButtonText | -"Cancel" | -Use this to change the text on the "Cancel"-button. | -
closeOnConfirm | -true | -Set to false if you want the modal to stay open even if the user presses the "Confirm"-button. This is especially useful if the function attached to the "Confirm"-button is another SweetAlert. | -
closeOnCancel | -true | -Same as closeOnConfirm, but for the cancel button. | -
imageUrl | -null | -Add a customized icon for the modal. Should contain a string with the path to the image. | -
imageSize | -"80x80" | -If imageUrl is set, you can specify imageSize to describes how big you want the icon to be in px. Pass in a string with two values separated by an "x". The first value is the width, the second is the height. | -
timer | -null | -Auto close timer of the modal. Set in ms (milliseconds). | -
html | -false | -If set to true, will not escape title and text parameters. (Set to false if you're worried about XSS attacks.) | -
animation | -true | -If set to false, the modal's animation will be disabled. Possible (string) values : pop (default when animation set to true), slide-from-top, slide-from-bottom | -
inputType | -"text" | -Change the type of the input field when using type: "input" (this can be useful if you want users to type in their password for example). | -
inputPlaceholder | -null | -When using the input-type, you can specify a placeholder to help the user. | -
inputValue | -null | -Specify a default text value that you want your input to show when using type: "input" | -
showLoaderOnConfirm | -false | -Set to true to disable the buttons and show that something is loading. | -
SweetAlert also comes with some simple methods that you can call:
- -- - Function - | -Example | -- - Description - | -
---|---|---|
setDefaults | -swal.setDefaults({ confirmButtonColor: '#0000' }); | -If you end up using a lot of the same settings when calling SweetAlert, you can use setDefaults at the start of your program to set them once and for all! | -
close | -swal.close(); | -Close the currently open SweetAlert programatically. | -
showInputError | -swal.showInputError("Invalid email!"); | -Show an error message after validating the input field, if the user's data is bad | -
enableButtons, disableButtons | -swal.disableButtons(); | -Disable or enable the user to click on the cancel and confirm buttons. | -
SweetAlert was created by Tristan Edwards, you can follow him on Twitter or Dribbble for updates and other cool projects!
-Feel free to fork SweetAlert on GitHub if you have any features that you want to add!
- - - - - - - - - - - - diff --git a/web/public/libs/sweetalert/lib/modules/default-params.js b/web/public/libs/sweetalert/lib/modules/default-params.js deleted file mode 100755 index 8f07f2e..0000000 --- a/web/public/libs/sweetalert/lib/modules/default-params.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { - value: true -}); -var defaultParams = { - title: '', - text: '', - type: null, - allowOutsideClick: false, - showConfirmButton: true, - showCancelButton: false, - closeOnConfirm: true, - closeOnCancel: true, - confirmButtonText: 'OK', - confirmButtonColor: '#8CD4F5', - cancelButtonText: 'Cancel', - imageUrl: null, - imageSize: null, - timer: null, - customClass: '', - html: false, - animation: true, - allowEscapeKey: true, - inputType: 'text', - inputPlaceholder: '', - inputValue: '', - showLoaderOnConfirm: false -}; - -exports['default'] = defaultParams; -module.exports = exports['default']; \ No newline at end of file diff --git a/web/public/libs/sweetalert/lib/modules/handle-click.js b/web/public/libs/sweetalert/lib/modules/handle-click.js deleted file mode 100755 index 67a59b0..0000000 --- a/web/public/libs/sweetalert/lib/modules/handle-click.js +++ /dev/null @@ -1,135 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { - value: true -}); - -var _colorLuminance = require('./utils'); - -var _getModal = require('./handle-swal-dom'); - -var _hasClass$isDescendant = require('./handle-dom'); - -/* - * User clicked on "Confirm"/"OK" or "Cancel" - */ -var handleButton = function handleButton(event, params, modal) { - var e = event || window.event; - var target = e.target || e.srcElement; - - var targetedConfirm = target.className.indexOf('confirm') !== -1; - var targetedOverlay = target.className.indexOf('sweet-overlay') !== -1; - var modalIsVisible = _hasClass$isDescendant.hasClass(modal, 'visible'); - var doneFunctionExists = params.doneFunction && modal.getAttribute('data-has-done-function') === 'true'; - - // Since the user can change the background-color of the confirm button programmatically, - // we must calculate what the color should be on hover/active - var normalColor, hoverColor, activeColor; - if (targetedConfirm && params.confirmButtonColor) { - normalColor = params.confirmButtonColor; - hoverColor = _colorLuminance.colorLuminance(normalColor, -0.04); - activeColor = _colorLuminance.colorLuminance(normalColor, -0.14); - } - - function shouldSetConfirmButtonColor(color) { - if (targetedConfirm && params.confirmButtonColor) { - target.style.backgroundColor = color; - } - } - - switch (e.type) { - case 'mouseover': - shouldSetConfirmButtonColor(hoverColor); - break; - - case 'mouseout': - shouldSetConfirmButtonColor(normalColor); - break; - - case 'mousedown': - shouldSetConfirmButtonColor(activeColor); - break; - - case 'mouseup': - shouldSetConfirmButtonColor(hoverColor); - break; - - case 'focus': - var $confirmButton = modal.querySelector('button.confirm'); - var $cancelButton = modal.querySelector('button.cancel'); - - if (targetedConfirm) { - $cancelButton.style.boxShadow = 'none'; - } else { - $confirmButton.style.boxShadow = 'none'; - } - break; - - case 'click': - var clickedOnModal = modal === target; - var clickedOnModalChild = _hasClass$isDescendant.isDescendant(modal, target); - - // Ignore click outside if allowOutsideClick is false - if (!clickedOnModal && !clickedOnModalChild && modalIsVisible && !params.allowOutsideClick) { - break; - } - - if (targetedConfirm && doneFunctionExists && modalIsVisible) { - handleConfirm(modal, params); - } else if (doneFunctionExists && modalIsVisible || targetedOverlay) { - handleCancel(modal, params); - } else if (_hasClass$isDescendant.isDescendant(modal, target) && target.tagName === 'BUTTON') { - sweetAlert.close(); - } - break; - } -}; - -/* - * User clicked on "Confirm"/"OK" - */ -var handleConfirm = function handleConfirm(modal, params) { - var callbackValue = true; - - if (_hasClass$isDescendant.hasClass(modal, 'show-input')) { - callbackValue = modal.querySelector('input').value; - - if (!callbackValue) { - callbackValue = ''; - } - } - - params.doneFunction(callbackValue); - - if (params.closeOnConfirm) { - sweetAlert.close(); - } - // Disable cancel and confirm button if the parameter is true - if (params.showLoaderOnConfirm) { - sweetAlert.disableButtons(); - } -}; - -/* - * User clicked on "Cancel" - */ -var handleCancel = function handleCancel(modal, params) { - // Check if callback function expects a parameter (to track cancel actions) - var functionAsStr = String(params.doneFunction).replace(/\s/g, ''); - var functionHandlesCancel = functionAsStr.substring(0, 9) === 'function(' && functionAsStr.substring(9, 10) !== ')'; - - if (functionHandlesCancel) { - params.doneFunction(false); - } - - if (params.closeOnCancel) { - sweetAlert.close(); - } -}; - -exports['default'] = { - handleButton: handleButton, - handleConfirm: handleConfirm, - handleCancel: handleCancel -}; -module.exports = exports['default']; \ No newline at end of file diff --git a/web/public/libs/sweetalert/lib/modules/handle-dom.js b/web/public/libs/sweetalert/lib/modules/handle-dom.js deleted file mode 100755 index e8c22a5..0000000 --- a/web/public/libs/sweetalert/lib/modules/handle-dom.js +++ /dev/null @@ -1,191 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { - value: true -}); -var hasClass = function hasClass(elem, className) { - return new RegExp(' ' + className + ' ').test(' ' + elem.className + ' '); -}; - -var addClass = function addClass(elem, className) { - if (!hasClass(elem, className)) { - elem.className += ' ' + className; - } -}; - -var removeClass = function removeClass(elem, className) { - var newClass = ' ' + elem.className.replace(/[\t\r\n]/g, ' ') + ' '; - if (hasClass(elem, className)) { - while (newClass.indexOf(' ' + className + ' ') >= 0) { - newClass = newClass.replace(' ' + className + ' ', ' '); - } - elem.className = newClass.replace(/^\s+|\s+$/g, ''); - } -}; - -var escapeHtml = function escapeHtml(str) { - var div = document.createElement('div'); - div.appendChild(document.createTextNode(str)); - return div.innerHTML; -}; - -var _show = function _show(elem) { - elem.style.opacity = ''; - elem.style.display = 'block'; -}; - -var show = function show(elems) { - if (elems && !elems.length) { - return _show(elems); - } - for (var i = 0; i < elems.length; ++i) { - _show(elems[i]); - } -}; - -var _hide = function _hide(elem) { - elem.style.opacity = ''; - elem.style.display = 'none'; -}; - -var hide = function hide(elems) { - if (elems && !elems.length) { - return _hide(elems); - } - for (var i = 0; i < elems.length; ++i) { - _hide(elems[i]); - } -}; - -var isDescendant = function isDescendant(parent, child) { - var node = child.parentNode; - while (node !== null) { - if (node === parent) { - return true; - } - node = node.parentNode; - } - return false; -}; - -var getTopMargin = function getTopMargin(elem) { - elem.style.left = '-9999px'; - elem.style.display = 'block'; - - var height = elem.clientHeight, - padding; - if (typeof getComputedStyle !== 'undefined') { - // IE 8 - padding = parseInt(getComputedStyle(elem).getPropertyValue('padding-top'), 10); - } else { - padding = parseInt(elem.currentStyle.padding); - } - - elem.style.left = ''; - elem.style.display = 'none'; - return '-' + parseInt((height + padding) / 2) + 'px'; -}; - -var fadeIn = function fadeIn(elem, interval) { - if (+elem.style.opacity < 1) { - interval = interval || 16; - elem.style.opacity = 0; - elem.style.display = 'block'; - var last = +new Date(); - var tick = (function (_tick) { - function tick() { - return _tick.apply(this, arguments); - } - - tick.toString = function () { - return _tick.toString(); - }; - - return tick; - })(function () { - elem.style.opacity = +elem.style.opacity + (new Date() - last) / 100; - last = +new Date(); - - if (+elem.style.opacity < 1) { - setTimeout(tick, interval); - } - }); - tick(); - } - elem.style.display = 'block'; //fallback IE8 -}; - -var fadeOut = function fadeOut(elem, interval) { - interval = interval || 16; - elem.style.opacity = 1; - var last = +new Date(); - var tick = (function (_tick2) { - function tick() { - return _tick2.apply(this, arguments); - } - - tick.toString = function () { - return _tick2.toString(); - }; - - return tick; - })(function () { - elem.style.opacity = +elem.style.opacity - (new Date() - last) / 100; - last = +new Date(); - - if (+elem.style.opacity > 0) { - setTimeout(tick, interval); - } else { - elem.style.display = 'none'; - } - }); - tick(); -}; - -var fireClick = function fireClick(node) { - // Taken from http://www.nonobtrusive.com/2011/11/29/programatically-fire-crossbrowser-click-event-with-javascript/ - // Then fixed for today's Chrome browser. - if (typeof MouseEvent === 'function') { - // Up-to-date approach - var mevt = new MouseEvent('click', { - view: window, - bubbles: false, - cancelable: true - }); - node.dispatchEvent(mevt); - } else if (document.createEvent) { - // Fallback - var evt = document.createEvent('MouseEvents'); - evt.initEvent('click', false, false); - node.dispatchEvent(evt); - } else if (document.createEventObject) { - node.fireEvent('onclick'); - } else if (typeof node.onclick === 'function') { - node.onclick(); - } -}; - -var stopEventPropagation = function stopEventPropagation(e) { - // In particular, make sure the space bar doesn't scroll the main window. - if (typeof e.stopPropagation === 'function') { - e.stopPropagation(); - e.preventDefault(); - } else if (window.event && window.event.hasOwnProperty('cancelBubble')) { - window.event.cancelBubble = true; - } -}; - -exports.hasClass = hasClass; -exports.addClass = addClass; -exports.removeClass = removeClass; -exports.escapeHtml = escapeHtml; -exports._show = _show; -exports.show = show; -exports._hide = _hide; -exports.hide = hide; -exports.isDescendant = isDescendant; -exports.getTopMargin = getTopMargin; -exports.fadeIn = fadeIn; -exports.fadeOut = fadeOut; -exports.fireClick = fireClick; -exports.stopEventPropagation = stopEventPropagation; \ No newline at end of file diff --git a/web/public/libs/sweetalert/lib/modules/handle-key.js b/web/public/libs/sweetalert/lib/modules/handle-key.js deleted file mode 100755 index 4869f9e..0000000 --- a/web/public/libs/sweetalert/lib/modules/handle-key.js +++ /dev/null @@ -1,79 +0,0 @@ -'use strict'; - -Object.defineProperty(exports, '__esModule', { - value: true -}); - -var _stopEventPropagation$fireClick = require('./handle-dom'); - -var _setFocusStyle = require('./handle-swal-dom'); - -var handleKeyDown = function handleKeyDown(event, params, modal) { - var e = event || window.event; - var keyCode = e.keyCode || e.which; - - var $okButton = modal.querySelector('button.confirm'); - var $cancelButton = modal.querySelector('button.cancel'); - var $modalButtons = modal.querySelectorAll('button[tabindex]'); - - if ([9, 13, 32, 27].indexOf(keyCode) === -1) { - // Don't do work on keys we don't care about. - return; - } - - var $targetElement = e.target || e.srcElement; - - var btnIndex = -1; // Find the button - note, this is a nodelist, not an array. - for (var i = 0; i < $modalButtons.length; i++) { - if ($targetElement === $modalButtons[i]) { - btnIndex = i; - break; - } - } - - if (keyCode === 9) { - // TAB - if (btnIndex === -1) { - // No button focused. Jump to the confirm button. - $targetElement = $okButton; - } else { - // Cycle to the next button - if (btnIndex === $modalButtons.length - 1) { - $targetElement = $modalButtons[0]; - } else { - $targetElement = $modalButtons[btnIndex + 1]; - } - } - - _stopEventPropagation$fireClick.stopEventPropagation(e); - $targetElement.focus(); - - if (params.confirmButtonColor) { - _setFocusStyle.setFocusStyle($targetElement, params.confirmButtonColor); - } - } else { - if (keyCode === 13) { - if ($targetElement.tagName === 'INPUT') { - $targetElement = $okButton; - $okButton.focus(); - } - - if (btnIndex === -1) { - // ENTER/SPACE clicked outside of a button. - $targetElement = $okButton; - } else { - // Do nothing - let the browser handle it. - $targetElement = undefined; - } - } else if (keyCode === 27 && params.allowEscapeKey === true) { - $targetElement = $cancelButton; - _stopEventPropagation$fireClick.fireClick($targetElement, e); - } else { - // Fallback - let the browser handle it. - $targetElement = undefined; - } - } -}; - -exports['default'] = handleKeyDown; -module.exports = exports['default']; \ No newline at end of file diff --git a/web/public/libs/sweetalert/lib/modules/handle-swal-dom.js b/web/public/libs/sweetalert/lib/modules/handle-swal-dom.js deleted file mode 100755 index 1a18bea..0000000 --- a/web/public/libs/sweetalert/lib/modules/handle-swal-dom.js +++ /dev/null @@ -1,167 +0,0 @@ -'use strict'; - -var _interopRequireWildcard = function (obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }; - -Object.defineProperty(exports, '__esModule', { - value: true -}); - -var _hexToRgb = require('./utils'); - -var _removeClass$getTopMargin$fadeIn$show$addClass = require('./handle-dom'); - -var _defaultParams = require('./default-params'); - -var _defaultParams2 = _interopRequireWildcard(_defaultParams); - -/* - * Add modal + overlay to DOM - */ - -var _injectedHTML = require('./injected-html'); - -var _injectedHTML2 = _interopRequireWildcard(_injectedHTML); - -var modalClass = '.sweet-alert'; -var overlayClass = '.sweet-overlay'; - -var sweetAlertInitialize = function sweetAlertInitialize() { - var sweetWrap = document.createElement('div'); - sweetWrap.innerHTML = _injectedHTML2['default']; - - // Append elements to body - while (sweetWrap.firstChild) { - document.body.appendChild(sweetWrap.firstChild); - } -}; - -/* - * Get DOM element of modal - */ -var getModal = (function (_getModal) { - function getModal() { - return _getModal.apply(this, arguments); - } - - getModal.toString = function () { - return _getModal.toString(); - }; - - return getModal; -})(function () { - var $modal = document.querySelector(modalClass); - - if (!$modal) { - sweetAlertInitialize(); - $modal = getModal(); - } - - return $modal; -}); - -/* - * Get DOM element of input (in modal) - */ -var getInput = function getInput() { - var $modal = getModal(); - if ($modal) { - return $modal.querySelector('input'); - } -}; - -/* - * Get DOM element of overlay - */ -var getOverlay = function getOverlay() { - return document.querySelector(overlayClass); -}; - -/* - * Add box-shadow style to button (depending on its chosen bg-color) - */ -var setFocusStyle = function setFocusStyle($button, bgColor) { - var rgbColor = _hexToRgb.hexToRgb(bgColor); - $button.style.boxShadow = '0 0 2px rgba(' + rgbColor + ', 0.8), inset 0 0 0 1px rgba(0, 0, 0, 0.05)'; -}; - -/* - * Animation when opening modal - */ -var openModal = function openModal(callback) { - var $modal = getModal(); - _removeClass$getTopMargin$fadeIn$show$addClass.fadeIn(getOverlay(), 10); - _removeClass$getTopMargin$fadeIn$show$addClass.show($modal); - _removeClass$getTopMargin$fadeIn$show$addClass.addClass($modal, 'showSweetAlert'); - _removeClass$getTopMargin$fadeIn$show$addClass.removeClass($modal, 'hideSweetAlert'); - - window.previousActiveElement = document.activeElement; - var $okButton = $modal.querySelector('button.confirm'); - $okButton.focus(); - - setTimeout(function () { - _removeClass$getTopMargin$fadeIn$show$addClass.addClass($modal, 'visible'); - }, 500); - - var timer = $modal.getAttribute('data-timer'); - - if (timer !== 'null' && timer !== '') { - var timerCallback = callback; - $modal.timeout = setTimeout(function () { - var doneFunctionExists = (timerCallback || null) && $modal.getAttribute('data-has-done-function') === 'true'; - if (doneFunctionExists) { - timerCallback(null); - } else { - sweetAlert.close(); - } - }, timer); - } -}; - -/* - * Reset the styling of the input - * (for example if errors have been shown) - */ -var resetInput = function resetInput() { - var $modal = getModal(); - var $input = getInput(); - - _removeClass$getTopMargin$fadeIn$show$addClass.removeClass($modal, 'show-input'); - $input.value = _defaultParams2['default'].inputValue; - $input.setAttribute('type', _defaultParams2['default'].inputType); - $input.setAttribute('placeholder', _defaultParams2['default'].inputPlaceholder); - - resetInputError(); -}; - -var resetInputError = function resetInputError(event) { - // If press enter => ignore - if (event && event.keyCode === 13) { - return false; - } - - var $modal = getModal(); - - var $errorIcon = $modal.querySelector('.sa-input-error'); - _removeClass$getTopMargin$fadeIn$show$addClass.removeClass($errorIcon, 'show'); - - var $errorContainer = $modal.querySelector('.sa-error-container'); - _removeClass$getTopMargin$fadeIn$show$addClass.removeClass($errorContainer, 'show'); -}; - -/* - * Set "margin-top"-property on modal based on its computed height - */ -var fixVerticalPosition = function fixVerticalPosition() { - var $modal = getModal(); - $modal.style.marginTop = _removeClass$getTopMargin$fadeIn$show$addClass.getTopMargin(getModal()); -}; - -exports.sweetAlertInitialize = sweetAlertInitialize; -exports.getModal = getModal; -exports.getOverlay = getOverlay; -exports.getInput = getInput; -exports.setFocusStyle = setFocusStyle; -exports.openModal = openModal; -exports.resetInput = resetInput; -exports.resetInputError = resetInputError; -exports.fixVerticalPosition = fixVerticalPosition; \ No newline at end of file diff --git a/web/public/libs/sweetalert/lib/modules/injected-html.js b/web/public/libs/sweetalert/lib/modules/injected-html.js deleted file mode 100755 index 67623dc..0000000 --- a/web/public/libs/sweetalert/lib/modules/injected-html.js +++ /dev/null @@ -1,42 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var injectedHTML = - -// Dark overlay -"" + - -// Modal -"Text
\n " + - -// Input errors -"Not valid!
\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod - tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, - quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo - consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse - cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non - proident, sunt in culpa qui officia deserunt mollit anim id est laborum.- ``` - -3. Set the "text/plain" clipboard segment via `data-clipboard-text` attribute on the button. Doing this will let ZeroClipboard take care of the rest. - - ```html - - ``` - -4. Set the data via the `ZeroClipboard.setData` (any segment) method. You can call this function at any time: when the page first loads, or later like in a `copy` event handler. Example: - - ```js - ZeroClipboard.setData( "text/plain", "Copy me!" ); - ``` - - The important caveat of using `ZeroClipboard.setData` is that the data it sets is **transient** and _will only be used for a single copy operation_. As such, we do not particularly - recommend using `ZeroClipboard.setData` (and friends) other than inside of a `copy` event handler; however, the API will not prevent you from using it in other ways. - -5. Set the data via the `client.setText` ("text/plain" segment), `client.setHtml` ("text/html" segment), `client.setRichText` ("application/rtf" segment), or `client.setData` (any segment) methods. You can call this function at any time: when the page first loads, or later like in a `copy` event handler. Example: - - ```js - client.setText( "Copy me!" ); - ``` - - The important caveat of using `client.setData` (and friends) is that the data it sets is **transient** and _will only be used for a single copy operation_. As such, we do not particularly - recommend using `client.setData` (and friends) other than inside of a `copy` event handler; however, the API will not prevent you from using it in other ways. - - -### Clipping - -Clipping refers to the process of "linking" the Flash movie to a DOM element on the page. Since the Flash movie is completely transparent, the user sees nothing out of the ordinary. - -The Flash movie receives the click event and copies the text to the clipboard. Also, mouse actions like hovering and `mousedown` generate events that you can capture (see [_Event Handlers_](#event-handlers) below). - -To clip elements, you must pass an element, or array of elements to the `clip` function. - -Here is how to clip your client library instance to a DOM element: - -```js -client.clip( document.getElementById("d_clip_button") ); -``` - -You can pass in a reference to the actual DOM element object itself or an array of DOM objects. The rest all happens automatically: the movie is created, all your options set, and it is floated above the element, awaiting clicks from the user. - - -### Example Implementation - -```html - -``` - -And the code: - -```js -var client = new ZeroClipboard( $("button#my-button") ); -``` - - -## CSS Effects - -Since the Flash movie is floating on top of your DOM element, it will receive all the mouse events before the browser has a chance to catch them. However, for convenience, these events are passed through to your clipboard client which you can capture (see _Event Handlers_ below), so long as the `bubbleEvents` configuration property remains set to `true`. - -In addition to this, ZeroClipboard can also manage CSS classes on the clipped elements that mimic the CSS pseudo-classes ":hover" and ":active" on your DOM element. This essentially allows your elements to behave normally, even though the floating Flash movie is the first object receiving all the mouse events during the event bubbling phase. These "pseudo-pseudo-class" names are configurable via the `hoverClass` and `activeClass` configuration properties. - -Example CSS, targeting a DOM element with a class of "clip_button": - -```css - .clip_button { - width: 150px; - text-align: center; - border: 1px solid black; - background-color: #ccc; - margin: 10px; - padding: 10px; - } - .clip_button.zeroclipboard-is-hover { background-color: #eee; } - .clip_button.zeroclipboard-is-active { background-color: #aaa; } -``` - - -## Examples - -The following are complete, working examples of using the clipboard client library in HTML pages. - - -### Minimal Example - -Here is a quick example using as few calls as possible: - -```html - - - - - - - - -``` - -When clicked, the text "Copy me!" will be copied to the clipboard. - - -### A More Complete Example - -Here is a more complete example which exercises many of the configuration options and event handlers: - -```html - - - - - - - - - - - - - - -``` - - -## Namespacing ZeroClipboard - -ZeroClipboard creates DOM elements with pre-configured attributes, e.g. a `div` element with an ID of `"global-zeroclipboard-html-bridge"` to encapsulate the Flash object. - -If you have a need to change the default values, they can be configured by passing in values for `containerId`, `containerClass`, and/or `swfObjectId` using the `ZeroClipboard.config` method. Configuration of these values is completely optional. These values cannot be reconfigured while the ZeroClipboard SWF is actively embedded, and so are completely ignored during that time. - -Values for `containerId` and `swfObjectId` are validated against the [HTML4 spec for `ID` and `Name` tokens][valid_ids]. - - -## AMD - -If using [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD) with a library such as [RequireJS](http://requirejs.org/), etc., you shouldn't need to do any special configuration for ZeroClipboard to work correctly as an AMD module. - - -## CommonJS - -If using [CommonJS](http://wiki.commonjs.org/wiki/Modules/1.1) with a library such as [Browserify](http://browserify.org/), [Webmake](https://github.com/medikoo/modules-webmake), etc., you shouldn't need to do any special configuration for ZeroClipboard to work correctly as an CommonJS module. - - -## Known Conflicts With Other Libraries - -### [IE freezes when clicking a ZeroClipboard clipped element within a Bootstrap Modal](https://github.com/zeroclipboard/zeroclipboard/issues/159). - - **Cause:** Bootstrap's Modal has an `enforceFocus` function that tries to keep the focus on the modal. - However, since the ZeroClipboard container is an immediate child of the `body`, this enforcement conflicts. Note that - this workaround actually _overrides_ a core Bootstrap Modal function, and as such must be kept in sync as this function - changes in future versions of Bootstrap. - - **Workaround:** _Targeted against [Bootstrap v3.x](https://github.com/twbs/bootstrap/blob/96a9e1bae06cb21f8cf72ec528b8e31b6ab27272/js/modal.js#L115-123)._ - -#### Workaround A - -```js -if (/MSIE|Trident/.test(window.navigator.userAgent)) { - (function($) { - var zcContainerId = ZeroClipboard.config('containerId'); - $('#' + zcContainerId).on('focusin', false); - })(window.jQuery); -} -``` - -#### Workaround B - -```js -if (/MSIE|Trident/.test(window.navigator.userAgent)) { - (function($) { - var zcClass = '.' + ZeroClipboard.config('containerClass'); - var proto = $.fn.modal.Constructor.prototype; - proto.enforceFocus = function() { - $(document) - .off('focusin.bs.modal') /* Guard against infinite focus loop */ - .on('focusin.bs.modal', $.proxy(function(e) { - if (this.$element[0] !== e.target && - !this.$element.has(e.target).length && - /* Adding this final condition check is the only real change */ - !$(e.target).closest(zcClass).length - ) { - this.$element.focus(); - } - }, this)); - }; - })(window.jQuery); -} -``` - - -### [IE freezes when clicking a ZeroClipboard clipped element within a jQuery UI [Modal] Dialog](https://github.com/zeroclipboard/zeroclipboard/issues/159). - - **Cause:** jQuery UI's Dialog (with `{ modal: true }` set) has a `_keepFocus` function that tries to keep the focus on the modal. - However, since the ZeroClipboard container is an immediate child of the `body`, this enforcement conflicts. Luckily, jQuery UI offers - more natural extension points than Bootstrap, so the workaround is smaller and less likely to be broken in future versions. - - **Workaround:** _Targeted against [jQuery UI v1.10.x](https://github.com/jquery/jquery-ui/blob/457b275880b63b05b16b7c9ee6c22f29f682ebc8/ui/jquery.ui.dialog.js#L695-703)._ - -```js -if (/MSIE|Trident/.test(window.navigator.userAgent)) { - (function($) { - var zcClass = '.' + ZeroClipboard.config('containerClass'); - $.widget( 'ui.dialog', $.ui.dialog, { - _allowInteraction: function( event ) { - return this._super(event) || $( event.target ).closest( zcClass ).length; - } - } ); - })(window.jQuery); -} -``` - - -## Support - -This library is fully compatible with Flash Player 11.0.0 and above, which requires -that the clipboard copy operation be initiated by a user click event inside the -Flash movie. This is achieved by automatically floating the invisible movie on top -of a [DOM](http://en.wikipedia.org/wiki/Document_Object_Model) element of your -choice. Standard mouse events are even propagated out to your DOM element, so you -can still have rollover and mousedown effects with just a _little_ extra effort. - -ZeroClipboard `v2.x` is expected to work in IE9+ and all of the evergreen browsers. -Although support for IE7 & IE8 was officially dropped in `v2.0.0`, it was actually -still _technically_ supported through `v2.0.2`. - - - -## Browser-Specific Known Issues - -### Opera - - [Issue #459](https://github.com/zeroclipboard/zeroclipboard/issues/459) - - **Problem:** Both the implicit observation of clipped elements' `cursor` CSS property and the `forceHandCursor: true` [Configuration Option](api/ZeroClipboard.md#configuration-options) cannot be honored in Opera's NPAPI Flash Player plugin. - - **Workaround:** End users must install both Opera 24+ **AND** the separate PPAPI Flash Player plugin that is currently only available in [Adobe Flash Player 16 Beta](http://labs.adobe.com/downloads/flashplayer.html) (look for the OS-specific download entitled "Download Flash Player for Opera and Chromium based applications – PPAPI"). Beginning with Opera 27 (currently in the alpha/dev channel cycle), Opera will automatically warn users that only have the NPAPI Flash Player plugin installed and guide them into installing the PPAPI Flash Player plugin from Adobe. - - - -## OS Considerations - -Because ZeroClipboard will be interacting with your users' system clipboards, there are some special considerations -specific to the users' operating systems that you should be aware of. With this information, you can make informed -decisions of how _your_ site should handle each of these situations. - -### Windows - - If you want to ensure that your Windows users will be able to paste their copied text into Windows - Notepad and have it honor line breaks, you'll need to ensure that the text uses the sequence `\r\n` - instead of just `\n` for line breaks. If the text to copy is based on user input (e.g. a `textarea`), - then you can achieve this transformation by utilizing the `copy` event handler, e.g. - - ```js - client.on('copy', function(event) { - var text = document.getElementById('yourTextArea').value; - var windowsText = text.replace(/\n/g, '\r\n'); - event.clipboardData.setData('text/plain', windowsText); - }); - ``` - -### Linux - - The Linux Clipboard system (a.k.a. "Selection Atoms" within the [X Consortium's Standard Inter-Client Communication Conventions Manual](http://www.x.org/docs/ICCCM/icccm.pdf)) is a complex but capable setup. However, for normal end users, it stinks. Flash Player's Clipboard API can either: - 1. Insert plain text into the "System Clipboard" and have it available everywhere; or - 2. Insert plain, HTML, and RTF text into the "Desktop Clipboard" but it will only be available in applications whose UI are managed by the Desktop Manager System (e.g. GNOME, etc.). This, for example, means that a user on a typical Linux configuration would not be able to paste something copied with ZeroClipboard into a terminal shell but they may still be able to paste it into OpenOffice, the browser, etc. - - As such, the default behavior for ZeroClipboard while running on Linux is to only inject plain text into the "System Clipboard" to cover the most bases. If you want to ignore that caution and use the "Desktop Clipboard" anyway, just set the `forceEnhancedClipboard` [configuration option](api/ZeroClipboard.md#configuration-options) to `true`, i.e.: - - ```js - ZeroClipboard.config({ - forceEnhancedClipboard: true - }); - ``` - - Also, a final related behavioral caveat: if the pending clipboard data **ONLY** contains data of the - format `"text/plain"`, ZeroClipboard will intelligently choose to use the "System Clipboard" regardless - of the `forceEnhancedClipboard` configuration property value. - - - -## Protocol Limitations - -### Cross-Protocol Limitations - -ZeroClipboard was intentionally configured to _not_ allow the SWF to be served from a secure domain (HTTPS) but scripted by an insecure domain (HTTP). - -If you find yourself in this situation (as in [Issue #170](https://github.com/zeroclipboard/zeroclipboard/issues/170)), please consider the following options: - 1. Serve the SWF over HTTP instead of HTTPS. If the page's protocol can vary (e.g. authorized/unauthorized, staging/production, etc.), you should include add the SWF with a relative protocol (`//s3.amazonaws.com/blah/ZeroClipboard.swf`) instead of an absolute protocol (`https://s3.amazonaws.com/blah/ZeroClipboard.swf`). - 2. Serve the page over HTTPS instead of HTTP. If the page's protocol can vary, see the note on the previous option (1). - 3. Fork ZeroClipboard and update "src/flash/ZeroClipboard.as" to call the [`allowInsecureDomain`](http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/system/Security.html#allowInsecureDomain\(\)) method as needed, then recompile the SWF with your custom changes. - - -### `file://` Protocol Limitations - -If you want to either use ZeroClipboard on a page hosted via the `file://` protocol or serve ZeroClipboard's assets via the `file://` protocol, you are almost guaranteed to run into some roadblocks due to Flash Player security restrictions. Whether you will be able to work around these roadblocks depends heavily on the specifics of the browser and Flash Player plugin being used. - -The various potential and/or partial workarounds are detailed below. We recommend trying them in the -order they are listed, with the exception of any that are not applicable to your browser/Flash setup. - -#### Stop Hosting It Over The `file://` Protocol - -Do you really need to be hosting this via the `file://` protocol? If not, please don't: it may turn into a neverending (or outright _losing_) security configuration battle for you. - -We recommend that you instead just get a simple HTTP server installed and use it. Many HTTP server applications exist today that don't even require configuration or proper "installation", they are just executable files that can dynamically host the current working directory (or accept command line configuration options). Simple, easy, done. - -But, if you really do _need_ to be hosting this via the `file://` protocol, please read on... and we wish you much-needed luck. - - -#### Tell ZeroClipboard To Trust Anyone & Everyone - -Rarely, for some browser/Flash setups, you can bypass this security restriction as easily as specifically -configuring ZeroClipboard to trust ALL domains for SWF interaction via a wildcard. This -configuration must be set _before_ creating ZeroClipboard client instances as a typical consumer, -or before calling `ZeroClipboard.create()` in a 3rd party wrapper: - -```js -ZeroClipboard.config({ trustedDomains: ["*"] }); -``` - -This wildcard configuration should _**NOT**_ be used in environments hosted over HTTP/HTTPS. - - -#### Tell Flash Player Local Settings Manager To Trust Your SWF URL - -If you are using any browser with the traditional NPAPI Flash Player plugin enabled **AND** _preferred_ -(i.e. PPAPI Flash Player plugins are not supported, are not installed, or are disabled for the browser -instance in question) or using the PPAPI Flash Player plugin `v16.0.0` (or higher), you can edit your -system-level Flash Player security settings to whitelist your SWF URL using the [Flash Player -Local Settings Manager](http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager.html): - 1. Open the Flash Player Local Settings Manager via your system's [OS-specific access procedure](http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager.html#124401). - 2. Go to the ["Advanced" tab](http://help.adobe.com/en_US/FlashPlayer/LSM/WS6aa5ec234ff3f285139dc56112e3786b68c-7ff0.html). - 3. Locate the ["Developer Tools" subsection](http://help.adobe.com/en_US/FlashPlayer/LSM/WS6aa5ec234ff3f285139dc56112e3786b68c-7ff0.html#WS6aa5ec234ff3f285139dc56112e3786b68c-7feb) (may require you to scroll down). - 4. Click the ["Trusted Location Settings..." button](http://help.adobe.com/en_US/FlashPlayer/LSM/WS6aa5ec234ff3f285139dc56112e3786b68c-7ff0.html#WS6aa5ec234ff3f285139dc56112e3786b68c-7fea). - 5. Click "Add location" (may be represented as a `+` button). - 6. Add the absolute path of your local "ZeroClipboard.swf" file to the trusted files whitelist. - -This should work for all NPAPI Flash Player plugins. However, this _may_ **not** work for all PPAPI Flash Player plugins. - - -#### Tell Flash Player Online Settings Manager To Trust Your SWF URL - -If you are using any browser with the traditional NPAPI Flash Player plugin enabled **AND** _preferred_ -(i.e. PPAPI Flash Player plugins are not supported, are not installed, or are disabled for the browser -instance in question), you can edit your device-level NPAPI Flash Player security settings to whitelist -your SWF URL using the [Flash Player Online Settings Manager](http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04a.html): - 1. Using the same browser, go to the [Adobe Flash Player Online Settings Manager page](http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04a.html). - 2. In the small embedded Flash app (which looks more like a screen capture rather than an interactive UI), click "Add location". This may be inside of an "Edit locations..." dropdown menu. - 3. Add the absolute path of your local "ZeroClipboard.swf" file to the trusted files whitelist. - -Some versions of Flash also include an "allow all" option in the Global Settings Manager. - -This should work for all NPAPI Flash Player plugins. However, this **WILL NOT** work for _any_ PPAPI Flash Player plugins. - - -#### Tell PPAPI Flash Player Plugins To Take A Hike - -If you are using a PPAPI Flash Player plugin and all of the aforementioned workarounds **combined** still didn't allow you to bypass this security restriction, you have officially run out of proper workarounds as you have almost certainly run into the [even more restrictive security model in Chromium's "Pepper" (PPAPI) Flash layer](https://code.google.com/p/chromium/issues/detail?id=137734). This elevated security will affect PPAPI Flash Player plugin usage in Chromium, Chrome Canary, Chrome, and possibly all Blink-based versions of Opera. - -At this point, your only remaining option is to disable your PPAPI Flash Player plugin and fallback to an NPAPI Flash Player plugin instead. - -If you are unwilling to disable your PPAPI Flash Player plugin, your goal has now officially been defeated by Flash Player's security restrictions. You should now reconsider our earlier recommendation to [stop hosting it over the `file://` protocol](#stop-hosting-it-over-the-file-protocol)... we _tried_ to warn you! - - - - -[valid_ids]: http://www.w3.org/TR/html4/types.html#type-id "HTML4 specification for `ID` and `Name` tokens" diff --git a/web/public/libs/zeroclipboard/docs/roadmap.md b/web/public/libs/zeroclipboard/docs/roadmap.md deleted file mode 100755 index 4967b72..0000000 --- a/web/public/libs/zeroclipboard/docs/roadmap.md +++ /dev/null @@ -1,9 +0,0 @@ -# Roadmap - -These are things that we have expressed interest in but haven't implemented yet. There is no order, if you feel like you can complete one of the tasks. Feel free to fork the project and send a pull request with the new code. - -## HTML5 Clipboard API -In a perfect world we wouldn't need ZeroClipboard, and the browsers would just take care of it. We would like to write ZeroClipboard to use the browser's clipboard API when available. See Issues [#171](https://github.com/zeroclipboard/zeroclipboard/issues/171) and [~~#105~~](https://github.com/zeroclipboard/zeroclipboard/issues/105). - -## Flash Tests -We want to setup a unit test suite for the Flash SWF and/or its underlying ActionScript files. See Issue [#43](https://github.com/zeroclipboard/zeroclipboard/issues/43). diff --git a/web/public/libs/zeroclipboard/docs/security.md b/web/public/libs/zeroclipboard/docs/security.md deleted file mode 100755 index 0b20fd2..0000000 --- a/web/public/libs/zeroclipboard/docs/security.md +++ /dev/null @@ -1,32 +0,0 @@ -# Security - -We try our best to keep ZeroClipboard secure but there are some rules that you should consider following to keep your site safe. - - -## Existing Configuration - -For the existing configuration options available for security, see [Configuration Options](api/ZeroClipboard.md#configuration-options). - - -## Rules - -Basically, if an attacker gets access to the main window/global object via an XSS exploit, it's pretty much an instant "GAME OVER" unless **ALL** of the following are true: - 1. The `ZeroClipboard` object itself is not globally accessible. - 2. The `ZeroClipboard.prototype` object itself is not globally accessible. - 3. No `ZeroClipboard` instances are globally accessible. - 4. No callback functions for dispatched ZeroClipboard events are globally accessible. - 5. If a variable is used to set the path to the SWF via `ZeroClipboard.config`, that variable must not be globally accessible. - 6. The DOM is not accessible (due to built-in support for `data-clipboard-text` and `data-clipboard-target` attributes). - - -## Examples - - 1. Having `ZeroClipboard` instances globally accessible (versus encapsulated in a closure). This allows an attacker to manually call a client's `setText` method and inject their own text. - 2. As with all globally accessible functions in JavaScript, any globally accessible callback functions (hooked to events) can be overridden by an attacker. This isn't terribly dangerous but could be annoying. - 3. Overriding any of the `ZeroClipboard` or `ZeroClipboard.prototype` properties or methods, if globally accessible. - 4. Adding `data-clipboard-text` or `data-clipboard-target` attributes to every element in the DOM. - - -### Responsible Disclosure - -If you find any security holes that you believe can be patched, please submit a pull request or file an issue. We will be very appreciative! diff --git a/web/public/libs/zeroclipboard/package.json b/web/public/libs/zeroclipboard/package.json deleted file mode 100755 index e0d51ee..0000000 --- a/web/public/libs/zeroclipboard/package.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "name": "zeroclipboard", - "title": "ZeroClipboard", - "version": "2.2.0", - "description": "The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface.", - "keywords": [ - "flash", - "clipboard", - "copy", - "cut", - "paste", - "zclip", - "clip", - "clippy" - ], - "homepage": "http://zeroclipboard.org/", - "licenses": [ - { - "type": "MIT", - "url": "https://github.com/zeroclipboard/zeroclipboard/blob/master/LICENSE" - } - ], - "contributors": [ - { - "name": "Jon Rohan", - "url": "http://jonrohan.me/" - }, - { - "name": "James M. Greene", - "email": "james.m.greene@gmail.com", - "url": "http://greene.io/" - } - ], - "repository": { - "type": "git", - "url": "https://github.com/zeroclipboard/zeroclipboard.git" - }, - "bugs": { - "url": "https://github.com/zeroclipboard/zeroclipboard/issues" - }, - "dependencies": {}, - "devDependencies": { - "flex-sdk": "~4.6.0-0", - "flexpmd": "^1.3.0-1", - "grunt": "^0.4.5", - "grunt-chmod": "^1.0.3", - "grunt-contrib-clean": "^0.6.0", - "grunt-contrib-concat": "^0.5.0", - "grunt-contrib-connect": "^0.9.0", - "grunt-contrib-jshint": "^0.10.0", - "grunt-contrib-uglify": "^0.6.0", - "grunt-contrib-watch": "^0.6.1", - "grunt-coveralls": "^1.0.0", - "grunt-flexpmd": "^0.1.2", - "grunt-json-format": "^1.0.0", - "grunt-mxmlc": "^0.5.2", - "grunt-qunit-istanbul": "^0.4.5", - "grunt-template": "^0.2.3", - "jquery": "^2.1.1", - "load-grunt-tasks": "^1.0.0", - "qunit-composite": "^1.0.2", - "qunitjs": "^1.15.0", - "spm": "^3.2.3" - }, - "main": "dist/ZeroClipboard.js", - "files": [ - "dist/ZeroClipboard.*", - "package.json", - "LICENSE" - ], - "spm": { - "main": "dist/ZeroClipboard.js", - "output": [ - "dist/ZeroClipboard.swf", - "dist/ZeroClipboard.Core.js" - ] - }, - "scripts": { - "test": "grunt travis --verbose", - "postpublish": "spm publish" - } -} \ No newline at end of file diff --git a/web/public/libs/zeroclipboard/src/flash/ClipboardInjector.as b/web/public/libs/zeroclipboard/src/flash/ClipboardInjector.as deleted file mode 100755 index 1797088..0000000 --- a/web/public/libs/zeroclipboard/src/flash/ClipboardInjector.as +++ /dev/null @@ -1,219 +0,0 @@ -package { - - import flash.system.Capabilities; - import flash.system.System; - import flash.desktop.Clipboard; - import flash.desktop.ClipboardFormats; - import flash.utils.ByteArray; - - - /** - * An abstraction for injecting data into the user's clipboard. - */ - internal class ClipboardInjector { - /** - * Use the fancy "Desktop" clipboard for expanded text support (e.g. HTML, RTF, etc.) if not on Linux - */ - private var useEnhancedClipboard:Boolean = Capabilities.os.slice(0, 5).toLowerCase() !== "linux"; - - - /** - * @constructor - */ - public function ClipboardInjector(forceEnhancedClipboard:Boolean = false) { - // The JIT Compiler does not compile constructors, so any - // cyclomatic complexity higher than 1 is discouraged. - this.ctor(forceEnhancedClipboard); - } - - - /** - * The real constructor. - * - * @return `undefined` - */ - private function ctor(forceEnhancedClipboard:Boolean = false): void { - // Should we use the fancy "Desktop" clipboard for expanded text support (e.g. HTML, RTF, etc.)? - this.useEnhancedClipboard = this.useEnhancedClipboard || forceEnhancedClipboard; - } - - - /** - * Inject data into the user's clipboard. - * - * @return A clipboard "results" object - */ - public function inject( - clipData:Object // NOPMD - ): Object { // NOPMD - var results:Object = {}; // NOPMD - results.success = {}; - results.errors = []; - - // Set all data formats' results to `false` (failed) initially - for (var dataFormat:String in clipData) { - if (dataFormat && clipData.hasOwnProperty(dataFormat)) { - results.success[dataFormat] = false; - } - } - - // If there is any viable data to copy... - if (ClipboardInjector.hasData(clipData)) { - var plainTextOnly:Boolean = ClipboardInjector.hasOnlyPlainText(clipData); - - // ...and we only need to handle plain text... - if (!this.useEnhancedClipboard || plainTextOnly) { - // Use the system clipboard - ClipboardInjector.injectPlainTextOnly(clipData, results); - } - - // ...otherwise, if there is viable data to copy and we can copy enhanced formats, OR - // if using the system clipboard for plain text failed unexpectedly... - if (this.useEnhancedClipboard || (plainTextOnly && !results.success.text)) { - // Use the desktop clipboard - ClipboardInjector.injectEnhancedData(clipData, results); - } - } - - return results; - } - - - - /** - * Inject plain text into the System clipboard (i.e. Flash 9+ Clipboard). - * - * @return `undefined` - */ - private static function injectPlainTextOnly( - clipData:Object, // NOPMD - results:Object // NOPMD - ): void { - // Linux currently doesn't use the correct clipboard buffer with the new - // Flash 10 API, so we need to use this until we can figure out an alternative - try { - System.setClipboard(clipData.text); - results.success.text = true; - } - catch (err:Error) { - results.success.text = false; - results.errors.push(ClipboardInjector.serializeError(err, "text", "system")); - } - } - - - /** - * Inject plain text, HTML, and RTF into the Desktop clipboard (i.e. Flash 10+ Clipboard). - * - * @return `undefined` - */ - private static function injectEnhancedData( - clipData:Object, // NOPMD - results:Object // NOPMD - ): void { - // Clear out the clipboard before starting to copy data - Clipboard.generalClipboard.clear(); - - // - // Handle each data type in succession... - // - // Plain text - if (typeof clipData.text === "string" && clipData.text) { - try { - results.success.text = Clipboard.generalClipboard.setData(ClipboardFormats.TEXT_FORMAT, clipData.text); - } - catch (err:Error) { - results.success.text = false; - results.errors.push(ClipboardInjector.serializeError(err, "text", "desktop")); - } - } - - // HTML - if (typeof clipData.html === "string" && clipData.html) { - try { - results.success.html = Clipboard.generalClipboard.setData(ClipboardFormats.HTML_FORMAT, clipData.html); - } - catch (err:Error) { - results.success.html = false; - results.errors.push(ClipboardInjector.serializeError(err, "html", "desktop")); - } - } - - // Rich Text (RTF) - if (typeof clipData.rtf === "string" && clipData.rtf) { - try { - var bytes:ByteArray = new ByteArray(); - bytes.writeUTFBytes(clipData.rtf); - if (bytes && bytes.length > 0) { - results.success.rtf = Clipboard.generalClipboard.setData(ClipboardFormats.RICH_TEXT_FORMAT, bytes); - } - } - catch (err:Error) { - results.success.rtf = false; - results.errors.push(ClipboardInjector.serializeError(err, "rtf", "desktop")); - } - } - } - - - /** - * Check if data object contains any keys with associated values that are non-empty Strings. - * - * @return Boolean - */ - private static function hasData( - clipData:Object // NOPMD - ): Boolean { - return typeof clipData === "object" && clipData && - ( - (typeof clipData.text === "string" && clipData.text) || - (typeof clipData.html === "string" && clipData.html) || - (typeof clipData.rtf === "string" && clipData.rtf ) - ); - } - - - /** - * Check if a data object's ONLY injectable data is plain text. - * - * @return Boolean - */ - private static function hasOnlyPlainText( - clipData:Object // NOPMD - ): Boolean { - var hasPlainText:Boolean = false; - var hasOtherTypes:Boolean = false; - if (typeof clipData === "object" && clipData) { - hasPlainText = typeof clipData.text === "string" && clipData.text; - hasOtherTypes = ( - (typeof clipData.html === "string" && clipData.html) || - (typeof clipData.rtf === "string" && clipData.rtf ) - ); - } - return !hasOtherTypes && hasPlainText; - } - - - /** - * Convert an ActionScript Error object into a serializable plain object - * - * @return Object - */ - private static function serializeError( - err:Error, - format:String, - clipboardType:String - ): Object { // NOPMD - return { - name: err.name, - message: err.message, - errorID: err.errorID, - // NOTE: In Flash Player <= 11.4, `err.getStackTrace()` will always return `null` unless - // you are using the debug version of Flash Player. - stack: err.getStackTrace() || null, - format: format, - clipboard: clipboardType - }; - } - } -} \ No newline at end of file diff --git a/web/public/libs/zeroclipboard/src/flash/JsProxy.as b/web/public/libs/zeroclipboard/src/flash/JsProxy.as deleted file mode 100755 index b5d2a25..0000000 --- a/web/public/libs/zeroclipboard/src/flash/JsProxy.as +++ /dev/null @@ -1,373 +0,0 @@ -package { - - import flash.external.ExternalInterface; - import flash.net.navigateToURL; - import flash.net.URLRequest; - - - /** - * An abstraction for communicating with JavaScript from Flash. - */ - internal class JsProxy { - private static const PROXIED_CALLBACK_PREFIX:String = "__proxied__"; - private static const JS_DATA_PROCESSOR_FN:String = '\ -function processData(data, stringProcessorFn) {\ - if (typeof data === "string" && data.length > 0) {\ - data = stringProcessorFn(data);\ - }\ - else if (typeof data === "object" && data.length > 0) {\ - for (var i = 0; i < data.length; i++) {\ - data[i] = processData(data[i], stringProcessorFn);\ - }\ - }\ - else if (typeof data === "object" && data != null) {\ - for (var prop in data) {\ - if (data.hasOwnProperty(prop)) {\ - data[prop] = processData(data[prop], stringProcessorFn);\ - }\ - }\ - }\ - return data;\ -};\ -'; - private static const JS_DATA_ENCODER_FN:String = '\ -function encodeDataForFlash(data) {\ - return processData(data, encodeURIComponent);\ -};\ -'; - private static const JS_DATA_DECODER_FN:String = '\ -function decodeDataFromFlash(data) {\ - return processData(data, decodeURIComponent);\ -};\ -'; - private static const processData:Function = function( - data:*, // NOPMD - stringProcessorFn:Function - ): * { // NOPMD - if (typeof data === "string" && data.length > 0) { - data = stringProcessorFn(data); - } - else if (typeof data === "object" && data.length > 0) { - for (var i:int = 0; i < data.length; i++) { - data[i] = processData(data[i], stringProcessorFn); - } - } - else if (typeof data === "object" && data != null) { - for (var prop:String in data) { - if (data.hasOwnProperty(prop)) { - data[prop] = processData(data[prop], stringProcessorFn); - } - } - } - return data; - }; - private static const encodeDataForJS:Function = function( - data:* // NOPMD - ): * { // NOPMD - return processData(data, encodeURIComponent); - }; - private static const decodeDataFromJS:Function = function( - data:* // NOPMD - ): * { // NOPMD - return processData(data, decodeURIComponent); - }; - - private var metadata:Object = { // NOPMD - objectId: null, - hosted: false, - bidirectional: false, - disabled: false, - fidelityEnsured: false - }; - - - /** - * @constructor - */ - public function JsProxy() { - // The JIT Compiler does not compile constructors, so any - // cyclomatic complexity higher than 1 is discouraged. - this.ctor(); - } - - - /** - * The real constructor. - * - * @return `undefined` - */ - private function ctor(): void { - // We do NOT want to marshall JS exceptions into Flash (other than during detection) - var preferredMarshalling:Boolean = false; - ExternalInterface.marshallExceptions = preferredMarshalling; - - // What is the HTML element ID that is actually hosting this SWF object? - this.metadata.objectId = ExternalInterface.objectID || null; - - // Do we authoritatively know that this Flash object is hosted in a browser? - this.metadata.hosted = ExternalInterface.available === true && !!this.metadata.objectId; - - // Temporarily start marshalling JS exceptions into Flash - ExternalInterface.marshallExceptions = true; - - // Try this regardless of the value of `this.metadata.hosted`. - try { - // Can we retrieve values from JavaScript? - this.metadata.bidirectional = ExternalInterface.call("(function() { return true; })") === true; - } - catch (err:Error) { - // We do NOT authoritatively know if this Flash object is hosted in a browser, - // nor if JavaScript is disabled. - this.metadata.bidirectional = false; - } - - // Revert the behavior for marshalling JS exceptions into Flash - ExternalInterface.marshallExceptions = preferredMarshalling; - - // If hosted but cannot bidirectionally communicate with JavaScript, - // then JavaScript is disabled on the page! - this.metadata.disabled = this.metadata.hosted && !this.metadata.bidirectional; - - // Do some feature testing and patching to ensure string fidelity - // during cross-boundary communications between Flash and JavaScript. - this.metadata.fidelityEnsured = this.ensureStringFidelity(); - } - - - /** - * Test the Flash -> JS communication channel for data fidelity. - * If any data experiences loss of fidelity, try to patch it. - * If the data still loses fidelity on a subsequent test, it cannot - * be patched simply. - * - * @return Boolean: `true` if high fidelity, `false` if not - */ - private function ensureStringFidelity(): Boolean { // NOPMD - var didPatchJS:Boolean = false; - - // Export some data fidelity-patching functions in advance - try { - didPatchJS = ExternalInterface.call([ - '(function() {', - JS_DATA_PROCESSOR_FN, - '', - ' var objectId = "' + this.metadata.objectId + '",', - ' swf = document[objectId] || document.getElementById(objectId);', - ' if (swf) {', - ' swf._encodeDataForFlash = ' + JS_DATA_ENCODER_FN + ';', - ' swf._decodeDataFromFlash = ' + JS_DATA_DECODER_FN + ';', - ' }', - ' return !!swf && typeof swf._encodeDataForFlash === "function" && typeof swf._decodeDataFromFlash === "function";', - '})' - ].join('\n')) === true; - } - catch (err:Error) { - didPatchJS = false; - } - - return didPatchJS; - } - - - /** - * What is the actual `ExternalInterface.objectID`? - * - * @return Boolean - */ - public function getObjectId(): String { - return this.metadata.objectId; - } - - - /** - * Are we authoritatively certain that we can execute JavaScript bidirectionally? - * - * @return Boolean - */ - public function isComplete(): Boolean { - return this.metadata.hosted && this.metadata.bidirectional; - } - - - /** - * Can we authoritatively communicate with JavaScript without any loss of data fidelity? - * - * @return Boolean - */ - public function isHighFidelity(): Boolean { - return this.isComplete() && this.metadata.fidelityEnsured; - } - - - /** - * Register an ActionScript closure as callable from the container's JavaScript. - * To unregister, pass `null` as the closure to remove an existing callback. - * - * This will execute the JavaScript ONLY if ExternalInterface is completely - * available (hosted in the browser AND supporting bidirectional communication). - * - * @return anything - */ - public function addCallback(functionName:String, closure:Function): void { - if (closure == null) { - this.removeCallback(functionName); - } - - if (this.isComplete()) { - - // Patch addCallback's outgoing result value on Flash side before returning it - var wrapperFn:Function = function(...args): * { // NOPMD - args = decodeDataFromJS(args); - var result:* = //NOPMD - closure.apply(this, args); - return encodeDataForJS(result); - }; - - - // IMPORTANT: - // This patch changes the name of the registered callback as some browser/Flash - // implementations will not allow us to directly override the exposed callback - // on the SWF object, despite the fact that the JS object property descriptors - // indicate it should be allowed! - - var proxiedFunctionName:String = PROXIED_CALLBACK_PREFIX + functionName; - ExternalInterface.addCallback(proxiedFunctionName, wrapperFn); - - // Patch addCallback's incoming parameters on JS side before calling it - this.call( - [ - '(function() {', - ' var objectId = "' + this.metadata.objectId + '",', - ' swf = document[objectId] || document.getElementById(objectId),', - ' desiredSwfCallbackName = "' + functionName + '",', - ' actualSwfCallbackName = "' + proxiedFunctionName + '",', - ' swfCallback;', - '', - ' if (swf && typeof swf[actualSwfCallbackName] === "function" && typeof swf._encodeDataForFlash === "function" && typeof swf._decodeDataFromFlash === "function") {', - ' swfCallback = swf && swf[actualSwfCallbackName];', - ' swf[desiredSwfCallbackName] = function() {', - ' var swf = this;', - ' var args = swf._encodeDataForFlash([].slice.call(arguments));', - ' var result = swfCallback.apply(this, args);', - ' return swf._decodeDataFromFlash(result);', - ' };', - ' }', - ' // Drop the reference', - ' swf = null;', - '})' - ].join('\n') - ); - } - } - - - /** - * Unegister an ActionScript closure as callable from the container's JavaScript. - * - * This will execute the JavaScript ONLY if ExternalInterface is completely - * available (hosted in the browser AND supporting bidirectional communication). - * - * @return `undefined` - */ - public function removeCallback(functionName:String): void { - if (this.isComplete()) { - - // IMPORTANT: - // See comments in the `JsProxy#addCallback` method body for more information - // on why special cleanup is necessary to remove this proxied callback fully. - - var proxiedFunctionName:String = PROXIED_CALLBACK_PREFIX + functionName; - ExternalInterface.addCallback(proxiedFunctionName, null); - - this.call( - [ - '(function() {', - ' var objectId = "' + this.metadata.objectId + '",', - ' swf = document[objectId] || document.getElementById(objectId),', - ' desiredSwfCallbackName = "' + functionName + '";', - '', - ' if (swf && typeof swf[desiredSwfCallbackName] === "function") {', - ' swf[desiredSwfCallbackName] = null;', - ' delete swf[desiredSwfCallbackName];', - ' }', - ' // Drop the reference', - ' swf = null;', - '})' - ].join('\n') - ); - } - } - - - /** - * Execute a function expression or named function, with optional arguments, - * and receive its return value. - * - * This will execute the JavaScript ONLY if ExternalInterface is completely - * available (hosted in the browser AND supporting bidirectional communication). - * - * @example - * var jsProxy:JsProxy = new JsProxy("global-zeroclipboard-flash-bridge"); - * var result:Object = jsProxy.call("ZeroClipboard.emit", { type: "copy" }); - * jsProxy.call("(function(eventObj) { return ZeroClipboard.emit(eventObj); })", { type: "ready"}); - * - * @return `undefined`, or anything - */ - public function call( - jsFuncExpr:String, - ...args - ): * { // NOPMD - var result:* = undefined; // NOPMD - if (jsFuncExpr && this.isComplete()) { - args = encodeDataForJS(args); - - jsFuncExpr = [ - '(function() {', - ' var objectId = "' + this.metadata.objectId + '",', - ' swf = document[objectId] || document.getElementById(objectId),', - ' args, result;', - ' if (swf && typeof swf._encodeDataForFlash === "function" && typeof swf._decodeDataFromFlash === "function") {', - ' args = swf._decodeDataFromFlash([].slice.call(arguments));', - ' result = (' + jsFuncExpr + ').apply(this, args);', - ' return swf._encodeDataForFlash(result);', - ' }', - '})' - ].join('\n'); - - result = ExternalInterface.call.apply(ExternalInterface, [jsFuncExpr].concat(args)); - result = decodeDataFromJS(result); - } - return result; - } - - - /** - * Execute a function expression or named function, with optional arguments. - * No return values will ever be received. - * - * This will attempt to execute the JavaScript, even if ExternalInterface is - * not available; in which case: the worst thing that can happen is that - * the JavaScript is not executed (i.e. if JavaScript is disabled, or if - * the SWF is not allowed to communicate with JavaScript on its host page). - * - * @return `undefined` - */ - public function send(jsFuncExpr:String, ...args): void { - if (jsFuncExpr) { - if (this.isComplete()) { - this.call.apply(this, [jsFuncExpr].concat(args)); - } - else if (!this.metadata.disabled) { - var argsStr:String = ""; - for (var counter:int = 0; counter < args.length; counter++) { - argsStr += JSON.stringify(args[counter]); - if ((counter + 1) < args.length) { - argsStr += ", "; - } - } - navigateToURL(new URLRequest("javascript:" + jsFuncExpr + "(" + encodeDataForJS(argsStr) + ");"), "_self"); - } - } - } - } -} \ No newline at end of file diff --git a/web/public/libs/zeroclipboard/src/flash/XssUtils.as b/web/public/libs/zeroclipboard/src/flash/XssUtils.as deleted file mode 100755 index ca2665d..0000000 --- a/web/public/libs/zeroclipboard/src/flash/XssUtils.as +++ /dev/null @@ -1,104 +0,0 @@ -package { - - import flash.net.URLVariables; - - - /** - * Utility methods for XSS attack prevention. - */ - internal class XssUtils { - - /** - * Sanitize any common JSON-serializable object (string, array, object) - * to mitigate XSS vulnerabilities. - * - * @return an XSS safe object - * @static - */ - public static function sanitize( - data:* // NOPMD - ): * { // NOPMD - if (typeof data === "string") { - data = XssUtils.sanitizeString(data); - } - else if (typeof data === "object" && data.length > 0) { - for (var i:int = 0; i < data.length; i++) { - data[i] = XssUtils.sanitize(data[i]); - } - } - else if (typeof data === "object" && data != null) { - for (var prop:String in data) { - if (data.hasOwnProperty(prop)) { - data[prop] = XssUtils.sanitize(data[prop]); - } - } - } - return data; - } - - - /** - * Sanitize a string to mitigate XSS vulnerabilities. - * - * @return an XSS safe String - * @static - */ - public static function sanitizeString(dirty:String): String { - return (typeof dirty === "string" && dirty) ? dirty.replace(/\\/g, "\\\\") : ""; - } - - - /** - * Validate the ID against the HTML4 spec for `ID` tokens. - * - * @return Boolean - * @static - */ - public static function isValidHtmlId(id:String): Boolean { - return typeof id === "string" && !!id && /^[A-Za-z][A-Za-z0-9_:\-\.]*$/.test(id); - } - - - /** - * Parse the query string of a URL into an object (hash). The URL provided - * MUST contain a "?" query string indicator or it will be ignored. - * - * @return an object of key-value string pairs (dictionary/hash) - * @static - */ - public static function parseQuery( - url:String - ): Object { // NOPMD - var queryParams:Object = {}; // NOPMD - if (url) { - var index:Number = url.indexOf("?"); - url = index !== -1 ? url.slice(index + 1) : ""; - index = url.indexOf("#"); - url = index === -1 ? url : url.slice(0, index); - - // - // Try to achieve parity with `LoaderInfo#parameters` - // - // Eliminate invalid URL escapes. This can prevent a lot of XSS hacks. - url = url.replace(/%[A-Fa-f0-9]?([^A-Fa-f0-9]|$)/g, ""); - // Double-encode the NUL (null) character. In Firefox, this character actually prevents Flash from loading the SWF at all. - url = url.replace(/%00/g, "%2500"); - // Eliminate extraneous ampersands - url = url.replace(/&&+/g, "&"); - - if (url) { - queryParams = new URLVariables(url); - - // If any query with multiple of the same key present, only take the last value - for (var key:String in queryParams) { - if (queryParams.hasOwnProperty(key) && queryParams[key] is Array && queryParams[key].length) { - queryParams[key] = queryParams[key].pop() as String; - } - } - } - } - return queryParams; - } - - } -} \ No newline at end of file diff --git a/web/public/libs/zeroclipboard/src/flash/ZeroClipboard.as b/web/public/libs/zeroclipboard/src/flash/ZeroClipboard.as deleted file mode 100755 index d2911b9..0000000 --- a/web/public/libs/zeroclipboard/src/flash/ZeroClipboard.as +++ /dev/null @@ -1,401 +0,0 @@ -package { - - import flash.display.Stage; - import flash.display.StageAlign; - import flash.display.StageScaleMode; - import flash.display.StageQuality; - import flash.display.Sprite; - import flash.events.Event; - import flash.events.MouseEvent; - import flash.system.Security; - - - /** - * The ZeroClipboard class creates a simple Sprite button that will put - * text in the user's clipboard when clicked. - */ - [SWF(widthPercent="100%", heightPercent="100%", backgroundColor="#FFFFFF")] - public class ZeroClipboard extends Sprite { - - /** - * ZeroClipboard library version number at the time this SWF was compiled. - */ - public static const VERSION:String = "<%= version %>"; - - - /** - * Function through which JavaScript events are emitted. Accounts for scenarios - * in which ZeroClipboard is used via AMD/CommonJS module loaders, too. - */ - private var jsEmitter:String = null; - - /** - * JavaScript proxy object. - */ - private var jsProxy:JsProxy = null; - - /** - * Clipboard proxy object. - */ - private var clipboard:ClipboardInjector = null; - - - /** - * @constructor - */ - public function ZeroClipboard() { - // The JIT Compiler does not compile constructors, so ANY - // cyclomatic complexity higher than 1 is discouraged. - this.ctor(); - } - - - /** - * The real constructor. - * - * @return `undefined` - */ - private function ctor(): void { - // If the `stage` is available, begin! - if (stage) { - this.init(); - } - else { - // Otherwise, wait for the `stage`.... - this.addEventListener(Event.ADDED_TO_STAGE, this.init); - } - } - - - /** - * Initialize the class when the Stage is ready. - * - * @return `undefined` - */ - private function init(): void { - // Remove the event listener, if any - this.removeEventListener(Event.ADDED_TO_STAGE, this.init); - - // Establish a communication line with JavaScript - this.jsProxy = new JsProxy(); - - // Collect the real FlashVars - var expectedFlashVars:Object; // NOPMD - expectedFlashVars = this.getExpectedFlashVars(); - - // Allow the SWF object to communicate with a page on a different origin than its own (e.g. SWF served from CDN) - Security.allowDomain.apply(Security, expectedFlashVars.trustedOrigins); - - var jsProxyObjectId:String = this.jsProxy.getObjectId(); - var expectedObjectId:String = expectedFlashVars.swfObjectId; - - this.jsEmitter = - "(function(eventObj) {\n" + - " var objectId = '" + jsProxyObjectId + "',\n" + - " swf = document[objectId] || document.getElementById(objectId),\n" + - " ZC, result;\n\n" + - " if (swf && typeof swf.ZeroClipboard === 'function' && typeof swf.ZeroClipboard.emit === 'function') {\n" + - " ZC = swf.ZeroClipboard;\n" + - " }\n" + - " else if (typeof ZeroClipboard === 'function' && typeof ZeroClipboard.emit === 'function') {\n" + - " ZC = ZeroClipboard;\n" + - " }\n" + - " // Drop the element reference, if any\n" + - " swf = null;\n" + - " if (!ZC) {\n" + - " throw new Error('ERROR: ZeroClipboard SWF could not locate ZeroClipboard JS object!\\n" + - "Expected element ID: ' + objectId);\n" + - " }\n\n" + - " result = ZC.emit(eventObj);\n\n" + - " // Drop the reference\n" + - " ZC = null;\n\n" + - " return result;\n" + - "})"; - - // Create an invisible "button" and transparently fill the entire Stage - var button:Sprite = this.prepareUI(); - - // Configure the clipboard injector - this.clipboard = new ClipboardInjector(expectedFlashVars.forceEnhancedClipboard); - - // Only proceed if this SWF is hosted in the browser as expected - if (!this.jsProxy.isComplete()) { - // Signal to the browser that something is wrong - this.emit("error", { - name: "flash-unavailable" - }); - } - else if (!this.jsProxy.isHighFidelity()) { - // Signal to the browser that data fidelity cannot be guaranteed - this.emit("error", { - name: "flash-degraded" - }); - } - else if (!expectedFlashVars.jsVersion || !ZeroClipboard.VERSION || expectedFlashVars.jsVersion !== ZeroClipboard.VERSION) { - this.emit("error", { - name: "version-mismatch", - jsVersion: expectedFlashVars.jsVersion || null, - swfVersion: ZeroClipboard.VERSION || null - }); - } - else if (!expectedObjectId || jsProxyObjectId !== expectedObjectId) { - // Signal to the browser that the expected ID does not match the actual ID - this.emit("error", { - name: "config-mismatch", - property: "swfObjectId", - configuredValue: expectedObjectId || null, - actualValue: jsProxyObjectId || null - }); - } - else { - // Add the MouseEvent listeners - this.addMouseHandlers(button); - - // Expose the external functions - this.jsProxy.addCallback( - "setHandCursor", - function(enabled:Boolean): void { - button.useHandCursor = enabled === true; - } - ); - - // Signal to the browser that we are ready - this.emit("ready", { - swfVersion: ZeroClipboard.VERSION - }); - } - } - - - /** - * Get an accurate interpretation of the FlashVars for this SWF instance. - * - * IMPORTANT: This also serves the double purpose of reestablishing the correct FlashVars when - * the SWF is retrieved from the browser cache but originally hosted on an external domain. - * - * @return Object - */ - private function getFlashVarsFromHtml( - ): Object { // NOPMD - var flashVars:Object = null; // NOPMD - - if (this.jsProxy && this.jsProxy.isComplete() && this.jsProxy.isHighFidelity()) { - var rawFlashVars:String = this.jsProxy.call( - "(function() {\n" + - " var objectId = '" + this.jsProxy.getObjectId() + "',\n" + - " swf = document[objectId] || document.getElementById(objectId),\n" + - " result, i, len, paramEl;\n\n" + - " if (swf && swf.nodeName === 'OBJECT') {\n" + - " for (i = 0, len = swf.children.length; i < len; i++) {\n" + - " paramEl = swf.children[i];\n" + - " if (paramEl && paramEl.nodeName === 'PARAM' && (paramEl.getAttribute('name') || '').toLowerCase() === 'flashvars') {\n" + - " result = paramEl.getAttribute('value') || null;\n" + - " }\n" + - " }\n" + - " }\n\n" + - " // Drop the element references, if any\n" + - " swf = paramEl = null;\n\n" + - " return result;\n" + - "})" - ); - - flashVars = rawFlashVars ? XssUtils.sanitize(XssUtils.parseQuery("?" + rawFlashVars)) : null; - } - - return flashVars; - } - - - /** - * Retrieve and transform (or default) the expected FlashVars values. - * - * @return Object - */ - private function getExpectedFlashVars( - ): Object { // NOPMD - var expectedFlashVars:Object; // NOPMD - expectedFlashVars = { - swfObjectId: "global-zeroclipboard-flash-bridge", - trustedOrigins: [], - forceEnhancedClipboard: false, - jsVersion: null - }; - - // Get the FlashVars - var flashVars:Object; // NOPMD - flashVars = this.getFlashVarsFromHtml() || {}; - - // Configure the SWF object's ID - if (flashVars.swfObjectId && typeof flashVars.swfObjectId === "string") { - var swfId:String = flashVars.swfObjectId; - - // Validate the ID against the HTML4 spec for `ID` tokens. - if (XssUtils.isValidHtmlId(swfId)) { - expectedFlashVars.swfObjectId = swfId; - } - } - - // Allow the SWF object to communicate with a page on a different origin than its own (e.g. SWF served from CDN) - if (flashVars.trustedOrigins && typeof flashVars.trustedOrigins === "string") { - expectedFlashVars.trustedOrigins = flashVars.trustedOrigins.split(","); - } - - // Enable use of the fancy "Desktop" clipboard, even on Linux where it is known to suck - if (flashVars.forceEnhancedClipboard === "true" || flashVars.forceEnhancedClipboard === true) { - expectedFlashVars.forceEnhancedClipboard = true; - } - - // Get the version number of the ZeroClipboard JS side of the library - if (typeof flashVars.jsVersion === "string") { - expectedFlashVars.jsVersion = flashVars.jsVersion; - } - - return expectedFlashVars; - } - - - /** - * Prepare the Stage and Button. - * - * @return Button - */ - private function prepareUI(): Sprite { - // Set the stage! - stage.align = StageAlign.TOP_LEFT; - stage.scaleMode = StageScaleMode.EXACT_FIT; - stage.quality = StageQuality.BEST; - - // Create an invisible "button" and transparently fill the entire Stage - var button:Sprite = new Sprite(); - button.graphics.beginFill(0xFFFFFF); - button.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); - button.alpha = 0.0; - - // Act like a button. This includes: - // - Showing a hand cursor by default - // - Receiving click events - // - Receiving keypress events of space/"Enter" as click - // events IF AND ONLY IF the Sprite is focused. - button.buttonMode = true; - - // Override the hand cursor default - button.useHandCursor = false; - - // Add the invisible "button" to the stage! - this.addChild(button); - - // Return the button for adding event listeners - return button; - } - - - /** - * Clears the clipboard and sets new clipboard text. It gets this from the "_clipData" - * variable on the JavaScript side. Once the text has been placed in the clipboard, it - * then signals to the JavaScript that it is done. - * - * @return `undefined` - */ - private function onClick(event:MouseEvent): void { - var clipData:Object; // NOPMD - var clipInjectResults:Object = {}; // NOPMD - - // Allow for any "UI preparation" work before the "copy" event begins - this.emit("beforecopy"); - - // Request pending clipboard data from the page - clipData = this.emit("copy"); - - // Inject all pending data into the user's clipboard - clipInjectResults = this.clipboard.inject(clipData); - - // Compose and serialize a results object, send it back to the page - this.emit( - "aftercopy", - { - success: clipInjectResults.success, - data: clipData, - errors: clipInjectResults.errors - } - ); - } - - - /** - * Emit events to JavaScript. - * - * @return `undefined`, or the new "_clipData" object - */ - private function emit( - eventType:String, - eventObj:Object = null // NOPMD - ): Object { // NOPMD - if (eventObj == null) { - eventObj = {}; - } - eventObj.type = eventType; - - var result:Object = undefined; // NOPMD - if (this.jsProxy.isComplete()) { - result = this.jsProxy.call(this.jsEmitter, eventObj); - } - else { - this.jsProxy.send(this.jsEmitter, eventObj); - } - return result; - } - - - /** - * Signals to the page that a MouseEvent occurred. - * - * @return `undefined` - */ - private function onMouseEvent(event:MouseEvent): void { - var evtData:Object = {}; // NOPMD - - // If an event is passed in, return what modifier keys are pressed, etc. - if (event) { - var props:Object; // NOPMD - props = { - "altKey": "altKey", - "commandKey": "metaKey", - "controlKey": "ctrlKey", - "shiftKey": "shiftKey", - "clickCount": "detail", - "movementX": "movementX", - "movementY": "movementY", - "stageX": "_stageX", - "stageY": "_stageY" - }; - - for (var prop:String in props) { - if (event.hasOwnProperty(prop) && event[prop] != null) { - evtData[props[prop]] = event[prop]; - } - } - evtData.type = "_" + event.type.toLowerCase(); - evtData._source = "swf"; - } - - this.emit(evtData.type, evtData); - } - - - /** - * Add mouse event handlers to the button. - * - * @return `undefined` - */ - private function addMouseHandlers(button:Sprite): Sprite { - button.addEventListener(MouseEvent.MOUSE_MOVE, this.onMouseEvent); - button.addEventListener(MouseEvent.MOUSE_OVER, this.onMouseEvent); - button.addEventListener(MouseEvent.MOUSE_OUT, this.onMouseEvent); - button.addEventListener(MouseEvent.MOUSE_DOWN, this.onMouseEvent); - button.addEventListener(MouseEvent.MOUSE_UP, this.onMouseEvent); - button.addEventListener(MouseEvent.CLICK, this.onClick); - button.addEventListener(MouseEvent.CLICK, this.onMouseEvent); - return button; - } - } -} diff --git a/web/public/libs/zeroclipboard/src/js/client/api.js b/web/public/libs/zeroclipboard/src/js/client/api.js deleted file mode 100755 index 1f123fe..0000000 --- a/web/public/libs/zeroclipboard/src/js/client/api.js +++ /dev/null @@ -1,180 +0,0 @@ -/** - * Creates a new ZeroClipboard client instance. - * Optionally, auto-`clip` an element or collection of elements. - * - * @constructor - */ -ZeroClipboard._createClient = function(/* elements */) { - // Invoke the real constructor - _clientConstructor.apply(this, _args(arguments)); -}; - - -/** - * Register an event listener to the client. - * - * @returns `this` - */ -ZeroClipboard.prototype.on = function(/* eventType, listener */) { - return _clientOn.apply(this, _args(arguments)); -}; - - -/** - * Unregister an event handler from the client. - * If no `listener` function/object is provided, it will unregister all handlers for the provided `eventType`. - * If no `eventType` is provided, it will unregister all handlers for every event type. - * - * @returns `this` - */ -ZeroClipboard.prototype.off = function(/* eventType, listener */) { - return _clientOff.apply(this, _args(arguments)); -}; - - -/** - * Retrieve event listeners for an `eventType` from the client. - * If no `eventType` is provided, it will retrieve all listeners for every event type. - * - * @returns array of listeners for the `eventType`; if no `eventType`, then a map/hash object of listeners for all event types; or `null` - */ -ZeroClipboard.prototype.handlers = function(/* eventType */) { - return _clientListeners.apply(this, _args(arguments)); -}; - - -/** - * Event emission receiver from the Flash object for this client's registered JavaScript event listeners. - * - * @returns For the "copy" event, returns the Flash-friendly "clipData" object; otherwise `undefined`. - */ -ZeroClipboard.prototype.emit = function(/* event */) { - return _clientEmit.apply(this, _args(arguments)); -}; - - -/** - * Register clipboard actions for new element(s) to the client. - * - * @returns `this` - */ -ZeroClipboard.prototype.clip = function(/* elements */) { - return _clientClip.apply(this, _args(arguments)); -}; - - -/** - * Unregister the clipboard actions of previously registered element(s) on the page. - * If no elements are provided, ALL registered elements will be unregistered. - * - * @returns `this` - */ -ZeroClipboard.prototype.unclip = function(/* elements */) { - return _clientUnclip.apply(this, _args(arguments)); -}; - - -/** - * Get all of the elements to which this client is clipped. - * - * @returns array of clipped elements - */ -ZeroClipboard.prototype.elements = function() { - return _clientElements.apply(this, _args(arguments)); -}; - - -/** - * Self-destruct and clean up everything for a single client. - * This will NOT destroy the embedded Flash object. - * - * @returns `undefined` - */ -ZeroClipboard.prototype.destroy = function() { - return _clientDestroy.apply(this, _args(arguments)); -}; - - -/** - * Stores the pending plain text to inject into the clipboard. - * - * @returns `this` - */ -ZeroClipboard.prototype.setText = function(text) { - if (!_clientMeta[this.id]) { - throw new Error("Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance"); - } - ZeroClipboard.setData("text/plain", text); - return this; -}; - - -/** - * Stores the pending HTML text to inject into the clipboard. - * - * @returns `this` - */ -ZeroClipboard.prototype.setHtml = function(html) { - if (!_clientMeta[this.id]) { - throw new Error("Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance"); - } - ZeroClipboard.setData("text/html", html); - return this; -}; - - -/** - * Stores the pending rich text (RTF) to inject into the clipboard. - * - * @returns `this` - */ -ZeroClipboard.prototype.setRichText = function(richText) { - if (!_clientMeta[this.id]) { - throw new Error("Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance"); - } - ZeroClipboard.setData("application/rtf", richText); - return this; -}; - - -/** - * Stores the pending data to inject into the clipboard. - * - * @returns `this` - */ -ZeroClipboard.prototype.setData = function(/* format, data */) { - if (!_clientMeta[this.id]) { - throw new Error("Attempted to set pending clipboard data from a destroyed ZeroClipboard client instance"); - } - ZeroClipboard.setData.apply(this, _args(arguments)); - return this; -}; - - -/** - * Clears the pending data to inject into the clipboard. - * If no `format` is provided, all pending data formats will be cleared. - * - * @returns `this` - */ -ZeroClipboard.prototype.clearData = function(/* format */) { - if (!_clientMeta[this.id]) { - throw new Error("Attempted to clear pending clipboard data from a destroyed ZeroClipboard client instance"); - } - ZeroClipboard.clearData.apply(this, _args(arguments)); - return this; -}; - - -/** - * Gets a copy of the pending data to inject into the clipboard. - * If no `format` is provided, a copy of ALL pending data formats will be returned. - * - * @returns `String` or `Object` - */ -ZeroClipboard.prototype.getData = function(/* format */) { - if (!_clientMeta[this.id]) { - throw new Error("Attempted to get pending clipboard data from a destroyed ZeroClipboard client instance"); - } - return ZeroClipboard.getData.apply(this, _args(arguments)); -}; diff --git a/web/public/libs/zeroclipboard/src/js/client/private.js b/web/public/libs/zeroclipboard/src/js/client/private.js deleted file mode 100755 index dc693bf..0000000 --- a/web/public/libs/zeroclipboard/src/js/client/private.js +++ /dev/null @@ -1,507 +0,0 @@ -/** - * The real constructor for `ZeroClipboard` client instances. - * @private - */ -var _clientConstructor = function(elements) { - // Save a closure reference for the following event handlers - var client = this; - - // Assign an ID to the client instance - client.id = "" + (_clientIdCounter++); - - // Create the meta information store for this client - _clientMeta[client.id] = { - instance: client, - elements: [], - handlers: {} - }; - - // If the elements argument exists, clip it - if (elements) { - client.clip(elements); - } - - // ECHO! Our client's sounding board. - ZeroClipboard.on("*", function(event) { - return client.emit(event); - }); - - // Await imminent destruction... - ZeroClipboard.on("destroy", function() { - client.destroy(); - }); - - // Move on: embed the SWF - ZeroClipboard.create(); -}; - - -/** - * The underlying implementation of `ZeroClipboard.Client.prototype.on`. - * @private - */ -var _clientOn = function(eventType, listener) { - /*jshint maxstatements:26 */ - - // add user event handler for event - var i, len, events, - added = {}, - meta = _clientMeta[this.id], - handlers = meta && meta.handlers; - - if (!meta) { - throw new Error("Attempted to add new listener(s) to a destroyed ZeroClipboard client instance"); - } - - if (typeof eventType === "string" && eventType) { - events = eventType.toLowerCase().split(/\s+/); - } - else if (typeof eventType === "object" && eventType && typeof listener === "undefined") { - for (i in eventType) { - if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") { - this.on(i, eventType[i]); - } - } - } - - if (events && events.length) { - for (i = 0, len = events.length; i < len; i++) { - eventType = events[i].replace(/^on/, ""); - added[eventType] = true; - if (!handlers[eventType]) { - handlers[eventType] = []; - } - handlers[eventType].push(listener); - } - - // The following events must be memorized and fired immediately if relevant as they only occur - // once per Flash object load. - - // If the SWF was already loaded, we're à gogo! - if (added.ready && _flashState.ready) { - this.emit({ - type: "ready", - client: this - }); - } - if (added.error) { - for (i = 0, len = _flashStateErrorNames.length; i < len; i++) { - if (_flashState[_flashStateErrorNames[i].replace(/^flash-/, "")]) { - this.emit({ - type: "error", - name: _flashStateErrorNames[i], - client: this - }); - break; - } - } - if (_zcSwfVersion !== undefined && ZeroClipboard.version !== _zcSwfVersion) { - this.emit({ - type: "error", - name: "version-mismatch", - jsVersion: ZeroClipboard.version, - swfVersion: _zcSwfVersion - }); - } - } - } - return this; -}; - - -/** - * The underlying implementation of `ZeroClipboard.Client.prototype.off`. - * @private - */ -var _clientOff = function(eventType, listener) { - var i, len, foundIndex, events, perEventHandlers, - meta = _clientMeta[this.id], - handlers = meta && meta.handlers; - - if (!handlers) { - return this; - } - - if (arguments.length === 0) { - // Remove ALL of the handlers for ALL event types - events = _keys(handlers); - } - else if (typeof eventType === "string" && eventType) { - events = eventType.split(/\s+/); - } - else if (typeof eventType === "object" && eventType && typeof listener === "undefined") { - for (i in eventType) { - if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") { - this.off(i, eventType[i]); - } - } - } - - if (events && events.length) { - for (i = 0, len = events.length; i < len; i++) { - eventType = events[i].toLowerCase().replace(/^on/, ""); - perEventHandlers = handlers[eventType]; - if (perEventHandlers && perEventHandlers.length) { - if (listener) { - foundIndex = perEventHandlers.indexOf(listener); - while (foundIndex !== -1) { - perEventHandlers.splice(foundIndex, 1); - foundIndex = perEventHandlers.indexOf(listener, foundIndex); - } - } - else { - // If no `listener` was provided, remove ALL of the handlers for this event type - perEventHandlers.length = 0; - } - } - } - } - return this; -}; - - -/** - * The underlying implementation of `ZeroClipboard.Client.prototype.handlers`. - * @private - */ -var _clientListeners = function(eventType) { - var copy = null, - handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers; - - if (handlers) { - if (typeof eventType === "string" && eventType) { - copy = handlers[eventType] ? handlers[eventType].slice(0) : []; - } - else { - // Make a deep copy of the handlers object - copy = _deepCopy(handlers); - } - } - return copy; -}; - - -/** - * The underlying implementation of `ZeroClipboard.Client.prototype.emit`. - * @private - */ -var _clientEmit = function(event) { - if (_clientShouldEmit.call(this, event)) { - // Don't modify the original Event, if it is an object (as expected) - if (typeof event === "object" && event && typeof event.type === "string" && event.type) { - event = _extend({}, event); - } - var eventCopy = _extend({}, _createEvent(event), { client: this }); - _clientDispatchCallbacks.call(this, eventCopy); - } - return this; -}; - - -/** - * The underlying implementation of `ZeroClipboard.Client.prototype.clip`. - * @private - */ -var _clientClip = function(elements) { - if (!_clientMeta[this.id]) { - throw new Error("Attempted to clip element(s) to a destroyed ZeroClipboard client instance"); - } - - elements = _prepClip(elements); - - for (var i = 0; i < elements.length ; i++) { - if (_hasOwn.call(elements, i) && elements[i] && elements[i].nodeType === 1) { - // If the element hasn't been clipped to ANY client yet, add a metadata ID and event handler - if (!elements[i].zcClippingId) { - elements[i].zcClippingId = "zcClippingId_" + (_elementIdCounter++); - _elementMeta[elements[i].zcClippingId] = [this.id]; - if (_globalConfig.autoActivate === true) { - _addMouseHandlers(elements[i]); - } - } - else if (_elementMeta[elements[i].zcClippingId].indexOf(this.id) === -1) { - _elementMeta[elements[i].zcClippingId].push(this.id); - } - - // If the element hasn't been clipped to THIS client yet, add it - var clippedElements = _clientMeta[this.id] && _clientMeta[this.id].elements; - if (clippedElements.indexOf(elements[i]) === -1) { - clippedElements.push(elements[i]); - } - } - } - return this; -}; - - -/** - * The underlying implementation of `ZeroClipboard.Client.prototype.unclip`. - * @private - */ -var _clientUnclip = function(elements) { - var meta = _clientMeta[this.id]; - - if (!meta) { - return this; - } - - var clippedElements = meta.elements; - var arrayIndex; - - // If no elements were provided, unclip ALL of this client's clipped elements - if (typeof elements === "undefined") { - elements = clippedElements.slice(0); - } - else { - elements = _prepClip(elements); - } - - for (var i = elements.length; i--; ) { - if (_hasOwn.call(elements, i) && elements[i] && elements[i].nodeType === 1) { - // If the element was clipped to THIS client yet, remove it - arrayIndex = 0; - while ((arrayIndex = clippedElements.indexOf(elements[i], arrayIndex)) !== -1) { - clippedElements.splice(arrayIndex, 1); - } - - // If the element isn't clipped to ANY other client, remove its metadata ID and event handler - var clientIds = _elementMeta[elements[i].zcClippingId]; - if (clientIds) { - arrayIndex = 0; - while ((arrayIndex = clientIds.indexOf(this.id, arrayIndex)) !== -1) { - clientIds.splice(arrayIndex, 1); - } - if (clientIds.length === 0) { - if (_globalConfig.autoActivate === true) { - _removeMouseHandlers(elements[i]); - } - delete elements[i].zcClippingId; - } - } - } - } - return this; -}; - - -/** - * The underlying implementation of `ZeroClipboard.Client.prototype.elements`. - * @private - */ -var _clientElements = function() { - var meta = _clientMeta[this.id]; - return (meta && meta.elements) ? meta.elements.slice(0) : []; -}; - - -/** - * The underlying implementation of `ZeroClipboard.Client.prototype.destroy`. - * @private - */ -var _clientDestroy = function() { - if (!_clientMeta[this.id]) { - return; - } - - // Unclip all the elements - this.unclip(); - - // Remove all event handlers - this.off(); - - // Delete the client's metadata store - delete _clientMeta[this.id]; -}; - - - - -// -// Helper functions -// - -/** - * Inspect an Event to see if the Client (`this`) should honor it for emission. - * @private - */ -var _clientShouldEmit = function(event) { - // If no event is received - if (!(event && event.type)) { - return false; - } - - // If this event's `client` was specifically set to a client other than this client, bail out - if (event.client && event.client !== this) { - return false; - } - - // If this event's targeted element(s) is/are not clipped by this client, bail out - // unless the event's `client` was specifically set to this client. - var meta = _clientMeta[this.id]; - var clippedEls = meta && meta.elements; - var hasClippedEls = !!clippedEls && clippedEls.length > 0; - var goodTarget = !event.target || (hasClippedEls && clippedEls.indexOf(event.target) !== -1); - var goodRelTarget = event.relatedTarget && hasClippedEls && clippedEls.indexOf(event.relatedTarget) !== -1; - var goodClient = event.client && event.client === this; - - // At least one of these must be true.... - if (!meta || !(goodTarget || goodRelTarget || goodClient)) { - return false; - } - - // Otherwise... go for it! - return true; -}; - - -/** - * Handle the actual dispatching of events to a client instance. - * - * @returns `undefined` - * @private - */ -var _clientDispatchCallbacks = function(event) { - var meta = _clientMeta[this.id]; - - if (!(typeof event === "object" && event && event.type && meta)) { - return; - } - - var async = _shouldPerformAsync(event); - - // User defined handlers for events - var wildcardTypeHandlers = (meta && meta.handlers["*"]) || []; - var specificTypeHandlers = (meta && meta.handlers[event.type]) || []; - // Execute wildcard handlers before type-specific handlers - var handlers = wildcardTypeHandlers.concat(specificTypeHandlers); - - if (handlers && handlers.length) { - var i, len, func, context, eventCopy, - originalContext = this; - for (i = 0, len = handlers.length; i < len; i++) { - func = handlers[i]; - context = originalContext; - - // If the user provided a string for their callback, grab that function - if (typeof func === "string" && typeof _window[func] === "function") { - func = _window[func]; - } - if (typeof func === "object" && func && typeof func.handleEvent === "function") { - context = func; - func = func.handleEvent; - } - - if (typeof func === "function") { - eventCopy = _extend({}, event); - _dispatchCallback(func, context, [eventCopy], async); - } - } - } -}; - - -/** - * Prepares the elements for clipping/unclipping. - * - * @returns An Array of elements. - * @private - */ -var _prepClip = function(elements) { - // if elements is a string, ignore it - if (typeof elements === "string") { - elements = []; - } - // if the elements isn't an array, wrap it with one - return typeof elements.length !== "number" ? [elements] : elements; -}; - - -/** - * Add a `mouseover` handler function for a clipped element. - * - * @returns `undefined` - * @private - */ -var _addMouseHandlers = function(element) { - if (!(element && element.nodeType === 1)) { - return; - } - - // Create a `mouseout` handler function - var _suppressMouseEvents = function(event) { - if (!(event || (event = _window.event))) { - return; - } - - // Don't allow this event to be handled by consumers unless it originated from ZeroClipboard - if (event._source !== "js") { - event.stopImmediatePropagation(); - event.preventDefault(); - } - delete event._source; - }; - - // Create a `mouseover` handler function - var _elementMouseOver = function(event) { - if (!(event || (event = _window.event))) { - return; - } - - // Don't allow this event to be handled by consumers unless it originated from ZeroClipboard - _suppressMouseEvents(event); - - // Set this as the new currently active element - ZeroClipboard.focus(element); - }; - - // Add the `mouseover` handler function - element.addEventListener("mouseover", _elementMouseOver, false); - - // Add other mouse event handler functions - element.addEventListener("mouseout", _suppressMouseEvents, false); - element.addEventListener("mouseenter", _suppressMouseEvents, false); - element.addEventListener("mouseleave", _suppressMouseEvents, false); - element.addEventListener("mousemove", _suppressMouseEvents, false); - - // Save these function references to a global variable - _mouseHandlers[element.zcClippingId] = { - mouseover: _elementMouseOver, - mouseout: _suppressMouseEvents, - mouseenter: _suppressMouseEvents, - mouseleave: _suppressMouseEvents, - mousemove: _suppressMouseEvents - }; -}; - - -/** - * Remove a `mouseover` handler function for a clipped element. - * - * @returns `undefined` - * @private - */ -var _removeMouseHandlers = function(element) { - if (!(element && element.nodeType === 1)) { - return; - } - - // Retrieve these function references from a global variable - var mouseHandlers = _mouseHandlers[element.zcClippingId]; - if (!(typeof mouseHandlers === "object" && mouseHandlers)) { - return; - } - - // Remove the mouse event handlers - var key, val, - mouseEvents = ["move", "leave", "enter", "out", "over"]; - for (var i = 0, len = mouseEvents.length; i < len; i++) { - key = "mouse" + mouseEvents[i]; - val = mouseHandlers[key]; - if (typeof val === "function") { - element.removeEventListener(key, val, false); - } - } - - // Delete these function references from a global variable - delete _mouseHandlers[element.zcClippingId]; -}; diff --git a/web/public/libs/zeroclipboard/src/js/client/state.js b/web/public/libs/zeroclipboard/src/js/client/state.js deleted file mode 100755 index 7620641..0000000 --- a/web/public/libs/zeroclipboard/src/js/client/state.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Keep track of the ZeroClipboard client instance counter. - */ -var _clientIdCounter = 0; - - -/** - * Keep track of the state of the client instances. - * - * Entry structure: - * _clientMeta[client.id] = { - * instance: client, - * elements: [], - * handlers: {} - * }; - */ -var _clientMeta = {}; - - -/** - * Keep track of the ZeroClipboard clipped elements counter. - */ -var _elementIdCounter = 0; - - -/** - * Keep track of the state of the clipped element relationships to clients. - * - * Entry structure: - * _elementMeta[element.zcClippingId] = [client1.id, client2.id]; - */ -var _elementMeta = {}; - - -/** - * Keep track of the state of the mouse event handlers for clipped elements. - * - * Entry structure: - * _mouseHandlers[element.zcClippingId] = { - * mouseover: function(event) {}, - * mouseout: function(event) {}, - * mouseenter: function(event) {}, - * mouseleave: function(event) {}, - * mousemove: function(event) {} - * }; - */ -var _mouseHandlers = {}; - - -/** - * Extending the ZeroClipboard configuration defaults for the Client module. - */ -_extend(_globalConfig, { - - // Setting this to `false` would allow users to handle calling - // `ZeroClipboard.focus(...);` themselves instead of relying on our - // per-element `mouseover` handler. - autoActivate: true - -}); diff --git a/web/public/libs/zeroclipboard/src/js/core/api.js b/web/public/libs/zeroclipboard/src/js/core/api.js deleted file mode 100755 index 0870de9..0000000 --- a/web/public/libs/zeroclipboard/src/js/core/api.js +++ /dev/null @@ -1,211 +0,0 @@ -/** - * A shell constructor for `ZeroClipboard` client instances. - * - * @constructor - */ -var ZeroClipboard = function() { - - // Ensure the constructor is invoked with the `new` keyword. - if (!(this instanceof ZeroClipboard)) { - return new ZeroClipboard(); - } - - // EXTREMELY IMPORTANT! - // Ensure the `ZeroClipboard._createClient` function is invoked if available. - // This allows an extension point for 3rd parties to create their own - // interpretations of what a ZeroClipboard "Client" should be like. - if (typeof ZeroClipboard._createClient === "function") { - ZeroClipboard._createClient.apply(this, _args(arguments)); - } - -}; - - -/** - * The ZeroClipboard library's version number. - * - * @static - * @readonly - * @property {string} - */ -_defineProperty(ZeroClipboard, "version", { - value: "<%= version %>", - writable: false, - configurable: true, - enumerable: true -}); - - -/** - * Update or get a copy of the ZeroClipboard global configuration. - * Returns a copy of the current/updated configuration. - * - * @returns Object - * @static - */ -ZeroClipboard.config = function(/* options */) { - return _config.apply(this, _args(arguments)); -}; - - -/** - * Diagnostic method that describes the state of the browser, Flash Player, and ZeroClipboard. - * - * @returns Object - * @static - */ -ZeroClipboard.state = function() { - return _state.apply(this, _args(arguments)); -}; - - -/** - * Check if Flash is unusable for any reason: disabled, outdated, deactivated, etc. - * - * @returns Boolean - * @static - */ -ZeroClipboard.isFlashUnusable = function() { - return _isFlashUnusable.apply(this, _args(arguments)); -}; - - -/** - * Register an event listener. - * - * @returns `ZeroClipboard` - * @static - */ -ZeroClipboard.on = function(/* eventType, listener */) { - return _on.apply(this, _args(arguments)); -}; - - -/** - * Unregister an event listener. - * If no `listener` function/object is provided, it will unregister all listeners for the provided `eventType`. - * If no `eventType` is provided, it will unregister all listeners for every event type. - * - * @returns `ZeroClipboard` - * @static - */ -ZeroClipboard.off = function(/* eventType, listener */) { - return _off.apply(this, _args(arguments)); -}; - - -/** - * Retrieve event listeners for an `eventType`. - * If no `eventType` is provided, it will retrieve all listeners for every event type. - * - * @returns array of listeners for the `eventType`; if no `eventType`, then a map/hash object of listeners for all event types; or `null` - */ -ZeroClipboard.handlers = function(/* eventType */) { - return _listeners.apply(this, _args(arguments)); -}; - - -/** - * Event emission receiver from the Flash object, forwarding to any registered JavaScript event listeners. - * - * @returns For the "copy" event, returns the Flash-friendly "clipData" object; otherwise `undefined`. - * @static - */ -ZeroClipboard.emit = function(/* event */) { - return _emit.apply(this, _args(arguments)); -}; - - -/** - * Create and embed the Flash object. - * - * @returns The Flash object - * @static - */ -ZeroClipboard.create = function() { - return _create.apply(this, _args(arguments)); -}; - - -/** - * Self-destruct and clean up everything, including the embedded Flash object. - * - * @returns `undefined` - * @static - */ -ZeroClipboard.destroy = function() { - return _destroy.apply(this, _args(arguments)); -}; - - -/** - * Set the pending data for clipboard injection. - * - * @returns `undefined` - * @static - */ -ZeroClipboard.setData = function(/* format, data */) { - return _setData.apply(this, _args(arguments)); -}; - - -/** - * Clear the pending data for clipboard injection. - * If no `format` is provided, all pending data formats will be cleared. - * - * @returns `undefined` - * @static - */ -ZeroClipboard.clearData = function(/* format */) { - return _clearData.apply(this, _args(arguments)); -}; - - -/** - * Get a copy of the pending data for clipboard injection. - * If no `format` is provided, a copy of ALL pending data formats will be returned. - * - * @returns `String` or `Object` - * @static - */ -ZeroClipboard.getData = function(/* format */) { - return _getData.apply(this, _args(arguments)); -}; - - -/** - * Sets the current HTML object that the Flash object should overlay. This will put the global - * Flash object on top of the current element; depending on the setup, this may also set the - * pending clipboard text data as well as the Flash object's wrapping element's title attribute - * based on the underlying HTML element and ZeroClipboard configuration. - * - * @returns `undefined` - * @static - */ -ZeroClipboard.focus = ZeroClipboard.activate = function(/* element */) { - return _focus.apply(this, _args(arguments)); -}; - - -/** - * Un-overlays the Flash object. This will put the global Flash object off-screen; depending on - * the setup, this may also unset the Flash object's wrapping element's title attribute based on - * the underlying HTML element and ZeroClipboard configuration. - * - * @returns `undefined` - * @static - */ -ZeroClipboard.blur = ZeroClipboard.deactivate = function() { - return _blur.apply(this, _args(arguments)); -}; - - -/** - * Returns the currently focused/"activated" HTML element that the Flash object is wrapping. - * - * @returns `HTMLElement` or `null` - * @static - */ -ZeroClipboard.activeElement = function() { - return _activeElement.apply(this, _args(arguments)); -}; diff --git a/web/public/libs/zeroclipboard/src/js/core/private.js b/web/public/libs/zeroclipboard/src/js/core/private.js deleted file mode 100755 index 72cff5c..0000000 --- a/web/public/libs/zeroclipboard/src/js/core/private.js +++ /dev/null @@ -1,1975 +0,0 @@ -/** - * The underlying implementation of `ZeroClipboard.config`. - * @private - */ -var _config = function(options) { - /*jshint maxdepth:6 */ - if (typeof options === "object" && options !== null) { - for (var prop in options) { - if (_hasOwn.call(options, prop)) { - // These configuration values CAN be modified while a SWF is actively embedded. - if (/^(?:forceHandCursor|title|zIndex|bubbleEvents)$/.test(prop)) { - _globalConfig[prop] = options[prop]; - } - // All other configuration values CANNOT be modified while a SWF is actively embedded. - else if (_flashState.bridge == null) { - if (prop === "containerId" || prop === "swfObjectId") { - // Validate values against the HTML4 spec for `ID` and `Name` tokens - if (_isValidHtml4Id(options[prop])) { - _globalConfig[prop] = options[prop]; - } - else { - throw new Error("The specified `" + prop + "` value is not valid as an HTML4 Element ID"); - } - } - else { - _globalConfig[prop] = options[prop]; - } - } - } - } - } - - if (typeof options === "string" && options) { - if (_hasOwn.call(_globalConfig, options)) { - // TODO: MAYBE do a `_deepCopy` of this as well? It is convenient to NOT - // do a `_deepCopy` if we want to allow consumers to, for example, be - // able to update the `trustedDomains` array on their own terms rather - // than having to send in a whole new array. - return _globalConfig[options]; - } - // else `return undefined;` - return; - } - - return _deepCopy(_globalConfig); -}; - - -/** - * The underlying implementation of `ZeroClipboard.state`. - * @private - */ -var _state = function() { - // Always reassess the `sandboxed` state of the page at important Flash-related moments - _detectSandbox(); - - return { - browser: _pick(_navigator, ["userAgent", "platform", "appName"]), - flash: _omit(_flashState, ["bridge"]), - zeroclipboard: { - version: ZeroClipboard.version, - config: ZeroClipboard.config() - } - }; -}; - - -/** - * The underlying implementation of `ZeroClipboard.isFlashUnusable`. - * @private - */ -var _isFlashUnusable = function() { - return !!( - _flashState.disabled || - _flashState.outdated || - _flashState.sandboxed || - _flashState.unavailable || - _flashState.degraded || - _flashState.deactivated - ); -}; - - -/** - * The underlying implementation of `ZeroClipboard.on`. - * @private - */ -var _on = function(eventType, listener) { - var i, len, events, - added = {}; - - if (typeof eventType === "string" && eventType) { - events = eventType.toLowerCase().split(/\s+/); - } - else if (typeof eventType === "object" && eventType && typeof listener === "undefined") { - for (i in eventType) { - if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") { - ZeroClipboard.on(i, eventType[i]); - } - } - } - - if (events && events.length) { - for (i = 0, len = events.length; i < len; i++) { - eventType = events[i].replace(/^on/, ""); - added[eventType] = true; - if (!_handlers[eventType]) { - _handlers[eventType] = []; - } - _handlers[eventType].push(listener); - } - - // The following events must be memorized and fired immediately if relevant as they only occur - // once per Flash object load. - - // If the SWF was already loaded, we're à gogo! - if (added.ready && _flashState.ready) { - ZeroClipboard.emit({ - type: "ready" - }); - } - if (added.error) { - for (i = 0, len = _flashStateErrorNames.length; i < len; i++) { - if (_flashState[_flashStateErrorNames[i].replace(/^flash-/, "")] === true) { - ZeroClipboard.emit({ - type: "error", - name: _flashStateErrorNames[i] - }); - break; - } - } - if (_zcSwfVersion !== undefined && ZeroClipboard.version !== _zcSwfVersion) { - ZeroClipboard.emit({ - type: "error", - name: "version-mismatch", - jsVersion: ZeroClipboard.version, - swfVersion: _zcSwfVersion - }); - } - } - } - - return ZeroClipboard; -}; - - -/** - * The underlying implementation of `ZeroClipboard.off`. - * @private - */ -var _off = function(eventType, listener) { - var i, len, foundIndex, events, perEventHandlers; - if (arguments.length === 0) { - // Remove ALL of the _handlers for ALL event types - events = _keys(_handlers); - } - else if (typeof eventType === "string" && eventType) { - events = eventType.split(/\s+/); - } - else if (typeof eventType === "object" && eventType && typeof listener === "undefined") { - for (i in eventType) { - if (_hasOwn.call(eventType, i) && typeof i === "string" && i && typeof eventType[i] === "function") { - ZeroClipboard.off(i, eventType[i]); - } - } - } - - if (events && events.length) { - for (i = 0, len = events.length; i < len; i++) { - eventType = events[i].toLowerCase().replace(/^on/, ""); - perEventHandlers = _handlers[eventType]; - if (perEventHandlers && perEventHandlers.length) { - if (listener) { - foundIndex = perEventHandlers.indexOf(listener); - while (foundIndex !== -1) { - perEventHandlers.splice(foundIndex, 1); - foundIndex = perEventHandlers.indexOf(listener, foundIndex); - } - } - else { - // If no `listener` was provided, remove ALL of the handlers for this event type - perEventHandlers.length = 0; - } - } - } - } - - return ZeroClipboard; -}; - - -/** - * The underlying implementation of `ZeroClipboard.handlers`. - * @private - */ -var _listeners = function(eventType) { - var copy; - if (typeof eventType === "string" && eventType) { - copy = _deepCopy(_handlers[eventType]) || null; - } - else { - copy = _deepCopy(_handlers); - } - return copy; -}; - - -/** - * The underlying implementation of `ZeroClipboard.emit`. - * @private - */ -var _emit = function(event) { - var eventCopy, returnVal, tmp; - - // Create an event object for this event type - event = _createEvent(event); - - if (!event) { - return; - } - - // Preprocess any special behaviors, reactions, or state changes after receiving this event - if (_preprocessEvent(event)) { - return; - } - - // If this was a Flash "ready" event that was overdue, bail out and fire an "error" event instead - if (event.type === "ready" && _flashState.overdue === true) { - return ZeroClipboard.emit({ "type": "error", "name": "flash-overdue" }); - } - - // Trigger any and all registered event handlers - eventCopy = _extend({}, event); - _dispatchCallbacks.call(this, eventCopy); - - // For the `copy` event, be sure to return the `_clipData` to Flash to be injected into the clipboard - if (event.type === "copy") { - tmp = _mapClipDataToFlash(_clipData); - returnVal = tmp.data; - _clipDataFormatMap = tmp.formatMap; - } - return returnVal; -}; - - -/** - * The underlying implementation of `ZeroClipboard.create`. - * @private - */ -var _create = function() { - // Make note of the most recent sandbox assessment - var previousState = _flashState.sandboxed; - - // Always reassess the `sandboxed` state of the page at important Flash-related moments - _detectSandbox(); - - // Setup the Flash <-> JavaScript bridge - if (typeof _flashState.ready !== "boolean") { - _flashState.ready = false; - } - - // If the page is newly sandboxed (or newly understood to be sandboxed), inform the consumer - if (_flashState.sandboxed !== previousState && _flashState.sandboxed === true) { - _flashState.ready = false; - ZeroClipboard.emit({ type: "error", name: "flash-sandboxed" }); - } - else if (!ZeroClipboard.isFlashUnusable() && _flashState.bridge === null) { - var maxWait = _globalConfig.flashLoadTimeout; - if (typeof maxWait === "number" && maxWait >= 0) { - _flashCheckTimeout = _setTimeout(function() { - // If it took longer than `_globalConfig.flashLoadTimeout` milliseconds to receive - // a `ready` event, so consider Flash "deactivated". - if (typeof _flashState.deactivated !== "boolean") { - _flashState.deactivated = true; - } - if (_flashState.deactivated === true) { - ZeroClipboard.emit({ "type": "error", "name": "flash-deactivated" }); - } - }, maxWait); - } - - // If attempting a fresh SWF embedding, it is safe to ignore the `overdue` status - _flashState.overdue = false; - - // Embed the SWF - _embedSwf(); - } -}; - - -/** - * The underlying implementation of `ZeroClipboard.destroy`. - * @private - */ -var _destroy = function() { - // Clear any pending clipboard data - ZeroClipboard.clearData(); - - // Deactivate during self-destruct, even if `_globalConfig.autoActivate` !== `true` - ZeroClipboard.blur(); - - // Emit a special [synchronously handled] event so that Clients may listen - // for it and destroy themselves - ZeroClipboard.emit("destroy"); - - // Un-embed the SWF - _unembedSwf(); - - // Remove all event handlers - ZeroClipboard.off(); -}; - - -/** - * The underlying implementation of `ZeroClipboard.setData`. - * @private - */ -var _setData = function(format, data) { - var dataObj; - - if (typeof format === "object" && format && typeof data === "undefined") { - dataObj = format; - - // Clear out existing pending data if an object is provided - ZeroClipboard.clearData(); - } - else if (typeof format === "string" && format) { - dataObj = {}; - dataObj[format] = data; - } - else { - return; - } - - // Copy over owned properties with non-empty string values - for (var dataFormat in dataObj) { - if ( - typeof dataFormat === "string" && dataFormat && - _hasOwn.call(dataObj, dataFormat) && typeof dataObj[dataFormat] === "string" && dataObj[dataFormat] - ) { - _clipData[dataFormat] = dataObj[dataFormat]; - } - } -}; - - -/** - * The underlying implementation of `ZeroClipboard.clearData`. - * @private - */ -var _clearData = function(format) { - // If no format is passed, delete all of the pending data - if (typeof format === "undefined") { - _deleteOwnProperties(_clipData); - _clipDataFormatMap = null; - } - // Otherwise, delete only the pending data of the specified format - else if (typeof format === "string" && _hasOwn.call(_clipData, format)) { - delete _clipData[format]; - } -}; - - -/** - * The underlying implementation of `ZeroClipboard.getData`. - * @private - */ -var _getData = function(format) { - // If no format is passed, get a copy of ALL of the pending data - if (typeof format === "undefined") { - return _deepCopy(_clipData); - } - // Otherwise, get only the pending data of the specified format - else if (typeof format === "string" && _hasOwn.call(_clipData, format)) { - return _clipData[format]; - } -}; - - -/** - * The underlying implementation of `ZeroClipboard.focus`/`ZeroClipboard.activate`. - * @private - */ -var _focus = function(element) { - if (!(element && element.nodeType === 1)) { - return; - } - - // "Ignore" the currently active element - if (_currentElement) { - _removeClass(_currentElement, _globalConfig.activeClass); - - if (_currentElement !== element) { - _removeClass(_currentElement, _globalConfig.hoverClass); - } - } - - // Mark the element as currently activated - _currentElement = element; - _addClass(element, _globalConfig.hoverClass); - - // If the element has a title, mimic it - var newTitle = element.getAttribute("title") || _globalConfig.title; - if (typeof newTitle === "string" && newTitle) { - var htmlBridge = _getHtmlBridge(_flashState.bridge); - if (htmlBridge) { - htmlBridge.setAttribute("title", newTitle); - } - } - - // If the element has a pointer style, set to hand cursor - var useHandCursor = _globalConfig.forceHandCursor === true || _getStyle(element, "cursor") === "pointer"; - // Update the hand cursor state without updating the `forceHandCursor` option - _setHandCursor(useHandCursor); - - // Move the Flash object over the newly activated element - _reposition(); -}; - - -/** - * The underlying implementation of `ZeroClipboard.blur`/`ZeroClipboard.deactivate`. - * @private - */ -var _blur = function() { - // Hide the Flash object off-screen - var htmlBridge = _getHtmlBridge(_flashState.bridge); - if (htmlBridge) { - htmlBridge.removeAttribute("title"); - htmlBridge.style.left = "0px"; - htmlBridge.style.top = "-9999px"; - htmlBridge.style.width = "1px"; - htmlBridge.style.height = "1px"; - } - - // "Ignore" the currently active element - if (_currentElement) { - _removeClass(_currentElement, _globalConfig.hoverClass); - _removeClass(_currentElement, _globalConfig.activeClass); - _currentElement = null; - } -}; - - -/** - * The underlying implementation of `ZeroClipboard.activeElement`. - * @private - */ -var _activeElement = function() { - return _currentElement || null; -}; - - - -// -// Helper functions -// - -/** - * Check if a value is a valid HTML4 `ID` or `Name` token. - * @private - */ -var _isValidHtml4Id = function(id) { - return typeof id === "string" && id && /^[A-Za-z][A-Za-z0-9_:\-\.]*$/.test(id); -}; - - -/** - * Create or update an `event` object, based on the `eventType`. - * @private - */ -var _createEvent = function(event) { - /*jshint maxstatements:30 */ - - var eventType; - if (typeof event === "string" && event) { - eventType = event; - event = {}; - } - else if (typeof event === "object" && event && typeof event.type === "string" && event.type) { - eventType = event.type; - } - - // Bail if we don't have an event type - if (!eventType) { - return; - } - - eventType = eventType.toLowerCase(); - - // Sanitize the event type and set the `target` and `relatedTarget` properties if not already set - if (!event.target && - ( - /^(copy|aftercopy|_click)$/.test(eventType) || - (eventType === "error" && event.name === "clipboard-error") - ) - ) { - event.target = _copyTarget; - } - - _extend(event, { - type: eventType, - target: event.target || _currentElement || null, - relatedTarget: event.relatedTarget || null, - currentTarget: (_flashState && _flashState.bridge) || null, - timeStamp: event.timeStamp || _now() || null - }); - - var msg = _eventMessages[event.type]; - if (event.type === "error" && event.name && msg) { - msg = msg[event.name]; - } - if (msg) { - event.message = msg; - } - - if (event.type === "ready") { - _extend(event, { - target: null, - version: _flashState.version - }); - } - - if (event.type === "error") { - if (_flashStateErrorNameMatchingRegex.test(event.name)) { - _extend(event, { - target: null, - minimumVersion: _minimumFlashVersion - }); - } - if (_flashStateEnabledErrorNameMatchingRegex.test(event.name)) { - _extend(event, { - version: _flashState.version - }); - } - } - - // Add all of the special properties and methods for a `copy` event - if (event.type === "copy") { - event.clipboardData = { - setData: ZeroClipboard.setData, - clearData: ZeroClipboard.clearData - }; - } - - if (event.type === "aftercopy") { - event = _mapClipResultsFromFlash(event, _clipDataFormatMap); - } - - if (event.target && !event.relatedTarget) { - event.relatedTarget = _getRelatedTarget(event.target); - } - - return _addMouseData(event); -}; - - -/** - * Get a relatedTarget from the target's `data-clipboard-target` attribute - * @private - */ -var _getRelatedTarget = function(targetEl) { - var relatedTargetId = targetEl && targetEl.getAttribute && targetEl.getAttribute("data-clipboard-target"); - return relatedTargetId ? _document.getElementById(relatedTargetId) : null; -}; - - -/** - * Add element and position data to `MouseEvent` instances - * @private - */ -var _addMouseData = function(event) { - if (event && /^_(?:click|mouse(?:over|out|down|up|move))$/.test(event.type)) { - // Element data - var srcElement = event.target; - var fromElement = event.type === "_mouseover" && event.relatedTarget ? event.relatedTarget : undefined; - var toElement = event.type === "_mouseout" && event.relatedTarget ? event.relatedTarget : undefined; - - // Calculate positional data - var pos = _getElementPosition(srcElement); - var screenLeft = _window.screenLeft || _window.screenX || 0; - var screenTop = _window.screenTop || _window.screenY || 0; - var scrollLeft = _document.body.scrollLeft + _document.documentElement.scrollLeft; - var scrollTop = _document.body.scrollTop + _document.documentElement.scrollTop; - var pageX = pos.left + (typeof event._stageX === "number" ? event._stageX : 0); - var pageY = pos.top + (typeof event._stageY === "number" ? event._stageY : 0); - var clientX = pageX - scrollLeft; - var clientY = pageY - scrollTop; - var screenX = screenLeft + clientX; - var screenY = screenTop + clientY; - var moveX = typeof event.movementX === "number" ? event.movementX : 0; - var moveY = typeof event.movementY === "number" ? event.movementY : 0; - - // Remove these transient properties, if present - delete event._stageX; - delete event._stageY; - - // Update the appropriate properties of `event`, mostly with position data. - // Good notes: - // http://www.jacklmoore.com/notes/mouse-position/ - _extend(event, { - srcElement: srcElement, - fromElement: fromElement, - toElement: toElement, - screenX: screenX, // screenLeft + clientX - screenY: screenY, // screenTop + clientY - pageX: pageX, // scrollLeft + clientX - pageY: pageY, // scrollTop + clientY - clientX: clientX, // pageX - scrollLeft - clientY: clientY, // pageY - scrollTop - x: clientX, // clientX - y: clientY, // clientY - movementX: moveX, // movementX - movementY: moveY, // movementY - offsetX: 0, // Unworthy of calculation - offsetY: 0, // Unworthy of calculation - layerX: 0, // Unworthy of calculation - layerY: 0 // Unworthy of calculation - }); - } - - return event; -}; - - -/** - * Determine if an event's registered handlers should be execute synchronously or asynchronously. - * - * @returns {boolean} - * @private - */ -var _shouldPerformAsync = function(event) { - var eventType = (event && typeof event.type === "string" && event.type) || ""; - - // Determine if the event handlers for this event can be performed asynchronously. - // - `beforecopy`: This event's callback cannot be performed asynchronously because the - // subsequent `copy` event cannot. - // - `copy`: This event's callback cannot be performed asynchronously as it would prevent the - // user from being able to call `.setText` successfully before the pending clipboard - // injection associated with this event fires. - // - `destroy`: This event's callback cannot be performed asynchronously as it is necessary - // to allow any downstream clients the chance to destroy themselves as well - // as well before the final destruction of the SWF object and removal of all - // registered event handlers. - // - The handlers for all other event types should be performed asynchronously. - return !/^(?:(?:before)?copy|destroy)$/.test(eventType); -}; - - -/** - * Control if a callback should be executed asynchronously or not. - * - * @returns `undefined` - * @private - */ -var _dispatchCallback = function(func, context, args, async) { - if (async) { - _setTimeout(function() { - func.apply(context, args); - }, 0); - } - else { - func.apply(context, args); - } -}; - - -/** - * Handle the actual dispatching of events to client instances. - * - * @returns `undefined` - * @private - */ -var _dispatchCallbacks = function(event) { - if (!(typeof event === "object" && event && event.type)) { - return; - } - - var async = _shouldPerformAsync(event); - - // User defined handlers for events - var wildcardTypeHandlers = _handlers["*"] || []; - var specificTypeHandlers = _handlers[event.type] || []; - // Execute wildcard handlers before type-specific handlers - var handlers = wildcardTypeHandlers.concat(specificTypeHandlers); - - if (handlers && handlers.length) { - var i, len, func, context, eventCopy, - originalContext = this; - for (i = 0, len = handlers.length; i < len; i++) { - func = handlers[i]; - context = originalContext; - - // If the user provided a string for their callback, grab that function - if (typeof func === "string" && typeof _window[func] === "function") { - func = _window[func]; - } - if (typeof func === "object" && func && typeof func.handleEvent === "function") { - context = func; - func = func.handleEvent; - } - - if (typeof func === "function") { - eventCopy = _extend({}, event); - _dispatchCallback(func, context, [eventCopy], async); - } - } - } - return this; -}; - - -/** - * Check an `error` event's `name` property to see if Flash has - * already loaded, which rules out possible `iframe` sandboxing. - * @private - */ -var _getSandboxStatusFromErrorEvent = function(event) { - var isSandboxed = null; // `null` === uncertain - - if ( - // If the page is not framed, bail out immediately - _pageIsFramed === false || - ( - event && - event.type === "error" && - event.name && - _errorsThatOnlyOccurAfterFlashLoads.indexOf(event.name) !== -1 - ) - ) { - isSandboxed = false; // `false` === not sandboxed - } - - return isSandboxed; -}; - - -/** - * Preprocess any special behaviors, reactions, or state changes after receiving this event. - * Executes only once per event emitted, NOT once per client. - * @private - */ -var _preprocessEvent = function(event) { - /*jshint maxstatements:27 */ - - var element = event.target || _currentElement || null; - - var sourceIsSwf = event._source === "swf"; - delete event._source; - - switch (event.type) { - case "error": - var isSandboxed = event.name === "flash-sandboxed" || _getSandboxStatusFromErrorEvent(event); - if (typeof isSandboxed === "boolean") { - _flashState.sandboxed = isSandboxed; - } - - if (_flashStateErrorNames.indexOf(event.name) !== -1) { - _extend(_flashState, { - disabled: event.name === "flash-disabled", - outdated: event.name === "flash-outdated", - unavailable: event.name === "flash-unavailable", - degraded: event.name === "flash-degraded", - deactivated: event.name === "flash-deactivated", - overdue: event.name === "flash-overdue", - ready: false - }); - } - else if (event.name === "version-mismatch") { - _zcSwfVersion = event.swfVersion; - - _extend(_flashState, { - disabled: false, - outdated: false, - unavailable: false, - degraded: false, - deactivated: false, - overdue: false, - ready: false - }); - } - - // Remove for cleanliness - _clearTimeoutsAndPolling(); - - break; - - case "ready": - _zcSwfVersion = event.swfVersion; - - var wasDeactivated = _flashState.deactivated === true; - _extend(_flashState, { - disabled: false, - outdated: false, - sandboxed: false, - unavailable: false, - degraded: false, - deactivated: false, - overdue: wasDeactivated, - ready: !wasDeactivated - }); - - // Remove for cleanliness - _clearTimeoutsAndPolling(); - - break; - - case "beforecopy": - _copyTarget = element; - break; - - case "copy": - var textContent, - htmlContent, - targetEl = event.relatedTarget; - if ( - !(_clipData["text/html"] || _clipData["text/plain"]) && - targetEl && - (htmlContent = targetEl.value || targetEl.outerHTML || targetEl.innerHTML) && - (textContent = targetEl.value || targetEl.textContent || targetEl.innerText) - ) { - event.clipboardData.clearData(); - event.clipboardData.setData("text/plain", textContent); - if (htmlContent !== textContent) { - event.clipboardData.setData("text/html", htmlContent); - } - } - else if (!_clipData["text/plain"] && event.target && (textContent = event.target.getAttribute("data-clipboard-text"))) { - event.clipboardData.clearData(); - event.clipboardData.setData("text/plain", textContent); - } - break; - - case "aftercopy": - _queueEmitClipboardErrors(event); - - // If the copy has [or should have] occurred, clear out all of the data - ZeroClipboard.clearData(); - - // Focus the context back on the trigger element (blur the Flash element) - if (element && element !== _safeActiveElement() && element.focus) { - element.focus(); - } - break; - - case "_mouseover": - // Set this as the new currently active element - ZeroClipboard.focus(element); - - if (_globalConfig.bubbleEvents === true && sourceIsSwf) { - if ( - element && - element !== event.relatedTarget && - !_containedBy(event.relatedTarget, element) - ) { - _fireMouseEvent( - _extend({}, event, { - type: "mouseenter", - bubbles: false, - cancelable: false - }) - ); - } - - _fireMouseEvent( - _extend({}, event, { - type: "mouseover" - }) - ); - } - break; - - case "_mouseout": - // If the mouse is moving to any other element, deactivate and... - ZeroClipboard.blur(); - - if (_globalConfig.bubbleEvents === true && sourceIsSwf) { - if ( - element && - element !== event.relatedTarget && - !_containedBy(event.relatedTarget, element) - ) { - _fireMouseEvent( - _extend({}, event, { - type: "mouseleave", - bubbles: false, - cancelable: false - }) - ); - } - - _fireMouseEvent( - _extend({}, event, { - type: "mouseout" - }) - ); - } - break; - - case "_mousedown": - _addClass(element, _globalConfig.activeClass); - - if (_globalConfig.bubbleEvents === true && sourceIsSwf) { - _fireMouseEvent(_extend({}, event, { type: event.type.slice(1) })); - } - break; - - case "_mouseup": - _removeClass(element, _globalConfig.activeClass); - - if (_globalConfig.bubbleEvents === true && sourceIsSwf) { - _fireMouseEvent(_extend({}, event, { type: event.type.slice(1) })); - } - break; - - case "_click": - _copyTarget = null; - - if (_globalConfig.bubbleEvents === true && sourceIsSwf) { - _fireMouseEvent(_extend({}, event, { type: event.type.slice(1) })); - } - break; - - case "_mousemove": - if (_globalConfig.bubbleEvents === true && sourceIsSwf) { - _fireMouseEvent(_extend({}, event, { type: event.type.slice(1) })); - } - break; - } // end `switch` - - // Return a flag to indicate that this event should stop being processed - if (/^_(?:click|mouse(?:over|out|down|up|move))$/.test(event.type)) { - return true; - } -}; - - -/** - * Check an "aftercopy" event for clipboard errors and emit a corresponding "error" event. - * @private - */ -var _queueEmitClipboardErrors = function(aftercopyEvent) { - if (aftercopyEvent.errors && aftercopyEvent.errors.length > 0) { - var errorEvent = _deepCopy(aftercopyEvent); - _extend(errorEvent, { - type: "error", - name: "clipboard-error" - }); - delete errorEvent.success; - - // Delay emitting this until AFTER the "aftercopy" event has finished emitting - _setTimeout(function() { - ZeroClipboard.emit(errorEvent); - }, 0); - } -}; - - -/** - * Dispatch a synthetic MouseEvent. - * - * @returns `undefined` - * @private - */ -var _fireMouseEvent = function(event) { - if (!(event && typeof event.type === "string" && event)) { - return; - } - - var e, - target = event.target || null, - doc = (target && target.ownerDocument) || _document, - defaults = { - view: doc.defaultView || _window, - canBubble: true, - cancelable: true, - detail: event.type === "click" ? 1 : 0, - button: - typeof event.which === "number" ? - (event.which - 1) : - ( - typeof event.button === "number" ? - event.button : - (doc.createEvent ? 0 : 1) - ) - }, - // Update the Event data to its final state - args = _extend(defaults, event); - - if (!target) { - return; - } - - // Create and fire the MouseEvent - if (doc.createEvent && target.dispatchEvent) { - args = [ - args.type, args.canBubble, args.cancelable, args.view, args.detail, - args.screenX, args.screenY, args.clientX, args.clientY, - args.ctrlKey, args.altKey, args.shiftKey, args.metaKey, - args.button, args.relatedTarget - ]; - e = doc.createEvent("MouseEvents"); - if (e.initMouseEvent) { - e.initMouseEvent.apply(e, args); - e._source = "js"; - target.dispatchEvent(e); - } - } -}; - - -/** - * Continuously poll the DOM until either: - * (a) the fallback content becomes visible, or - * (b) we receive an event from SWF (handled elsewhere) - * - * IMPORTANT: - * This is NOT a necessary check but it can result in significantly faster - * detection of bad `swfPath` configuration and/or network/server issues [in - * supported browsers] than waiting for the entire `flashLoadTimeout` duration - * to elapse before detecting that the SWF cannot be loaded. The detection - * duration can be anywhere from 10-30 times faster [in supported browsers] by - * using this approach. - * - * @returns `undefined` - * @private - */ -var _watchForSwfFallbackContent = function() { - var maxWait = _globalConfig.flashLoadTimeout; - if (typeof maxWait === "number" && maxWait >= 0) { - var pollWait = Math.min(1000, (maxWait / 10)); - var fallbackContentId = _globalConfig.swfObjectId + "_fallbackContent"; - _swfFallbackCheckInterval = _setInterval(function() { - // If the fallback content is showing, the SWF failed to load - // NOTE: Only works in Firefox and IE10 (specifically; not IE9, not IE11... o_O) - var el = _document.getElementById(fallbackContentId); - if (_isElementVisible(el)) { - // Remove the polling checks immediately - _clearTimeoutsAndPolling(); - - // Do NOT count a missing SWF as a Flash deactivation - _flashState.deactivated = null; - - ZeroClipboard.emit({ "type": "error", "name": "swf-not-found" }); - } - }, pollWait); - } -}; - - -/** - * Create the HTML bridge element to embed the Flash object into. - * @private - */ -var _createHtmlBridge = function() { - var container = _document.createElement("div"); - container.id = _globalConfig.containerId; - container.className = _globalConfig.containerClass; - container.style.position = "absolute"; - container.style.left = "0px"; - container.style.top = "-9999px"; - container.style.width = "1px"; - container.style.height = "1px"; - container.style.zIndex = "" + _getSafeZIndex(_globalConfig.zIndex); - return container; -}; - - -/** - * Get the HTML element container that wraps the Flash bridge object/element. - * @private - */ -var _getHtmlBridge = function(flashBridge) { - var htmlBridge = flashBridge && flashBridge.parentNode; - while (htmlBridge && htmlBridge.nodeName === "OBJECT" && htmlBridge.parentNode) { - htmlBridge = htmlBridge.parentNode; - } - return htmlBridge || null; -}; - - -/** - * Create the SWF object. - * - * @returns The SWF object reference. - * @private - */ -var _embedSwf = function() { - /*jshint maxstatements:26 */ - - var len, - flashBridge = _flashState.bridge, - container = _getHtmlBridge(flashBridge); - - if (!flashBridge) { - // Set `allowScriptAccess`/`allowNetworking` based on `trustedDomains` and `window.location.host` vs. `swfPath` - var allowScriptAccess = _determineScriptAccess(_window.location.host, _globalConfig); - var allowNetworking = allowScriptAccess === "never" ? "none" : "all"; - - // Prepare the FlashVars and cache-busting query param - var flashvars = _vars(_extend({ jsVersion: ZeroClipboard.version }, _globalConfig)); - var swfUrl = _globalConfig.swfPath + _cacheBust(_globalConfig.swfPath, _globalConfig); - - // Create the outer container - container = _createHtmlBridge(); - - // Create a to-be-replaced child node - var divToBeReplaced = _document.createElement("div"); - container.appendChild(divToBeReplaced); - - // Add this outer container (and its to-be-replaced child node) to the DOM in advance in order - // to avoid Flash quirks in various browsers, e.g. https://github.com/zeroclipboard/zeroclipboard/issues/204 - _document.body.appendChild(container); - - // Create the actual Flash object's shell - var tmpDiv = _document.createElement("div"); - // The object element plus its movie source URL both MUST be created together. - // Other attributes and child nodes can techncially be added afterward. - // Hybrid of Flash Satay markup is from Ambience: - // - Flash Satay version: http://alistapart.com/article/flashsatay - // - Ambience version: http://www.ambience.sk/flash-valid.htm - var usingActiveX = _flashState.pluginType === "activex"; - /*jshint quotmark:single */ - tmpDiv.innerHTML = - ''; - /*jshint quotmark:double */ - flashBridge = tmpDiv.firstChild; - tmpDiv = null; - - // Store a reference to the `ZeroClipboard` object as a DOM property - // on the ZeroClipboard-owned "object" element. This will help us - // easily avoid issues with AMD/CommonJS loaders that don't have - // a global `ZeroClipboard` reliably available. - _unwrap(flashBridge).ZeroClipboard = ZeroClipboard; - - // NOTE: Using `replaceChild` is very important! - // - https://github.com/swfobject/swfobject/blob/562fe358216edbb36445aa62f817c1a56252950c/swfobject/src/swfobject.js - // - http://pipwerks.com/2011/05/30/using-the-object-element-to-dynamically-embed-flash-swfs-in-internet-explorer/ - container.replaceChild(flashBridge, divToBeReplaced); - - // Watch the DOM for the fallback content to become visible, indicating a SWF load failure - _watchForSwfFallbackContent(); - } - - if (!flashBridge) { - flashBridge = _document[_globalConfig.swfObjectId]; - if (flashBridge && (len = flashBridge.length)) { - flashBridge = flashBridge[len - 1]; - } - if (!flashBridge && container) { - flashBridge = container.firstChild; - } - } - - _flashState.bridge = flashBridge || null; - - return flashBridge; -}; - - -/** - * Destroy the SWF object. - * @private - */ -var _unembedSwf = function() { - // Remove the Flash bridge - var flashBridge = _flashState.bridge; - if (flashBridge) { - var htmlBridge = _getHtmlBridge(flashBridge); - if (htmlBridge) { - // Some extra caution is necessary to prevent Flash from causing memory leaks in oldIE - // NOTE: Removing the SWF in IE may not be completed synchronously - if (_flashState.pluginType === "activex" && "readyState" in flashBridge) { - flashBridge.style.display = "none"; - (function removeSwfFromIE() { - if (flashBridge.readyState === 4) { - // This step prevents memory leaks in oldIE - for (var prop in flashBridge) { - if (typeof flashBridge[prop] === "function") { - flashBridge[prop] = null; - } - } - if (flashBridge.parentNode) { - flashBridge.parentNode.removeChild(flashBridge); - } - if (htmlBridge.parentNode) { - htmlBridge.parentNode.removeChild(htmlBridge); - } - } - else { - _setTimeout(removeSwfFromIE, 10); - } - })(); - } - else { - if (flashBridge.parentNode) { - flashBridge.parentNode.removeChild(flashBridge); - } - if (htmlBridge.parentNode) { - htmlBridge.parentNode.removeChild(htmlBridge); - } - } - } - - // Remove the availability and SWF network error checking timeout/interval, as they could - // inappropriately trigger events like "flash-deactivated" and "swf-not-found" after destroy. - _clearTimeoutsAndPolling(); - - _flashState.ready = null; - _flashState.bridge = null; - - // Reset the `deactivated` status in case the user wants to "try again", i.e. - // after receiving an `error[name="flash-overdue"]` event - _flashState.deactivated = null; - - // Don't keep track of the SWF's ZC library version number - // The use of `undefined` here instead of `null` is important - _zcSwfVersion = undefined; - } -}; - - -/** - * Map the data format names of the "clipData" to Flash-friendly names. - * - * @returns A new transformed object. - * @private - */ -var _mapClipDataToFlash = function(clipData) { - var newClipData = {}, - formatMap = {}; - if (!(typeof clipData === "object" && clipData)) { - return; - } - - for (var dataFormat in clipData) { - if (dataFormat && _hasOwn.call(clipData, dataFormat) && typeof clipData[dataFormat] === "string" && clipData[dataFormat]) { - // Standardize the allowed clipboard segment names to reduce complexity on the Flash side - switch (dataFormat.toLowerCase()) { - case "text/plain": - case "text": - case "air:text": - case "flash:text": - newClipData.text = clipData[dataFormat]; - formatMap.text = dataFormat; - break; - case "text/html": - case "html": - case "air:html": - case "flash:html": - newClipData.html = clipData[dataFormat]; - formatMap.html = dataFormat; - break; - case "application/rtf": - case "text/rtf": - case "rtf": - case "richtext": - case "air:rtf": - case "flash:rtf": - newClipData.rtf = clipData[dataFormat]; - formatMap.rtf = dataFormat; - break; - default: - // Just ignore it: the Flash clipboard cannot handle any other formats - break; - } - } - } - return { - data: newClipData, - formatMap: formatMap - }; -}; - - -/** - * Map the data format names from Flash-friendly names back to their original "clipData" names (via a format mapping). - * - * @returns A new transformed object. - * @private - */ -var _mapClipResultsFromFlash = function(clipResults, formatMap) { - if (!(typeof clipResults === "object" && clipResults && typeof formatMap === "object" && formatMap)) { - return clipResults; - } - - var newResults = {}; - - for (var prop in clipResults) { - if (_hasOwn.call(clipResults, prop)) { - if (prop === "errors") { - newResults[prop] = clipResults[prop] ? clipResults[prop].slice() : []; - for (var i = 0, len = newResults[prop].length; i < len; i++) { - newResults[prop][i].format = formatMap[newResults[prop][i].format]; - } - } - else if (prop !== "success" && prop !== "data") { - newResults[prop] = clipResults[prop]; - } - else { - newResults[prop] = {}; - - // Standardize the allowed clipboard segment names to reduce complexity on the Flash side - var tmpHash = clipResults[prop]; - for (var dataFormat in tmpHash) { - if (dataFormat && _hasOwn.call(tmpHash, dataFormat) && _hasOwn.call(formatMap, dataFormat)) { - newResults[prop][formatMap[dataFormat]] = tmpHash[dataFormat]; - } - } - } - } - } - return newResults; -}; - - -/** - * Will look at a path, and will create a "?noCache={time}" or "&noCache={time}" - * query param string to return. Does NOT append that string to the original path. - * This is useful because ExternalInterface often breaks when a Flash SWF is cached. - * - * @returns The `noCache` query param with necessary "?"/"&" prefix. - * @private - */ -var _cacheBust = function(path, options) { - var cacheBust = options == null || (options && options.cacheBust === true); - if (cacheBust) { - return (path.indexOf("?") === -1 ? "?" : "&") + "noCache=" + _now(); - } - else { - return ""; - } -}; - - -/** - * Creates a query string for the FlashVars param. - * Does NOT include the cache-busting query param. - * - * @returns FlashVars query string - * @private - */ -var _vars = function(options) { - var i, len, domain, domains, - str = "", - trustedOriginsExpanded = []; - - if (options.trustedDomains) { - if (typeof options.trustedDomains === "string") { - domains = [options.trustedDomains]; - } - else if (typeof options.trustedDomains === "object" && "length" in options.trustedDomains) { - domains = options.trustedDomains; - } - } - if (domains && domains.length) { - for (i = 0, len = domains.length; i < len; i++) { - if (_hasOwn.call(domains, i) && domains[i] && typeof domains[i] === "string") { - domain = _extractDomain(domains[i]); - - if (!domain) { - continue; - } - - // If we encounter a wildcard, ignore everything else as they are irrelevant - if (domain === "*") { - trustedOriginsExpanded.length = 0; - trustedOriginsExpanded.push(domain); - break; - } - - // Add the domain, relative protocol + domain, and absolute protocol + domain ("origin") - // because Flash Player seems to handle these inconsistently (perhaps in different versions) - trustedOriginsExpanded.push.apply( - trustedOriginsExpanded, - [ - domain, - "//" + domain, - _window.location.protocol + "//" + domain - ] - ); - } - } - } - - if (trustedOriginsExpanded.length) { - str += "trustedOrigins=" + _encodeURIComponent(trustedOriginsExpanded.join(",")); - } - - if (options.forceEnhancedClipboard === true) { - str += (str ? "&" : "") + "forceEnhancedClipboard=true"; - } - - if (typeof options.swfObjectId === "string" && options.swfObjectId) { - str += (str ? "&" : "") + "swfObjectId=" + _encodeURIComponent(options.swfObjectId); - } - - if (typeof options.jsVersion === "string" && options.jsVersion) { - str += (str ? "&" : "") + "jsVersion=" + _encodeURIComponent(options.jsVersion); - } - - return str; -}; - - -/** - * Extract the domain (e.g. "github.com") from an origin (e.g. "https://github.com") or - * URL (e.g. "https://github.com/zeroclipboard/zeroclipboard/"). - * - * @returns the domain - * @private - */ -var _extractDomain = function(originOrUrl) { - if (originOrUrl == null || originOrUrl === "") { - return null; - } - - // Trim - originOrUrl = originOrUrl.replace(/^\s+|\s+$/g, ""); - if (originOrUrl === "") { - return null; - } - - // Strip the protocol, if any was provided - var protocolIndex = originOrUrl.indexOf("//"); - originOrUrl = protocolIndex === -1 ? originOrUrl : originOrUrl.slice(protocolIndex + 2); - - // Strip the path, if any was provided - var pathIndex = originOrUrl.indexOf("/"); - originOrUrl = pathIndex === -1 ? originOrUrl : protocolIndex === -1 || pathIndex === 0 ? null : originOrUrl.slice(0, pathIndex); - - if (originOrUrl && originOrUrl.slice(-4).toLowerCase() === ".swf") { - return null; - } - return originOrUrl || null; -}; - - -/** - * Set `allowScriptAccess` based on `trustedDomains` and `window.location.host` vs. `swfPath`. - * - * @returns The appropriate script access level. - * @private - */ -var _determineScriptAccess = (function() { - var _extractAllDomains = function(origins) { - var i, len, tmp, - resultsArray = []; - if (typeof origins === "string") { - origins = [origins]; - } - if (!(typeof origins === "object" && origins && typeof origins.length === "number")) { - return resultsArray; - } - for (i = 0, len = origins.length; i < len; i++) { - if (_hasOwn.call(origins, i) && (tmp = _extractDomain(origins[i]))) { - if (tmp === "*") { - resultsArray.length = 0; - resultsArray.push("*"); - break; - } - if (resultsArray.indexOf(tmp) === -1) { - resultsArray.push(tmp); - } - } - } - return resultsArray; - }; - - return function(currentDomain, configOptions) { - // Get SWF domain - var swfDomain = _extractDomain(configOptions.swfPath); - if (swfDomain === null) { - swfDomain = currentDomain; - } - // Get all trusted domains - var trustedDomains = _extractAllDomains(configOptions.trustedDomains); - - var len = trustedDomains.length; - if (len > 0) { - if (len === 1 && trustedDomains[0] === "*") { - return "always"; - } - if (trustedDomains.indexOf(currentDomain) !== -1) { - if (len === 1 && currentDomain === swfDomain) { - return "sameDomain"; - } - return "always"; - } - } - return "never"; - }; -})(); - - -/** - * Get the currently active/focused DOM element. - * - * @returns the currently active/focused element, or `null` - * @private - */ -var _safeActiveElement = function() { - try { - return _document.activeElement; - } - catch (err) { - return null; - } -}; - - -/** - * Add a class to an element, if it doesn't already have it. - * - * @returns The element, with its new class added. - * @private - */ -var _addClass = function(element, value) { - var c, cl, className, - classNames = []; - - if (typeof value === "string" && value) { - classNames = value.split(/\s+/); - } - - if (element && element.nodeType === 1 && classNames.length > 0) { - // If the element has `classList` - if (element.classList) { - // IE11 cannot add a list of classNames anyway, so just iterate - for (c = 0, cl = classNames.length; c < cl; c++) { - // Supposedly do NOT need to check if the class is not contained first - element.classList.add(classNames[c]); - } - } - else if (element.hasOwnProperty("className")) { - className = " " + element.className + " "; - for (c = 0, cl = classNames.length; c < cl; c++) { - if (className.indexOf(" " + classNames[c] + " ") === -1) { - className += classNames[c] + " "; - } - } - // trim - element.className = className.replace(/^\s+|\s+$/g, ""); - } - } - - return element; -}; - - -/** - * Remove a class from an element, if it has it. - * - * @returns The element, with its class removed. - * @private - */ -var _removeClass = function(element, value) { - var c, cl, className, - classNames = []; - - if (typeof value === "string" && value) { - classNames = value.split(/\s+/); - } - - if (element && element.nodeType === 1 && classNames.length > 0) { - // If the element has `classList` - if (element.classList && element.classList.length > 0) { - for (c = 0, cl = classNames.length; c < cl; c++) { - // Supposedly do NOT need to check if the class is contained first - element.classList.remove(classNames[c]); - } - } - // Checking the actual `className` property vs. its `hasOwnProperty` - // existence is OK here since we need it to have content in order to - // have any removable classes - else if (element.className) { - className = (" " + element.className + " ").replace(/[\r\n\t]/g, " "); - for (c = 0, cl = classNames.length; c < cl; c++) { - className = className.replace(" " + classNames[c] + " ", " "); - } - // trim - element.className = className.replace(/^\s+|\s+$/g, ""); - } - } - - return element; -}; - - -/** - * Attempt to interpret the element's CSS styling. If `prop` is `"cursor"`, - * then we assume that it should be a hand ("pointer") cursor if the element - * is an anchor element ("a" tag). - * - * @returns The computed style property. - * @private - */ -var _getStyle = function(el, prop) { - var value = _getComputedStyle(el, null).getPropertyValue(prop); - if (prop === "cursor") { - if (!value || value === "auto") { - if (el.nodeName === "A") { - return "pointer"; - } - } - } - - return value; -}; - - -/** - * Get the absolutely positioned coordinates of a DOM element. - * - * @returns Object containing the element's position, width, and height. - * @private - */ -var _getElementPosition = function(el) { - var pos = { - left: 0, - top: 0, - width: 0, - height: 0 - }; - - // Use getBoundingClientRect where available (almost everywhere). - // See: http://www.quirksmode.org/dom/w3c_cssom.html - if (el.getBoundingClientRect) { - // Compute left / top offset (works for `position:fixed`, too!) - var elRect = el.getBoundingClientRect(); - - // Get the document's scroll offsets - var pageXOffset = _window.pageXOffset; - var pageYOffset = _window.pageYOffset; - - // `clientLeft`/`clientTop` are to fix IE's 2px offset in standards mode - var leftBorderWidth = _document.documentElement.clientLeft || 0; - var topBorderWidth = _document.documentElement.clientTop || 0; - - // Compensate for the `body` offset relative to the `html` root - // This is critical for when the `body` element's CSS includes `position:relative` - var leftBodyOffset = 0; - var topBodyOffset = 0; - if (_getStyle(_document.body, "position") === "relative") { - var bodyRect = _document.body.getBoundingClientRect(); - var htmlRect = _document.documentElement.getBoundingClientRect(); - leftBodyOffset = (bodyRect.left - htmlRect.left) || 0; - topBodyOffset = (bodyRect.top - htmlRect.top) || 0; - } - - pos.left = elRect.left + pageXOffset - leftBorderWidth - leftBodyOffset; - pos.top = elRect.top + pageYOffset - topBorderWidth - topBodyOffset; - pos.width = "width" in elRect ? elRect.width : elRect.right - elRect.left; - pos.height = "height" in elRect ? elRect.height : elRect.bottom - elRect.top; - } - - return pos; -}; - - -/** - * Determine is an element is visible somewhere within the document (page). - * - * @returns Boolean - * @private - */ -var _isElementVisible = function(el) { - if (!el) { - return false; - } - - var styles = _getComputedStyle(el, null); - var hasCssHeight = _parseFloat(styles.height) > 0; - var hasCssWidth = _parseFloat(styles.width) > 0; - var hasCssTop = _parseFloat(styles.top) >= 0; - var hasCssLeft = _parseFloat(styles.left) >= 0; - var cssKnows = hasCssHeight && hasCssWidth && hasCssTop && hasCssLeft; - var rect = cssKnows ? null : _getElementPosition(el); - - var isVisible = ( - styles.display !== "none" && - styles.visibility !== "collapse" && - ( - cssKnows || - ( - !!rect && - (hasCssHeight || rect.height > 0) && - (hasCssWidth || rect.width > 0) && - (hasCssTop || rect.top >= 0) && - (hasCssLeft || rect.left >= 0) - ) - ) - ); - return isVisible; -}; - - -/** - * Clear all existing timeouts and interval polling delegates. - * - * @returns `undefined` - * @private - */ -var _clearTimeoutsAndPolling = function() { - // Remove the availability checking timeout - _clearTimeout(_flashCheckTimeout); - _flashCheckTimeout = 0; - - // Remove the SWF network error polling - _clearInterval(_swfFallbackCheckInterval); - _swfFallbackCheckInterval = 0; -}; - - -/** - * Reposition the Flash object to cover the currently activated element. - * - * @returns `undefined` - * @private - */ -var _reposition = function() { - var htmlBridge; - // If there is no `_currentElement`, skip it - if (_currentElement && (htmlBridge = _getHtmlBridge(_flashState.bridge))) { - var pos = _getElementPosition(_currentElement); - _extend(htmlBridge.style, { - width: pos.width + "px", - height: pos.height + "px", - top: pos.top + "px", - left: pos.left + "px", - zIndex: "" + _getSafeZIndex(_globalConfig.zIndex) - }); - } -}; - - -/** - * Sends a signal to the Flash object to display the hand cursor if `true`. - * - * @returns `undefined` - * @private - */ -var _setHandCursor = function(enabled) { - if (_flashState.ready === true) { - if (_flashState.bridge && typeof _flashState.bridge.setHandCursor === "function") { - _flashState.bridge.setHandCursor(enabled); - } - else { - _flashState.ready = false; - } - } -}; - - -/** - * Get a safe value for `zIndex` - * - * @returns an integer, or "auto" - * @private - */ -var _getSafeZIndex = function(val) { - if (/^(?:auto|inherit)$/.test(val)) { - return val; - } - - var zIndex; - if (typeof val === "number" && !_isNaN(val)) { - zIndex = val; - } - else if (typeof val === "string") { - zIndex = _getSafeZIndex(_parseInt(val, 10)); - } - return typeof zIndex === "number" ? zIndex : "auto"; -}; - - -/** - * Attempt to detect if ZeroClipboard is executing inside of a sandboxed iframe. - * If it is, Flash Player cannot be used, so ZeroClipboard is dead in the water. - * - * @see {@link http://lists.w3.org/Archives/Public/public-whatwg-archive/2014Dec/0002.html} - * @see {@link https://github.com/zeroclipboard/zeroclipboard/issues/511} - * @see {@link http://zeroclipboard.org/test-iframes.html} - * - * @returns `true` (is sandboxed), `false` (is not sandboxed), or `null` (uncertain) - * @private - */ -var _detectSandbox = function(doNotReassessFlashSupport) { - var effectiveScriptOrigin, frame, frameError, - previousState = _flashState.sandboxed, - isSandboxed = null; - - doNotReassessFlashSupport = doNotReassessFlashSupport === true; - - // If the page is not framed, bail out immediately - if (_pageIsFramed === false) { - isSandboxed = false; - } - else { - try { - frame = window.frameElement || null; - } - catch (e) { - frameError = { name: e.name, message: e.message }; - } - - if (frame && frame.nodeType === 1 && frame.nodeName === "IFRAME") { - try { - isSandboxed = frame.hasAttribute("sandbox"); - } - catch (e) { - isSandboxed = null; - } - } - else { - try { - effectiveScriptOrigin = document.domain || null; - } - catch (e) { - effectiveScriptOrigin = null; - } - - if ( - effectiveScriptOrigin === null || - ( - frameError && - frameError.name === "SecurityError" && - /(^|[\s\(\[@])sandbox(es|ed|ing|[\s\.,!\)\]@]|$)/.test(frameError.message.toLowerCase()) - ) - ) { - isSandboxed = true; - } - } - } - - // `true` == ZeroClipboard definitely will NOT work - // `false` == ZeroClipboard should work if all Flash configurations are right - // `null` == ZeroClipboard may or may not work, so assume it can and attempt - _flashState.sandboxed = isSandboxed; - - // If the state of sandboxing has changed, also re-detect Flash support - if (previousState !== isSandboxed && !doNotReassessFlashSupport) { - _detectFlashSupport(_ActiveXObject); - } - - return isSandboxed; -}; - - -/** - * Detect the Flash Player status, version, and plugin type. - * - * @see {@link https://code.google.com/p/doctype-mirror/wiki/ArticleDetectFlash#The_code} - * @see {@link http://stackoverflow.com/questions/12866060/detecting-pepper-ppapi-flash-with-javascript} - * - * @returns `undefined` - * @private - */ -var _detectFlashSupport = function(ActiveXObject) { - var plugin, ax, mimeType, - hasFlash = false, - isActiveX = false, - isPPAPI = false, - flashVersion = ""; - - /** - * Derived from Apple's suggested sniffer. - * @param {String} desc e.g. "Shockwave Flash 7.0 r61" - * @returns {String} "7.0.61" - * @private - */ - function parseFlashVersion(desc) { - var matches = desc.match(/[\d]+/g); - matches.length = 3; // To standardize IE vs FF - return matches.join("."); - } - - function isPepperFlash(flashPlayerFileName) { - return !!flashPlayerFileName && - (flashPlayerFileName = flashPlayerFileName.toLowerCase()) && - ( - /^(pepflashplayer\.dll|libpepflashplayer\.so|pepperflashplayer\.plugin)$/.test(flashPlayerFileName) || - flashPlayerFileName.slice(-13) === "chrome.plugin" - ); - } - - function inspectPlugin(plugin) { - if (plugin) { - hasFlash = true; - if (plugin.version) { - flashVersion = parseFlashVersion(plugin.version); - } - if (!flashVersion && plugin.description) { - flashVersion = parseFlashVersion(plugin.description); - } - if (plugin.filename) { - isPPAPI = isPepperFlash(plugin.filename); - } - } - } - - if (_navigator.plugins && _navigator.plugins.length) { - plugin = _navigator.plugins["Shockwave Flash"]; - inspectPlugin(plugin); - - if (_navigator.plugins["Shockwave Flash 2.0"]) { - hasFlash = true; - flashVersion = "2.0.0.11"; - } - } - else if (_navigator.mimeTypes && _navigator.mimeTypes.length) { - mimeType = _navigator.mimeTypes["application/x-shockwave-flash"]; - plugin = mimeType && mimeType.enabledPlugin; - inspectPlugin(plugin); - } - else if (typeof ActiveXObject !== "undefined") { - // - // Using IE < 11 - // - isActiveX = true; - - try { - // Try 7 first, since we know we can use GetVariable with it - ax = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7"); - hasFlash = true; - flashVersion = parseFlashVersion(ax.GetVariable("$version")); - } - catch (e1) { - // Try 6 next, some versions are known to crash with GetVariable calls - try { - ax = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6"); - hasFlash = true; - flashVersion = "6.0.21"; // First public version of Flash 6 - } - catch (e2) { - try { - // Try the default ActiveX - ax = new ActiveXObject("ShockwaveFlash.ShockwaveFlash"); - hasFlash = true; - flashVersion = parseFlashVersion(ax.GetVariable("$version")); - } - catch (e3) { - // No flash - isActiveX = false; - } - } - } - } - - _flashState.disabled = hasFlash !== true; - _flashState.outdated = flashVersion && (_parseFloat(flashVersion) < _parseFloat(_minimumFlashVersion)); - _flashState.version = flashVersion || "0.0.0"; - _flashState.pluginType = isPPAPI ? "pepper" : (isActiveX ? "activex" : (hasFlash ? "netscape" : "unknown")); -}; - - -/** - * Invoke the Flash detection algorithms immediately upon inclusion so we're not waiting later. - */ -_detectFlashSupport(_ActiveXObject); -/** - * Always assess the `sandboxed` state of the page at important Flash-related moments. - */ -_detectSandbox(true); diff --git a/web/public/libs/zeroclipboard/src/js/core/state.js b/web/public/libs/zeroclipboard/src/js/core/state.js deleted file mode 100755 index 81456ea..0000000 --- a/web/public/libs/zeroclipboard/src/js/core/state.js +++ /dev/null @@ -1,256 +0,0 @@ -/** - * Keep track of if the page is framed (in an `iframe`). This can never change. - * @private - */ -var _pageIsFramed = (function() { - /*jshint eqeqeq:false */ - // Cannot use ===/!== for comparing WindowProxy objects - return ( - window.opener == null && - ( - (!!window.top && window != window.top) || - (!!window.parent && window != window.parent) - ) - ); -})(); - - -/** - * Keep track of the state of the Flash object. - * @private - */ -var _flashState = { - // Flash object reference - bridge: null, - - // Flash metadata - version: "0.0.0", - pluginType: "unknown", - - // Flash SWF state - disabled: null, - outdated: null, - sandboxed: null, - unavailable: null, - degraded: null, - deactivated: null, - overdue: null, - ready: null -}; - - -/** - * The minimum Flash Player version required to use ZeroClipboard completely. - * @readonly - * @private - */ -var _minimumFlashVersion = "11.0.0"; - - -/** - * The ZeroClipboard library version number, as reported by Flash, at the time the SWF was compiled. - */ -var _zcSwfVersion; - - -/** - * Keep track of all event listener registrations. - * @private - */ -var _handlers = {}; - - -/** - * Keep track of the currently activated element. - * @private - */ -var _currentElement; - - -/** - * Keep track of the element that was activated when a `copy` process started. - * @private - */ -var _copyTarget; - - -/** - * Keep track of data for the pending clipboard transaction. - * @private - */ -var _clipData = {}; - - -/** - * Keep track of data formats for the pending clipboard transaction. - * @private - */ -var _clipDataFormatMap = null; - -/** - * Keep track of the Flash availability check timeout. - * @private - */ -var _flashCheckTimeout = 0; - - -/** - * Keep track of SWF network errors interval polling. - * @private - */ -var _swfFallbackCheckInterval = 0; - - -/** - * The `message` store for events - * @private - */ -var _eventMessages = { - "ready": "Flash communication is established", - "error": { - "flash-disabled": "Flash is disabled or not installed. May also be attempting to run Flash in a sandboxed iframe, which is impossible.", - "flash-outdated": "Flash is too outdated to support ZeroClipboard", - "flash-sandboxed": "Attempting to run Flash in a sandboxed iframe, which is impossible", - "flash-unavailable": "Flash is unable to communicate bidirectionally with JavaScript", - "flash-degraded": "Flash is unable to preserve data fidelity when communicating with JavaScript", - "flash-deactivated": "Flash is too outdated for your browser and/or is configured as click-to-activate.\nThis may also mean that the ZeroClipboard SWF object could not be loaded, so please check your `swfPath` configuration and/or network connectivity.\nMay also be attempting to run Flash in a sandboxed iframe, which is impossible.", - "flash-overdue": "Flash communication was established but NOT within the acceptable time limit", - "version-mismatch": "ZeroClipboard JS version number does not match ZeroClipboard SWF version number", - "clipboard-error": "At least one error was thrown while ZeroClipboard was attempting to inject your data into the clipboard", - "config-mismatch": "ZeroClipboard configuration does not match Flash's reality", - "swf-not-found": "The ZeroClipboard SWF object could not be loaded, so please check your `swfPath` configuration and/or network connectivity" - } -}; - - -/** - * The `name`s of `error` events that can only occur is Flash has at least - * been able to load the SWF successfully. - * @private - */ -var _errorsThatOnlyOccurAfterFlashLoads = [ - "flash-unavailable", - "flash-degraded", - "flash-overdue", - "version-mismatch", - "config-mismatch", - "clipboard-error" -]; - - -/** - * The `name`s of `error` events that should likely result in the `_flashState` - * variable's property values being updated. - * @private - */ -var _flashStateErrorNames = [ - "flash-disabled", - "flash-outdated", - "flash-sandboxed", - "flash-unavailable", - "flash-degraded", - "flash-deactivated", - "flash-overdue" -]; - - -/** - * A RegExp to match the `name` property of `error` events related to Flash. - * @private - */ -var _flashStateErrorNameMatchingRegex = - new RegExp( - "^flash-(" + - _flashStateErrorNames - .map(function(errorName) { - return errorName.replace(/^flash-/, ""); - }) - .join("|") + - ")$" - ); - - -/** - * A RegExp to match the `name` property of `error` events related to Flash, - * which is enabled. - * @private - */ -var _flashStateEnabledErrorNameMatchingRegex = - new RegExp( - "^flash-(" + - _flashStateErrorNames - .slice(1) - .map(function(errorName) { - return errorName.replace(/^flash-/, ""); - }) - .join("|") + - ")$" - ); - - -/** - * ZeroClipboard configuration defaults for the Core module. - * @private - */ -var _globalConfig = { - - // SWF URL, relative to the page. Default value will be "ZeroClipboard.swf" - // under the same path as the ZeroClipboard JS file. - swfPath: _getDefaultSwfPath(), - - // SWF inbound scripting policy: page domains that the SWF should trust. - // (single string, or array of strings) - trustedDomains: window.location.host ? [window.location.host] : [], - - // Include a "noCache" query parameter on requests for the SWF. - cacheBust: true, - - // Enable use of the fancy "Desktop" clipboard, even on Linux where it is - // known to suck. - forceEnhancedClipboard: false, - - // How many milliseconds to wait for the Flash SWF to load and respond before assuming that - // Flash is deactivated (e.g. click-to-play) in the user's browser. If you don't care about - // how long it takes to load the SWF, you can set this to `null`. - flashLoadTimeout: 30000, - - // Setting this to `false` would allow users to handle calling `ZeroClipboard.focus(...);` - // themselves instead of relying on our per-element `mouseover` handler. - autoActivate: true, - - // Bubble synthetic events in JavaScript after they are received by the Flash object. - bubbleEvents: true, - - // Sets the ID of the `div` encapsulating the Flash object. - // Value is validated against the HTML4 spec for `ID` tokens. - containerId: "global-zeroclipboard-html-bridge", - - // Sets the class of the `div` encapsulating the Flash object. - containerClass: "global-zeroclipboard-container", - - // Sets the ID and name of the Flash `object` element. - // Value is validated against the HTML4 spec for `ID` and `Name` tokens. - swfObjectId: "global-zeroclipboard-flash-bridge", - - // The class used to indicate that a clipped element is being hovered over. - hoverClass: "zeroclipboard-is-hover", - - // The class used to indicate that a clipped element is active (is being clicked). - activeClass: "zeroclipboard-is-active", - - - - // Forcibly set the hand cursor ("pointer") for all clipped elements. - // IMPORTANT: This configuration value CAN be modified while a SWF is actively embedded. - forceHandCursor: false, - - // Sets the title of the `div` encapsulating the Flash object. - // IMPORTANT: This configuration value CAN be modified while a SWF is actively embedded. - title: null, - - // The z-index used by the Flash object. - // Max value (32-bit): 2147483647. - // IMPORTANT: This configuration value CAN be modified while a SWF is actively embedded. - zIndex: 999999999 - -}; diff --git a/web/public/libs/zeroclipboard/src/js/end.js b/web/public/libs/zeroclipboard/src/js/end.js deleted file mode 100755 index 9ff87ef..0000000 --- a/web/public/libs/zeroclipboard/src/js/end.js +++ /dev/null @@ -1,21 +0,0 @@ - - -// The AMDJS logic branch is evaluated first to avoid potential confusion over -// the CommonJS syntactical sugar offered by AMD. -if (typeof define === "function" && define.amd) { - define(function() { - return ZeroClipboard; - }); -} -else if (typeof module === "object" && module && typeof module.exports === "object" && module.exports) { - // CommonJS module loaders.... - module.exports = ZeroClipboard; -} -else { - window.ZeroClipboard = ZeroClipboard; -} - -})((function() { - /*jshint strict: false */ - return this || window; -})()); diff --git a/web/public/libs/zeroclipboard/src/js/shared/private.js b/web/public/libs/zeroclipboard/src/js/shared/private.js deleted file mode 100755 index 79a2af3..0000000 --- a/web/public/libs/zeroclipboard/src/js/shared/private.js +++ /dev/null @@ -1,317 +0,0 @@ -/** - * Convert an `arguments` object into an Array. - * - * @returns The arguments as an Array - * @private - */ -var _args = function(argumentsObj) { - return _slice.call(argumentsObj, 0); -}; - - -/** - * Shallow-copy the owned, enumerable properties of one object over to another, similar to jQuery's `$.extend`. - * - * @returns The target object, augmented - * @private - */ -var _extend = function() { - var i, len, arg, prop, src, copy, - args = _args(arguments), - target = args[0] || {}; - - for (i = 1, len = args.length; i < len; i++) { - // Only deal with non-null/undefined values - if ((arg = args[i]) != null) { - // Extend the base object - for (prop in arg) { - if (_hasOwn.call(arg, prop)) { - src = target[prop]; - copy = arg[prop]; - - // Prevent never-ending loops and copying `undefined` valeus - if (target !== copy && copy !== undefined) { - target[prop] = copy; - } - } - } - } - } - return target; -}; - - -/** - * Return a deep copy of the source object or array. - * - * @returns Object or Array - * @private - */ -var _deepCopy = function(source) { - var copy, i, len, prop; - - // If not a non-null, non-element object, just return the original - if (typeof source !== "object" || source == null || typeof source.nodeType === "number") { - copy = source; - } - // If an Array, iterate and recurse - else if (typeof source.length === "number") { - copy = []; - for (i = 0, len = source.length; i < len; i++) { - // Skip empty indices in sparse arrays - if (_hasOwn.call(source, i)) { - // Recurse - copy[i] = _deepCopy(source[i]); - } - } - } - // If an Object, enumerate and recurse - else { - copy = {}; - for (prop in source) { - // Skip prototype properties - if (_hasOwn.call(source, prop)) { - copy[prop] = _deepCopy(source[prop]); - } - } - } - - return copy; -}; - - -/** - * Makes a shallow copy of `obj` (like `_extend`) but filters its properties based on a list of `keys` to keep. - * The inverse of `_omit`, mostly. The big difference is that these properties do NOT need to be enumerable to - * be kept. - * - * @returns A new filtered object. - * @private - */ -var _pick = function(obj, keys) { - var newObj = {}; - for (var i = 0, len = keys.length; i < len; i++) { - if (keys[i] in obj) { - newObj[keys[i]] = obj[keys[i]]; - } - } - return newObj; -}; - - -/** - * Makes a shallow copy of `obj` (like `_extend`) but filters its properties based on a list of `keys` to omit. - * The inverse of `_pick`. - * - * @returns A new filtered object. - * @private - */ -var _omit = function(obj, keys) { - var newObj = {}; - for (var prop in obj) { - if (keys.indexOf(prop) === -1) { - newObj[prop] = obj[prop]; - } - } - return newObj; -}; - - -/** - * Remove all owned, enumerable properties from an object. - * - * @returns The original object without its owned, enumerable properties. - * @private - */ -var _deleteOwnProperties = function(obj) { - if (obj) { - for (var prop in obj) { - if (_hasOwn.call(obj, prop)) { - delete obj[prop]; - } - } - } - return obj; -}; - - -/** - * Determine if an element is contained within another element. - * - * @returns Boolean - * @private - */ -var _containedBy = function(el, ancestorEl) { - if ( - el && el.nodeType === 1 && el.ownerDocument && - ancestorEl && ( - (ancestorEl.nodeType === 1 && ancestorEl.ownerDocument && ancestorEl.ownerDocument === el.ownerDocument) || - (ancestorEl.nodeType === 9 && !ancestorEl.ownerDocument && ancestorEl === el.ownerDocument) - ) - ) { - do { - if (el === ancestorEl) { - return true; - } - el = el.parentNode; - } - while (el); - } - - return false; -}; - - -/** - * Get the URL path's parent directory. - * - * @returns String or `undefined` - * @private - */ -var _getDirPathOfUrl = function(url) { - var dir; - if (typeof url === "string" && url) { - dir = url.split("#")[0].split("?")[0]; - dir = url.slice(0, url.lastIndexOf("/") + 1); - } - return dir; -}; - - -/** - * Get the current script's URL by throwing an `Error` and analyzing it. - * - * @returns String or `undefined` - * @private - */ -var _getCurrentScriptUrlFromErrorStack = function(stack) { - var url, matches; - if (typeof stack === "string" && stack) { - matches = stack.match(/^(?:|[^:@]*@|.+\)@(?=http[s]?|file)|.+?\s+(?: at |@)(?:[^:\(]+ )*[\(]?)((?:http[s]?|file):\/\/[\/]?.+?\/[^:\)]*?)(?::\d+)(?::\d+)?/); - if (matches && matches[1]) { - url = matches[1]; - } - else { - matches = stack.match(/\)@((?:http[s]?|file):\/\/[\/]?.+?\/[^:\)]*?)(?::\d+)(?::\d+)?/); - if (matches && matches[1]) { - url = matches[1]; - } - } - } - return url; -}; - - -/** - * Get the current script's URL by throwing an `Error` and analyzing it. - * - * @returns String or `undefined` - * @private - */ -var _getCurrentScriptUrlFromError = function() { - /*jshint newcap:false */ - var url, err; - try { - throw new _Error(); - } - catch (e) { - err = e; - } - - if (err) { - url = err.sourceURL || err.fileName || _getCurrentScriptUrlFromErrorStack(err.stack); - } - return url; -}; - - -/** - * Get the current script's URL. - * - * @returns String or `undefined` - * @private - */ -var _getCurrentScriptUrl = function() { - var jsPath, scripts, i; - - // Try to leverage the `currentScript` feature - if (_document.currentScript && (jsPath = _document.currentScript.src)) { - return jsPath; - } - - // If it it not available, then seek the script out instead... - scripts = _document.getElementsByTagName("script"); - - // If there is only one script - if (scripts.length === 1) { - return scripts[0].src || undefined; - } - - // If `script` elements have the `readyState` property in this browser - if ("readyState" in scripts[0]) { - for (i = scripts.length; i--; ) { - if (scripts[i].readyState === "interactive" && (jsPath = scripts[i].src)) { - return jsPath; - } - } - } - - // If the document is still parsing, then the last script in the document is the one that is currently loading - if (_document.readyState === "loading" && (jsPath = scripts[scripts.length - 1].src)) { - return jsPath; - } - - // Else take more drastic measures... - if ((jsPath = _getCurrentScriptUrlFromError())) { - return jsPath; - } - - // Otherwise we cannot reliably know which exact script is executing.... - return undefined; -}; - - -/** - * Get the unanimous parent directory of ALL script tags. - * If any script tags are either (a) inline or (b) from differing parent - * directories, this method must return `undefined`. - * - * @returns String or `undefined` - * @private - */ -var _getUnanimousScriptParentDir = function() { - var i, jsDir, jsPath, - scripts = _document.getElementsByTagName("script"); - - // If every `script` has a `src` attribute AND they all come from the same directory - for (i = scripts.length; i--; ) { - if (!(jsPath = scripts[i].src)) { - jsDir = null; - break; - } - jsPath = _getDirPathOfUrl(jsPath); - if (jsDir == null) { - jsDir = jsPath; - } - else if (jsDir !== jsPath) { - jsDir = null; - break; - } - } - - // Otherwise we cannot reliably know what script is executing.... - return jsDir || undefined; -}; - - -/** - * Get the presumed location of the "ZeroClipboard.swf" file, based on the location - * of the executing JavaScript file (e.g. "ZeroClipboard.js", etc.). - * - * @returns String - * @private - */ -var _getDefaultSwfPath = function() { - var jsDir = _getDirPathOfUrl(_getCurrentScriptUrl()) || _getUnanimousScriptParentDir() || ""; - return jsDir + "ZeroClipboard.swf"; -}; diff --git a/web/public/libs/zeroclipboard/src/js/shared/state.js b/web/public/libs/zeroclipboard/src/js/shared/state.js deleted file mode 100755 index 6ac4be0..0000000 --- a/web/public/libs/zeroclipboard/src/js/shared/state.js +++ /dev/null @@ -1,44 +0,0 @@ -/*jshint -W079 */ - -/** - * Store references to critically important global functions that may be - * overridden on certain web pages. - */ -var _window = window, - _document = _window.document, - _navigator = _window.navigator, - _setTimeout = _window.setTimeout, - _clearTimeout = _window.clearTimeout, - _setInterval = _window.setInterval, - _clearInterval = _window.clearInterval, - _getComputedStyle = _window.getComputedStyle, - _encodeURIComponent = _window.encodeURIComponent, - _ActiveXObject = _window.ActiveXObject, - _Error = _window.Error, - _parseInt = _window.Number.parseInt || _window.parseInt, - _parseFloat = _window.Number.parseFloat || _window.parseFloat, - _isNaN = _window.Number.isNaN || _window.isNaN, - _now = _window.Date.now, - _keys = _window.Object.keys, - _defineProperty = _window.Object.defineProperty, - _hasOwn = _window.Object.prototype.hasOwnProperty, - _slice = _window.Array.prototype.slice, - _unwrap = (function() { - var unwrapper = function(el) { - return el; - }; - // For Polymer - if (typeof _window.wrap === "function" && typeof _window.unwrap === "function") { - try { - var div = _document.createElement("div"); - var unwrappedDiv = _window.unwrap(div); - if (div.nodeType === 1 && unwrappedDiv && unwrappedDiv.nodeType === 1) { - unwrapper = _window.unwrap; - } - } - catch (e) { - // Some unreliable `window.unwrap` function is exposed - } - } - return unwrapper; - })(); diff --git a/web/public/libs/zeroclipboard/src/js/start.js b/web/public/libs/zeroclipboard/src/js/start.js deleted file mode 100755 index 802443d..0000000 --- a/web/public/libs/zeroclipboard/src/js/start.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(window, undefined) { - "use strict"; diff --git a/web/public/libs/zeroclipboard/src/meta/LICENSE.tmpl b/web/public/libs/zeroclipboard/src/meta/LICENSE.tmpl deleted file mode 100755 index c7f5f77..0000000 --- a/web/public/libs/zeroclipboard/src/meta/LICENSE.tmpl +++ /dev/null @@ -1,8 +0,0 @@ -The MIT License (MIT) -Copyright (c) 2009-<%= grunt.template.today("yyyy") %> <%= _.pluck(contributors, "name").join(", ") %> - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/web/public/libs/zeroclipboard/src/meta/bower.json.tmpl b/web/public/libs/zeroclipboard/src/meta/bower.json.tmpl deleted file mode 100755 index c4aadfd..0000000 --- a/web/public/libs/zeroclipboard/src/meta/bower.json.tmpl +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "<%= name %>", - "description": "<%= description %>", - "version": "<%= version %>", - "main": ["<%= main %>", "<%= main.replace(/\.js$/, ".swf") %>"], - "keywords": <%= JSON.stringify(keywords) %>, - "license": "<%= licenses[0].url %>", - "authors": <%= JSON.stringify(contributors) %>, - "homepage": "<%= homepage %>", - "repository": <%= JSON.stringify(repository) %>, - "location": "<%= repository.url.replace(/^https:\/\//, "git://") %>", - "ignore": [ - "*", - "/dist/.jshintrc", - "!/bower.json", - "!/dist/**" - ] -} \ No newline at end of file diff --git a/web/public/libs/zeroclipboard/src/meta/component.json.tmpl b/web/public/libs/zeroclipboard/src/meta/component.json.tmpl deleted file mode 100755 index 13defbe..0000000 --- a/web/public/libs/zeroclipboard/src/meta/component.json.tmpl +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "<%= name %>", - "repository": "<%= repository.url.replace(/^https:\/\/github.com\//, "").replace(/\.git$/, "") %>", - "description": "<%= description %>", - "version": "<%= version %>", - "keywords": <%= JSON.stringify(keywords) %>, - "main": ["<%= main %>"], - "scripts": ["<%= main %>"], - "files": ["<%= main.replace(/\.js$/, ".swf") %>"], - "license": "<%= licenses[0].type %>", - "authors": <%= JSON.stringify(contributors) %> -} \ No newline at end of file diff --git a/web/public/libs/zeroclipboard/src/meta/composer.json.tmpl b/web/public/libs/zeroclipboard/src/meta/composer.json.tmpl deleted file mode 100755 index 884d1ea..0000000 --- a/web/public/libs/zeroclipboard/src/meta/composer.json.tmpl +++ /dev/null @@ -1,47 +0,0 @@ -{ - "name": "<%= name %>/<%= name %>", - "description": "<%= description %>", - "type": "component", - "keywords": <%= JSON.stringify(keywords) %>, - "license": "<%= licenses[0].type %>", - "authors": <%= JSON.stringify(_.filter(_.map(contributors, function(c) { - var a; - /* Does not currently support the NPM package.json string format (as opposed to object format) for "people" types */ - if (c && typeof c === "object") { - /* The `name` property is required */ - if (c.name) { - a = {}; - a.name = c.name; - - if (c.email) { - a.email = c.email; - } - if (c.url) { - a.homepage = c.url; - } - a.role = c.role || "Developer"; - } - } - return a; - }), function(a) { return !!a; })) %>, - "homepage": "<%= homepage %>", - "support": { - "source": "<%= repository.url %>", - "issues": "<%= bugs.url %>" - }, - "extra": { - "component": { - "scripts": [ - "dist/ZeroClipboard.js" - ], - "files": [ - "dist/ZeroClipboard.swf", - "dist/ZeroClipboard.min.js", - "dist/ZeroClipboard.min.map", - "dist/ZeroClipboard.Core.js", - "dist/ZeroClipboard.Core.min.js", - "dist/ZeroClipboard.Core.min.map" - ] - } - } -} \ No newline at end of file diff --git a/web/public/libs/zeroclipboard/src/meta/source-banner.tmpl b/web/public/libs/zeroclipboard/src/meta/source-banner.tmpl deleted file mode 100755 index 116e142..0000000 --- a/web/public/libs/zeroclipboard/src/meta/source-banner.tmpl +++ /dev/null @@ -1,8 +0,0 @@ -/*! - * <%= title || name %> - * <%= description %> - * Copyright (c) 2009-<%= grunt.template.today("yyyy") %> <%= _.pluck(contributors, "name").join(", ") %> - * Licensed <%= _.pluck(licenses, "type").join(", ") %> - * <%= homepage %> - * v<%= version %> - */ diff --git a/web/public/libs/zeroclipboard/test/.jshintrc b/web/public/libs/zeroclipboard/test/.jshintrc deleted file mode 100755 index 10a7be3..0000000 --- a/web/public/libs/zeroclipboard/test/.jshintrc +++ /dev/null @@ -1,68 +0,0 @@ -{ - /* Enforcing options */ - "bitwise": true, - "camelcase": true, - "curly": true, - "eqeqeq": true, - "es3": true, - "es5": false, - "forin": true, - "freeze": true, - "immed": true, - "indent": 2, - "latedef": true, - "newcap": true, - "noarg": true, - "noempty": true, - "nonbsp": true, - "nonew": true, - "plusplus": false, - "quotmark": "double", - "undef": true, - "unused": true, - "strict": true, - "trailing": true, - "maxparams": 2, - "maxdepth": 3, - "maxstatements": false, - "maxlen": false, /* IDEAL: 120? */ - - - /* Relaxing options */ - "asi": false, - "boss": false, - "debug": false, - "eqnull": true, - "esnext": false, - "evil": false, - "expr": false, - "funcscope": false, - "gcl": false, - "globalstrict": false, - "iterator": false, - "lastsemic": false, - "laxbreak": false, - "laxcomma": false, - "loopfunc": false, - "maxerr": 50, - "moz": false, - "multistr": false, - "notypeof": false, - "proto": false, - "scripturl": false, - "smarttabs": false, - "shadow": false, - "sub": false, - "supernew": false, - "validthis": false, - "noyield": false, - - /* Environments */ - "browser": true, - - /* Global variables */ - "globals": { - "$": false, - "QUnit": false - } -} diff --git a/web/public/libs/zeroclipboard/test/built/ZeroClipboard.Core.tests.js b/web/public/libs/zeroclipboard/test/built/ZeroClipboard.Core.tests.js deleted file mode 100755 index d0588cc..0000000 --- a/web/public/libs/zeroclipboard/test/built/ZeroClipboard.Core.tests.js +++ /dev/null @@ -1,67 +0,0 @@ -/*global ZeroClipboard */ - -(function(module, test) { - "use strict"; - - // Helper functions - var TestUtils = { - getHtmlBridge: function() { - return document.getElementById(ZeroClipboard.config("containerId")); - } - }; - - var originalConfig, originalFlashDetect; - - - module("ZeroClipboard.Core.js (built) unit tests", { - setup: function() { - // Store - originalConfig = ZeroClipboard.config(); - originalFlashDetect = ZeroClipboard.isFlashUnusable; - // Modify - ZeroClipboard.isFlashUnusable = function() { - return false; - }; - }, - teardown: function() { - // Restore - ZeroClipboard.destroy(); - ZeroClipboard.config(originalConfig); - ZeroClipboard.isFlashUnusable = originalFlashDetect; - } - }); - - - test("`swfPath` finds the expected default URL", function(assert) { - assert.expect(1); - - // Assert, act, assert - var rootOrigin = window.location.protocol + "//" + window.location.host + "/"; - var indexOfTest = window.location.pathname.toLowerCase().indexOf("/test/"); - var rootDir = window.location.pathname.slice(1, indexOfTest + 1); - var rootPath = rootOrigin + rootDir; - //var zcJsUrl = rootPath + "dist/ZeroClipboard.Core.js"; - var swfPathBasedOnZeroClipboardJsPath = rootPath + "dist/ZeroClipboard.swf"; - - // Test that the client has the expected default URL [even if it's not correct] - assert.strictEqual(ZeroClipboard.config("swfPath"), swfPathBasedOnZeroClipboardJsPath); - }); - - - test("`destroy` destroys the bridge", function(assert) { - assert.expect(3); - - // Arrange - ZeroClipboard.isFlashUnusable = function() { - return false; - }; - - // Assert, arrange, assert, act, assert - assert.equal(TestUtils.getHtmlBridge(), null, "The bridge does not exist before creating a client"); - ZeroClipboard.create(); - assert.notEqual(TestUtils.getHtmlBridge(), null, "The bridge does exist after creating a client"); - ZeroClipboard.destroy(); - assert.equal(TestUtils.getHtmlBridge(), null, "The bridge does not exist after calling `destroy`"); - }); - -})(QUnit.module, QUnit.test); diff --git a/web/public/libs/zeroclipboard/test/built/ZeroClipboard.Core.tests.js.html b/web/public/libs/zeroclipboard/test/built/ZeroClipboard.Core.tests.js.html deleted file mode 100755 index 18cfe80..0000000 --- a/web/public/libs/zeroclipboard/test/built/ZeroClipboard.Core.tests.js.html +++ /dev/null @@ -1,43 +0,0 @@ - - - - -
- -
-- -
-- -
-- -
-- -
- - - -Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod -tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, -quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo -consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse -cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non -proident, sunt in culpa qui officia deserunt mollit anim id est laborum.-
- -
-- -
-- -
-- -
-- -
-- -
- - - -Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod -tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, -quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo -consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse -cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non -proident, sunt in culpa qui officia deserunt mollit anim id est laborum.-
- -
-"+ - "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\n"+ - "tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\n"+ - "quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\n"+ - "consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\n"+ - "cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\n"+ - "proident, sunt in culpa qui officia deserunt mollit anim id est laborum."+ - ""; - - ZeroClipboard.create(); - - // Act - ZeroClipboard.activate(currentEl); - var pendingText = ZeroClipboard.emit("copy"); - - // Assert - assert.strictEqual(_clipData["text/plain"].replace(/\r\n/g, "\n"), expectedText); - assert.strictEqual( - _clipData["text/html"] - .replace(/\r\n/g, "\n") - .replace(/<\/?pre(?:\s+[^>]*)?>/gi, function($0) { return $0.toLowerCase(); }), - expectedHtml - ); - assert.strictEqual(pendingText.text.replace(/\r\n/g, "\n"), expectedText); - assert.strictEqual( - pendingText.html - .replace(/\r\n/g, "\n") - .replace(/<\/?pre(?:\s+[^>]*)?>/gi, function($0) { return $0.toLowerCase(); }), - expectedHtml - ); - assert.deepEqual(_clipDataFormatMap, { "text": "text/plain", "html": "text/html" }); - - // Revert - ZeroClipboard.deactivate(); - }); - - - test("Object has data-clipboard-target input", function(assert) { - assert.expect(3); - - // Arrange - var currentEl = document.getElementById("d_clip_button_input_text"); - ZeroClipboard.create(); - - // Act - ZeroClipboard.activate(currentEl); - var pendingText = ZeroClipboard.emit("copy"); - - // Assert - assert.deepEqual(_clipData, { "text/plain": "Clipboard Text" }); - assert.deepEqual(pendingText, { "text": "Clipboard Text" }); - assert.deepEqual(_clipDataFormatMap, { "text": "text/plain" }); - - // Revert - ZeroClipboard.deactivate(); - }); - - - test("Object doesn't have data-clipboard-text", function(assert) { - assert.expect(1); - - // Arrange - var currentEl = document.getElementById("d_clip_button_no_text"); - ZeroClipboard.create(); - - // Act - ZeroClipboard.activate(currentEl); - - // Assert - assert.ok(!TestUtils.getHtmlBridge().getAttribute("data-clipboard-text")); - - // Revert - ZeroClipboard.deactivate(); - }); - - - test("Calculations based on borderWidth never return NaN", function(assert) { - assert.expect(4); - - // Arrange - var currentEl = document.getElementById("d_clip_button"); - ZeroClipboard.create(); - - // Act - ZeroClipboard.activate(currentEl); - - // Assert - assert.strictEqual(/^-?[0-9\.]+px$/.test(TestUtils.getHtmlBridge().style.top), true); - assert.strictEqual(/^-?[0-9\.]+px$/.test(TestUtils.getHtmlBridge().style.left), true); - assert.strictEqual(/^-?[0-9\.]+px$/.test(TestUtils.getHtmlBridge().style.width), true); - assert.strictEqual(/^-?[0-9\.]+px$/.test(TestUtils.getHtmlBridge().style.height), true); - }); - -})(QUnit.module, QUnit.test); diff --git a/web/public/libs/zeroclipboard/test/core/api.tests.js.html b/web/public/libs/zeroclipboard/test/core/api.tests.js.html deleted file mode 100755 index 797fe8f..0000000 --- a/web/public/libs/zeroclipboard/test/core/api.tests.js.html +++ /dev/null @@ -1,77 +0,0 @@ - - - - -
- -
-- -
-- -
-- -
-- -
- - - -Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod -tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, -quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo -consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse -cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non -proident, sunt in culpa qui officia deserunt mollit anim id est laborum.-