@cocreate/element-prototype 1.8.29 → 1.9.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.
package/docs/index.html CHANGED
@@ -11,10 +11,10 @@
11
11
  sizes="32x32"
12
12
  href="https://cocreate.app/images/favicon.ico" />
13
13
  <meta
14
- name="description"
14
+ key="description"
15
15
  content="A simple HTML5 and pure javascript component. Easy configuration using data-attributes and highly styleable." />
16
16
  <meta
17
- name="keywords"
17
+ key="keywords"
18
18
  content="helper classes, utility classes, css framework, css library, inline style classes" />
19
19
  <meta name="robots" content="index,follow" />
20
20
 
@@ -28,11 +28,7 @@
28
28
  </head>
29
29
 
30
30
  <body>
31
- <div
32
- collection=""
33
- document_id=""
34
- name=""
35
- id="cocreate-element-prototype">
31
+ <div array="" object="" key="" id="cocreate-element-prototype">
36
32
  <div
37
33
  class="display:flex flex-wrap:wrap justify-content:space-between margin:10px">
38
34
  <div class="display:flex align-items:center">
@@ -177,9 +173,9 @@
177
173
  <textarea
178
174
  type="code"
179
175
  lang="html"
180
- collection="demos"
181
- document_id=""
182
- name="demo"
176
+ array="demos"
177
+ object=""
178
+ key="demo"
183
179
  save="false"
184
180
  id="demo"
185
181
  class="height:100% width:100% outline:none border:none resize:none padding:5px"></textarea>
@@ -202,7 +198,7 @@
202
198
  show="#eye-slash"
203
199
  hide="#eye, #demo-preview"
204
200
  toggle="code-height"
205
- toggle-target="#demo-code"
201
+ toggle-selector="#demo-code"
206
202
  ><i
207
203
  class="height:18px fill:#505050"
208
204
  src="/assets/svg/eye.svg"></i
@@ -214,7 +210,7 @@
214
210
  show="#eye, #demo-preview"
215
211
  hide="#eye-slash"
216
212
  toggle="code-height"
217
- toggle-target="#demo-code"
213
+ toggle-selector="#demo-code"
218
214
  ><i
219
215
  class="height:20px fill:#505050"
220
216
  src="/assets/svg/eye-slash.svg"></i
@@ -241,7 +237,7 @@
241
237
  <a
242
238
  class="margin-right:5px"
243
239
  fullscreen
244
- fullscreen-target="#playground"></a>
240
+ fullscreen-selector="#playground"></a>
245
241
  </div>
246
242
  </div>
247
243
  <!-- End SandBox -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/element-prototype",
3
- "version": "1.8.29",
3
+ "version": "1.9.0",
4
4
  "description": "A simple element-prototype component in vanilla javascript. Easily configured using HTML5 data-attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "element-prototype",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "scripts": {
27
27
  "start": "npx webpack --config webpack.config.js",
28
- "build": "NODE_ENV=production npx webpack --config webpack.config.js",
28
+ "build": "npx webpack --mode=production --config webpack.config.js",
29
29
  "dev": "npx webpack --config webpack.config.js --watch",
30
30
  "postinstall": "node -e \"const { execSync } = require('child_process'); try { execSync('coc --version', { stdio: 'ignore' }); } catch (error) { try { execSync('npm install -g @cocreate/cli', { stdio: 'inherit' }); console.log('Installed \"@cocreate/cli\" globally.'); } catch (error) { console.error('Failed to install \"@cocreate/cli\" globally:', error); } }\""
31
31
  },
@@ -34,7 +34,7 @@
34
34
  "url": "git+https://github.com/CoCreate-app/CoCreate-element-prototype.git"
35
35
  },
36
36
  "author": "CoCreate LLC",
37
- "license": "MIT",
37
+ "license": "AGPL-3.0",
38
38
  "bugs": {
39
39
  "url": "https://github.com/CoCreate-app/CoCreate-element-prototype/issues"
40
40
  },
@@ -58,7 +58,6 @@
58
58
  "webpack-log": "^3.0.1"
59
59
  },
60
60
  "dependencies": {
61
- "@cocreate/cli": "^1.33.8",
62
- "@cocreate/utils": "^1.21.14"
61
+ "@cocreate/utils": "^1.21.16"
63
62
  }
64
63
  }
package/src/getValue.js CHANGED
@@ -1,101 +1,105 @@
1
- HTMLElement.prototype.getValue = function() {
2
- let value = getValue(this)
3
- return value;
4
- };
1
+ const storage = new Map()
5
2
 
6
- HTMLInputElement.prototype.getValue = function() {
7
- let value = getValue(this)
8
- return value;
3
+ HTMLElement.prototype.getValue = function () {
4
+ let value = getValue(this)
5
+ return value;
9
6
  };
10
7
 
11
- HTMLHeadingElement.prototype.getValue = function() {
12
- let value = getValue(this)
13
- return value;
8
+ HTMLInputElement.prototype.getValue = function () {
9
+ let value = getValue(this)
10
+ return value;
14
11
  };
15
12
 
13
+ HTMLHeadingElement.prototype.getValue = function () {
14
+ let value = getValue(this)
15
+ return value;
16
+ };
16
17
 
17
- // TODO: replace esle if with switch case
18
+ // TODO: check if using a a switch case will provide better performance
18
19
  const getValue = (element) => {
19
- let value = element.value;
20
- let prefix = element.getAttribute('value-prefix') || "";
21
- let suffix = element.getAttribute('value-suffix') || "";
22
-
23
- if (element.type === "checkbox") {
24
- let inputs = [element]
25
- let name = element.getAttribute('name');
26
- if (name)
27
- inputs = document.querySelectorAll(`input[type="${element.type}"][name="${name}"]`);
28
-
29
-
30
- if (inputs.length > 1) {
31
- value = [];
32
- inputs.forEach(el => {
33
- if (el.checked) {
34
- let checkedValue = el.value
35
- if (prefix || suffix)
36
- checkedValue = prefix + checkedValue + suffix;
37
-
38
- value.push(checkedValue);
39
- }
40
- });
41
- } else {
42
- if (element.checked)
43
- value = element.value || 'true'
44
- else if (!element.value)
45
- value = 'false'
46
-
47
- }
48
- } else if (element.type === 'radio') {
49
- let name = element.getAttribute('name');
50
- value = document.querySelector(`input[name="${name}"]:checked`).value
51
- }
52
- else if (element.type === "number") {
53
- value = Number(value);
54
- }
55
- else if (element.type === 'range') {
56
- value = [Number(element.min), Number(element.value)];
57
- }
58
- else if (element.type === "password") {
59
- value = btoa(value);
60
- }
61
- else if (element.tagName == "SELECT" && element.hasAttribute('multiple')) {
62
- let options = element.selectedOptions;
63
- value = [];
64
- for (let i = 0; i < options.length; i++) {
65
- let optionValue = options[i].value
66
- if (prefix || suffix)
67
- optionValue = prefix + optionValue + suffix;
68
- value.push(optionValue);
69
- }
70
- }
71
- else if (element.tagName == 'INPUT' || element.tagName == 'SELECT') {
72
- value = element.value;
73
- }
74
- else if (element.tagName == 'TEXTAREA') {
75
- if (element.hasAttribute('value'))
76
- value = element.getAttribute('value');
77
- else
78
- value = element.value;
79
- }
80
- else if (element.t1agName === 'IFRAME') {
81
- value = element.srcdoc;
82
- }
83
- else if (element.hasAttribute('value')){
84
- value = element.getAttribute('value');
85
- }
86
- else {
87
- value = element.innerHTML;
88
- }
89
- if (!Array.isArray(value)) {
90
- if (prefix || suffix)
91
- value = prefix + value + suffix;
92
-
93
- if (element.getAttribute('value-type') == 'array')
94
- value = [value];
95
- }
96
-
97
-
98
- return value;
20
+ let value;
21
+ if (element.hasAttribute('component') || element.hasAttribute('plugin')) {
22
+ value = storage.get(element)
23
+ storage.delete(element)
24
+ return value
25
+ }
26
+
27
+ let prefix = element.getAttribute('value-prefix') || "";
28
+ let suffix = element.getAttribute('value-suffix') || "";
29
+
30
+ if (element.type === "checkbox") {
31
+ let inputs = [element]
32
+ let key = element.getAttribute('key');
33
+ if (key)
34
+ inputs = document.querySelectorAll(`input[type="${element.type}"][key="${key}"]`);
35
+
36
+
37
+ if (inputs.length > 1) {
38
+ value = [];
39
+ inputs.forEach(el => {
40
+ if (el.checked) {
41
+ let checkedValue = el.value
42
+ if (prefix || suffix)
43
+ checkedValue = prefix + checkedValue + suffix;
44
+
45
+ value.push(checkedValue);
46
+ }
47
+ });
48
+ } else {
49
+ if (element.checked)
50
+ value = element.value || 'true'
51
+ else if (!element.value)
52
+ value = 'false'
53
+
54
+ }
55
+ } else if (element.type === 'radio') {
56
+ let key = element.getAttribute('key');
57
+ value = document.querySelector(`input[key="${key}"]:checked`).value
58
+ } else if (element.type === "number") {
59
+ value = Number(value);
60
+ } else if (element.type === 'range') {
61
+ value = [Number(element.min), Number(element.value)];
62
+ } else if (element.type === "password") {
63
+ value = btoa(value);
64
+ } else if (element.tagName == "SELECT" && element.hasAttribute('multiple')) {
65
+ let options = element.selectedOptions;
66
+ value = [];
67
+ for (let i = 0; i < options.length; i++) {
68
+ let optionValue = options[i].value
69
+ if (prefix || suffix)
70
+ optionValue = prefix + optionValue + suffix;
71
+ value.push(optionValue);
72
+ }
73
+ } else if (element.tagName == 'INPUT' || element.tagName == 'SELECT') {
74
+ value = element.value;
75
+ } else if (element.tagName == 'TEXTAREA') {
76
+ if (element.hasAttribute('value'))
77
+ value = element.getAttribute('value');
78
+ else
79
+ value = element.value;
80
+ } else if (element.tagName === 'IFRAME') {
81
+ value = element.srcdoc;
82
+ } else if (element.hasAttribute('value')) {
83
+ value = element.getAttribute('value');
84
+ } else {
85
+ value = element.innerHTML;
86
+ }
87
+
88
+ let valueType = element.getAttribute('value-type');
89
+ if (!Array.isArray(value)) {
90
+ if (prefix || suffix)
91
+ value = prefix + value + suffix;
92
+
93
+ if (valueType == 'array')
94
+ value = [value];
95
+ }
96
+
97
+ if (valueType == 'object' || valueType == 'json') {
98
+ value = JSON.parse(value)
99
+ }
100
+
101
+
102
+ return value;
99
103
  };
100
104
 
101
- export { getValue };
105
+ export { getValue, storage };
package/src/index.js CHANGED
@@ -1,12 +1,27 @@
1
1
  /********************************************************************************
2
- * Copyright (C) 2020 CoCreate LLC and others.
2
+ * Copyright (C) 2023 CoCreate and Contributors.
3
3
  *
4
+ * This program is free software: you can redistribute it and/or modify
5
+ * it under the terms of the GNU Affero General Public License as published
6
+ * by the Free Software Foundation, either version 3 of the License, or
7
+ * (at your option) any later version.
4
8
  *
5
- * SPDX-License-Identifier: MIT
9
+ * This program is distributed in the hope that it will be useful,
10
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ * GNU Affero General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU Affero General Public License
15
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
6
16
  ********************************************************************************/
7
17
 
8
- import { setValue } from './setValue';
9
- import { getValue } from './getValue';
10
-
18
+ // Commercial Licensing Information:
19
+ // For commercial use of this software without the copyleft provisions of the AGPLv3,
20
+ // you must obtain a commercial license from CoCreate LLC.
21
+ // For details, visit <https://cocreate.app/licenses/> or contact us at sales@cocreate.app.
22
+
23
+ import { setValue } from './setValue';
24
+ import { getValue } from './getValue';
25
+
11
26
 
12
- export default {getValue, setValue}
27
+ export default { getValue, setValue }
package/src/setValue.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { getAttributes } from '@cocreate/utils';
2
-
2
+ import { storage } from './getValue';
3
3
 
4
4
  HTMLElement.prototype.setValue = function (value) {
5
5
  setValue(this, value)
@@ -9,19 +9,25 @@ HTMLInputElement.prototype.setValue = function (value) {
9
9
  setValue(this, value)
10
10
  };
11
11
 
12
-
13
12
  HTMLHeadingElement.prototype.setValue = function (value) {
14
13
  setValue(this, value)
15
14
  };
16
15
 
17
-
16
+ // TODO: check if using a a switch case will provide better performance
18
17
  const setValue = (el, value) => {
18
+
19
19
  if (value === null || value === undefined) return;
20
+ if (el.hasAttribute('component') || el.hasAttribute('plugin'))
21
+ return storage.set(el, value)
22
+ else if (typeof value === 'object')
23
+ value = JSON.stringify(value, null, 2)
24
+
20
25
  let valueType = el.getAttribute('value-type');
21
26
  let prefix = el.getAttribute('value-prefix') || "";
22
- let suffix = el.getAttribute('value-suffix') || "";
23
27
  if (prefix)
24
28
  value = value.replace(prefix, "");
29
+
30
+ let suffix = el.getAttribute('value-suffix') || "";
25
31
  if (suffix)
26
32
  value = value.replace(suffix, "");
27
33
 
@@ -33,9 +39,9 @@ const setValue = (el, value) => {
33
39
 
34
40
  if (el.type == 'checkbox') {
35
41
  let inputs = [el]
36
- let name = el.getAttribute('name');
37
- if (name)
38
- inputs = document.querySelectorAll(`input[type="${el.type}"][name="${name}"]`);
42
+ let key = el.getAttribute('key');
43
+ if (key)
44
+ inputs = document.querySelectorAll(`input[type="${el.type}"][key="${key}"]`);
39
45
 
40
46
  for (let i = 0; i < inputs.length; i++) {
41
47
  if (inputs[i].value) {
@@ -51,14 +57,11 @@ const setValue = (el, value) => {
51
57
 
52
58
  }
53
59
  }
54
- }
55
- else if (el.type === 'radio') {
60
+ } else if (el.type === 'radio') {
56
61
  el.value == value ? el.checked = true : el.checked = false;
57
- }
58
- else if (el.type === 'password') {
62
+ } else if (el.type === 'password') {
59
63
  el.value = __decryptPassword(value);
60
- }
61
- else if (el.tagName == "SELECT" && el.hasAttribute('multiple') && Array.isArray(value)) {
64
+ } else if (el.tagName == "SELECT" && el.hasAttribute('multiple') && Array.isArray(value)) {
62
65
  let options = el.options;
63
66
  for (let i = 0; i < options.length; i++) {
64
67
  if (value.includes(options[i].value)) {
@@ -67,26 +70,18 @@ const setValue = (el, value) => {
67
70
  options[i].selected = "";
68
71
  }
69
72
  }
70
- }
71
- else
73
+ } else
72
74
  el.value = value;
75
+
73
76
  dispatchEvents(el)
74
- }
75
- else if (el.tagName === 'IMG' || el.tagName === 'SOURCE')
77
+ } else if (el.tagName === 'IMG' || el.tagName === 'SOURCE') {
76
78
  el.src = value;
77
-
78
- else if (el.tagName === 'IFRAME')
79
+ } else if (el.tagName === 'IFRAME') {
79
80
  el.srcdoc = value;
80
-
81
- else if (el.tagName === 'SCRIPT')
81
+ } else if (el.tagName === 'SCRIPT') {
82
82
  setScript(el, value);
83
-
84
- else {
83
+ } else {
85
84
  if (el.hasAttribute('contenteditable') && el == document.activeElement) return;
86
- // if (el.tagName === 'DIV') {
87
- // if (!el.classList.contains('domEditor')
88
- // return
89
- // }
90
85
 
91
86
  if (valueType == 'string' || valueType == 'text')
92
87
  el.textContent = value;
@@ -103,11 +98,11 @@ const setValue = (el, value) => {
103
98
  if (CoCreateCSS)
104
99
  CoCreateCSS.remove()
105
100
 
106
- let css = newElement.querySelector('link[collection], link[document]')
101
+ let css = newElement.querySelector('link[array], link[object]')
107
102
  if (css)
108
103
  css.remove()
109
104
 
110
- if (el.getAttribute('domEditor') == "replace") {
105
+ if (valueType == 'outerHTML') {
111
106
  let parentNode = el.parentNode;
112
107
  if (parentNode) {
113
108
  if (newElement.children[0]) {
@@ -117,9 +112,8 @@ const setValue = (el, value) => {
117
112
  parentNode.replaceChild(newElement, el);
118
113
  }
119
114
  }
120
- } else {
115
+ } else
121
116
  el.innerHTML = newElement.innerHTML;
122
- }
123
117
  }
124
118
 
125
119
  if (el.hasAttribute("value")) {
@@ -131,8 +125,8 @@ const setValue = (el, value) => {
131
125
  dispatchEvents(el);
132
126
 
133
127
  if (el.tagName == 'HEAD' || el.tagName == 'BODY') {
134
- el.removeAttribute('collection');
135
- el.removeAttribute('document_id');
128
+ el.removeAttribute('array');
129
+ el.removeAttribute('object');
136
130
  el.removeAttribute('pass_id');
137
131
 
138
132
  let scripts = el.querySelectorAll('script');
@@ -176,6 +170,7 @@ function dispatchEvents(el) {
176
170
  skip: true
177
171
  },
178
172
  });
173
+
179
174
  Object.defineProperty(inputEvent, 'target', {
180
175
  writable: false,
181
176
  value: el
@@ -188,6 +183,7 @@ function dispatchEvents(el) {
188
183
  skip: true
189
184
  },
190
185
  });
186
+
191
187
  Object.defineProperty(changeEvent, 'target', {
192
188
  writable: false,
193
189
  value: el
package/webpack.config.js CHANGED
@@ -1,84 +1,90 @@
1
1
  const path = require("path")
2
2
  const TerserPlugin = require("terser-webpack-plugin")
3
3
  const MiniCssExtractPlugin = require("mini-css-extract-plugin")
4
- let isProduction = process.env.NODE_ENV === "production"
5
4
  const { CleanWebpackPlugin } = require("clean-webpack-plugin")
6
5
 
7
- module.exports = {
8
- entry: {
9
- "CoCreate-element-prototype": "./src/index.js",
10
- },
11
- output: {
12
- path: path.resolve(__dirname, "dist"),
13
- filename: isProduction ? "[name].min.js" : "[name].js",
14
- libraryTarget: "umd",
15
- libraryExport: "default",
16
- library: ["CoCreate", "element-prototype"],
17
- globalObject: "this",
18
- },
6
+ module.exports = (env, argv) => {
7
+ let isProduction = false
8
+ if (argv.mode === 'production')
9
+ isProduction = true
19
10
 
20
- plugins: [
21
- new CleanWebpackPlugin(),
22
- new MiniCssExtractPlugin({
23
- filename: "[name].css",
24
- }),
25
- ],
26
- // Default mode for Webpack is production.
27
- // Depending on mode Webpack will apply different things
28
- // on final bundle. For now we don't need production's JavaScript
29
- // minifying and other thing so let's set mode to development
30
- mode: isProduction ? "production" : "development",
31
- module: {
32
- rules: [
33
- {
34
- test: /.js$/,
35
- exclude: /(node_modules)/,
36
- use: {
37
- loader: "babel-loader",
38
- options: {
39
- plugins: ["@babel/plugin-transform-modules-commonjs"],
40
- },
11
+ const config = {
12
+ entry: {
13
+ "CoCreate-element-prototype": "./src/index.js",
41
14
  },
42
- },
43
- {
44
- test: /.css$/i,
45
- use: [
46
- { loader: "style-loader", options: { injectType: "linkTag" } },
47
- "file-loader",
15
+ output: {
16
+ path: path.resolve(__dirname, "dist"),
17
+ filename: isProduction ? "[name].min.js" : "[name].js",
18
+ libraryTarget: "umd",
19
+ libraryExport: "default",
20
+ library: ["CoCreate", "element-prototype"],
21
+ globalObject: "this",
22
+ },
23
+
24
+ plugins: [
25
+ new CleanWebpackPlugin(),
26
+ new MiniCssExtractPlugin({
27
+ filename: "[name].css",
28
+ }),
48
29
  ],
49
- },
50
- ],
51
- },
30
+ // Default mode for Webpack is production.
31
+ // Depending on mode Webpack will apply different things
32
+ // on final bundle. For now we don't need production's JavaScript
33
+ // minifying and other thing so let's set mode to development
34
+ mode: isProduction ? "production" : "development",
35
+ module: {
36
+ rules: [
37
+ {
38
+ test: /.js$/,
39
+ exclude: /(node_modules)/,
40
+ use: {
41
+ loader: "babel-loader",
42
+ options: {
43
+ plugins: ["@babel/plugin-transform-modules-commonjs"],
44
+ },
45
+ },
46
+ },
47
+ {
48
+ test: /.css$/i,
49
+ use: [
50
+ { loader: "style-loader", options: { injectType: "linkTag" } },
51
+ "file-loader",
52
+ ],
53
+ },
54
+ ],
55
+ },
52
56
 
53
- // add source map
54
- ...(isProduction ? {} : { devtool: "eval-source-map" }),
57
+ // add source map
58
+ ...(isProduction ? {} : { devtool: "eval-source-map" }),
55
59
 
56
- optimization: {
57
- minimize: true,
58
- minimizer: [
59
- new TerserPlugin({
60
- extractComments: true,
61
- // cache: true,
62
- parallel: true,
63
- // sourceMap: true, // Must be set to true if using source-maps in production
64
- terserOptions: {
65
- // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
66
- // extractComments: 'all',
67
- compress: {
68
- drop_console: true,
69
- },
70
- },
71
- }),
72
- ],
73
- splitChunks: {
74
- chunks: "all",
75
- minSize: 200,
76
- // maxSize: 99999,
77
- //minChunks: 1,
60
+ optimization: {
61
+ minimize: true,
62
+ minimizer: [
63
+ new TerserPlugin({
64
+ extractComments: true,
65
+ // cache: true,
66
+ parallel: true,
67
+ // sourceMap: true, // Must be set to true if using source-maps in production
68
+ terserOptions: {
69
+ // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions
70
+ // extractComments: 'all',
71
+ compress: {
72
+ drop_console: true,
73
+ },
74
+ },
75
+ }),
76
+ ],
77
+ splitChunks: {
78
+ chunks: "all",
79
+ minSize: 200,
80
+ // maxSize: 99999,
81
+ //minChunks: 1,
78
82
 
79
- cacheGroups: {
80
- defaultVendors: false,
81
- },
82
- },
83
- },
84
- }
83
+ cacheGroups: {
84
+ defaultVendors: false,
85
+ },
86
+ },
87
+ },
88
+ }
89
+ return config
90
+ }