syncings
This commit is contained in:
1 parent
d1533abc5f
commit
0acfc76176
23 files changed
+1318
No files matched your search
+33
@@ -0,0 +1,33 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "4.2"
|
||||
|
||||
env:
|
||||
- E2E_BROWSER_VENDOR="internet explorer" E2E_PLATFORM="Windows 8.1" E2E_BROWSER_VERSION="latest"
|
||||
- E2E_BROWSER_VENDOR="internet explorer" E2E_PLATFORM="Windows 10" E2E_BROWSER_VERSION="latest"
|
||||
- E2E_BROWSER_VENDOR="MicrosoftEdge" E2E_PLATFORM="Windows 10" E2E_BROWSER_VERSION="latest"
|
||||
- E2E_BROWSER_VENDOR="chrome" E2E_PLATFORM="Windows 8.1" E2E_BROWSER_VERSION="latest"
|
||||
- E2E_BROWSER_VENDOR="chrome" E2E_PLATFORM="Windows 8.1" E2E_BROWSER_VERSION="latest-1"
|
||||
- E2E_BROWSER_VENDOR="chrome" E2E_PLATFORM="Windows 10" E2E_BROWSER_VERSION="latest"
|
||||
- E2E_BROWSER_VENDOR="chrome" E2E_PLATFORM="Windows 10" E2E_BROWSER_VERSION="latest-1"
|
||||
- E2E_BROWSER_VENDOR="firefox" E2E_PLATFORM="Windows 8.1" E2E_BROWSER_VERSION="latest"
|
||||
- E2E_BROWSER_VENDOR="firefox" E2E_PLATFORM="Windows 8.1" E2E_BROWSER_VERSION="latest-1"
|
||||
- E2E_BROWSER_VENDOR="firefox" E2E_PLATFORM="Windows 10" E2E_BROWSER_VERSION="latest"
|
||||
- E2E_BROWSER_VENDOR="firefox" E2E_PLATFORM="Windows 10" E2E_BROWSER_VERSION="latest-1"
|
||||
# TODO: add workaround for chromedriver issue
|
||||
# - E2E_BROWSER_VENDOR="chrome" E2E_PLATFORM="OS X 10.11" E2E_BROWSER_VERSION="latest"
|
||||
# - E2E_BROWSER_VENDOR="chrome" E2E_PLATFORM="OS X 10.11" E2E_BROWSER_VERSION="latest-1"
|
||||
# TODO: look into execCommand(“copy”) support in Safari
|
||||
# window.document.queryCommandSupported('copy') - false in 9.1.1
|
||||
# - E2E_BROWSER_VENDOR="safari" E2E_PLATFORM="OS X 10.11" E2E_BROWSER_VERSION="latest"
|
||||
- E2E_BROWSER_VENDOR="firefox" E2E_PLATFORM="OS X 10.11" E2E_BROWSER_VERSION="latest"
|
||||
- E2E_BROWSER_VENDOR="firefox" E2E_PLATFORM="OS X 10.11" E2E_BROWSER_VERSION="latest-1"
|
||||
|
||||
addons:
|
||||
sauce_connect:
|
||||
username: "sudodoki"
|
||||
access_key:
|
||||
secure: "MBHn7+lxuJ0uNuFC8HjIZtosuOHICNW52fEhvtnJhXmaGOUXGLrQFUCvECJOoGrdOWmkiFaGgYINdF57HbYpyAICmv51UBlzHYftkTspYooH5+vni0ezPPpvxqNpUM/dlwfrdzC/ag97VYDeIxdYRKREwhRsNd5npE0Zrx1xmvzmnpdqdVhQ7Z/wQUDjv7talKC2fkaIYP+wEhVblnr18u0phFLqyADNsCV7D9QmILQWC4ieSz6ylTW9fb69B4rZElLj+D8qGvyvgmLnu+dK4Vlh0WuTdmVZ8TZS4OeBRIbjq/Mi2vMVuQLXz3DTiGWRZeDOBB5PYm/orgjgsnNg5hPx6t7yc4ypcBYf2gHxc31lV9VZRb10py33D8qPtcmPptwIWlsCQ4ANDyOwxck0FejMpjT+Ktkyme4nAvt9op289x8KKI0w8W7nHIB930lEookJCeMHWjyycPLJDTwYe60zBS24vNRF46ixhfpeO1zGw8nEj5qqSoEltunCOQ3Uvl25tNEuk9R649TyWbegjTuS4txqAsSjUnVMGvRBcZef4YyOQsggos1YbJMNnFSvDH9VaPYiJbg/qR7tb0YJ8gtAC9/6iqba6EZadkJQe9DHs6qu5zuoiwfSgBZTON2oWL6AGwySADm44SL7ikKJN8Zb8bLjQ1o15KinBVKLuOk="
|
||||
|
||||
script:
|
||||
- REMOTE_SELENIUM=true npm test -- -e saucelabs
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 sudodoki <smd.deluzion@gmail.com>
|
||||
|
||||
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.
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
# Copy to clipboard [](https://travis-ci.org/sudodoki/copy-to-clipboard)
|
||||
|
||||
Simple module exposing `copy` function that will try to use [execCommand](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand#) with fallback to IE-specific `clipboardData` interface and finally, resort to usual `prompt` with proper text content and message.
|
||||
|
||||
> If you are building using [Electron](http://electronjs.org/), use [their API](https://www.electronjs.org/docs/api/clipboard).
|
||||
|
||||
# Example
|
||||
|
||||
```js
|
||||
import copy from 'copy-to-clipboard';
|
||||
|
||||
copy('Text');
|
||||
|
||||
// Copy with options
|
||||
copy('Text', {
|
||||
debug: true,
|
||||
message: 'Press #{key} to copy',
|
||||
});
|
||||
```
|
||||
|
||||
# API
|
||||
|
||||
`copy(text: string, options: object): boolean` — tries to copy text to clipboard. Returns `true` if no additional keystrokes were required from user (so, `execCommand`, IE's `clipboardData` worked) or `false`.
|
||||
|
||||
|Value |Default |Notes|
|
||||
|------|--------|-----|
|
||||
|options.debug |false| `Boolean`. Optional. Enable output to console. |
|
||||
|options.message|Copy to clipboard: `#{key}`, Enter| `String`. Optional. Prompt message. `*` |
|
||||
|options.format|"text/html"| `String`. Optional. Set the MIME type of what you want to copy as. Use `text/html` to copy as HTML, `text/plain` to avoid inherited styles showing when pasted into rich text editor. |
|
||||
|options.onCopy|null| `function onCopy(clipboardData: object): void`. Optional. Receives the clipboardData element for adding custom behavior such as additional formats |
|
||||
|
||||
`*` all occurrences of `#{key}` are replaced with `⌘+C` for macOS/iOS users, and `Ctrl+C` otherwise.
|
||||
|
||||
# [Browser support](http://caniuse.com/#feat=document-execcommand)
|
||||
|
||||
Works everywhere where `prompt`* is available. Works best (i.e. without additional keystrokes) in Chrome, FF, Safari 10+, and, supposedly, IE/Edge.
|
||||
|
||||
Note: **does not work on some older iOS devices.**
|
||||
`*` – even though **Safari 8** has `prompt`, you cannot specify prefilled content for prompt modal – thus it **doesn't work** as expected.
|
||||
|
||||
# Installation
|
||||
|
||||
+ Can be used as npm package and then leveraged using commonjs bundler/loader:
|
||||
```
|
||||
npm i --save copy-to-clipboard
|
||||
```
|
||||
+ Can be utilized using [wzrd.in](https://wzrd.in/). Add following script to your page:
|
||||
```html
|
||||
<script src="https://wzrd.in/standalone/copy-to-clipboard@latest" async></script>
|
||||
```
|
||||
You will have `window.copyToClipboard` exposed for you to use.
|
||||
|
||||
# UI components based on this package:
|
||||
+ [react-copy-to-clipboard](https://github.com/nkbt/react-copy-to-clipboard)
|
||||
+ [copy-button](https://github.com/sudodoki/copy-button)
|
||||
|
||||
# See also:
|
||||
+ [clipboard-copy](https://github.com/feross/clipboard-copy) by [@feross](https://github.com/feross)
|
||||
+ [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand#Browser_Compatibility)
|
||||
+ [April 2015 update on Cut and Copy Commands](http://updates.html5rocks.com/2015/04/cut-and-copy-commands)
|
||||
|
||||
# Running Tests
|
||||
This project has some automated tests, that will run using [nightwatch](nightwatchjs.org) on top of [selenium](http://www.seleniumhq.org/).
|
||||
|
||||
```
|
||||
npm i
|
||||
npm test
|
||||
```
|
||||
# Typescript
|
||||
This library has built-in Typescript definitions.
|
||||
|
||||
```
|
||||
import * as copy from 'copy-to-clipboard';
|
||||
```
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
html, body, h1, h2, h3, h4, h5, h6, p, ol, ul, li, dl,
|
||||
dt, dd, blockquote, address {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.container {
|
||||
overflow: hidden;
|
||||
}
|
||||
.half:first-child {
|
||||
padding-left: 20px;
|
||||
}
|
||||
.half:last-child {
|
||||
padding-right: 20px;
|
||||
}
|
||||
@media screen and (max-width: 568px) {
|
||||
.half {
|
||||
width: 100% !important;
|
||||
padding-left: 20px;
|
||||
padding-right: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.half {
|
||||
width: 50%;
|
||||
float: left;
|
||||
padding: 10px;
|
||||
}
|
||||
.code {
|
||||
font-size: 18px;
|
||||
min-height: 150px;
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
!function(e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).copyToClipboard=e()}(function(){return function n(r,a,c){function i(t,e){if(!a[t]){if(!r[t]){var o="function"==typeof require&&require;if(!e&&o)return o(t,!0);if(l)return l(t,!0);throw(e=new Error("Cannot find module '"+t+"'")).code="MODULE_NOT_FOUND",e}o=a[t]={exports:{}},r[t][0].call(o.exports,function(e){return i(r[t][1][e]||e)},o,o.exports,n,r,a,c)}return a[t].exports}for(var l="function"==typeof require&&require,e=0;e<c.length;e++)i(c[e]);return i}({1:[function(e,t,o){"use strict";var d=e("toggle-selection"),f={"text/plain":"Text","text/html":"Url",default:"Text"};t.exports=function(o,n){var t,e,r,a,c=!1,i=(n=n||{}).debug||!1;try{var l=d(),s=document.createRange(),u=document.getSelection();if((e=document.createElement("span")).textContent=o,e.ariaHidden="true",e.style.all="unset",e.style.position="fixed",e.style.top=0,e.style.clip="rect(0, 0, 0, 0)",e.style.whiteSpace="pre",e.style.webkitUserSelect="text",e.style.MozUserSelect="text",e.style.msUserSelect="text",e.style.userSelect="text",e.addEventListener("copy",function(e){var t;e.stopPropagation(),n.format&&(e.preventDefault(),void 0===e.clipboardData?(i&&console.warn("unable to use e.clipboardData"),i&&console.warn("trying IE specific stuff"),window.clipboardData.clearData(),t=f[n.format]||f.default,window.clipboardData.setData(t,o)):(e.clipboardData.clearData(),e.clipboardData.setData(n.format,o))),n.onCopy&&(e.preventDefault(),n.onCopy(e.clipboardData))}),document.body.appendChild(e),s.selectNodeContents(e),u.addRange(s),!document.execCommand("copy"))throw new Error("copy command was unsuccessful");c=!0}catch(e){i&&console.error("unable to copy using execCommand: ",e),i&&console.warn("trying IE specific stuff");try{window.clipboardData.setData(n.format||"text",o),n.onCopy&&n.onCopy(window.clipboardData),c=!0}catch(e){i&&console.error("unable to copy using clipboardData: ",e),i&&console.error("falling back to prompt"),r="message"in n?n.message:"Copy to clipboard: #{key}, Enter",a=(/mac os x/i.test(navigator.userAgent)?"⌘":"Ctrl")+"+C",t=r.replace(/#{\s*key\s*}/g,a),window.prompt(t,o)}}finally{u&&("function"==typeof u.removeRange?u.removeRange(s):u.removeAllRanges()),e&&document.body.removeChild(e),l()}return c}},{"toggle-selection":2}],2:[function(e,t,o){t.exports=function(){var t=document.getSelection();if(!t.rangeCount)return function(){};for(var e=document.activeElement,o=[],n=0;n<t.rangeCount;n++)o.push(t.getRangeAt(n));switch(e.tagName.toUpperCase()){case"INPUT":case"TEXTAREA":e.blur();break;default:e=null}return t.removeAllRanges(),function(){"Caret"===t.type&&t.removeAllRanges(),t.rangeCount||o.forEach(function(e){t.addRange(e)}),e&&e.focus()}}},{}]},{},[1])(1)});
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// Type definitions for copy-to-clipboard 3.0
|
||||
// Project: https://github.com/sudodoki/copy-to-clipboard
|
||||
// Definitions by: Denis Carriere <https://github.com/DenisCarriere>, MartynasZilinskas <https://github.com/MartynasZilinskas>
|
||||
|
||||
interface Options {
|
||||
debug?: boolean;
|
||||
message?: string;
|
||||
format?: string; // MIME type
|
||||
onCopy?: (clipboardData: object) => void;
|
||||
}
|
||||
|
||||
declare function copy(text: string, options?: Options): boolean;
|
||||
declare namespace copy { }
|
||||
export = copy;
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
"use strict";
|
||||
|
||||
var deselectCurrent = require("toggle-selection");
|
||||
|
||||
var clipboardToIE11Formatting = {
|
||||
"text/plain": "Text",
|
||||
"text/html": "Url",
|
||||
"default": "Text"
|
||||
}
|
||||
|
||||
var defaultMessage = "Copy to clipboard: #{key}, Enter";
|
||||
|
||||
function format(message) {
|
||||
var copyKey = (/mac os x/i.test(navigator.userAgent) ? "⌘" : "Ctrl") + "+C";
|
||||
return message.replace(/#{\s*key\s*}/g, copyKey);
|
||||
}
|
||||
|
||||
function copy(text, options) {
|
||||
var debug,
|
||||
message,
|
||||
reselectPrevious,
|
||||
range,
|
||||
selection,
|
||||
mark,
|
||||
success = false;
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
debug = options.debug || false;
|
||||
try {
|
||||
reselectPrevious = deselectCurrent();
|
||||
|
||||
range = document.createRange();
|
||||
selection = document.getSelection();
|
||||
|
||||
mark = document.createElement("span");
|
||||
mark.textContent = text;
|
||||
// avoid screen readers from reading out loud the text
|
||||
mark.ariaHidden = "true"
|
||||
// reset user styles for span element
|
||||
mark.style.all = "unset";
|
||||
// prevents scrolling to the end of the page
|
||||
mark.style.position = "fixed";
|
||||
mark.style.top = 0;
|
||||
mark.style.clip = "rect(0, 0, 0, 0)";
|
||||
// used to preserve spaces and line breaks
|
||||
mark.style.whiteSpace = "pre";
|
||||
// do not inherit user-select (it may be `none`)
|
||||
mark.style.webkitUserSelect = "text";
|
||||
mark.style.MozUserSelect = "text";
|
||||
mark.style.msUserSelect = "text";
|
||||
mark.style.userSelect = "text";
|
||||
mark.addEventListener("copy", function(e) {
|
||||
e.stopPropagation();
|
||||
if (options.format) {
|
||||
e.preventDefault();
|
||||
if (typeof e.clipboardData === "undefined") { // IE 11
|
||||
debug && console.warn("unable to use e.clipboardData");
|
||||
debug && console.warn("trying IE specific stuff");
|
||||
window.clipboardData.clearData();
|
||||
var format = clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting["default"]
|
||||
window.clipboardData.setData(format, text);
|
||||
} else { // all other browsers
|
||||
e.clipboardData.clearData();
|
||||
e.clipboardData.setData(options.format, text);
|
||||
}
|
||||
}
|
||||
if (options.onCopy) {
|
||||
e.preventDefault();
|
||||
options.onCopy(e.clipboardData);
|
||||
}
|
||||
});
|
||||
|
||||
document.body.appendChild(mark);
|
||||
|
||||
range.selectNodeContents(mark);
|
||||
selection.addRange(range);
|
||||
|
||||
var successful = document.execCommand("copy");
|
||||
if (!successful) {
|
||||
throw new Error("copy command was unsuccessful");
|
||||
}
|
||||
success = true;
|
||||
} catch (err) {
|
||||
debug && console.error("unable to copy using execCommand: ", err);
|
||||
debug && console.warn("trying IE specific stuff");
|
||||
try {
|
||||
window.clipboardData.setData(options.format || "text", text);
|
||||
options.onCopy && options.onCopy(window.clipboardData);
|
||||
success = true;
|
||||
} catch (err) {
|
||||
debug && console.error("unable to copy using clipboardData: ", err);
|
||||
debug && console.error("falling back to prompt");
|
||||
message = format("message" in options ? options.message : defaultMessage);
|
||||
window.prompt(message, text);
|
||||
}
|
||||
} finally {
|
||||
if (selection) {
|
||||
if (typeof selection.removeRange == "function") {
|
||||
selection.removeRange(range);
|
||||
} else {
|
||||
selection.removeAllRanges();
|
||||
}
|
||||
}
|
||||
|
||||
if (mark) {
|
||||
document.body.removeChild(mark);
|
||||
}
|
||||
reselectPrevious();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
module.exports = copy;
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "copy-to-clipboard",
|
||||
"version": "3.3.3",
|
||||
"description": "Copy stuff into clipboard using JS with fallbacks",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"scripts": {
|
||||
"pretest": "browserify ./index.js --standalone copyToClipboard | uglifyjs -cm > example/index.js",
|
||||
"test": "nightwatch"
|
||||
},
|
||||
"keywords": [
|
||||
"clipboard",
|
||||
"copy",
|
||||
"browser"
|
||||
],
|
||||
"author": "sudodoki <smd.deluzion@gmail.com>",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/sudodoki/copy-to-clipboard"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Aleksej Shvajka",
|
||||
"url": "https://github.com/shvaikalesh"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"toggle-selection": "^1.0.6"
|
||||
},
|
||||
"directories": {
|
||||
"example": "example"
|
||||
},
|
||||
"devDependencies": {
|
||||
"browserify": "^13.0.1",
|
||||
"minimist": "^1.2.6",
|
||||
"nightwatch": "^2.3.0",
|
||||
"@brettz9/node-static": "^0.1.1",
|
||||
"optimist": "^0.5.2",
|
||||
"selenium-server-standalone-jar": "2.53.0",
|
||||
"uglify-js": "^3.5.3"
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Nik Butenko
|
||||
|
||||
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.
|
||||
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
# react-copy-to-clipboard [](https://www.npmjs.com/package/react-copy-to-clipboard)
|
||||
|
||||
[](https://gitter.im/nkbt/help)
|
||||
|
||||
[](https://circleci.com/gh/nkbt/react-copy-to-clipboard)
|
||||
[](https://david-dm.org/nkbt/react-copy-to-clipboard)
|
||||
[](https://david-dm.org/nkbt/react-copy-to-clipboard#info=devDependencies)
|
||||
|
||||
Copy to clipboard React component
|
||||
|
||||
Based on [copy-to-clipboard](https://npm.im/copy-to-clipboard)
|
||||
|
||||
> Would try to use execCommand with fallback to IE specific clipboardData interface and finally, fallback to simple prompt with proper text content & 'Copy to clipboard: Ctrl+C, Enter'
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
### NPM
|
||||
|
||||
```sh
|
||||
npm install --save react-copy-to-clipboard
|
||||
```
|
||||
|
||||
Don't forget to manually install peer dependencies (`react`) if you use npm@3.
|
||||
|
||||
|
||||
### 1998 Script Tag:
|
||||
```html
|
||||
<script src="https://unpkg.com/react@16.0.0/umd/react.production.min.js"></script>
|
||||
<script src="https://unpkg.com/react-copy-to-clipboard/build/react-copy-to-clipboard.js"></script>
|
||||
(Module exposed as `CopyToClipboard`)
|
||||
```
|
||||
|
||||
## Live design system demo
|
||||
|
||||
[https://www.jinno.io/app/18/](https://www.jinno.io/app/18/?source=react-copy-to-clipboard)
|
||||
|
||||
## Simple web demo
|
||||
|
||||
[http://nkbt.github.io/react-copy-to-clipboard](http://nkbt.github.io/react-copy-to-clipboard)
|
||||
|
||||
## Codepen demo
|
||||
|
||||
[http://codepen.io/nkbt/pen/eNPoQv](http://codepen.io/nkbt/pen/eNPoQv?editors=0010)
|
||||
|
||||
## Usage
|
||||
```js
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import {CopyToClipboard} from 'react-copy-to-clipboard';
|
||||
|
||||
class App extends React.Component {
|
||||
state = {
|
||||
value: '',
|
||||
copied: false,
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<input value={this.state.value}
|
||||
onChange={({target: {value}}) => this.setState({value, copied: false})} />
|
||||
|
||||
<CopyToClipboard text={this.state.value}
|
||||
onCopy={() => this.setState({copied: true})}>
|
||||
<span>Copy to clipboard with span</span>
|
||||
</CopyToClipboard>
|
||||
|
||||
<CopyToClipboard text={this.state.value}
|
||||
onCopy={() => this.setState({copied: true})}>
|
||||
<button>Copy to clipboard with button</button>
|
||||
</CopyToClipboard>
|
||||
|
||||
{this.state.copied ? <span style={{color: 'red'}}>Copied.</span> : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const appRoot = document.createElement('div');
|
||||
document.body.appendChild(appRoot);
|
||||
ReactDOM.render(<App />, appRoot);
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
|
||||
#### `text`: PropTypes.string.isRequired
|
||||
|
||||
Text to be copied to clipboard
|
||||
|
||||
|
||||
#### `onCopy`: PropTypes.func
|
||||
|
||||
Optional callback, will be called when text is copied
|
||||
|
||||
```
|
||||
onCopy(text, result)
|
||||
```
|
||||
`result (bool)`: Returns `true` if copied successfully, else `false`.
|
||||
|
||||
|
||||
#### `options`: PropTypes.shape({debug: bool, message: string})
|
||||
|
||||
Optional [copy-to-clipboard](https://npm.im/copy-to-clipboard) options.
|
||||
|
||||
See [API docs](https://npm.im/copy-to-clipboard#api) for details
|
||||
|
||||
#### `children`: PropTypes.node.isRequired
|
||||
|
||||
CopyToClipboard is a simple wrapping component, it does not render any tags, so it requires the only child element to be present, which will be used to capture clicks.
|
||||
|
||||
```js
|
||||
<CopyToClipboard text="Hello!">
|
||||
<button>Copy to clipboard</button>
|
||||
</CopyToClipboard>
|
||||
```
|
||||
|
||||
## Development and testing
|
||||
|
||||
Currently is being developed and tested with the latest stable `Node 8` on `OSX`.
|
||||
|
||||
To run example covering all `CopyToClipboard` features, use `yarn start`, which will compile `example/Example.js`
|
||||
|
||||
```bash
|
||||
git clone git@github.com:nkbt/react-copy-to-clipboard.git
|
||||
cd react-copy-to-clipboard
|
||||
yarn install
|
||||
yarn start
|
||||
|
||||
# then
|
||||
open http://localhost:8080
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
# to run ESLint check
|
||||
yarn lint
|
||||
|
||||
# to run tests
|
||||
yarn test
|
||||
|
||||
# to run end-to-end tests
|
||||
# first, run `selenium/standalone-firefox:3.4.0` docker image
|
||||
docker run -p 4444:4444 selenium/standalone-firefox:3.4.0
|
||||
# then run test
|
||||
yarn e2e
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
+390
@@ -0,0 +1,390 @@
|
||||
(function webpackUniversalModuleDefinition(root, factory) {
|
||||
if(typeof exports === 'object' && typeof module === 'object')
|
||||
module.exports = factory(require("React"));
|
||||
else if(typeof define === 'function' && define.amd)
|
||||
define(["React"], factory);
|
||||
else if(typeof exports === 'object')
|
||||
exports["CopyToClipboard"] = factory(require("React"));
|
||||
else
|
||||
root["CopyToClipboard"] = factory(root["React"]);
|
||||
})(self, (__WEBPACK_EXTERNAL_MODULE_react__) => {
|
||||
return /******/ (() => { // webpackBootstrap
|
||||
/******/ var __webpack_modules__ = ({
|
||||
|
||||
/***/ "./src/Component.js":
|
||||
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
||||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
||||
/* harmony export */ "CopyToClipboard": () => (/* binding */ CopyToClipboard)
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("react");
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var copy_to_clipboard__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("./node_modules/copy-to-clipboard/index.js");
|
||||
/* harmony import */ var copy_to_clipboard__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(copy_to_clipboard__WEBPACK_IMPORTED_MODULE_1__);
|
||||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
||||
|
||||
var _excluded = ["text", "onCopy", "options", "children"];
|
||||
|
||||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
||||
|
||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
||||
|
||||
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
||||
|
||||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
||||
|
||||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
||||
|
||||
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
||||
|
||||
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
||||
|
||||
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
|
||||
|
||||
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||
|
||||
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
||||
|
||||
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
|
||||
|
||||
var CopyToClipboard = /*#__PURE__*/function (_React$PureComponent) {
|
||||
_inherits(CopyToClipboard, _React$PureComponent);
|
||||
|
||||
var _super = _createSuper(CopyToClipboard);
|
||||
|
||||
function CopyToClipboard() {
|
||||
var _this;
|
||||
|
||||
_classCallCheck(this, CopyToClipboard);
|
||||
|
||||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
||||
args[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
_this = _super.call.apply(_super, [this].concat(args));
|
||||
|
||||
_defineProperty(_assertThisInitialized(_this), "onClick", function (event) {
|
||||
var _this$props = _this.props,
|
||||
text = _this$props.text,
|
||||
onCopy = _this$props.onCopy,
|
||||
children = _this$props.children,
|
||||
options = _this$props.options;
|
||||
var elem = react__WEBPACK_IMPORTED_MODULE_0___default().Children.only(children);
|
||||
var result = copy_to_clipboard__WEBPACK_IMPORTED_MODULE_1___default()(text, options);
|
||||
|
||||
if (onCopy) {
|
||||
onCopy(text, result);
|
||||
} // Bypass onClick if it was present
|
||||
|
||||
|
||||
if (elem && elem.props && typeof elem.props.onClick === 'function') {
|
||||
elem.props.onClick(event);
|
||||
}
|
||||
});
|
||||
|
||||
return _this;
|
||||
}
|
||||
|
||||
_createClass(CopyToClipboard, [{
|
||||
key: "render",
|
||||
value: function render() {
|
||||
var _this$props2 = this.props,
|
||||
_text = _this$props2.text,
|
||||
_onCopy = _this$props2.onCopy,
|
||||
_options = _this$props2.options,
|
||||
children = _this$props2.children,
|
||||
props = _objectWithoutProperties(_this$props2, _excluded);
|
||||
|
||||
var elem = react__WEBPACK_IMPORTED_MODULE_0___default().Children.only(children);
|
||||
return /*#__PURE__*/react__WEBPACK_IMPORTED_MODULE_0___default().cloneElement(elem, _objectSpread(_objectSpread({}, props), {}, {
|
||||
onClick: this.onClick
|
||||
}));
|
||||
}
|
||||
}]);
|
||||
|
||||
return CopyToClipboard;
|
||||
}((react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent));
|
||||
|
||||
_defineProperty(CopyToClipboard, "defaultProps", {
|
||||
onCopy: undefined,
|
||||
options: undefined
|
||||
});
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "./src/index.js":
|
||||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||||
|
||||
var _require = __webpack_require__("./src/Component.js"),
|
||||
CopyToClipboard = _require.CopyToClipboard;
|
||||
|
||||
CopyToClipboard.CopyToClipboard = CopyToClipboard;
|
||||
module.exports = CopyToClipboard;
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "./node_modules/copy-to-clipboard/index.js":
|
||||
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
var deselectCurrent = __webpack_require__("./node_modules/toggle-selection/index.js");
|
||||
|
||||
var clipboardToIE11Formatting = {
|
||||
"text/plain": "Text",
|
||||
"text/html": "Url",
|
||||
"default": "Text"
|
||||
}
|
||||
|
||||
var defaultMessage = "Copy to clipboard: #{key}, Enter";
|
||||
|
||||
function format(message) {
|
||||
var copyKey = (/mac os x/i.test(navigator.userAgent) ? "⌘" : "Ctrl") + "+C";
|
||||
return message.replace(/#{\s*key\s*}/g, copyKey);
|
||||
}
|
||||
|
||||
function copy(text, options) {
|
||||
var debug,
|
||||
message,
|
||||
reselectPrevious,
|
||||
range,
|
||||
selection,
|
||||
mark,
|
||||
success = false;
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
debug = options.debug || false;
|
||||
try {
|
||||
reselectPrevious = deselectCurrent();
|
||||
|
||||
range = document.createRange();
|
||||
selection = document.getSelection();
|
||||
|
||||
mark = document.createElement("span");
|
||||
mark.textContent = text;
|
||||
// reset user styles for span element
|
||||
mark.style.all = "unset";
|
||||
// prevents scrolling to the end of the page
|
||||
mark.style.position = "fixed";
|
||||
mark.style.top = 0;
|
||||
mark.style.clip = "rect(0, 0, 0, 0)";
|
||||
// used to preserve spaces and line breaks
|
||||
mark.style.whiteSpace = "pre";
|
||||
// do not inherit user-select (it may be `none`)
|
||||
mark.style.webkitUserSelect = "text";
|
||||
mark.style.MozUserSelect = "text";
|
||||
mark.style.msUserSelect = "text";
|
||||
mark.style.userSelect = "text";
|
||||
mark.addEventListener("copy", function(e) {
|
||||
e.stopPropagation();
|
||||
if (options.format) {
|
||||
e.preventDefault();
|
||||
if (typeof e.clipboardData === "undefined") { // IE 11
|
||||
debug && console.warn("unable to use e.clipboardData");
|
||||
debug && console.warn("trying IE specific stuff");
|
||||
window.clipboardData.clearData();
|
||||
var format = clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting["default"]
|
||||
window.clipboardData.setData(format, text);
|
||||
} else { // all other browsers
|
||||
e.clipboardData.clearData();
|
||||
e.clipboardData.setData(options.format, text);
|
||||
}
|
||||
}
|
||||
if (options.onCopy) {
|
||||
e.preventDefault();
|
||||
options.onCopy(e.clipboardData);
|
||||
}
|
||||
});
|
||||
|
||||
document.body.appendChild(mark);
|
||||
|
||||
range.selectNodeContents(mark);
|
||||
selection.addRange(range);
|
||||
|
||||
var successful = document.execCommand("copy");
|
||||
if (!successful) {
|
||||
throw new Error("copy command was unsuccessful");
|
||||
}
|
||||
success = true;
|
||||
} catch (err) {
|
||||
debug && console.error("unable to copy using execCommand: ", err);
|
||||
debug && console.warn("trying IE specific stuff");
|
||||
try {
|
||||
window.clipboardData.setData(options.format || "text", text);
|
||||
options.onCopy && options.onCopy(window.clipboardData);
|
||||
success = true;
|
||||
} catch (err) {
|
||||
debug && console.error("unable to copy using clipboardData: ", err);
|
||||
debug && console.error("falling back to prompt");
|
||||
message = format("message" in options ? options.message : defaultMessage);
|
||||
window.prompt(message, text);
|
||||
}
|
||||
} finally {
|
||||
if (selection) {
|
||||
if (typeof selection.removeRange == "function") {
|
||||
selection.removeRange(range);
|
||||
} else {
|
||||
selection.removeAllRanges();
|
||||
}
|
||||
}
|
||||
|
||||
if (mark) {
|
||||
document.body.removeChild(mark);
|
||||
}
|
||||
reselectPrevious();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
module.exports = copy;
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "./node_modules/toggle-selection/index.js":
|
||||
/***/ ((module) => {
|
||||
|
||||
|
||||
module.exports = function () {
|
||||
var selection = document.getSelection();
|
||||
if (!selection.rangeCount) {
|
||||
return function () {};
|
||||
}
|
||||
var active = document.activeElement;
|
||||
|
||||
var ranges = [];
|
||||
for (var i = 0; i < selection.rangeCount; i++) {
|
||||
ranges.push(selection.getRangeAt(i));
|
||||
}
|
||||
|
||||
switch (active.tagName.toUpperCase()) { // .toUpperCase handles XHTML
|
||||
case 'INPUT':
|
||||
case 'TEXTAREA':
|
||||
active.blur();
|
||||
break;
|
||||
|
||||
default:
|
||||
active = null;
|
||||
break;
|
||||
}
|
||||
|
||||
selection.removeAllRanges();
|
||||
return function () {
|
||||
selection.type === 'Caret' &&
|
||||
selection.removeAllRanges();
|
||||
|
||||
if (!selection.rangeCount) {
|
||||
ranges.forEach(function(range) {
|
||||
selection.addRange(range);
|
||||
});
|
||||
}
|
||||
|
||||
active &&
|
||||
active.focus();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
||||
/***/ "react":
|
||||
/***/ ((module) => {
|
||||
|
||||
"use strict";
|
||||
module.exports = __WEBPACK_EXTERNAL_MODULE_react__;
|
||||
|
||||
/***/ })
|
||||
|
||||
/******/ });
|
||||
/************************************************************************/
|
||||
/******/ // The module cache
|
||||
/******/ var __webpack_module_cache__ = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/ // Check if module is in cache
|
||||
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
||||
/******/ if (cachedModule !== undefined) {
|
||||
/******/ return cachedModule.exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = __webpack_module_cache__[moduleId] = {
|
||||
/******/ // no module.id needed
|
||||
/******/ // no module.loaded needed
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/ /* webpack/runtime/compat get default export */
|
||||
/******/ (() => {
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = (module) => {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ () => (module['default']) :
|
||||
/******/ () => (module);
|
||||
/******/ __webpack_require__.d(getter, { a: getter });
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/define property getters */
|
||||
/******/ (() => {
|
||||
/******/ // define getter functions for harmony exports
|
||||
/******/ __webpack_require__.d = (exports, definition) => {
|
||||
/******/ for(var key in definition) {
|
||||
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
|
||||
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
||||
/******/ }
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
||||
/******/ (() => {
|
||||
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
||||
/******/ })();
|
||||
/******/
|
||||
/******/ /* webpack/runtime/make namespace object */
|
||||
/******/ (() => {
|
||||
/******/ // define __esModule on exports
|
||||
/******/ __webpack_require__.r = (exports) => {
|
||||
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
||||
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
||||
/******/ }
|
||||
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
||||
/******/ };
|
||||
/******/ })();
|
||||
/******/
|
||||
/************************************************************************/
|
||||
/******/
|
||||
/******/ // startup
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ // This entry module is referenced by other modules so it can't be inlined
|
||||
/******/ var __webpack_exports__ = __webpack_require__("./src/index.js");
|
||||
/******/
|
||||
/******/ return __webpack_exports__;
|
||||
/******/ })()
|
||||
;
|
||||
});
|
||||
+1
@@ -0,0 +1 @@
|
||||
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("React")):"function"==typeof define&&define.amd?define(["React"],t):"object"==typeof exports?exports.CopyToClipboard=t(require("React")):e.CopyToClipboard=t(e.React)}(self,(e=>(()=>{var t={"./src/Component.js":(e,t,o)=>{"use strict";o.r(t),o.d(t,{CopyToClipboard:()=>g});var r=o("react"),n=o.n(r),c=o("./node_modules/copy-to-clipboard/index.js"),a=o.n(c);function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}var l=["text","onCopy","options","children"];function p(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),o.push.apply(o,r)}return o}function u(e){for(var t=1;t<arguments.length;t++){var o=null!=arguments[t]?arguments[t]:{};t%2?p(Object(o),!0).forEach((function(t){v(e,t,o[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(o)):p(Object(o)).forEach((function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(o,t))}))}return e}function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function f(e,t){for(var o=0;o<t.length;o++){var r=t[o];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function y(e,t){return y=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},y(e,t)}function d(e,t){if(t&&("object"===i(t)||"function"==typeof t))return t;if(void 0!==t)throw new TypeError("Derived constructors may only return object or undefined");return b(e)}function b(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function m(e){return m=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},m(e)}function v(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}var g=function(e){!function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&y(e,t)}(p,e);var t,o,r,c,i=(r=p,c=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}(),function(){var e,t=m(r);if(c){var o=m(this).constructor;e=Reflect.construct(t,arguments,o)}else e=t.apply(this,arguments);return d(this,e)});function p(){var e;s(this,p);for(var t=arguments.length,o=new Array(t),r=0;r<t;r++)o[r]=arguments[r];return v(b(e=i.call.apply(i,[this].concat(o))),"onClick",(function(t){var o=e.props,r=o.text,c=o.onCopy,i=o.children,l=o.options,p=n().Children.only(i),u=a()(r,l);c&&c(r,u),p&&p.props&&"function"==typeof p.props.onClick&&p.props.onClick(t)})),e}return t=p,(o=[{key:"render",value:function(){var e=this.props,t=(e.text,e.onCopy,e.options,e.children),o=function(e,t){if(null==e)return{};var o,r,n=function(e,t){if(null==e)return{};var o,r,n={},c=Object.keys(e);for(r=0;r<c.length;r++)o=c[r],t.indexOf(o)>=0||(n[o]=e[o]);return n}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(r=0;r<c.length;r++)o=c[r],t.indexOf(o)>=0||Object.prototype.propertyIsEnumerable.call(e,o)&&(n[o]=e[o])}return n}(e,l),r=n().Children.only(t);return n().cloneElement(r,u(u({},o),{},{onClick:this.onClick}))}}])&&f(t.prototype,o),Object.defineProperty(t,"prototype",{writable:!1}),p}(n().PureComponent);v(g,"defaultProps",{onCopy:void 0,options:void 0})},"./src/index.js":(e,t,o)=>{var r=o("./src/Component.js").CopyToClipboard;r.CopyToClipboard=r,e.exports=r},"./node_modules/copy-to-clipboard/index.js":(e,t,o)=>{"use strict";var r=o("./node_modules/toggle-selection/index.js"),n={"text/plain":"Text","text/html":"Url",default:"Text"};e.exports=function(e,t){var o,c,a,i,l,p,u=!1;t||(t={}),o=t.debug||!1;try{if(a=r(),i=document.createRange(),l=document.getSelection(),(p=document.createElement("span")).textContent=e,p.style.all="unset",p.style.position="fixed",p.style.top=0,p.style.clip="rect(0, 0, 0, 0)",p.style.whiteSpace="pre",p.style.webkitUserSelect="text",p.style.MozUserSelect="text",p.style.msUserSelect="text",p.style.userSelect="text",p.addEventListener("copy",(function(r){if(r.stopPropagation(),t.format)if(r.preventDefault(),void 0===r.clipboardData){o&&console.warn("unable to use e.clipboardData"),o&&console.warn("trying IE specific stuff"),window.clipboardData.clearData();var c=n[t.format]||n.default;window.clipboardData.setData(c,e)}else r.clipboardLine truncated
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
"use strict";
|
||||
|
||||
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.CopyToClipboard = void 0;
|
||||
|
||||
var _react = _interopRequireDefault(require("react"));
|
||||
|
||||
var _copyToClipboard = _interopRequireDefault(require("copy-to-clipboard"));
|
||||
|
||||
var _excluded = ["text", "onCopy", "options", "children"];
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||
|
||||
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
||||
|
||||
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
||||
|
||||
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
||||
|
||||
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
||||
|
||||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
||||
|
||||
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
||||
|
||||
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
||||
|
||||
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
|
||||
|
||||
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
||||
|
||||
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
||||
|
||||
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
||||
|
||||
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
||||
|
||||
var CopyToClipboard = /*#__PURE__*/function (_React$PureComponent) {
|
||||
_inherits(CopyToClipboard, _React$PureComponent);
|
||||
|
||||
var _super = _createSuper(CopyToClipboard);
|
||||
|
||||
function CopyToClipboard() {
|
||||
var _this;
|
||||
|
||||
_classCallCheck(this, CopyToClipboard);
|
||||
|
||||
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
||||
args[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
_this = _super.call.apply(_super, [this].concat(args));
|
||||
|
||||
_defineProperty(_assertThisInitialized(_this), "onClick", function (event) {
|
||||
var _this$props = _this.props,
|
||||
text = _this$props.text,
|
||||
onCopy = _this$props.onCopy,
|
||||
children = _this$props.children,
|
||||
options = _this$props.options;
|
||||
|
||||
var elem = _react["default"].Children.only(children);
|
||||
|
||||
var result = (0, _copyToClipboard["default"])(text, options);
|
||||
|
||||
if (onCopy) {
|
||||
onCopy(text, result);
|
||||
} // Bypass onClick if it was present
|
||||
|
||||
|
||||
if (elem && elem.props && typeof elem.props.onClick === 'function') {
|
||||
elem.props.onClick(event);
|
||||
}
|
||||
});
|
||||
|
||||
return _this;
|
||||
}
|
||||
|
||||
_createClass(CopyToClipboard, [{
|
||||
key: "render",
|
||||
value: function render() {
|
||||
var _this$props2 = this.props,
|
||||
_text = _this$props2.text,
|
||||
_onCopy = _this$props2.onCopy,
|
||||
_options = _this$props2.options,
|
||||
children = _this$props2.children,
|
||||
props = _objectWithoutProperties(_this$props2, _excluded);
|
||||
|
||||
var elem = _react["default"].Children.only(children);
|
||||
|
||||
return /*#__PURE__*/_react["default"].cloneElement(elem, _objectSpread(_objectSpread({}, props), {}, {
|
||||
onClick: this.onClick
|
||||
}));
|
||||
}
|
||||
}]);
|
||||
|
||||
return CopyToClipboard;
|
||||
}(_react["default"].PureComponent);
|
||||
|
||||
exports.CopyToClipboard = CopyToClipboard;
|
||||
|
||||
_defineProperty(CopyToClipboard, "defaultProps", {
|
||||
onCopy: undefined,
|
||||
options: undefined
|
||||
});
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
"use strict";
|
||||
|
||||
var _require = require('./Component'),
|
||||
CopyToClipboard = _require.CopyToClipboard;
|
||||
|
||||
CopyToClipboard.CopyToClipboard = CopyToClipboard;
|
||||
module.exports = CopyToClipboard;
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"name": "react-copy-to-clipboard",
|
||||
"version": "5.1.0",
|
||||
"description": "Copy-to-clipboard React component",
|
||||
"main": "lib/index.js",
|
||||
"config": {
|
||||
"component": "CopyToClipboard",
|
||||
"externals": {
|
||||
"react": "React",
|
||||
"react-dom": "ReactDOM"
|
||||
},
|
||||
"include": [
|
||||
"https://unpkg.com/react/umd/react.production.min.js",
|
||||
"https://unpkg.com/react-dom/umd/react-dom.production.min.js"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"build": "yarn lib && yarn dist",
|
||||
"start": "NODE_ENV=development webpack-cli serve --config ./webpack/dev.config.js",
|
||||
"predist": "rm -rf ./build",
|
||||
"dist": "NODE_ENV=production webpack-cli --config ./webpack/dist.config.js && NODE_ENV=production webpack-cli --config ./webpack/min.config.js",
|
||||
"preghPages": "yarn pub",
|
||||
"ghPages": "gh-pages --dist ./pub --repo git@github.com:nkbt/react-copy-to-clipboard.git --user nik@butenko.me --branch gh-pages --message 'Publish examples' ",
|
||||
"prelib": "rm -rf ./lib",
|
||||
"lib": "NODE_ENV=production babel src --out-dir lib",
|
||||
"lint": "eslint .",
|
||||
"prepub": "rm -rf ./pub",
|
||||
"pub": "NODE_ENV=production webpack-cli --config ./webpack/pub.config.js",
|
||||
"test": "node test/Component-test.js",
|
||||
"prepublishOnly": "yarn build",
|
||||
"postversion": "git push --follow-tags",
|
||||
"deps": "depcheck",
|
||||
"check:deps": "[ ! $(depcheck | grep --invert-match 'No depcheck issue') ]"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nkbt/react-copy-to-clipboard.git"
|
||||
},
|
||||
"keywords": [
|
||||
"component",
|
||||
"react-component",
|
||||
"react",
|
||||
"copy to clipboard",
|
||||
"clipboard"
|
||||
],
|
||||
"author": "Nik Butenko <nik@butenko.me>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nkbt/react-copy-to-clipboard/issues"
|
||||
},
|
||||
"homepage": "https://github.com/nkbt/react-copy-to-clipboard",
|
||||
"peerDependencies": {
|
||||
"react": "^15.3.0 || 16 || 17 || 18"
|
||||
},
|
||||
"dependencies": {
|
||||
"copy-to-clipboard": "^3.3.1",
|
||||
"prop-types": "^15.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.17.6",
|
||||
"@babel/core": "^7.17.9",
|
||||
"@babel/eslint-parser": "^7.17.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.16.7",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.17.3",
|
||||
"@babel/preset-env": "^7.16.11",
|
||||
"@babel/preset-react": "^7.16.7",
|
||||
"@babel/register": "^7.17.7",
|
||||
"babel-loader": "^8.2.4",
|
||||
"babel-plugin-transform-react-remove-prop-types": "^0.4.24",
|
||||
"css-loader": "^6.7.1",
|
||||
"depcheck": "^1.4.3",
|
||||
"eslint": "^8.13.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-react": "^7.29.4",
|
||||
"eslint-plugin-react-hooks": "^4.4.0",
|
||||
"gh-pages": "^3.2.3",
|
||||
"html-webpack-plugin": "^5.5.0",
|
||||
"html-webpack-tags-plugin": "^3.0.2",
|
||||
"mini-css-extract-plugin": "^2.6.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"style-loader": "^3.3.1",
|
||||
"tape": "^5.5.3",
|
||||
"webpack": "^5.72.0",
|
||||
"webpack-cli": "^4.9.2",
|
||||
"webpack-dev-server": "^4.8.1"
|
||||
},
|
||||
"files": [
|
||||
"build",
|
||||
"lib",
|
||||
"src",
|
||||
"LICENSE",
|
||||
"package.json",
|
||||
"README.md"
|
||||
],
|
||||
"packageManager": "yarn@3.2.0"
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import copy from 'copy-to-clipboard';
|
||||
|
||||
|
||||
export class CopyToClipboard extends React.PureComponent {
|
||||
static propTypes = {
|
||||
text: PropTypes.string.isRequired,
|
||||
children: PropTypes.element.isRequired,
|
||||
onCopy: PropTypes.func,
|
||||
options: PropTypes.shape({
|
||||
debug: PropTypes.bool,
|
||||
message: PropTypes.string,
|
||||
format: PropTypes.string
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
static defaultProps = {
|
||||
onCopy: undefined,
|
||||
options: undefined
|
||||
};
|
||||
|
||||
|
||||
onClick = event => {
|
||||
const {
|
||||
text,
|
||||
onCopy,
|
||||
children,
|
||||
options
|
||||
} = this.props;
|
||||
|
||||
const elem = React.Children.only(children);
|
||||
|
||||
const result = copy(text, options);
|
||||
|
||||
if (onCopy) {
|
||||
onCopy(text, result);
|
||||
}
|
||||
|
||||
// Bypass onClick if it was present
|
||||
if (elem && elem.props && typeof elem.props.onClick === 'function') {
|
||||
elem.props.onClick(event);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
render() {
|
||||
const {
|
||||
text: _text,
|
||||
onCopy: _onCopy,
|
||||
options: _options,
|
||||
children,
|
||||
...props
|
||||
} = this.props;
|
||||
const elem = React.Children.only(children);
|
||||
|
||||
return React.cloneElement(elem, {...props, onClick: this.onClick});
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
|
||||
const {CopyToClipboard} = require('./Component');
|
||||
|
||||
|
||||
CopyToClipboard.CopyToClipboard = CopyToClipboard;
|
||||
module.exports = CopyToClipboard;
|
||||
+1
@@ -0,0 +1 @@
|
||||
node_modules
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
# Toggle Selection
|
||||
|
||||
Simple module exposing function that deselects current browser selection and returns function that restores selection.
|
||||
|
||||
```
|
||||
var deselect = require('toggle-selection');
|
||||
var reselect = deselect(); // remove all selection
|
||||
// …
|
||||
// do something with current selection, text, etc;
|
||||
// …
|
||||
reselect(); // restore selection
|
||||
```
|
||||
|
||||
All credits go to [@shvaikalesh](https://github.com/shvaikalesh).
|
||||
|
||||
# [Example](https://github.com/sudodoki/toggle-selection/blob/master/example)
|
||||
|
||||

|
||||
+16
@@ -0,0 +1,16 @@
|
||||
var selection = document.getSelection();
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function(event) {
|
||||
setTimeout(function() {
|
||||
if (!selection.rangeCount) { // for demo purposes only
|
||||
return;
|
||||
}
|
||||
reselect = module.exports();
|
||||
setTimeout(function() {
|
||||
reselect();
|
||||
console.log('reselected');
|
||||
}, 1000);
|
||||
|
||||
console.log('deselected');
|
||||
}, 2000);
|
||||
});
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Example Page</title>
|
||||
<script src="../index.js"></script>
|
||||
<script src="demo.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<textarea cols="30" rows="10">Some random stuff.</textarea>
|
||||
<textarea cols="30" rows="10">Some random stuff.</textarea>
|
||||
<textarea cols="30" rows="10">Some random stuff.</textarea>
|
||||
<div contentEditable>Some random stuff.</div>
|
||||
<input value="Some random stuff.">
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
|
||||
Aenean commodo ligula eget dolor. Aenean massa.
|
||||
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.
|
||||
Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.
|
||||
Nulla consequat massa quis enim.
|
||||
Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu.
|
||||
In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo.
|
||||
Nullam dictum felis eu pede mollis pretium. Integer tincidunt.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
|
||||
module.exports = function () {
|
||||
var selection = document.getSelection();
|
||||
if (!selection.rangeCount) {
|
||||
return function () {};
|
||||
}
|
||||
var active = document.activeElement;
|
||||
|
||||
var ranges = [];
|
||||
for (var i = 0; i < selection.rangeCount; i++) {
|
||||
ranges.push(selection.getRangeAt(i));
|
||||
}
|
||||
|
||||
switch (active.tagName.toUpperCase()) { // .toUpperCase handles XHTML
|
||||
case 'INPUT':
|
||||
case 'TEXTAREA':
|
||||
active.blur();
|
||||
break;
|
||||
|
||||
default:
|
||||
active = null;
|
||||
break;
|
||||
}
|
||||
|
||||
selection.removeAllRanges();
|
||||
return function () {
|
||||
selection.type === 'Caret' &&
|
||||
selection.removeAllRanges();
|
||||
|
||||
if (!selection.rangeCount) {
|
||||
ranges.forEach(function(range) {
|
||||
selection.addRange(range);
|
||||
});
|
||||
}
|
||||
|
||||
active &&
|
||||
active.focus();
|
||||
};
|
||||
};
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "toggle-selection",
|
||||
"version": "1.0.6",
|
||||
"description": "Toggle current selected content in browser",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/sudodoki/toggle-selection"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [
|
||||
"selection",
|
||||
"toggle",
|
||||
"browser",
|
||||
"deselect"
|
||||
],
|
||||
"author": "sudodoki <smd.deluzion@gmail.com> (sudodoki.name)",
|
||||
"license": "MIT",
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Aleksej Shvajka",
|
||||
"url": "https://github.com/shvaikalesh"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user