@cocreate/clipboard 1.7.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,3 @@
1
1
  # These are supported funding model platforms
2
2
 
3
- github: CoCreate-app
3
+ github: CoCreateJS
@@ -12,16 +12,27 @@ jobs:
12
12
  - name: Checkout repository
13
13
  uses: actions/checkout@v7
14
14
 
15
- - name: Sync package.json description to GitHub About
15
+ - name: Sync package.json description and keywords to GitHub repository
16
16
  env:
17
- GITHUB_TOKEN: ${{ secrets.GITHUB }}
17
+ GH_TOKEN: ${{ secrets.GITHUB }}
18
18
  run: |
19
- DESC=$(jq -r '.description // empty' package.json)
20
- if [ -n "$DESC" ]; then
21
- echo "Updating repository description to: $DESC"
22
- gh api -X PATCH repos/${{ github.repository }} -f description="$DESC"
19
+ if [ ! -f package.json ]; then
20
+ echo "No package.json found; skipping repository metadata sync."
21
+ exit 0
22
+ fi
23
+
24
+ DESCRIPTION=$(jq -r '.description // empty' package.json)
25
+ if [ -n "$DESCRIPTION" ]; then
26
+ gh api --method PATCH "repos/${GITHUB_REPOSITORY}" -f description="$DESCRIPTION"
27
+ else
28
+ echo "No package description found; leaving GitHub description unchanged."
29
+ fi
30
+
31
+ if jq -e '.keywords | type == "array"' package.json >/dev/null; then
32
+ TOPICS=$(jq -c '.keywords | map(ascii_downcase | gsub("[^a-z0-9-]+"; "-") | gsub("(^-+|-+$)"; "") | .[0:50]) | map(select(length > 0)) | unique | .[0:20]' package.json)
33
+ printf '{"names":%s}' "$TOPICS" | gh api --method PUT -H "Accept: application/vnd.github+json" "repos/${GITHUB_REPOSITORY}/topics" --input -
23
34
  else
24
- echo "No description found in package.json."
35
+ echo "No package keywords found; leaving GitHub topics unchanged."
25
36
  fi
26
37
 
27
38
  release:
package/CHANGELOG.md CHANGED
@@ -1,58 +1,83 @@
1
- ## [1.2.2](https://github.com/CoCreate-app/CoCreate-clipboard/compare/v1.2.1...v1.2.2) (2026-07-19)
1
+ # [2.0.0](https://github.com/CoCreateJS/clipboard/compare/v1.2.2...v2.0.0) (2026-11-02)
2
2
 
3
3
 
4
4
  ### Bug Fixes
5
5
 
6
- * set default branch to main ([65e7f7f](https://github.com/CoCreate-app/CoCreate-clipboard/commit/65e7f7f02e62af923a1a3417730dbc408559d165))
6
+ * add Deno specific entries to .gitignore ([df7ed52](https://github.com/CoCreateJS/clipboard/commit/df7ed528a533cef9158573f2293b7ae11adaa484))
7
+ * bump [@cocreate](https://github.com/cocreate) dependencies ([8b7a4b9](https://github.com/CoCreateJS/clipboard/commit/8b7a4b9fbc0e888eb4f95caa979ccb1ad4244dcb))
8
+ * bump [@cocreate](https://github.com/cocreate) package versions ([bcb7ccb](https://github.com/CoCreateJS/clipboard/commit/bcb7ccbe1123d9815142e4a781284903704f7b00))
9
+ * bump versions ([9745901](https://github.com/CoCreateJS/clipboard/commit/9745901c54b7a61ddb691d2bd12a690df058d474))
10
+ * bump versions ([791f6c9](https://github.com/CoCreateJS/clipboard/commit/791f6c992c41a4c0eaff12880fc228e6556247ec))
11
+ * remove trailing slash from node_modules entry in .gitignore ([e81f21a](https://github.com/CoCreateJS/clipboard/commit/e81f21ad45d395cf448a64be00023471ca155928))
12
+ * update git url ([2f8d441](https://github.com/CoCreateJS/clipboard/commit/2f8d441936df84a9ae6fec3516de2832a7f02fbf))
13
+ * update GitHub Actions to use latest versions and sync package.json description ([e5fe7ed](https://github.com/CoCreateJS/clipboard/commit/e5fe7edbd09b1af22fc466f980e4558664e2d9cb))
7
14
 
8
- ## [1.2.1](https://github.com/CoCreate-app/CoCreate-clipboard/compare/v1.2.0...v1.2.1) (2026-07-17)
15
+
16
+ ### Features
17
+
18
+ * align CoCreate repository and package naming ([eb6179d](https://github.com/CoCreateJS/clipboard/commit/eb6179d40d7251a1e78cd8fc40508c6355b0546a))
19
+ * replace uuid import and usage with utils ([05054ce](https://github.com/CoCreateJS/clipboard/commit/05054ce8454cfd26c16f10c64c83f89955d94ba4))
20
+
21
+
22
+ ### BREAKING CHANGES
23
+
24
+ * consumers must use the renamed CoCreate package and repository identities; the previous prefixed names are no longer supported.
25
+
26
+ ## [1.2.2](https://github.com/CoCreateJS/CoCreate-clipboard/compare/v1.2.1...v1.2.2) (2026-07-19)
27
+
28
+
29
+ ### Bug Fixes
30
+
31
+ * set default branch to main ([65e7f7f](https://github.com/CoCreateJS/CoCreate-clipboard/commit/65e7f7f02e62af923a1a3417730dbc408559d165))
32
+
33
+ ## [1.2.1](https://github.com/CoCreateJS/CoCreate-clipboard/compare/v1.2.0...v1.2.1) (2026-07-17)
9
34
 
10
35
 
11
36
  ### Bug Fixes
12
37
 
13
- * bump dependencies ([b965074](https://github.com/CoCreate-app/CoCreate-clipboard/commit/b96507433d68007e378ab6aa061f7a925a110e6a))
38
+ * bump dependencies ([b965074](https://github.com/CoCreateJS/CoCreate-clipboard/commit/b96507433d68007e378ab6aa061f7a925a110e6a))
14
39
 
15
- # [1.2.0](https://github.com/CoCreate-app/CoCreate-clipboard/compare/v1.1.2...v1.2.0) (2026-07-17)
40
+ # [1.2.0](https://github.com/CoCreateJS/CoCreate-clipboard/compare/v1.1.2...v1.2.0) (2026-07-17)
16
41
 
17
42
 
18
43
  ### Features
19
44
 
20
- * update automated workflow and release configuration for improved semantic release handling ([2b573e6](https://github.com/CoCreate-app/CoCreate-clipboard/commit/2b573e6c36e92f8615769e0408e1ebaa0bef236b))
45
+ * update automated workflow and release configuration for improved semantic release handling ([2b573e6](https://github.com/CoCreateJS/CoCreate-clipboard/commit/2b573e6c36e92f8615769e0408e1ebaa0bef236b))
21
46
 
22
- ## [1.1.2](https://github.com/CoCreate-app/CoCreate-clipboard/compare/v1.1.1...v1.1.2) (2026-07-11)
47
+ ## [1.1.2](https://github.com/CoCreateJS/CoCreate-clipboard/compare/v1.1.1...v1.1.2) (2026-07-11)
23
48
 
24
49
 
25
50
  ### Bug Fixes
26
51
 
27
- * bump package versions ([4802ef1](https://github.com/CoCreate-app/CoCreate-clipboard/commit/4802ef11961218c2ed071f2c08f39f00130b839e))
28
- * removed post install and add add packages to apprved list ([1b2701f](https://github.com/CoCreate-app/CoCreate-clipboard/commit/1b2701f833e4e7b8b39d5c6078428f1585b01935))
29
- * semantic version handling ([d5f849d](https://github.com/CoCreate-app/CoCreate-clipboard/commit/d5f849dc16702952e359e3a227dd7c2da6f6f2f4))
52
+ * bump package versions ([4802ef1](https://github.com/CoCreateJS/CoCreate-clipboard/commit/4802ef11961218c2ed071f2c08f39f00130b839e))
53
+ * removed post install and add add packages to apprved list ([1b2701f](https://github.com/CoCreateJS/CoCreate-clipboard/commit/1b2701f833e4e7b8b39d5c6078428f1585b01935))
54
+ * semantic version handling ([d5f849d](https://github.com/CoCreateJS/CoCreate-clipboard/commit/d5f849dc16702952e359e3a227dd7c2da6f6f2f4))
30
55
 
31
- ## [1.1.1](https://github.com/CoCreate-app/CoCreate-clipboard/compare/v1.1.0...v1.1.1) (2026-01-18)
56
+ ## [1.1.1](https://github.com/CoCreateJS/CoCreate-clipboard/compare/v1.1.0...v1.1.1) (2026-01-18)
32
57
 
33
58
 
34
59
  ### Bug Fixes
35
60
 
36
- * update worklow ([c54f11a](https://github.com/CoCreate-app/CoCreate-clipboard/commit/c54f11a9df499522afc5805d99538099d7314704))
61
+ * update worklow ([c54f11a](https://github.com/CoCreateJS/CoCreate-clipboard/commit/c54f11a9df499522afc5805d99538099d7314704))
37
62
 
38
- # [1.1.0](https://github.com/CoCreate-app/CoCreate-clipboard/compare/v1.0.0...v1.1.0) (2025-05-01)
63
+ # [1.1.0](https://github.com/CoCreateJS/CoCreate-clipboard/compare/v1.0.0...v1.1.0) (2025-05-01)
39
64
 
40
65
 
41
66
  ### Bug Fixes
42
67
 
43
- * added css-loader ([03d2c12](https://github.com/CoCreate-app/CoCreate-clipboard/commit/03d2c12b1f56ced186877939c15e81932ed6e871))
44
- * update [@cocreate](https://github.com/cocreate) dependencies ([22fa8a8](https://github.com/CoCreate-app/CoCreate-clipboard/commit/22fa8a8329001ba632b2430ae564c941090a6c09))
45
- * update query attributes ([48297b3](https://github.com/CoCreate-app/CoCreate-clipboard/commit/48297b37408552c5c765d812124ff510e65e7751))
46
- * webpack.config and devdependencies ([bd741fc](https://github.com/CoCreate-app/CoCreate-clipboard/commit/bd741fca61bd135a811f743689d2ba5faaaa13bd))
68
+ * added css-loader ([03d2c12](https://github.com/CoCreateJS/CoCreate-clipboard/commit/03d2c12b1f56ced186877939c15e81932ed6e871))
69
+ * update [@cocreate](https://github.com/cocreate) dependencies ([22fa8a8](https://github.com/CoCreateJS/CoCreate-clipboard/commit/22fa8a8329001ba632b2430ae564c941090a6c09))
70
+ * update query attributes ([48297b3](https://github.com/CoCreateJS/CoCreate-clipboard/commit/48297b37408552c5c765d812124ff510e65e7751))
71
+ * webpack.config and devdependencies ([bd741fc](https://github.com/CoCreateJS/CoCreate-clipboard/commit/bd741fca61bd135a811f743689d2ba5faaaa13bd))
47
72
 
48
73
 
49
74
  ### Features
50
75
 
51
- * handles rich text editors and plain text editors ([3cfd47b](https://github.com/CoCreate-app/CoCreate-clipboard/commit/3cfd47ba9f3837f87aa7c46644edcfb28dc304b9))
76
+ * handles rich text editors and plain text editors ([3cfd47b](https://github.com/CoCreateJS/CoCreate-clipboard/commit/3cfd47ba9f3837f87aa7c46644edcfb28dc304b9))
52
77
 
53
78
  # 1.0.0 (2024-12-14)
54
79
 
55
80
 
56
81
  ### Features
57
82
 
58
- * Initial Release ([8421d97](https://github.com/CoCreate-app/CoCreate-clipboard/commit/8421d971b1ee2fda99a41d87de41ce767b9c49ee))
83
+ * Initial Release ([8421d97](https://github.com/CoCreateJS/CoCreate-clipboard/commit/8421d971b1ee2fda99a41d87de41ce767b9c49ee))
package/CONTRIBUTING.md CHANGED
@@ -1,19 +1,19 @@
1
1
  # Contributing to CoCreate-clipboard
2
2
 
3
- This project is work of [many contributors](https://github.com/CoCreate-app/CoCreate-clipboard/graphs/contributors).
4
- You're encouraged to submit [pull requests](https://github.com/CoCreate-app/CoCreate-clipboard/pulls),
5
- [propose features and discuss issues](https://github.com/CoCreate-app/CoCreate-clipboard/issues).
3
+ This project is work of [many contributors](https://github.com/CoCreateJS/clipboard/graphs/contributors).
4
+ You're encouraged to submit [pull requests](https://github.com/CoCreateJS/clipboard/pulls),
5
+ [propose features and discuss issues](https://github.com/CoCreateJS/clipboard/issues).
6
6
 
7
7
  In the examples below, substitute your Github username for `contributor` in URLs.
8
8
 
9
9
  ## Fork the Project
10
10
 
11
- Fork the [project on Github](https://github.com/CoCreate-app/CoCreate-clipboard) and check out your copy.
11
+ Fork the [project on Github](https://github.com/CoCreateJS/clipboard) and check out your copy.
12
12
 
13
13
  ```
14
14
  git clone https://github.com/contributor/CoCreate-clipboard.git
15
15
  cd CoCreate-clipboard
16
- git remote add upstream https://gitlab.com/cocreatejs/CoCreate-clipboard.git
16
+ git remote add upstream https://github.com/CoCreateJS/clipboard.git
17
17
  ```
18
18
 
19
19
  ## Create a Topic Branch
@@ -74,7 +74,7 @@ git push origin my-feature-branch
74
74
 
75
75
  ## Make a Pull Request
76
76
 
77
- Go to [https://github.com/CoCreate-app/CoCreate-clipboard](https://github.com/CoCreate-app/CoCreate-clipboard) and select your feature branch.
77
+ Go to [https://github.com/CoCreateJS/clipboard](https://github.com/CoCreateJS/clipboard) and select your feature branch.
78
78
  Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days.
79
79
 
80
80
  ## Rebase
@@ -10,7 +10,7 @@ module.exports = {
10
10
  name: "index.html",
11
11
  path: "/docs/clipboard/index.html",
12
12
  src: "{{./docs/index.html}}",
13
- host: ["cocreate.app", "general.cocreate.app"],
13
+ host: ["CoCreateJS.com", "general.CoCreateJS.com"],
14
14
  directory: "clipboard",
15
15
  "content-type": "{{content-type}}",
16
16
  public: "true"
package/README.md CHANGED
@@ -1,83 +1,112 @@
1
- # CoCreate-clipboard
2
-
3
- Highlights syntax within a textarea. Easily configured using HTML5 attributes and/or JavaScript API. Take it for a spin in our [playground!](https://cocreate.app/docs/clipboard)
4
-
5
- ![min file size in bytes](https://img.badgesize.io/https://cdn.cocreate.app/clipboard/latest/CoCreate-clipboard.min.js?style=flat-square&label=minified&color=orange)
6
- ![gzip file size in bytes](https://img.badgesize.io/https://cdn.cocreate.app/clipboard/latest/CoCreate-clipboard.min.js?compression=gzip&style=flat-square&label=gzip&color=yellow)
7
- ![brotlifile size in bytes](https://img.badgesize.io/https://cdn.cocreate.app/clipboard/latest/CoCreate-clipboard.min.js?compression=brotli&style=flat-square&label=brotli)
8
- ![GitHub latest release](https://img.shields.io/github/v/release/CoCreate-app/CoCreate-clipboard?style=flat-square)
9
- ![GitHub](https://img.shields.io/github/license/CoCreate-app/CoCreate-clipboard?style=flat-square)
10
- ![GitHub](https://img.shields.io/static/v1?style=flat-square&label=&message=Hiring&color=blueviolet)
11
-
12
- ![CoCreate-clipboard](https://cdn.cocreate.app/docs/CoCreate-clipboard.gif)
13
-
14
- ## [Docs & Demo](https://cocreate.app/docs/clipboard)
15
-
16
- For a complete guide and working demo refer to the [doumentation](https://cocreate.app/docs/clipboard)
17
-
18
- ## CDN
19
-
20
- ```html
21
- <script src="https://cdn.cocreate.app/clipboard/latest/CoCreate-clipboard.min.js"></script>
22
- ```
23
-
24
- ```html
25
- <script src="https://cdn.cocreate.app/clipboard/latest/CoCreate-clipboard.min.css"></script>
26
- ```
27
-
28
- ## NPM
29
-
30
- ```shell
31
- $ npm i @cocreate/clipboard
32
- ```
33
-
34
- ## yarn
35
-
36
- ```shell
37
- $ yarn install @cocreate/clipboard
38
- ```
39
-
40
- # Table of Contents
41
-
42
- - [Table of Contents](#table-of-contents)
43
- - [Announcements](#announcements)
44
- - [Roadmap](#roadmap)
45
- - [How to Contribute](#how-to-contribute)
46
- - [About](#about)
47
- - [License](#license)
48
-
49
- <a name="announcements"></a>
50
-
51
- # Announcements
52
-
53
- All updates to this library are documented in our [CHANGELOG](https://github.com/CoCreate-app/CoCreate-clipboard/blob/master/CHANGELOG.md) and [releases](https://github.com/CoCreate-app/CoCreate-clipboard/releases). You may also subscribe to email for releases and breaking changes.
54
-
55
- <a name="roadmap"></a>
56
-
57
- # Roadmap
58
-
59
- If you are interested in the future direction of this project, please take a look at our open [issues](https://github.com/CoCreate-app/CoCreate-clipboard/issues) and [pull requests](https://github.com/CoCreate-app/CoCreate-clipboard/pulls). We would love to hear your feedback.
60
-
61
- <a name="about"></a>
62
-
63
- # About
64
-
65
- CoCreate-clipboard is guided and supported by the CoCreate Developer Experience Team.
66
-
67
- Please Email the Developer Experience Team [here](mailto:develop@cocreate.app) in case of any queries.
68
-
69
- CoCreate-clipboard is maintained and funded by CoCreate. The names and logos for CoCreate are trademarks of CoCreate, LLC.
70
-
71
- <a name="contribute"></a>
72
-
73
- # How to Contribute
74
-
75
- We encourage contribution to our libraries (you might even score some nifty swag), please see our [CONTRIBUTING](https://github.com/CoCreate-app/CoCreate-clipboard/blob/master/CONTRIBUTING.md) guide for details.
76
-
77
- We want this library to be community-driven, and CoCreate led. We need your help to realize this goal. To help make sure we are building the right things in the right order, we ask that you create [issues](https://github.com/CoCreate-app/CoCreate-clipboard/issues) and [pull requests](https://github.com/CoCreate-app/CoCreate-clipboard/pulls) or merely upvote or comment on existing issues or pull requests.
78
-
79
- We appreciate your continued support, thank you!
80
-
81
- # License
82
-
83
- [The MIT License (MIT)](https://github.com/CoCreate-app/CoCreate-clipboard/blob/master/LICENSE)
1
+ # CoCreate-clipboard
2
+
3
+ Copies element values to the clipboard. Easily configured using HTML5 attributes and/or JavaScript API. Take it for a spin in our [playground!](https://CoCreateJS.com/docs/clipboard)
4
+
5
+ ![min file size in bytes](https://img.badgesize.io/https://cdn.CoCreateJS.com/clipboard/latest/CoCreate-clipboard.min.js?style=flat-square&label=minified&color=orange)
6
+ ![gzip file size in bytes](https://img.badgesize.io/https://cdn.CoCreateJS.com/clipboard/latest/CoCreate-clipboard.min.js?compression=gzip&style=flat-square&label=gzip&color=yellow)
7
+ ![brotlifile size in bytes](https://img.badgesize.io/https://cdn.CoCreateJS.com/clipboard/latest/CoCreate-clipboard.min.js?compression=brotli&style=flat-square&label=brotli)
8
+ ![GitHub latest release](https://img.shields.io/github/v/release/CoCreateJS/clipboard?style=flat-square)
9
+ ![GitHub](https://img.shields.io/github/license/CoCreateJS/clipboard?style=flat-square)
10
+ ![GitHub](https://img.shields.io/static/v1?style=flat-square&label=&message=Hiring&color=blueviolet)
11
+
12
+ ![CoCreate-clipboard](https://cdn.CoCreateJS.com/docs/CoCreate-clipboard.gif)
13
+
14
+ ## [Docs & Demo](https://CoCreateJS.com/docs/clipboard)
15
+
16
+ For a complete guide and working demo refer to the [doumentation](https://CoCreateJS.com/docs/clipboard)
17
+
18
+ ## Declarative controls
19
+
20
+ Use `clipboard` on an element to copy its own value, or `clipboard-query` to
21
+ select the source. Either attribute initializes a click listener, including on
22
+ dynamically added elements.
23
+
24
+ ```html
25
+ <button clipboard>Copy this text</button>
26
+ <button clipboard-query="#message">Copy message</button>
27
+ <textarea id="message">Hello</textarea>
28
+ ```
29
+
30
+ The trigger's `clipboard` attribute reflects `copying`, `copied`, or `error`.
31
+ These are output states: changing the value does not initiate a copy. Each click
32
+ copies again, including when the attribute already contains a state. The state
33
+ remains until the next copy; no timer or CSS is required.
34
+
35
+ ```css
36
+ [clipboard] .copy-success { display: none; }
37
+ [clipboard="copied"] .copy-success { display: inline; }
38
+ [clipboard="copied"] .copy-icon { display: none; }
39
+ ```
40
+
41
+ Successful copies emit the existing `clipboarded` event with `detail.clipboardItems`.
42
+ Failures emit `clipboard-error` with `detail.error`. Both events bubble, and state
43
+ is updated before the event fires. Elements with `actions` defer to the Actions
44
+ chain; use `actions="clipboard"` with either clipboard attribute. Disabled controls
45
+ and controls with `aria-disabled="true"` do not copy on click.
46
+
47
+ ## CDN
48
+
49
+ ```html
50
+ <script src="https://cdn.CoCreateJS.com/clipboard/latest/CoCreate-clipboard.min.js"></script>
51
+ ```
52
+
53
+ ```html
54
+ <script src="https://cdn.CoCreateJS.com/clipboard/latest/CoCreate-clipboard.min.css"></script>
55
+ ```
56
+
57
+ ## NPM
58
+
59
+ ```shell
60
+ $ npm i @cocreate/clipboard
61
+ ```
62
+
63
+ ## yarn
64
+
65
+ ```shell
66
+ $ yarn install @cocreate/clipboard
67
+ ```
68
+
69
+ # Table of Contents
70
+
71
+ - [Table of Contents](#table-of-contents)
72
+ - [Announcements](#announcements)
73
+ - [Roadmap](#roadmap)
74
+ - [How to Contribute](#how-to-contribute)
75
+ - [About](#about)
76
+ - [License](#license)
77
+
78
+ <a name="announcements"></a>
79
+
80
+ # Announcements
81
+
82
+ All updates to this library are documented in our [CHANGELOG](https://github.com/CoCreateJS/clipboard/blob/master/CHANGELOG.md) and [releases](https://github.com/CoCreateJS/clipboard/releases). You may also subscribe to email for releases and breaking changes.
83
+
84
+ <a name="roadmap"></a>
85
+
86
+ # Roadmap
87
+
88
+ If you are interested in the future direction of this project, please take a look at our open [issues](https://github.com/CoCreateJS/clipboard/issues) and [pull requests](https://github.com/CoCreateJS/clipboard/pulls). We would love to hear your feedback.
89
+
90
+ <a name="about"></a>
91
+
92
+ # About
93
+
94
+ CoCreate-clipboard is guided and supported by the CoCreate Developer Experience Team.
95
+
96
+ Please Email the Developer Experience Team [here](mailto:develop@CoCreateJS.com) in case of any queries.
97
+
98
+ CoCreate-clipboard is maintained and funded by CoCreate. The names and logos for CoCreate are trademarks of CoCreate, LLC.
99
+
100
+ <a name="contribute"></a>
101
+
102
+ # How to Contribute
103
+
104
+ We encourage contribution to our libraries (you might even score some nifty swag), please see our [CONTRIBUTING](https://github.com/CoCreateJS/clipboard/blob/master/CONTRIBUTING.md) guide for details.
105
+
106
+ We want this library to be community-driven, and CoCreate led. We need your help to realize this goal. To help make sure we are building the right things in the right order, we ask that you create [issues](https://github.com/CoCreateJS/clipboard/issues) and [pull requests](https://github.com/CoCreateJS/clipboard/pulls) or merely upvote or comment on existing issues or pull requests.
107
+
108
+ We appreciate your continued support, thank you!
109
+
110
+ # License
111
+
112
+ [The MIT License (MIT)](https://github.com/CoCreateJS/clipboard/blob/master/LICENSE)
package/demo/index.html CHANGED
@@ -37,6 +37,6 @@ test</textarea
37
37
 
38
38
  <!-- <script src="../dist/CoCreate-clipboard.js"></script> -->
39
39
  <script src="../../../CoCreateJS/dist/CoCreate.js"></script>
40
- <!-- <script src="https://CoCreate.app/dist/CoCreate.js"></script> -->
40
+ <!-- <script src="https://CoCreateJS.com/dist/CoCreate.js"></script> -->
41
41
  </body>
42
42
  </html>
package/docs/index.html CHANGED
@@ -9,7 +9,7 @@
9
9
  rel="icon"
10
10
  type="image/png"
11
11
  sizes="32x32"
12
- href="https://cocreate.app/images/favicon.ico" />
12
+ href="https://CoCreateJS.com/images/favicon.ico" />
13
13
  <meta
14
14
  name="description"
15
15
  content="A simple HTML5 and pure javascript component. Easy configuration using data-attributes and highly styleable." />
@@ -36,7 +36,7 @@
36
36
  share-width="500"
37
37
  share-media="https://via.placeholder.com/300/09f/fff.png">
38
38
  <a
39
- href="https://github.com/CoCreate-app/CoCreate-clipboard"
39
+ href="https://github.com/CoCreateJS/CoCreate-clipboard"
40
40
  target="_blank"
41
41
  class="margin-right:15px"
42
42
  ><i src="/assets/svg/github.svg"></i
@@ -80,7 +80,7 @@
80
80
  <pre
81
81
  class="margin-top:15px"><code class="language-javascript">npm install cocreate-clipboard</code></pre>
82
82
  <p class="padding:10px_0px">Or you can use cdn link:</p>
83
- <pre><code class="language-javascript">https://cdn.cocreate.app/js/CoCreate-clipboard.min.js</code></pre>
83
+ <pre><code class="language-javascript">https://cdn.CoCreateJS.com/js/CoCreate-clipboard.min.js</code></pre>
84
84
 
85
85
  <h2
86
86
  class="border-bottom:1px_solid_lightgrey margin-top:20px padding:5px_0px">
@@ -225,6 +225,6 @@
225
225
  </div>
226
226
 
227
227
  <!--CoCreateJS-->
228
- <script src="https://CoCreate.app/dist/CoCreate.js"></script>
228
+ <script src="https://CoCreateJS.com/dist/CoCreate.js"></script>
229
229
  </body>
230
230
  </html>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/clipboard",
3
- "version": "1.7.0",
3
+ "version": "2.0.0",
4
4
  "description": "A simple clipboard component in vanilla javascript. Easily configured using HTML5 data-attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "clipboard",
@@ -22,17 +22,17 @@
22
22
  },
23
23
  "repository": {
24
24
  "type": "git",
25
- "url": "git+https://gitlab.com/cocreatejs/CoCreate-clipboard.git"
25
+ "url": "git+https://github.com/CoCreateJS/clipboard.git"
26
26
  },
27
27
  "author": "CoCreate LLC",
28
28
  "license": "MIT",
29
29
  "bugs": {
30
- "url": "https://github.com/CoCreate-app/CoCreate-clipboard/issues"
30
+ "url": "https://github.com/CoCreateJS/clipboard/issues"
31
31
  },
32
- "homepage": "https://cocreate.app/docs/clipboard",
32
+ "homepage": "https://CoCreateJS.com/docs/clipboard",
33
33
  "funding": {
34
34
  "type": "GitHub Sponsors ❤",
35
- "url": "https://github.com/sponsors/CoCreate-app"
35
+ "url": "https://github.com/sponsors/CoCreateJS"
36
36
  },
37
37
  "main": "./src/index.js",
38
38
  "dependencies": {
package/src/index.js CHANGED
@@ -1,146 +1,313 @@
1
- /********************************************************************************
2
- * Copyright (C) 2020 CoCreate LLC and others.
3
- *
4
- *
5
- * SPDX-License-Identifier: MIT
6
- ********************************************************************************/
7
-
8
- import "@cocreate/element-prototype";
9
- import { queryElements } from "@cocreate/utils";
10
- import Actions from "@cocreate/actions";
11
- import Observer from "@cocreate/observer";
12
-
13
- const selector = "[clipboard-query]";
14
-
15
- function init(element) {
16
- if (!element) {
17
- element = document.querySelectorAll(selector);
18
- } else if (
19
- !(element instanceof HTMLCollection) &&
20
- !(element instanceof NodeList) &&
21
- !Array.isArray(element)
22
- ) {
23
- element = [element];
24
- }
25
- for (let i = 0; i < element.length; i++) {
26
- if (element[i].matches(selector)) {
27
- initElement(element[i]);
28
- }
29
- }
30
- }
31
-
32
- function initElement(element) {
33
- // Add a click event listener to trigger the clipboard action
34
- element.addEventListener("click", () => {
35
- let actions = element.getAttribute("actions");
36
- if (actions && !actions.includes("clipboard")) {
37
- queryClipboardElement(element);
38
- }
39
- });
40
- }
41
-
42
- function queryClipboardElement(element) {
43
- let elements = [];
44
- if (element.hasAttribute("clipboard-query")) {
45
- elements = queryElements({ element, prefix: "clipboard" });
46
- } else {
47
- elements = [element];
48
- }
49
-
50
- clipboard(element, elements);
51
- }
52
-
53
- async function clipboard(element, elements) {
54
- if (!elements) return;
55
- if (
56
- !(elements instanceof HTMLCollection) &&
57
- !(elements instanceof NodeList) &&
58
- !Array.isArray(elements)
59
- ) {
60
- elements = [elements];
61
- }
62
-
63
- try {
64
- const clipboardItems = [];
65
-
66
- for (const target of elements) {
67
- const value = await target.getValue();
68
- if (typeof value === "string") {
69
- // Handle string content as plain text
70
- clipboardItems.push(
71
- new ClipboardItem({
72
- "text/plain": new Blob([value], { type: "text/plain" }),
73
- "text/html": new Blob([value], {
74
- type: "text/html"
75
- }) // Render as code block in rich editors
76
- })
77
- );
78
- } else if (value instanceof Blob) {
79
- // Handle Blob content directly
80
- clipboardItems.push(
81
- new ClipboardItem({
82
- [value.type || "application/octet-stream"]: value
83
- })
84
- );
85
- } else if (value !== undefined) {
86
- const content = JSON.stringify(value, null, 2);
87
- clipboardItems.push(
88
- new ClipboardItem({
89
- "text/plain": new Blob([content], {
90
- type: "text/plain"
91
- })
92
- })
93
- );
94
- } else {
95
- console.warn("Unsupported value type for clipboard:", value);
96
- }
97
- }
98
-
99
- if (clipboardItems.length > 0) {
100
- await navigator.clipboard.write(clipboardItems);
101
- } else {
102
- console.warn("No valid content to copy to clipboard.");
103
- }
104
-
105
- element.dispatchEvent(
106
- new CustomEvent("clipboarded", {
107
- detail: { clipboardItems }
108
- })
109
- );
110
- } catch (error) {
111
- console.error("Failed to copy to clipboard:", error);
112
- }
113
- }
114
-
115
- init();
116
-
117
- Actions.init([
118
- {
119
- name: "clipboard",
120
- endEvent: "clipboarded",
121
- callback: (action) => {
122
- queryClipboardElement(action.element || action);
123
- }
124
- }
125
- ]);
126
-
127
- Observer.init({
128
- name: "CoCreateClipboardAddedNodes",
129
- types: ["addedNodes"],
130
- selector,
131
- callback(mutation) {
132
- initElement(mutation.target);
133
- }
134
- });
135
-
136
- Observer.init({
137
- name: "CoCreateClipboardObserver",
138
- types: ["attributes"],
139
- attributeFilter: ["clipboard-query"],
140
- selector,
141
- callback: function (mutation) {
142
- initElement(mutation.target);
143
- }
144
- });
145
-
146
- export default { init, clipboard };
1
+ /********************************************************************************
2
+ * Copyright (C) 2020 CoCreate LLC and others.
3
+ *
4
+ *
5
+ * SPDX-License-Identifier: MIT
6
+ ********************************************************************************/
7
+
8
+ import "@cocreate/element-prototype";
9
+ import { queryElements } from "@cocreate/utils";
10
+ import Actions from "@cocreate/actions";
11
+ import Observer from "@cocreate/observer";
12
+
13
+ const selector = "[clipboard], [clipboard-query]";
14
+ const initialized = new WeakSet();
15
+ const pending = new WeakMap();
16
+
17
+ /**
18
+ * Initializes matching elements. With no argument, scans the document; accepts an element, collection, NodeList, or array.
19
+ *
20
+ * @public
21
+ * @environment client
22
+ */
23
+ function init(element) {
24
+ if (!element) {
25
+ element = document.querySelectorAll(selector);
26
+ } else if (
27
+ !(element instanceof HTMLCollection) &&
28
+ !(element instanceof NodeList) &&
29
+ !Array.isArray(element)
30
+ ) {
31
+ element = [element];
32
+ }
33
+ for (let i = 0; i < element.length; i++) {
34
+ if (element[i].matches(selector)) {
35
+ initElement(element[i]);
36
+ }
37
+ }
38
+ }
39
+
40
+ function initElement(element) {
41
+ if (initialized.has(element)) return;
42
+ initialized.add(element);
43
+ element.addEventListener("click", () => {
44
+ if (
45
+ element.matches(selector) && !element.hasAttribute("actions") &&
46
+ !element.disabled && element.getAttribute("aria-disabled") !== "true"
47
+ ) queryClipboardElement(element);
48
+ });
49
+ }
50
+
51
+ function queryClipboardElement(element) {
52
+ let elements = [];
53
+ if (element.hasAttribute("clipboard-query")) {
54
+ elements = queryElements({ element, prefix: "clipboard" });
55
+ } else {
56
+ elements = [element];
57
+ }
58
+
59
+ return clipboard(element, elements);
60
+ }
61
+
62
+ /**
63
+ * Copies values from the supplied source elements to the system clipboard and returns a promise for the result.
64
+ *
65
+ * @public
66
+ * @environment client
67
+ */
68
+ function clipboard(element, elements = [element]) {
69
+ if (pending.has(element)) return pending.get(element);
70
+ const operation = copy(element, elements).finally(() => pending.delete(element));
71
+ pending.set(element, operation);
72
+ return operation;
73
+ }
74
+
75
+ async function copy(element, elements) {
76
+ if (
77
+ !(elements instanceof HTMLCollection) &&
78
+ !(elements instanceof NodeList) &&
79
+ !Array.isArray(elements)
80
+ ) {
81
+ elements = [elements];
82
+ }
83
+
84
+ try {
85
+ element.setAttribute("clipboard", "copying");
86
+ const clipboardItems = [];
87
+
88
+ for (const target of elements) {
89
+ const value = await target.getValue();
90
+ if (typeof value === "string") {
91
+ // Handle string content as plain text
92
+ clipboardItems.push(
93
+ new ClipboardItem({
94
+ "text/plain": new Blob([value], { type: "text/plain" }),
95
+ "text/html": new Blob([value], {
96
+ type: "text/html"
97
+ }) // Render as code block in rich editors
98
+ })
99
+ );
100
+ } else if (value instanceof Blob) {
101
+ // Handle Blob content directly
102
+ clipboardItems.push(
103
+ new ClipboardItem({
104
+ [value.type || "application/octet-stream"]: value
105
+ })
106
+ );
107
+ } else if (value !== undefined) {
108
+ const content = JSON.stringify(value, null, 2);
109
+ clipboardItems.push(
110
+ new ClipboardItem({
111
+ "text/plain": new Blob([content], {
112
+ type: "text/plain"
113
+ })
114
+ })
115
+ );
116
+ } else {
117
+ console.warn("Unsupported value type for clipboard:", value);
118
+ }
119
+ }
120
+
121
+ if (clipboardItems.length > 0) {
122
+ await navigator.clipboard.write(clipboardItems);
123
+ } else {
124
+ throw new Error("No valid content to copy to clipboard.");
125
+ }
126
+
127
+ element.setAttribute("clipboard", "copied");
128
+ element.dispatchEvent(
129
+ new CustomEvent("clipboarded", {
130
+ bubbles: true,
131
+ detail: { clipboardItems }
132
+ })
133
+ );
134
+ return { clipboardItems };
135
+ } catch (error) {
136
+ element.setAttribute("clipboard", "error");
137
+ element.dispatchEvent(new CustomEvent("clipboard-error", {
138
+ bubbles: true, detail: { error }
139
+ }));
140
+ return { error };
141
+ }
142
+ }
143
+
144
+ init();
145
+
146
+ Actions.init([
147
+ {
148
+ name: "clipboard",
149
+ endEvent: "clipboarded",
150
+ callback: async (action) => {
151
+ const result = await queryClipboardElement(action.element || action);
152
+ if (result.error) action.abort(result.error);
153
+ }
154
+ }
155
+ ]);
156
+
157
+ Observer.init({
158
+ name: "CoCreateClipboardAddedNodes",
159
+ types: ["addedNodes"],
160
+ selector,
161
+ callback(mutation) {
162
+ init(mutation.target);
163
+ }
164
+ });
165
+
166
+ Observer.init({
167
+ name: "CoCreateClipboardObserver",
168
+ types: ["attributes"],
169
+ attributeFilter: ["clipboard", "clipboard-query"],
170
+ selector,
171
+ callback: function (mutation) {
172
+ init(mutation.target);
173
+ }
174
+ });
175
+
176
+ export default { init, clipboard };
177
+
178
+ /**
179
+ * Bubbles after a successful copy; detail contains clipboardItems.
180
+ *
181
+ * @name clipboarded
182
+ * @kind member
183
+ * @public
184
+ * @environment client
185
+ */
186
+
187
+ /**
188
+ * Bubbles when copying fails; detail contains the error.
189
+ *
190
+ * @name clipboard-error
191
+ * @kind member
192
+ * @public
193
+ * @environment client
194
+ */
195
+
196
+ /**
197
+ * Copies the element's own value when used as a declarative control; also reflects the current operation state.
198
+ *
199
+ * @name clipboard
200
+ * @kind member
201
+ * @attribute
202
+ * @valueType string
203
+ * @acceptedValues copying, copied, error
204
+ * @environment client
205
+ */
206
+
207
+ /**
208
+ * Selects source elements relative to the control using CoCreate queryElements with the clipboard prefix.
209
+ *
210
+ * @name clipboard-query
211
+ * @kind member
212
+ * @attribute
213
+ * @valueType string
214
+ * @environment client
215
+ */
216
+
217
+ /**
218
+ * Declarative actions supported or registered by this module.
219
+ *
220
+ * @name declarative-actions
221
+ * @kind member
222
+ * @actions
223
+ * @environment client
224
+ * @example
225
+ * ```json
226
+ * [
227
+ * {
228
+ * "name": "clipboard",
229
+ * "description": "Copies the value of the action element or the elements selected by its clipboard-query attribute.",
230
+ * "endEvent": "clipboarded",
231
+ * "failure": "Aborts the action chain with the copy error."
232
+ * }
233
+ * ]
234
+ * ```
235
+ */
236
+
237
+ /**
238
+ * Declarative binding behavior for this module.
239
+ *
240
+ * @name declarative-binding
241
+ * @kind member
242
+ * @binding
243
+ * @environment client
244
+ * @example
245
+ * ```json
246
+ * {
247
+ * "selector": "[clipboard], [clipboard-query]",
248
+ * "trigger": "click",
249
+ * "initializesExistingElements": true,
250
+ * "observesAddedNodes": true,
251
+ * "actionsIntegration": "When an element has an actions attribute, direct click handling is skipped."
252
+ * }
253
+ * ```
254
+ */
255
+
256
+ /**
257
+ * Value conversion and handling behavior for this module.
258
+ *
259
+ * @name declarative-valueHandling
260
+ * @kind member
261
+ * @valueHandling
262
+ * @environment client
263
+ * @example
264
+ * ```json
265
+ * {
266
+ * "string": [
267
+ * "text/plain",
268
+ * "text/html"
269
+ * ],
270
+ * "blob": "Copied using its MIME type, or application/octet-stream when the type is empty.",
271
+ * "otherDefinedValues": "JSON-stringified and copied as text/plain.",
272
+ * "undefined": "Ignored; if no valid ClipboardItems remain, the operation fails."
273
+ * }
274
+ * ```
275
+ */
276
+
277
+ /**
278
+ * Result shape and state metadata for this API.
279
+ *
280
+ * @name api-result
281
+ * @kind member
282
+ * @result
283
+ * @environment client
284
+ * @example
285
+ * ```json
286
+ * {
287
+ * "success": "{ clipboardItems }",
288
+ * "failure": "{ error }",
289
+ * "stateAttribute": "clipboard",
290
+ * "stateValues": [
291
+ * "copying",
292
+ * "copied",
293
+ * "error"
294
+ * ]
295
+ * }
296
+ * ```
297
+ */
298
+
299
+ /**
300
+ * Usage constraints for this API.
301
+ *
302
+ * @name api-constraints
303
+ * @kind member
304
+ * @constraints
305
+ * @environment client
306
+ * @example
307
+ * ```json
308
+ * [
309
+ * "Direct click handling skips disabled controls and controls with aria-disabled=\"true\".",
310
+ * "Copying requires browser support for navigator.clipboard.write and ClipboardItem, plus the browser's applicable clipboard permissions and context requirements."
311
+ * ]
312
+ * ```
313
+ */
@@ -0,0 +1,104 @@
1
+ const { test } = require('node:test');
2
+ const assert = require('node:assert/strict');
3
+ const fs = require('node:fs');
4
+ const vm = require('node:vm');
5
+
6
+ function setup() {
7
+ const observers = [], actions = [], writes = [];
8
+ class Element extends EventTarget {
9
+ constructor(attributes = {}, value = 'Hello') {
10
+ super(); this.attributes = new Map(Object.entries(attributes)); this.value = value;
11
+ }
12
+ hasAttribute(name) { return this.attributes.has(name); }
13
+ getAttribute(name) { return this.attributes.get(name) ?? null; }
14
+ setAttribute(name, value) { this.attributes.set(name, value); }
15
+ matches() { return this.hasAttribute('clipboard') || this.hasAttribute('clipboard-query'); }
16
+ getValue() { return this.value; }
17
+ }
18
+ const context = vm.createContext({
19
+ Event, EventTarget, Blob, console,
20
+ CustomEvent: class extends Event { constructor(name, options) { super(name, options); this.detail = options.detail; } },
21
+ ClipboardItem: class { constructor(data) { this.data = data; } },
22
+ HTMLCollection: class {}, NodeList: class {},
23
+ document: { querySelectorAll: () => [] },
24
+ queryElements: ({ element }) => element.targets || [],
25
+ navigator: { clipboard: { write: async items => { writes.push(items); } } },
26
+ Actions: { init: items => actions.push(...items) },
27
+ Observer: { init: config => observers.push(config) }
28
+ });
29
+ const source = fs.readFileSync('src/index.js', 'utf8')
30
+ .replace(/^import .*;\r?\n/gm, '')
31
+ .replace('export default { init, clipboard };', 'globalThis.api = { init, clipboard };');
32
+ vm.runInContext(source, context);
33
+ return { ...context, Element, observers, actions, writes };
34
+ }
35
+ const flush = () => new Promise(resolve => setImmediate(resolve));
36
+
37
+ test('bare attribute copies itself and reflects state before its success event', async () => {
38
+ const s = setup(), element = new s.Element({ clipboard: '' });
39
+ s.api.init(element);
40
+ let state, bubbles;
41
+ element.addEventListener('clipboarded', event => { state = element.getAttribute('clipboard'); bubbles = event.bubbles; });
42
+ element.dispatchEvent(new Event('click'));
43
+ assert.equal(element.getAttribute('clipboard'), 'copying');
44
+ await flush();
45
+ assert.equal(state, 'copied');
46
+ assert.equal(bubbles, true);
47
+ assert.equal(await s.writes[0][0].data['text/plain'].text(), 'Hello');
48
+ element.dispatchEvent(new Event('click'));
49
+ await flush();
50
+ assert.equal(s.writes.length, 2);
51
+ });
52
+
53
+ test('query-only dynamic controls bind once across state and query mutations', async () => {
54
+ const s = setup(), element = new s.Element({ 'clipboard-query': '#source' });
55
+ element.targets = [new s.Element({}, 'Target')];
56
+ s.observers[0].callback({ target: element });
57
+ for (let i = 0; i < 3; i++) s.observers[1].callback({ target: element });
58
+ element.dispatchEvent(new Event('click'));
59
+ await flush();
60
+ assert.equal(s.writes.length, 1);
61
+ assert.equal(await s.writes[0][0].data['text/plain'].text(), 'Target');
62
+ assert.equal(element.getAttribute('clipboard'), 'copied');
63
+ });
64
+
65
+ test('actions own the click and disabled controls do not copy', async () => {
66
+ const s = setup();
67
+ for (const attrs of [{ clipboard: '', actions: 'clipboard' }, { clipboard: '', 'aria-disabled': 'true' }]) {
68
+ const element = new s.Element(attrs);
69
+ s.api.init(element);
70
+ element.dispatchEvent(new Event('click'));
71
+ }
72
+ await flush();
73
+ assert.equal(s.writes.length, 0);
74
+ const element = new s.Element({ clipboard: '', actions: 'clipboard' });
75
+ await s.actions[0].callback({ element });
76
+ assert.equal(s.writes.length, 1);
77
+ });
78
+
79
+ test('failed writes expose error state and event, abort actions and allow retry', async () => {
80
+ const s = setup(), element = new s.Element({ clipboard: '' });
81
+ const error = new Error('Permission denied');
82
+ s.navigator.clipboard.write = async () => { throw error; };
83
+ let detail, aborted;
84
+ element.addEventListener('clipboard-error', event => { detail = event.detail; });
85
+ await s.actions[0].callback({ element, abort: value => { aborted = value; } });
86
+ assert.equal(element.getAttribute('clipboard'), 'error');
87
+ assert.equal(detail.error, error);
88
+ assert.equal(aborted, error);
89
+ s.navigator.clipboard.write = async () => {};
90
+ await s.api.clipboard(element);
91
+ assert.equal(element.getAttribute('clipboard'), 'copied');
92
+ });
93
+
94
+ test('empty targets fail and overlapping copies share a single write', async () => {
95
+ const s = setup(), element = new s.Element({ clipboard: '' });
96
+ const result = await s.api.clipboard(element, []);
97
+ assert.ok(result.error);
98
+ assert.equal(element.getAttribute('clipboard'), 'error');
99
+ const first = s.api.clipboard(element);
100
+ const second = s.api.clipboard(element);
101
+ assert.equal(first, second);
102
+ await first;
103
+ assert.equal(s.writes.length, 1);
104
+ });