punkweb-bb 0.2.2__py3-none-any.whl → 0.3.0__py3-none-any.whl

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 (110) hide show
  1. punkweb_bb/__pycache__/admin.cpython-311.pyc +0 -0
  2. punkweb_bb/__pycache__/admin_forms.cpython-311.pyc +0 -0
  3. punkweb_bb/__pycache__/forms.cpython-311.pyc +0 -0
  4. punkweb_bb/__pycache__/models.cpython-311.pyc +0 -0
  5. punkweb_bb/__pycache__/settings.cpython-311.pyc +0 -0
  6. punkweb_bb/__pycache__/sitemap.cpython-311.pyc +0 -0
  7. punkweb_bb/__pycache__/tests.cpython-311.pyc +0 -0
  8. punkweb_bb/__pycache__/urls.cpython-311.pyc +0 -0
  9. punkweb_bb/__pycache__/utils.cpython-311.pyc +0 -0
  10. punkweb_bb/__pycache__/views.cpython-311.pyc +0 -0
  11. punkweb_bb/__pycache__/widgets.cpython-311.pyc +0 -0
  12. punkweb_bb/admin.py +0 -4
  13. punkweb_bb/admin_forms.py +6 -5
  14. punkweb_bb/forms.py +13 -5
  15. punkweb_bb/migrations/0005_alter_thread_options.py +24 -0
  16. punkweb_bb/migrations/0006_remove_boardprofile__signature_rendered_and_more.py +60 -0
  17. punkweb_bb/migrations/__pycache__/0005_alter_thread_options.cpython-311.pyc +0 -0
  18. punkweb_bb/migrations/__pycache__/0006_remove_boardprofile__signature_rendered_and_more.cpython-311.pyc +0 -0
  19. punkweb_bb/models.py +12 -9
  20. punkweb_bb/settings.py +1 -0
  21. punkweb_bb/static/punkweb_bb/css/thread.css +45 -28
  22. punkweb_bb/static/punkweb_bb/editor/markdown-editor.js +23 -0
  23. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/.eslintrc.json +15 -0
  24. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/.gitignore +108 -0
  25. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/.prettierrc.json +1 -0
  26. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/LICENSE +21 -0
  27. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/README.md +240 -0
  28. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/babel.config.json +14 -0
  29. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/blank.html +18 -0
  30. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/demo.html +126 -0
  31. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.css +231 -0
  32. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.js +3086 -0
  33. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.min.css +1 -0
  34. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.min.js +1 -0
  35. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/dist/tiny-mde.tiny.js +1 -0
  36. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/docs/_config.yml +1 -0
  37. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/docs/_layouts/default.html +50 -0
  38. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/docs/index.md +174 -0
  39. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/globals.d.ts +172 -0
  40. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/gulpfile.mjs +226 -0
  41. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/block.test.js +696 -0
  42. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/commandbar.test.js +84 -0
  43. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/inline.test.js +486 -0
  44. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/interaction.test.js +31 -0
  45. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/setup.test.js +164 -0
  46. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/util/config.js +2 -0
  47. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/util/server.js +9 -0
  48. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/util/setup.js +1 -0
  49. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest/util/test-helpers.js +98 -0
  50. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest-puppeteer.config.js +8 -0
  51. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/jest.config.js +13 -0
  52. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/package-lock.json +16295 -0
  53. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/package.json +72 -0
  54. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/TinyMDE.js +1926 -0
  55. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/TinyMDECommandBar.js +256 -0
  56. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/css/commandbar.css +72 -0
  57. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/css/editor.css +157 -0
  58. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/css/index.css +3 -0
  59. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/grammar.js +300 -0
  60. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/html/blank.html +18 -0
  61. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/html/demo.html +126 -0
  62. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/index.js +4 -0
  63. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/blockquote.svg +1 -0
  64. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/bold.svg +1 -0
  65. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/clear_formatting.svg +1 -0
  66. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/code.svg +1 -0
  67. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/h1.svg +1 -0
  68. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/h2.svg +1 -0
  69. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/hr.svg +1 -0
  70. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/image.svg +1 -0
  71. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/italic.svg +1 -0
  72. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/link.svg +1 -0
  73. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/ol.svg +1 -0
  74. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/strikethrough.svg +1 -0
  75. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/svg.js +17 -0
  76. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/svg/ul.svg +1 -0
  77. punkweb_bb/static/punkweb_bb/vendor/tiny-markdown-editor/src/tiny.js +3 -0
  78. punkweb_bb/templates/punkweb_bb/base_delete_modal.html +13 -0
  79. punkweb_bb/templates/punkweb_bb/index.html +2 -2
  80. punkweb_bb/templates/punkweb_bb/members.html +3 -1
  81. punkweb_bb/templates/punkweb_bb/partials/category_delete.html +4 -8
  82. punkweb_bb/templates/punkweb_bb/partials/post_delete.html +4 -8
  83. punkweb_bb/templates/punkweb_bb/partials/shout_delete.html +4 -8
  84. punkweb_bb/templates/punkweb_bb/partials/subcategory_delete.html +4 -8
  85. punkweb_bb/templates/punkweb_bb/partials/thread_delete.html +4 -8
  86. punkweb_bb/templates/punkweb_bb/partials/thread_move.html +24 -0
  87. punkweb_bb/templates/punkweb_bb/profile.html +8 -4
  88. punkweb_bb/templates/punkweb_bb/shoutbox/shout_list.html +3 -3
  89. punkweb_bb/templates/punkweb_bb/subcategory.html +1 -1
  90. punkweb_bb/templates/punkweb_bb/thread.html +89 -71
  91. punkweb_bb/templates/punkweb_bb/widgets/markdown-editor.html +3 -0
  92. punkweb_bb/templatetags/__pycache__/markdown.cpython-311.pyc +0 -0
  93. punkweb_bb/templatetags/__pycache__/render.cpython-311.pyc +0 -0
  94. punkweb_bb/templatetags/__pycache__/shoutbox_bbcode.cpython-311.pyc +0 -0
  95. punkweb_bb/templatetags/__pycache__/shoutbox_render.cpython-311.pyc +0 -0
  96. punkweb_bb/templatetags/__pycache__/styled_group_name.cpython-311.pyc +0 -0
  97. punkweb_bb/templatetags/render.py +48 -0
  98. punkweb_bb/templatetags/shoutbox_render.py +22 -0
  99. punkweb_bb/templatetags/styled_group_name.py +2 -2
  100. punkweb_bb/tests.py +3 -3
  101. punkweb_bb/urls.py +1 -0
  102. punkweb_bb/utils.py +23 -7
  103. punkweb_bb/views.py +36 -7
  104. punkweb_bb/widgets.py +20 -0
  105. {punkweb_bb-0.2.2.dist-info → punkweb_bb-0.3.0.dist-info}/METADATA +56 -41
  106. {punkweb_bb-0.2.2.dist-info → punkweb_bb-0.3.0.dist-info}/RECORD +109 -41
  107. punkweb_bb/templatetags/shoutbox_bbcode.py +0 -14
  108. {punkweb_bb-0.2.2.dist-info → punkweb_bb-0.3.0.dist-info}/LICENSE +0 -0
  109. {punkweb_bb-0.2.2.dist-info → punkweb_bb-0.3.0.dist-info}/WHEEL +0 -0
  110. {punkweb_bb-0.2.2.dist-info → punkweb_bb-0.3.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,164 @@
1
+
2
+ test('sets up correctly when passed an ID', async () => {
3
+ const newPage = await browser.newPage();
4
+ await newPage.goto(PATH, { waitUntil: 'load'});
5
+
6
+ await newPage.evaluate(() => {
7
+ const tinyMDE = new TinyMDE.Editor({element: 'tinymde'});
8
+ })
9
+ expect(await newPage.$eval('#tinymde > :first-child', el => el.className)).toBe('TinyMDE');
10
+ newPage.close();
11
+ });
12
+
13
+ test('sets up correctly when passed an element', async () => {
14
+ const newPage = await browser.newPage();
15
+ await newPage.goto(PATH, { waitUntil: 'load'});
16
+
17
+ await newPage.evaluate(() => {
18
+ const tinyMDE = new TinyMDE.Editor({element: document.getElementById('tinymde')});
19
+ })
20
+ expect(await newPage.$eval('#tinymde > :first-child', el => el.className)).toBe('TinyMDE');
21
+ newPage.close();
22
+ });
23
+
24
+ test('sets up correctly when passed a textarea ID as element', async () => {
25
+ const newPage = await browser.newPage();
26
+ await newPage.goto(PATH, { waitUntil: 'load'});
27
+ await newPage.$eval('#tinymde', el => el.innerHTML = '<textarea id="txt"></textarea>');
28
+ await newPage.evaluate(() => {
29
+ const tinyMDE = new TinyMDE.Editor({element: document.getElementById('txt')});
30
+ })
31
+ expect(await newPage.$eval('#tinymde > :last-child', el => el.className)).toBe('TinyMDE');
32
+ expect(await newPage.$eval('#tinymde > :first-child', el => el.tagName)).toBe('TEXTAREA');
33
+ expect(await newPage.$eval('#txt', el => el.style.display)).toBe('none');
34
+ newPage.close();
35
+ });
36
+
37
+ test('sets up correctly when passed an element AND a textarea', async () => {
38
+ const newPage = await browser.newPage();
39
+ await newPage.goto(PATH, { waitUntil: 'load'});
40
+ await newPage.$eval('#tinymde', el => el.innerHTML = '<textarea id="txt"></textarea>');
41
+
42
+ await newPage.evaluate(() => {
43
+ const tinyMDE = new TinyMDE.Editor({element: 'tinymde', textarea: 'txt'});
44
+ })
45
+ expect(await newPage.$eval('#tinymde > :last-child', el => el.className)).toBe('TinyMDE');
46
+ expect(await newPage.$eval('#txt', el => el.style.display)).toBe('none');
47
+
48
+ newPage.close();
49
+ });
50
+
51
+
52
+ test('Content can be passed to constructor', async () => {
53
+ const newPage = await browser.newPage();
54
+ await newPage.goto(PATH, { waitUntil: 'load'});
55
+
56
+ const content = '# XXXA\nXXXB *XXXC*';
57
+
58
+ const tinymdeContent = await newPage.evaluate((content) => {
59
+ const tinyMDE = new TinyMDE.Editor({element: 'tinymde', content: content});
60
+ return tinyMDE.getContent();
61
+ }, content);
62
+
63
+ expect(tinymdeContent).toEqual(content);
64
+ newPage.close();
65
+ });
66
+
67
+ test('Content can be passed from textarea', async () => {
68
+ const newPage = await browser.newPage();
69
+ await newPage.goto(PATH, { waitUntil: 'load'});
70
+
71
+ const content = '# XXXA';
72
+
73
+ const tinymdeContent = await newPage.evaluate((content) => {
74
+ const textarea = document.createElement('textarea');
75
+ textarea.value = content;
76
+ document.body.appendChild(textarea);
77
+ const tinyMDE = new TinyMDE.Editor({element: 'tinymde', textarea: textarea});
78
+ return tinyMDE.getContent();
79
+ }, content);
80
+
81
+ expect(tinymdeContent).toEqual(content);
82
+ newPage.close();
83
+ });
84
+
85
+ test('Content passed in constructor has precedence over textarea content', async () => {
86
+ const newPage = await browser.newPage();
87
+ await newPage.goto(PATH, { waitUntil: 'load'});
88
+
89
+ const textareaContent = '# XXXA';
90
+ const constructorContent = '# XXXB';
91
+
92
+ const tinymdeContent = await newPage.evaluate((textareaContent, constructorContent) => {
93
+ const textarea = document.createElement('textarea');
94
+ textarea.value = textareaContent;
95
+ document.body.appendChild(textarea);
96
+ const tinyMDE = new TinyMDE.Editor({element: 'tinymde', textarea: textarea, content: constructorContent});
97
+ return tinyMDE.getContent();
98
+ }, textareaContent, constructorContent)
99
+
100
+ expect(tinymdeContent).toEqual(constructorContent);
101
+ newPage.close();
102
+ });
103
+
104
+
105
+ test('Content can be set using setContent()', async () => {
106
+ const newPage = await browser.newPage();
107
+ await newPage.goto(PATH, { waitUntil: 'load'});
108
+
109
+ const content = '# XXXA\nXXXB *XXXC*';
110
+
111
+ const tinymdeContent = await newPage.evaluate((content) => {
112
+ const tinyMDE = new TinyMDE.Editor({element: 'tinymde'});
113
+ tinyMDE.setContent(content);
114
+ return tinyMDE.getContent();
115
+ }, content);
116
+
117
+ expect(tinymdeContent).toEqual(content);
118
+
119
+ newPage.close();
120
+ });
121
+
122
+ test('Linked textarea updated on setContent()', async () => {
123
+ const newPage = await browser.newPage();
124
+ await newPage.goto(PATH, { waitUntil: 'load'});
125
+
126
+ const content = '# XXXA\nXXXB *XXXC*';
127
+
128
+ const {tinymdeContent, textareaContent} = await newPage.evaluate((content) => {
129
+ const textarea = document.createElement('textarea');
130
+ document.body.appendChild(textarea);
131
+ const tinyMDE = new TinyMDE.Editor({element: 'tinymde', textarea: textarea});
132
+ tinyMDE.setContent(content);
133
+
134
+ return {
135
+ tinymdeContent: tinyMDE.getContent(),
136
+ textareaContent: textarea.value
137
+ }
138
+ }, content);
139
+
140
+ expect(tinymdeContent).toEqual(content);
141
+ expect(textareaContent).toEqual(content);
142
+
143
+ newPage.close();
144
+ })
145
+
146
+ test('Change event listeners called on setContent()', async () => {
147
+ const newPage = await browser.newPage();
148
+ await newPage.goto(PATH, { waitUntil: 'load'});
149
+
150
+ const content = '# XXXA\nXXXB *XXXC*';
151
+
152
+ const promise = newPage.evaluate((content) => {
153
+ return new Promise((resolve, reject) => {
154
+ const tinyMDE = new TinyMDE.Editor({element: 'tinymde'});
155
+ // If handler is called, resolve the promise
156
+ tinyMDE.addEventListener('change', () => resolve());
157
+ tinyMDE.setContent(content);
158
+ // If handler hasn't been called, reject the promise
159
+ reject();
160
+ });
161
+ }, content);
162
+
163
+ return expect(promise).resolves.not.toThrow();
164
+ });
@@ -0,0 +1,2 @@
1
+ const PORT = 8880;
2
+ exports.PORT = PORT;
@@ -0,0 +1,9 @@
1
+ const express = require('express');
2
+ const path = require('path');
3
+ const { PORT } = require("./config");
4
+
5
+ const app = express();
6
+ app.use('/', express.static(path.resolve(__dirname, '..', '..', 'dist')));
7
+ app.listen(PORT, () => {
8
+ console.log(`Serving TinyMDE files at http://localhost:${PORT}/`);
9
+ });
@@ -0,0 +1 @@
1
+ jest.setTimeout(30000);
@@ -0,0 +1,98 @@
1
+ const { PORT } = require('./config');
2
+
3
+
4
+ global.PATH = `http://localhost:${PORT}/blank.html`;
5
+
6
+ global.initTinyMDE = async (content) => {
7
+
8
+ // document.body.innerHTML = '<div id="container"></div>';
9
+ const newPage = await browser.newPage();
10
+ await newPage.goto(global.PATH, { waitUntil: 'load'});
11
+ content = content.replace(/(['"\\])/g, '\\$1').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\t/g, '\\t');
12
+ await newPage.evaluate(`
13
+ tinyMDE = new TinyMDE.Editor({element: 'tinymde', content: '${content}'});
14
+ `);
15
+ return {
16
+ // editorInstance: () => tinyMDE,
17
+ // editorElement: () => document.getElementById('container').firstChild,
18
+ lineType: async (lineNum) => newPage.$eval(`#tinymde > :first-child > :nth-child(${lineNum + 1})`, el => el.className),
19
+ lineHTML: async (lineNum) => newPage.$eval(`#tinymde > :first-child > :nth-child(${lineNum + 1})`, el => el.innerHTML),
20
+ numLines: async () => newPage.$eval(`#tinymde > :first-child`, el => el.childNodes.length),
21
+
22
+ content: async () => newPage.evaluate(() => tinyMDE.getContent()),
23
+ destroy: async () => newPage.close()
24
+ }
25
+ }
26
+
27
+ global.classTagRegExp = (content, className, tagName = 'span') => {
28
+ let match = content
29
+ .replace(/&/g, '&amp;')
30
+ .replace(/</g, '&lt;')
31
+ .replace(/>/g, '&gt;')
32
+ .replace(/([\\[\](){}.*+?|$^])/g, '\\$1');
33
+ return new RegExp(`<${tagName}[^>]*class\\s*=\\s*["']?[^"'>]*${className}[^>]*>${match}<\\/${tagName}>`);
34
+ };
35
+
36
+
37
+ /**
38
+ * Creates a selection
39
+ * @param {Page} thePage
40
+ * @param {*} fromLine zero-based line number
41
+ * @param {*} fromColumn zero-based column number. If greater than number of characters in the line, selection will end at end of line.
42
+ * @param {*} toLine zero-based line number. If null, set to equal fromLine.
43
+ * @param {*} toColumn zero-based column number. If null, set to equal toLine.
44
+ */
45
+ global.select = async (thePage, fromLine, fromColumn, toLine = null, toColumn = null) => {
46
+
47
+ // TODO Continue here
48
+
49
+ await thePage.$eval('.TinyMDE', (el, fromLine, fromColumn, toLine, toColumn) => {
50
+ const computeNodeAndOffset = (el, row, col) => {
51
+
52
+ if (row < 0 || row >= el.childNodes.length || col < 0) return null;
53
+
54
+ let parentNode = el.childNodes[row];
55
+ let node = parentNode.firstChild;
56
+ let childrenComplete = false;
57
+
58
+ while (node != parentNode) {
59
+ if (!childrenComplete && node.nodeType === Node.TEXT_NODE) {
60
+ if (node.nodeValue.length >= col) {
61
+ return({node: node, offset: col});
62
+ } else {
63
+ col -= node.nodeValue.length;
64
+ }
65
+ }
66
+ if (!childrenComplete && node.firstChild) {
67
+ node = node.firstChild;
68
+ } else if (node.nextSibling) {
69
+ childrenComplete = false;
70
+ node = node.nextSibling;
71
+ } else {
72
+ childrenComplete = true;
73
+ node = node.parentNode;
74
+ }
75
+ }
76
+
77
+ return null;
78
+ }
79
+
80
+ let range = document.createRange();
81
+
82
+ const from = computeNodeAndOffset(el, fromLine, fromColumn);
83
+ if (!from) return;
84
+
85
+ let to;
86
+ if (toLine === null && toColumn === null) to = from;
87
+ else to = computeNodeAndOffset(el, toLine === null ? fromLine : toLine, toColumn === null ? fromColumn : toColumn);
88
+ if (!to) return;
89
+
90
+ range.setStart(from.node, from.offset);
91
+ range.setEnd(to.node, to.offset);
92
+
93
+ const windowSelection = window.getSelection();
94
+ windowSelection.removeAllRanges();
95
+ windowSelection.addRange(range);
96
+
97
+ }, fromLine, fromColumn, toLine, toColumn);
98
+ }
@@ -0,0 +1,8 @@
1
+ const { PORT } = require('./jest/util/config');
2
+
3
+ module.exports = {
4
+ server: {
5
+ command: 'node jest/util/server.js',
6
+ port: PORT
7
+ }
8
+ }
@@ -0,0 +1,13 @@
1
+ const { PORT } = require('./jest/util/config');
2
+
3
+ module.exports = {
4
+ preset: "jest-puppeteer",
5
+ globals: {
6
+ },
7
+ setupFiles: [
8
+ "./jest/util/test-helpers.js"
9
+ ],
10
+ setupFilesAfterEnv: [
11
+ "./jest/util//setup.js"
12
+ ]
13
+ }