@zipify/wysiwyg 1.0.0-dev.1

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.
Files changed (255) hide show
  1. package/.editorconfig +18 -0
  2. package/.eslintrc.js +253 -0
  3. package/.github/actions/deploy-example/action.yaml +61 -0
  4. package/.github/actions/lint-css/action.yaml +15 -0
  5. package/.github/actions/lint-js/action.yaml +22 -0
  6. package/.github/actions/setup/action.yaml +19 -0
  7. package/.github/actions/unit-tests/action.yaml +13 -0
  8. package/.github/actions/unit-tests/jest.config.js +8 -0
  9. package/.github/dependabot.yaml +17 -0
  10. package/.github/pull_request_template.md +17 -0
  11. package/.github/workflows/frontend-ci.yaml +120 -0
  12. package/.husky/pre-commit +4 -0
  13. package/.lintstagedrc +12 -0
  14. package/.release-it.json +6 -0
  15. package/.stylelintrc +110 -0
  16. package/README.md +61 -0
  17. package/babel.config.js +15 -0
  18. package/ci/example/deploy.sh +25 -0
  19. package/config/jest/TestEnvironment.js +27 -0
  20. package/config/jest/matchers/index.js +6 -0
  21. package/config/jest/matchers/toElementHasStyle.js +27 -0
  22. package/config/jest/matchers/toVueContainComponent.js +20 -0
  23. package/config/jest/matchers/toVueContainElement.js +34 -0
  24. package/config/jest/matchers/toVueContainLazyComponent.js +19 -0
  25. package/config/jest/matchers/toVueEmpty.js +16 -0
  26. package/config/jest/matchers/toVuexActionHasBeenDispatched.js +19 -0
  27. package/config/jest/setupMatchers.js +4 -0
  28. package/config/jest/setupTests.js +32 -0
  29. package/config/jest/typing.d.ts +14 -0
  30. package/config/svgo.js +22 -0
  31. package/config/webpack/example.config.js +86 -0
  32. package/config/webpack/loaders/index.js +6 -0
  33. package/config/webpack/loaders/js-loader.js +5 -0
  34. package/config/webpack/loaders/style-loader.js +7 -0
  35. package/config/webpack/loaders/svg-loader.js +4 -0
  36. package/config/webpack/loaders/vue-loader.js +4 -0
  37. package/config/webpack/settings.js +9 -0
  38. package/example/ExampleApp.vue +136 -0
  39. package/example/example.html +17 -0
  40. package/example/example.js +19 -0
  41. package/example/fonts.js +474 -0
  42. package/example/presets.js +245 -0
  43. package/example/tooltip/Tooltip.js +241 -0
  44. package/example/tooltip/TooltipManager.js +132 -0
  45. package/example/tooltip/index.js +3 -0
  46. package/example/tooltip/modifiers/TooltipCloseOnScrollModifier.js +73 -0
  47. package/example/tooltip/modifiers/index.js +1 -0
  48. package/example/tooltip/tooltip.css +95 -0
  49. package/jest.config.js +17 -0
  50. package/lib/Wysiwyg.vue +156 -0
  51. package/lib/__mocks__/svgMock.js +1 -0
  52. package/lib/__tests__/utils/NodeFactory.js +67 -0
  53. package/lib/__tests__/utils/index.js +4 -0
  54. package/lib/__tests__/utils/setReadonlyProperty.js +9 -0
  55. package/lib/__tests__/utils/waitAsyncOperation.js +6 -0
  56. package/lib/__tests__/utils/withComponentContext.js +14 -0
  57. package/lib/assets/icons.svg +69 -0
  58. package/lib/components/base/Button.vue +117 -0
  59. package/lib/components/base/ButtonToggle.vue +40 -0
  60. package/lib/components/base/FieldLabel.vue +28 -0
  61. package/lib/components/base/Icon.vue +67 -0
  62. package/lib/components/base/Modal.vue +116 -0
  63. package/lib/components/base/NumberField.vue +242 -0
  64. package/lib/components/base/Range.vue +196 -0
  65. package/lib/components/base/ScrollView.vue +60 -0
  66. package/lib/components/base/__tests__/Button.test.js +50 -0
  67. package/lib/components/base/__tests__/Icon.test.js +56 -0
  68. package/lib/components/base/__tests__/Modal.test.js +69 -0
  69. package/lib/components/base/__tests__/Range.test.js +39 -0
  70. package/lib/components/base/colorPicker/ColorPicker.vue +93 -0
  71. package/lib/components/base/colorPicker/composables/__tests__/usePickerApi.test.js +81 -0
  72. package/lib/components/base/colorPicker/composables/index.js +2 -0
  73. package/lib/components/base/colorPicker/composables/usePickerApi.js +35 -0
  74. package/lib/components/base/colorPicker/composables/usePickerHotkeys.js +25 -0
  75. package/lib/components/base/colorPicker/index.js +1 -0
  76. package/lib/components/base/composables/__tests__/useActivatedListener.test.js +89 -0
  77. package/lib/components/base/composables/__tests__/useDeselectionLock.test.js +80 -0
  78. package/lib/components/base/composables/__tests__/useElementRef.test.js +29 -0
  79. package/lib/components/base/composables/__tests__/useModalToggler.test.js +55 -0
  80. package/lib/components/base/composables/__tests__/useNumberValue.test.js +153 -0
  81. package/lib/components/base/composables/__tests__/useScrollView.test.js +43 -0
  82. package/lib/components/base/composables/__tests__/useTempValue.test.js +38 -0
  83. package/lib/components/base/composables/index.js +7 -0
  84. package/lib/components/base/composables/useActivatedListener.js +23 -0
  85. package/lib/components/base/composables/useDeselectionLock.js +35 -0
  86. package/lib/components/base/composables/useElementRef.js +5 -0
  87. package/lib/components/base/composables/useModalToggler.js +58 -0
  88. package/lib/components/base/composables/useNumberValue.js +53 -0
  89. package/lib/components/base/composables/useScrollView.js +22 -0
  90. package/lib/components/base/composables/useTempValue.js +11 -0
  91. package/lib/components/base/dropdown/Dropdown.vue +88 -0
  92. package/lib/components/base/dropdown/DropdownActivator.vue +81 -0
  93. package/lib/components/base/dropdown/DropdownDivider.vue +21 -0
  94. package/lib/components/base/dropdown/DropdownGroup.vue +55 -0
  95. package/lib/components/base/dropdown/DropdownMenu.vue +62 -0
  96. package/lib/components/base/dropdown/DropdownOption.vue +91 -0
  97. package/lib/components/base/dropdown/__tests__/DropdownActivator.test.js +54 -0
  98. package/lib/components/base/dropdown/__tests__/DropdownMenu.test.js +67 -0
  99. package/lib/components/base/dropdown/__tests__/DropdownOption.test.js +81 -0
  100. package/lib/components/base/dropdown/composables/__tests__/useActiveOptionManager.test.js +41 -0
  101. package/lib/components/base/dropdown/composables/__tests__/useDropdownEntityTitle.test.js +24 -0
  102. package/lib/components/base/dropdown/composables/index.js +2 -0
  103. package/lib/components/base/dropdown/composables/useActiveOptionManager.js +25 -0
  104. package/lib/components/base/dropdown/composables/useDropdownEntityTitle.js +5 -0
  105. package/lib/components/base/dropdown/index.js +2 -0
  106. package/lib/components/base/dropdown/injectionTokens.js +5 -0
  107. package/lib/components/base/index.js +11 -0
  108. package/lib/components/index.js +1 -0
  109. package/lib/components/toolbar/Toolbar.vue +56 -0
  110. package/lib/components/toolbar/ToolbarDevice.vue +35 -0
  111. package/lib/components/toolbar/ToolbarDivider.vue +50 -0
  112. package/lib/components/toolbar/ToolbarFull.vue +94 -0
  113. package/lib/components/toolbar/ToolbarGroup.vue +18 -0
  114. package/lib/components/toolbar/ToolbarRow.vue +19 -0
  115. package/lib/components/toolbar/__tests__/Toolbar.test.js +33 -0
  116. package/lib/components/toolbar/__tests__/ToolbarDivider.test.js +26 -0
  117. package/lib/components/toolbar/controls/AlignmentControl.vue +72 -0
  118. package/lib/components/toolbar/controls/AlignmentDeviceControl.vue +67 -0
  119. package/lib/components/toolbar/controls/BackgroundColorControl.vue +48 -0
  120. package/lib/components/toolbar/controls/CaseStyleControl.vue +54 -0
  121. package/lib/components/toolbar/controls/FontColorControl.vue +48 -0
  122. package/lib/components/toolbar/controls/FontFamilyControl.vue +96 -0
  123. package/lib/components/toolbar/controls/FontSizeControl.vue +45 -0
  124. package/lib/components/toolbar/controls/FontWeightControl.vue +43 -0
  125. package/lib/components/toolbar/controls/ItalicControl.vue +47 -0
  126. package/lib/components/toolbar/controls/LineHeightControl.vue +102 -0
  127. package/lib/components/toolbar/controls/ListControl.vue +86 -0
  128. package/lib/components/toolbar/controls/RemoveFormatControl.vue +37 -0
  129. package/lib/components/toolbar/controls/StrikeThroughControl.vue +44 -0
  130. package/lib/components/toolbar/controls/StylePresetControl.vue +95 -0
  131. package/lib/components/toolbar/controls/SuperscriptControl.vue +44 -0
  132. package/lib/components/toolbar/controls/UnderlineControl.vue +44 -0
  133. package/lib/components/toolbar/controls/__tests__/AlignmentControl.test.js +51 -0
  134. package/lib/components/toolbar/controls/__tests__/AlignmentDeviceControl.test.js +77 -0
  135. package/lib/components/toolbar/controls/__tests__/BackgroundColorControl.test.js +59 -0
  136. package/lib/components/toolbar/controls/__tests__/CaseStyleControl.test.js +43 -0
  137. package/lib/components/toolbar/controls/__tests__/FontColorControl.test.js +59 -0
  138. package/lib/components/toolbar/controls/__tests__/FontFamilyControl.test.js +57 -0
  139. package/lib/components/toolbar/controls/__tests__/FontSizeControl.test.js +47 -0
  140. package/lib/components/toolbar/controls/__tests__/FontWeightControl.test.js +45 -0
  141. package/lib/components/toolbar/controls/__tests__/ItalicControl.test.js +63 -0
  142. package/lib/components/toolbar/controls/__tests__/LineHeightControl.test.js +120 -0
  143. package/lib/components/toolbar/controls/__tests__/ListControl.test.js +82 -0
  144. package/lib/components/toolbar/controls/__tests__/RemoveFormatControl.test.js +34 -0
  145. package/lib/components/toolbar/controls/__tests__/StrikeThroughControl.test.js +44 -0
  146. package/lib/components/toolbar/controls/__tests__/StylePresetControl.test.js +129 -0
  147. package/lib/components/toolbar/controls/__tests__/SuperscriptControl.test.js +44 -0
  148. package/lib/components/toolbar/controls/__tests__/UnderlineControl.test.js +44 -0
  149. package/lib/components/toolbar/controls/composables/__tests__/useRecentFonts.test.js +69 -0
  150. package/lib/components/toolbar/controls/composables/index.js +1 -0
  151. package/lib/components/toolbar/controls/composables/useRecentFonts.js +18 -0
  152. package/lib/components/toolbar/controls/index.js +16 -0
  153. package/lib/components/toolbar/index.js +1 -0
  154. package/lib/composables/__tests__/__snapshots__/useEditor.test.js.snap +24 -0
  155. package/lib/composables/__tests__/useEditor.test.js +67 -0
  156. package/lib/composables/__tests__/useToolbar.test.js +56 -0
  157. package/lib/composables/index.js +2 -0
  158. package/lib/composables/useEditor.js +21 -0
  159. package/lib/composables/useToolbar.js +44 -0
  160. package/lib/directives/__tests__/outClick.test.js +86 -0
  161. package/lib/directives/__tests__/tooltip.test.js +39 -0
  162. package/lib/directives/index.js +2 -0
  163. package/lib/directives/outClick.js +37 -0
  164. package/lib/directives/tooltip.js +7 -0
  165. package/lib/enums/Alignments.js +6 -0
  166. package/lib/enums/CaseStyles.js +5 -0
  167. package/lib/enums/Devices.js +15 -0
  168. package/lib/enums/ListTypes.js +23 -0
  169. package/lib/enums/NodeTypes.js +12 -0
  170. package/lib/enums/TextSettings.js +30 -0
  171. package/lib/enums/index.js +6 -0
  172. package/lib/extensions/Alignment.js +67 -0
  173. package/lib/extensions/BackgroundColor.js +28 -0
  174. package/lib/extensions/CaseStyle.js +36 -0
  175. package/lib/extensions/DeviceManager.js +16 -0
  176. package/lib/extensions/FontColor.js +36 -0
  177. package/lib/extensions/FontFamily.js +62 -0
  178. package/lib/extensions/FontSize.js +74 -0
  179. package/lib/extensions/FontStyle.js +62 -0
  180. package/lib/extensions/FontWeight.js +56 -0
  181. package/lib/extensions/LineHeight.js +60 -0
  182. package/lib/extensions/StylePreset.js +168 -0
  183. package/lib/extensions/Superscript.js +5 -0
  184. package/lib/extensions/TextDecoration.js +97 -0
  185. package/lib/extensions/__tests__/Alignment.test.js +107 -0
  186. package/lib/extensions/__tests__/BackgroundColor.test.js +75 -0
  187. package/lib/extensions/__tests__/CaseStyle.test.js +58 -0
  188. package/lib/extensions/__tests__/FontColor.test.js +85 -0
  189. package/lib/extensions/__tests__/FontFamily.test.js +171 -0
  190. package/lib/extensions/__tests__/FontSize.test.js +183 -0
  191. package/lib/extensions/__tests__/FontStyle.test.js +136 -0
  192. package/lib/extensions/__tests__/FontWeight.test.js +151 -0
  193. package/lib/extensions/__tests__/LineHeight.test.js +106 -0
  194. package/lib/extensions/__tests__/StylePreset.test.js +400 -0
  195. package/lib/extensions/__tests__/TextDecoration.test.js +258 -0
  196. package/lib/extensions/__tests__/__snapshots__/Alignment.test.js.snap +29 -0
  197. package/lib/extensions/__tests__/__snapshots__/BackgroundColor.test.js.snap +28 -0
  198. package/lib/extensions/__tests__/__snapshots__/CaseStyle.test.js.snap +69 -0
  199. package/lib/extensions/__tests__/__snapshots__/FontColor.test.js.snap +28 -0
  200. package/lib/extensions/__tests__/__snapshots__/FontFamily.test.js.snap +158 -0
  201. package/lib/extensions/__tests__/__snapshots__/FontSize.test.js.snap +140 -0
  202. package/lib/extensions/__tests__/__snapshots__/FontStyle.test.js.snap +87 -0
  203. package/lib/extensions/__tests__/__snapshots__/FontWeight.test.js.snap +140 -0
  204. package/lib/extensions/__tests__/__snapshots__/LineHeight.test.js.snap +29 -0
  205. package/lib/extensions/__tests__/__snapshots__/StylePreset.test.js.snap +310 -0
  206. package/lib/extensions/__tests__/__snapshots__/TextDecoration.test.js.snap +206 -0
  207. package/lib/extensions/core/NodeProcessor.js +32 -0
  208. package/lib/extensions/core/SelectionProcessor.js +37 -0
  209. package/lib/extensions/core/TextProcessor.js +57 -0
  210. package/lib/extensions/core/__tests__/NodeProcessor.test.js +120 -0
  211. package/lib/extensions/core/__tests__/SelectionProcessor.test.js +78 -0
  212. package/lib/extensions/core/__tests__/TextProcessor.test.js +61 -0
  213. package/lib/extensions/core/__tests__/__snapshots__/NodeProcessor.test.js.snap +93 -0
  214. package/lib/extensions/core/__tests__/__snapshots__/TextProcessor.test.js.snap +43 -0
  215. package/lib/extensions/core/index.js +17 -0
  216. package/lib/extensions/core/inputRules/closeDoubleQuote.js +6 -0
  217. package/lib/extensions/core/inputRules/closeSingleQuote.js +6 -0
  218. package/lib/extensions/core/inputRules/copyright.js +6 -0
  219. package/lib/extensions/core/inputRules/ellipsis.js +6 -0
  220. package/lib/extensions/core/inputRules/emDash.js +6 -0
  221. package/lib/extensions/core/inputRules/index.js +9 -0
  222. package/lib/extensions/core/inputRules/openDoubleQuote.js +6 -0
  223. package/lib/extensions/core/inputRules/openSingleQuote.js +6 -0
  224. package/lib/extensions/core/inputRules/registeredTrademark.js +6 -0
  225. package/lib/extensions/core/inputRules/trademark.js +6 -0
  226. package/lib/extensions/index.js +49 -0
  227. package/lib/extensions/list/List.js +81 -0
  228. package/lib/extensions/list/ListItem.js +12 -0
  229. package/lib/extensions/list/__tests__/List.test.js +130 -0
  230. package/lib/extensions/list/__tests__/__snapshots__/List.test.js.snap +212 -0
  231. package/lib/extensions/list/index.js +1 -0
  232. package/lib/index.js +1 -0
  233. package/lib/injectionTokens.js +7 -0
  234. package/lib/models/Font.js +37 -0
  235. package/lib/models/__tests__/Font.test.js +58 -0
  236. package/lib/models/index.js +1 -0
  237. package/lib/services/FavoriteColors.js +6 -0
  238. package/lib/services/JsonSerializer.js +15 -0
  239. package/lib/services/Storage.js +49 -0
  240. package/lib/services/index.js +3 -0
  241. package/lib/styles/content.css +39 -0
  242. package/lib/styles/helpers/common.css +3 -0
  243. package/lib/styles/helpers/offsets.css +3 -0
  244. package/lib/styles/helpers/text.css +6 -0
  245. package/lib/styles/main.css +5 -0
  246. package/lib/styles/variables.css +57 -0
  247. package/lib/utils/__tests__/__snapshots__/renderInlineSetting.test.js.snap +40 -0
  248. package/lib/utils/__tests__/capitalize.test.js +11 -0
  249. package/lib/utils/__tests__/renderInlineSetting.test.js +39 -0
  250. package/lib/utils/capitalize.js +3 -0
  251. package/lib/utils/createCommand.js +3 -0
  252. package/lib/utils/createKeyboardShortcut.js +6 -0
  253. package/lib/utils/index.js +4 -0
  254. package/lib/utils/renderInlineSetting.js +17 -0
  255. package/package.json +75 -0
package/.stylelintrc ADDED
@@ -0,0 +1,110 @@
1
+ {
2
+ "rules": {
3
+ "at-rule-name-case": "lower",
4
+ "at-rule-name-space-after": "always-single-line",
5
+ "at-rule-semicolon-newline-after": "always",
6
+ "selector-type-case": "lower",
7
+ "block-closing-brace-newline-after": "always",
8
+ "selector-pseudo-element-colon-notation": "double",
9
+ "selector-pseudo-element-case": "lower",
10
+ "selector-max-specificity": "0,4,2",
11
+ "number-no-trailing-zeros": true,
12
+ "color-named": "never",
13
+ "color-hex-length": "short",
14
+ "color-no-invalid-hex": true,
15
+ "font-weight-notation": "numeric",
16
+ "function-calc-no-unspaced-operator": true,
17
+ "function-comma-newline-before": "never-multi-line",
18
+ "function-comma-space-before": "never-single-line",
19
+ "function-linear-gradient-no-nonstandard-direction": true,
20
+ "function-name-case": "lower",
21
+ "function-parentheses-space-inside": "never",
22
+ "function-url-no-scheme-relative": true,
23
+ "function-url-quotes": "always",
24
+ "function-whitespace-after": "always",
25
+ "string-no-newline": true,
26
+ "string-quotes": "double",
27
+ "time-min-milliseconds": 100,
28
+ "length-zero-no-unit": [
29
+ true,
30
+ { "ignore": ["custom-properties"] }
31
+ ],
32
+ "unit-case": "lower",
33
+ "value-keyword-case": [
34
+ "lower",
35
+ {
36
+ "ignoreKeywords": ["currentColor", "optimizeLegibility"]
37
+ }
38
+ ],
39
+ "value-no-vendor-prefix": true,
40
+ "max-empty-lines": 2,
41
+ "no-descending-specificity": true,
42
+ "no-empty-source": true,
43
+ "no-eol-whitespace": true,
44
+ "no-extra-semicolons": true,
45
+ "no-unknown-animations": true,
46
+ "declaration-colon-space-before": "never",
47
+ "declaration-colon-space-after": "always",
48
+ "block-no-empty": true,
49
+ "shorthand-property-no-redundant-values": true,
50
+ "block-opening-brace-newline-after": "always-multi-line",
51
+ "block-opening-brace-space-before": "always",
52
+ "block-opening-brace-space-after": "always-single-line",
53
+ "named-grid-areas-no-invalid": true,
54
+ "declaration-empty-line-before": [
55
+ "always",
56
+ {
57
+ "except": [
58
+ "after-declaration",
59
+ "first-nested"
60
+ ]
61
+ }
62
+ ],
63
+ "block-closing-brace-empty-line-before": "never",
64
+ "rule-empty-line-before": [
65
+ "always-multi-line"
66
+ ],
67
+ "at-rule-empty-line-before": [
68
+ "always",
69
+ {
70
+ "except": [
71
+ "blockless-after-same-name-blockless",
72
+ "first-nested"
73
+ ],
74
+ "ignore": [
75
+ "after-comment"
76
+ ]
77
+ }
78
+ ],
79
+ "at-rule-no-unknown": [
80
+ true,
81
+ {
82
+ "ignoreAtRules": [
83
+ "include",
84
+ "mixin",
85
+ "content",
86
+ "at-root"
87
+ ]
88
+ }
89
+ ],
90
+ "number-leading-zero": "always",
91
+ "unit-allowed-list": ["em", "rem", "px", "%", "s", "vh", "deg", "ms", "fr"],
92
+ "color-hex-case": "upper",
93
+ "max-nesting-depth": 3,
94
+ "indentation": [
95
+ 4,
96
+ { "indentInsideParens": "twice" }
97
+ ],
98
+ "keyframe-block-no-duplicate-selectors": true
99
+ },
100
+ "overrides": [
101
+ {
102
+ "files": ["**/*.scss"],
103
+ "customSyntax": "postcss-scss"
104
+ },
105
+ {
106
+ "files": ["**/*.vue"],
107
+ "customSyntax": "postcss-html"
108
+ }
109
+ ]
110
+ }
package/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # ZipifyWysiwyg
2
+
3
+ Zipify modification of TipTap text editor
4
+
5
+ ## Usage
6
+ 1. Install library & dependencies
7
+ ```shell
8
+ # if npm
9
+ npm install @zipify/wysiwyg @vue/composition-api
10
+ # if yarn
11
+ yarn add @zipify/wysiwyg @vue/composition-api
12
+ ```
13
+ 2. Register plugins
14
+ ```js
15
+ import Vue from 'vue';
16
+ import VueCompositionAPI from '@vue/composition-api';
17
+
18
+ Vue.use(VueCompositionAPI);
19
+ ```
20
+ 3. Use editor
21
+
22
+ For more details see [example app](/example)
23
+ ```vue
24
+
25
+ <template>
26
+ <Wysiwyg v-model="content" />
27
+ </template>
28
+
29
+ <script>
30
+ import { Wysiwyg } from '@zipify/wysiwyg';
31
+
32
+ export default {
33
+ components: { Wysiwyg },
34
+
35
+ data: () => ({
36
+ content: {
37
+ type: 'doc',
38
+ content: [...]
39
+ }
40
+ })
41
+ }
42
+ </script>
43
+ ```
44
+
45
+ ## Contribute
46
+ 1. Clone repository
47
+ ```shell
48
+ git clone git@github.com:ZipifyApps/ZipifyWysiwyg.git
49
+ ```
50
+ 2. Install dependencies
51
+ ```shell
52
+ npm install
53
+ ```
54
+ 3. Open example project
55
+ ```shell
56
+ npm run example:start
57
+ # Will be available on http://localhost:7777
58
+ ```
59
+ 4. Create new branch
60
+ 5. Add changes & tests
61
+ 6. Open pull request
@@ -0,0 +1,15 @@
1
+ module.exports = function(api) {
2
+ api.cache(true);
3
+
4
+ return {
5
+ presets: [
6
+ [
7
+ '@babel/preset-env',
8
+ { ignoreBrowserslistConfig: false }
9
+ ]
10
+ ],
11
+ plugins: [
12
+ '@babel/plugin-transform-runtime'
13
+ ]
14
+ };
15
+ };
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env bash
2
+
3
+ export AWS_CONFIG_FILE=./ci/example/.aws-credentials
4
+
5
+ function throw_error() {
6
+ echo -e "\033[0;31m \n\n$1\n\n";
7
+ exit;
8
+ }
9
+
10
+ if ! command -v aws &> /dev/null; then
11
+ throw_error 'AWS CLI not found. Download from https://aws.amazon.com/cli/'
12
+ fi;
13
+
14
+ if [ ! -f "$AWS_CONFIG_FILE" ]; then
15
+ throw_error 'AWS credentials config not found'
16
+ fi;
17
+
18
+ echo Building... && \
19
+ rm -rf ./example/dist && \
20
+ npm run example:build > /dev/null && \
21
+ npx --yes gzipper compress ./example/dist > /dev/null && \
22
+ echo Uploading... && \
23
+ BRANCH_NAME=$(git branch --show-current) && \
24
+ aws s3 sync --acl public-read --cache-control 'max-age=0,no-cache,no-store,must-revalidate' "./example/dist" "s3://zipify-wysiwyg/$BRANCH_NAME" > /dev/null && \
25
+ echo "on https://zipify-wysiwyg.s3.eu-central-1.amazonaws.com/$BRANCH_NAME/index.html"
@@ -0,0 +1,27 @@
1
+ /* eslint-disable no-console */
2
+
3
+ import { ErrorWithStack } from 'jest-util';
4
+ import JSDOMEnvironment from 'jest-environment-jsdom';
5
+
6
+ export default class TestEnvironment extends JSDOMEnvironment {
7
+ constructor() {
8
+ super(...arguments);
9
+
10
+ this.rejectedPromises = [];
11
+
12
+ this.global.process.on('unhandledRejection', (error) => {
13
+ console.error(error);
14
+ this.rejectedPromises.push(error);
15
+ });
16
+ }
17
+
18
+ async teardown() {
19
+ await new Promise(setImmediate);
20
+
21
+ if (this.rejectedPromises.length > 0) {
22
+ throw new ErrorWithStack('Unhandled Promise rejections', this.teardown);
23
+ }
24
+
25
+ await super.teardown();
26
+ }
27
+ }
@@ -0,0 +1,6 @@
1
+ export { toVueContainComponent } from './toVueContainComponent';
2
+ export { toVueContainLazyComponent } from './toVueContainLazyComponent';
3
+ export { toVueContainElement } from './toVueContainElement';
4
+ export { toVuexActionHasBeenDispatched } from './toVuexActionHasBeenDispatched';
5
+ export { toVueEmpty } from './toVueEmpty';
6
+ export { toElementHasStyle } from './toElementHasStyle';
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @param element {HTMLElement}
3
+ * @param name {String}
4
+ * @param value {*}
5
+ */
6
+ export function toElementHasStyle(element, name, value = '') {
7
+ const renderedStyle = element.style.getPropertyValue(name);
8
+
9
+ if (renderedStyle && renderedStyle === value) {
10
+ return {
11
+ pass: true,
12
+ message: () => [
13
+ 'Element has style',
14
+ `Rendered "${name}: ${renderedStyle}"`
15
+ ].join('\n')
16
+ };
17
+ }
18
+
19
+ return {
20
+ pass: false,
21
+ message: () => [
22
+ 'Element hasn\'t style',
23
+ `Expected "${name}: ${value}"`,
24
+ `Rendered "${name}: ${renderedStyle}"`
25
+ ].join('\n')
26
+ };
27
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @param componentWrapper {Wrapper}
3
+ * @param Component {Vue} Vue component class
4
+ */
5
+ export function toVueContainComponent(componentWrapper, Component) {
6
+ const checkingComponent = componentWrapper.findComponent(Component);
7
+ const componentId = Component.name || `\n${JSON.stringify(Component, null, 4)}`;
8
+
9
+ if (checkingComponent.exists()) {
10
+ return {
11
+ pass: true,
12
+ message: () => `Vue component contains component: ${componentId}`
13
+ };
14
+ }
15
+
16
+ return {
17
+ pass: false,
18
+ message: () => `Vue component doesn't contain component: ${componentId}`
19
+ };
20
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @param componentWrapper {Wrapper}
3
+ * @param selector {selector} value of test data attribute
4
+ */
5
+ export function toVueContainElement(componentWrapper, selector) {
6
+ if (typeof selector !== 'string') {
7
+ throw new Error(`Expect value of data-test-selector attribute but found ${JSON.stringify(selector)}`);
8
+ }
9
+
10
+ function findElement() {
11
+ const checkingComponent = componentWrapper.find(selector);
12
+
13
+ try {
14
+ if (checkingComponent.exists()) {
15
+ return checkingComponent;
16
+ }
17
+ return componentWrapper.find(`[data-test-selector="${selector}"]`);
18
+ } catch (_) {
19
+ return null;
20
+ }
21
+ }
22
+
23
+ if (findElement()?.exists()) {
24
+ return {
25
+ pass: true,
26
+ message: () => 'Vue component contains expected element'
27
+ };
28
+ }
29
+
30
+ return {
31
+ pass: false,
32
+ message: () => `Vue component doesn't contain element: ${selector}`
33
+ };
34
+ }
@@ -0,0 +1,19 @@
1
+ import { toVueContainComponent } from './toVueContainComponent';
2
+
3
+ function importComponent(Component) {
4
+ if (typeof Component !== 'function') return Promise.resolve(Component);
5
+
6
+ return Component().then((module) => module.default);
7
+ }
8
+
9
+ /**
10
+ * @param componentWrapper {Wrapper}
11
+ * @param Component {Function|Vue} import of lazy Vue component
12
+ */
13
+ export async function toVueContainLazyComponent(componentWrapper, Component) {
14
+ const LoadedComponentClass = await importComponent(Component);
15
+
16
+ await componentWrapper.vm.$nextTick();
17
+
18
+ return toVueContainComponent(componentWrapper, LoadedComponentClass);
19
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @param componentWrapper {Wrapper}
3
+ */
4
+ export function toVueEmpty(componentWrapper) {
5
+ if (componentWrapper.vnode.isComment || !componentWrapper.html()) {
6
+ return {
7
+ pass: true,
8
+ message: () => 'Vue component is empty'
9
+ };
10
+ }
11
+
12
+ return {
13
+ pass: false,
14
+ message: () => 'Vue component isn\'t empty'
15
+ };
16
+ }
@@ -0,0 +1,19 @@
1
+ export function toVuexActionHasBeenDispatched(store, actionName) {
2
+ if (!store.dispatch || !jest.isMockFunction(store.dispatch)) {
3
+ throw new Error('You should mock "dispatch" method in component store');
4
+ }
5
+
6
+ const dispatchCalls = store.dispatch.mock.calls;
7
+ const isActionDispatched = dispatchCalls.some(([dispatchedAction]) => dispatchedAction === actionName);
8
+
9
+ if (isActionDispatched) {
10
+ return {
11
+ pass: true,
12
+ message: () => `Action "${actionName}" has been called`
13
+ };
14
+ }
15
+ return {
16
+ pass: false,
17
+ message: () => `Action "${actionName}" hasn't been called`
18
+ };
19
+ }
@@ -0,0 +1,4 @@
1
+ // eslint-disable-next-line import/no-namespace
2
+ import * as matchers from './matchers';
3
+
4
+ expect.extend(matchers);
@@ -0,0 +1,32 @@
1
+ import Vue from 'vue';
2
+ import CompositionAPI from '@vue/composition-api';
3
+
4
+ // eslint-disable-next-line no-console
5
+ console.warn = jest.fn();
6
+
7
+ Vue.use(CompositionAPI);
8
+
9
+ // Fail tests on vue warnings
10
+ Vue.config.warnHandler = (error) => { throw error; };
11
+ Vue.config.devtools = false;
12
+ Vue.config.productionTip = false;
13
+
14
+ // JSDOM DOESN'T support follow methods
15
+
16
+ global.HTMLElement.prototype.scrollIntoView = jest.fn();
17
+ global.HTMLElement.prototype.scrollTo = jest.fn();
18
+
19
+ Range.prototype.getBoundingClientRect = () => ({
20
+ bottom: 0,
21
+ height: 0,
22
+ left: 0,
23
+ right: 0,
24
+ top: 0,
25
+ width: 0
26
+ });
27
+
28
+ Range.prototype.getClientRects = () => ({
29
+ item: () => null,
30
+ length: 0,
31
+ [Symbol.iterator]: jest.fn()
32
+ });
@@ -0,0 +1,14 @@
1
+ // Add types for IDE autocomplete
2
+
3
+ declare global {
4
+ interface Matchers {
5
+ toVueContainElement(selectorId: string): void;
6
+ toVueContainComponent(component: object): void;
7
+ toVueContainLazyComponent(component: object | (() => Promise<object>)): void;
8
+ toVueEmpty(): void;
9
+ toVuexActionHasBeenDispatched(action: string): void;
10
+ toElementHasStyle(name: string, string?: any): void;
11
+ }
12
+
13
+ interface JestMatchers extends Matchers {}
14
+ }
package/config/svgo.js ADDED
@@ -0,0 +1,22 @@
1
+ module.exports = {
2
+ js2svg: {
3
+ indent: 4,
4
+ pretty: true
5
+ },
6
+ multipass: true,
7
+ plugins: [
8
+ {
9
+ name: 'preset-default',
10
+ params: { removeViewBox: false }
11
+ },
12
+ 'removeDimensions',
13
+ 'sortAttrs',
14
+ 'convertStyleToAttrs',
15
+ {
16
+ name: 'removeAttrs',
17
+ params: {
18
+ attrs: 'data.*'
19
+ }
20
+ }
21
+ ]
22
+ };
@@ -0,0 +1,86 @@
1
+ const path = require('path');
2
+ const { DefinePlugin } = require('webpack');
3
+ const HtmlWebpackPlugin = require('html-webpack-plugin');
4
+ const { VueLoaderPlugin } = require('vue-loader');
5
+ const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
6
+ const { resolvePath, isDevelopment } = require('./settings');
7
+ const loaders = require('./loaders');
8
+
9
+ const isAnalyzerEnabled = !!process.env.ANALYZE_BUILD;
10
+ const filename = isDevelopment ? '[name].js' : '[name].[contenthash].js';
11
+
12
+ module.exports = {
13
+ mode: isDevelopment ? 'development' : 'production',
14
+ entry: resolvePath('./example/example.js'),
15
+ devtool: isDevelopment ? 'eval-source-map' : false,
16
+
17
+ output: {
18
+ clean: true,
19
+ path: resolvePath('./example/dist'),
20
+ filename,
21
+ chunkFilename: filename,
22
+ devtoolFallbackModuleFilenameTemplate: 'webpack:///[resource-path]?[hash]',
23
+ devtoolModuleFilenameTemplate: (info) => {
24
+ let resPath = path.normalize(info.resourcePath);
25
+ let isVue = resPath.match(/\.vue$/);
26
+ let isGenerated = info.allLoaders;
27
+
28
+ let generated = `webpack-generated:///${resPath}?${info.hash}`;
29
+ let vuesource = `parsed:///${resPath}`;
30
+
31
+ return isVue && isGenerated ? generated : vuesource;
32
+ }
33
+ },
34
+
35
+ cache: {
36
+ type: 'filesystem',
37
+ cacheDirectory: resolvePath('./example/.cache')
38
+ },
39
+
40
+ devServer: {
41
+ host: 'localhost',
42
+ port: 7777,
43
+ devMiddleware: { publicPath: '/' }
44
+ },
45
+
46
+ resolve: {
47
+ extensions: ['*', '.js', '.vue', '.json']
48
+ },
49
+
50
+ optimization: {
51
+ splitChunks: {
52
+ chunks: 'all',
53
+ cacheGroups: {
54
+ vue: {
55
+ name: 'vue',
56
+ test: /[\\/]node_modules[\\/]@?vue/
57
+ },
58
+ tiptap: {
59
+ name: 'tiptap',
60
+ test: /[\\/]node_modules[\\/](@?tiptap|prosemirror)/
61
+ }
62
+ }
63
+ }
64
+ },
65
+
66
+ module: {
67
+ rules: [
68
+ loaders.style,
69
+ loaders.js,
70
+ loaders.svg,
71
+ loaders.vue
72
+ ]
73
+ },
74
+
75
+ plugins: [
76
+ new VueLoaderPlugin(),
77
+ new HtmlWebpackPlugin({
78
+ title: 'ZipifyWysiwyg',
79
+ template: resolvePath('./example/example.html')
80
+ }),
81
+ new DefinePlugin({
82
+ ZW_UPDATED_AT: JSON.stringify(Date.now())
83
+ }),
84
+ ...(isAnalyzerEnabled ? [new BundleAnalyzerPlugin()] : [])
85
+ ]
86
+ };
@@ -0,0 +1,6 @@
1
+ module.exports = {
2
+ style: require('./style-loader'),
3
+ svg: require('./svg-loader'),
4
+ js: require('./js-loader'),
5
+ vue: require('./vue-loader')
6
+ };
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ test: /\.js?$/,
3
+ exclude: /(node_modules)/,
4
+ loader: 'babel-loader'
5
+ };
@@ -0,0 +1,7 @@
1
+ module.exports = {
2
+ test: /\.s?css$/,
3
+ use: [
4
+ 'vue-style-loader',
5
+ 'css-loader'
6
+ ]
7
+ };
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ test: /\.svg$/,
3
+ type: 'asset/resource'
4
+ };
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ test: /\.vue$/,
3
+ use: { loader: 'vue-loader' }
4
+ };
@@ -0,0 +1,9 @@
1
+ const path = require('path');
2
+
3
+ const root = path.resolve(__dirname, '../..');
4
+
5
+ module.exports = {
6
+ root,
7
+ resolvePath: (...parts) => path.resolve(root, ...parts),
8
+ isDevelopment: process.env.NODE_ENV === 'development'
9
+ };