Улучшение оформления кода
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
# Бибилотека первоапрельских розыгрышей для форумов MyBB
|
# Бибилотека первоапрельских розыгрышей для форумов MyBB
|
||||||
|
|
||||||
Базовое использование:
|
Базовое использование:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- Первоапрельские шутки -->
|
<!-- Первоапрельские шутки -->
|
||||||
<script src="https://static.kozhilya.ru/script/april-fools.min.js"></script>
|
<script src="https://static.kozhilya.ru/script/april-fools.min.js"></script>
|
||||||
@@ -14,23 +15,43 @@
|
|||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Полный список шуток
|
## Полный список шуток
|
||||||
|
|
||||||
* `shake` — **Форумо-трясение**. Страница форума начинает трястись.
|
- `shake` — **Форумо-трясение**. Страница форума начинает трястись.
|
||||||
* `mirror` — **Зеркало**. Элементы форума отражаются... По крайней мере, пытаются.
|
- `mirror` — **Зеркало**. Элементы форума отражаются... По крайней мере, пытаются.
|
||||||
* `carnival` — **Карнавал**. Аватарки приобретают интересные цвета.
|
- `carnival` — **Карнавал**. Аватарки приобретают интересные цвета.
|
||||||
* `humanitarian_hell` — **Ад гуманитария**. Все "тся" заменяются на "ться", а все "ться" на "тся".
|
- `humanitarian_hell` — **Ад гуманитария**. Все "тся" заменяются на "ться", а все "ться" на "тся".
|
||||||
* `crazy_letters` — **Мама, Я сОшЛа С уМа!** иМеНа ЗаБоРчИкОм
|
- `crazy_letters` — **Мама, Я сОшЛа С уМа!** иМеНа ЗаБоРчИкОм
|
||||||
* `letter_chaos` — **Буквенный хаос**. Все буквы в словах, кроме первой и последней, перемешены.
|
- `letter_chaos` — **Буквенный хаос**. Все буквы в словах, кроме первой и последней, перемешены.
|
||||||
* `cursor` — **Красивые курсоры**. Эффекты, следующие за курсором.
|
- `cursor` — **Красивые курсоры**. Эффекты, следующие за курсором.
|
||||||
|
- `stupid_title` — **Глупые статусы**. Каждому пользователю даётся новый глупый статус.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Тестирование шуток
|
||||||
|
|
||||||
|
Что бы проверить работу системы, вы можете включить "режим тестера". Для этого добавьте свой `UserID` в настройку `core.testers`:
|
||||||
|
|
||||||
|
```js
|
||||||
|
window.AprilJokes.settings = {
|
||||||
|
// ...
|
||||||
|
core: {
|
||||||
|
testers: [ 2, 3, 1186 ],
|
||||||
|
},
|
||||||
|
// ...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Настройка шуток
|
## Настройка шуток
|
||||||
|
|
||||||
Настройка шуток происходит при присвоении объекта `window.AprilJokes.settings`.
|
Настройка шуток происходит при присвоении объекта `window.AprilJokes.settings`.
|
||||||
Это присвоедние должно произойти **после** загрузки скрипта.
|
Это присвоедние должно произойти **после** загрузки скрипта.
|
||||||
|
|
||||||
Для всех шуток определны 2 общих поля:
|
Для всех шуток определны 2 общих поля:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
window.AprilJokes.settings = {
|
window.AprilJokes.settings = {
|
||||||
// ...
|
// ...
|
||||||
@@ -65,7 +86,7 @@ window.AprilJokes.settings = {
|
|||||||
<!-- Конец первоапрельских шуток -->
|
<!-- Конец первоапрельских шуток -->
|
||||||
```
|
```
|
||||||
|
|
||||||
Заметьте, что во всех примерах приведены значения настроек по умолчанию. Вы *можете* удалять строки, значения по умолчанию которых вас устраивают.
|
Заметьте, что во всех примерах приведены значения настроек по умолчанию. Вы _можете_ удалять строки, значения по умолчанию которых вас устраивают.
|
||||||
|
|
||||||
Если вас интерсует только несколько шуток, вы можете использовать метод `disableAll()`, что бы выключить выполнение всех шуток, а потом включать отдельные шутки через установку настройки `enabled`:
|
Если вас интерсует только несколько шуток, вы можете использовать метод `disableAll()`, что бы выключить выполнение всех шуток, а потом включать отдельные шутки через установку настройки `enabled`:
|
||||||
|
|
||||||
@@ -82,11 +103,12 @@ window.AprilJokes.settings = {
|
|||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Обратите внимание, что метод `disableAll()` должен быть вызван *до* установки настроек `settings`, иначе заданные значения `enabled` будут сброшены.
|
Обратите внимание, что метод `disableAll()` должен быть вызван _до_ установки настроек `settings`, иначе заданные значения `enabled` будут сброшены.
|
||||||
|
|
||||||
Так же есть метод `window.AprilJokes.enableAll()`, который включает все шутки, в том числе отключённые по умолчанию.
|
Так же есть метод `window.AprilJokes.enableAll()`, который включает все шутки, в том числе отключённые по умолчанию.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Настройка `shake` (Форумо-трясение)
|
### Настройка `shake` (Форумо-трясение)
|
||||||
|
|
||||||
Тряска элементов происходит путём изменения перечисленных направлений `margin` на значение ±`force` от стандартного значения.
|
Тряска элементов происходит путём изменения перечисленных направлений `margin` на значение ±`force` от стандартного значения.
|
||||||
@@ -94,10 +116,13 @@ window.AprilJokes.settings = {
|
|||||||
> **Важно**: эта шутка может вызвать дискомфорт у пользователей. Настоятельно рекомендуется оставить вероятность срабатывания шутки (`chance`) очень низкой, что бы у пользователей была возможность избавиться от шутки простым обновлением страницы! Вариант отключить шутку (`enabled: false`) тоже вариант.
|
> **Важно**: эта шутка может вызвать дискомфорт у пользователей. Настоятельно рекомендуется оставить вероятность срабатывания шутки (`chance`) очень низкой, что бы у пользователей была возможность избавиться от шутки простым обновлением страницы! Вариант отключить шутку (`enabled: false`) тоже вариант.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Настройка `mirror` (Зеркало)
|
### Настройка `mirror` (Зеркало)
|
||||||
Элементы форума отражаются по весьма специфичному алгоритму... И из-за этого, шутка может работать *очень* плохо на некоторых дизайнах, поэтому данная шутка по умолчанию **отключена**
|
|
||||||
|
Элементы форума отражаются по весьма специфичному алгоритму... И из-за этого, шутка может работать _очень_ плохо на некоторых дизайнах, поэтому данная шутка по умолчанию **отключена**
|
||||||
|
|
||||||
Для того, что бы попробовать, сработает ли шутка для вашего дизайна, используйте в консоли разработчика:
|
Для того, что бы попробовать, сработает ли шутка для вашего дизайна, используйте в консоли разработчика:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
window.AprilJokes.start("mirror", true);
|
window.AprilJokes.start("mirror", true);
|
||||||
```
|
```
|
||||||
@@ -105,20 +130,73 @@ window.AprilJokes.start("mirror", true);
|
|||||||
Так же можете [посмотреть](./src/jokes/mirror.ts#L16) на метод `MirrorJoke.start`, что бы узнать как именно проиходит отражение.
|
Так же можете [посмотреть](./src/jokes/mirror.ts#L16) на метод `MirrorJoke.start`, что бы узнать как именно проиходит отражение.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### Настройка `cursor` (Красивые курсоры)
|
### Настройка `cursor` (Красивые курсоры)
|
||||||
|
|
||||||
Используются курсоры, предложенные в библотеке `tholman/cursor-effects` от Tim Holman ([Github](https://github.com/tholman/cursor-effects), [сайт](https://tholman.com/cursor-effects/)).
|
Используются курсоры, предложенные в библотеке `tholman/cursor-effects` от Tim Holman ([Github](https://github.com/tholman/cursor-effects), [сайт](https://tholman.com/cursor-effects/)).
|
||||||
|
|
||||||
Код предусматривает, что одновременно активировано не более 1 курсора из этой библиотеки. Так же для каждого курсора установлен свой шанс срабатывания, однако из-за необходимости активации строго одного эффекта, предусмотрено использование весового коэффициента `weight`: если говорить просто, то чем больше это значение, то тем больше шанс срабатывания эффекта относительно других эффектов.
|
Код предусматривает, что одновременно активировано не более 1 курсора из этой библиотеки. Так же для каждого курсора установлен свой шанс срабатывания, однако из-за необходимости активации строго одного эффекта, предусмотрено использование весового коэффициента `weight`: если говорить просто, то чем больше это значение, то тем больше шанс срабатывания эффекта относительно других эффектов.
|
||||||
|
|
||||||
Так же для каждого эффекта определена настройка `enabled`, позволяющая отключить эффекты, и метод `disableAll` для отключения эффектов:
|
Так же для каждого эффекта определена настройка `enabled`, позволяющая отключить эффекты, и метод `disableAll` для отключения эффектов:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
window.AprilJokes.jokes.cursor.disableAll();
|
window.AprilJokes.jokes.cursor.disableAll();
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
### Настройка `stupid_title` (Глупые статусы)
|
||||||
|
|
||||||
|
> **Важно**: этот блок может быть чрезвычайно капризым из-за особенностей хранения данных, особенно блок `variants`. Изменяя его, строго следуйте этой инструкции, иначе скрипт может перестать работать ожидаемым образом.
|
||||||
|
|
||||||
|
Данная шутка генерирет статус из случайных слов. За счёт использования псевдослучайного генератора, хеширования и привязки к времени UTC, ожидается что все пользователи одновременно будут видеть один и тот же статус для каждого пользователя, при этом он меняется каждые `change_frequency` минут. Установите это значение равным `0`, что бы статус генерировался при каждом обновлении страницы.
|
||||||
|
|
||||||
|
Для настройки списка слов используется функция `BuildStupdiTitleVariant`, которая преобразует список слов во внутренний формат скрипта. Настоятельно рекомендуется использовать именно её, а не записывать параметры напрямую:
|
||||||
|
|
||||||
|
```js
|
||||||
|
window.AprilJokes.settings = {
|
||||||
|
// ...
|
||||||
|
stupid_title: {
|
||||||
|
// ...
|
||||||
|
variants: {
|
||||||
|
adj: {
|
||||||
|
...window.AprilJokes.settings.stupid_title.variants.adj,
|
||||||
|
...BuildStupdiTitleVariant(true, "скромный, шутливый, !грубый"),
|
||||||
|
...BuildStupdiTitleVariant(false, "скромная, шутливая, !грубая"),
|
||||||
|
},
|
||||||
|
noun: { ...window.AprilJokes.settings.stupid_title.variants.noun },
|
||||||
|
verb: { ...window.AprilJokes.settings.stupid_title.variants.verb },
|
||||||
|
place: { ...window.AprilJokes.settings.stupid_title.variants.place },
|
||||||
|
adv: { ...window.AprilJokes.settings.stupid_title.variants.adv },
|
||||||
|
p: { ...window.AprilJokes.settings.stupid_title.variants.p },
|
||||||
|
},
|
||||||
|
// ...
|
||||||
|
},
|
||||||
|
// ...
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
Обратите внимание на конструкции вида `{ ...something }` — эта конструкция позволяет перенести все поля нескольких старых объектов в один новый. При этом, если в двух объединяемых объектах есть совпадающие значения, то будет сохранено последнее.
|
||||||
|
|
||||||
|
Говоря проще: добовляйте ваши настройки _после_ строки вида `...window.AprilJokes.settings.stupid_title.variants.adj`, что бы ваши настройки не были перезаписаны.
|
||||||
|
|
||||||
|
Метод `BuildStupdiTitleVariant` принимает 2 аргумента:
|
||||||
|
|
||||||
|
- `gender` — определённый род для генерации. Используйте `true` для мужского рода, `false` для женского и `null`, если добавляемые варианты могут использоваться в обоих случаях.
|
||||||
|
- `words` — строка, со списоком вариантов через запятую. В качестве вариантов могут быть слова из русских или английских букв, пробелов или дефисов, то есть можно использовать `"..., почему-то и зачем-то , ..."` и `почему-то и зачем-то` будет воспринят как один вариант. Также варианты можно модифицировать, добавив один или несколько модификаторов:
|
||||||
|
- `!` отключает использование слова. Этим модификатором можно отключать слова из списка по умолчанию (см `!грубый` в примере выше).
|
||||||
|
- `%` помечает слово как редкое. Шанс его использования понижается в 2 раза.
|
||||||
|
- `^` помечает слово как частое. Шанс его использования повышается в 2 раза.
|
||||||
|
- `$` помечает слово как грубое. Такие слова не будут отображаться, если в настройках отключена соответсвующая настройка `rude`.
|
||||||
|
|
||||||
|
Полный список слов по умолчанию вы можете посмотреть [в Google Таблице](https://docs.google.com/spreadsheets/d/1MJIfENqy7a9DczRj38c34t27ZQtEmBSi/edit?usp=sharing&ouid=112152128398997742033&rtpof=true&sd=true) или [в исходном файле](./src/data/stupid_title_variants.ts).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Разработка дополнений
|
## Разработка дополнений
|
||||||
|
|
||||||
Использование для тестирования:
|
Использование для тестирования:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- Первоапрельские шутки: версия для разработчиков -->
|
<!-- Первоапрельские шутки: версия для разработчиков -->
|
||||||
<script src="https://static.kozhilya.ru/script/april-fools.js"></script>
|
<script src="https://static.kozhilya.ru/script/april-fools.js"></script>
|
||||||
@@ -131,24 +209,24 @@ window.AprilJokes.jokes.cursor.disableAll();
|
|||||||
// Создание новой шутки
|
// Создание новой шутки
|
||||||
window.AprilJokes.addCustom(
|
window.AprilJokes.addCustom(
|
||||||
// ID шутки
|
// ID шутки
|
||||||
'alert',
|
"alert",
|
||||||
|
|
||||||
// Вызываемая функция шутки
|
// Вызываемая функция шутки
|
||||||
settings => {
|
(settings) => {
|
||||||
alert(settings.text)
|
alert(settings.text);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Стандартные настройки
|
// Стандартные настройки
|
||||||
{
|
{
|
||||||
enabled: true,
|
enabled: true,
|
||||||
chance: 30,
|
chance: 30,
|
||||||
text: 'Fooled!',
|
text: "Fooled!",
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// Запуск шутки
|
// Запуск шутки
|
||||||
// true - отключает проверки случайности
|
// true - отключает проверки случайности
|
||||||
window.AprilJokes.start('alert', true);
|
window.AprilJokes.start("alert", true);
|
||||||
</script>
|
</script>
|
||||||
<!-- Конец первоапрельских шуток: версия для разработчиков -->
|
<!-- Конец первоапрельских шуток: версия для разработчиков -->
|
||||||
```
|
```
|
||||||
|
|||||||
Vendored
+35
-15
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Generated
+1
@@ -32,6 +32,7 @@
|
|||||||
"markdown-it": "^13.0.1",
|
"markdown-it": "^13.0.1",
|
||||||
"markdown-it-container": "^3.0.0",
|
"markdown-it-container": "^3.0.0",
|
||||||
"prettier": "^2.8.2",
|
"prettier": "^2.8.2",
|
||||||
|
"terser-webpack-plugin": "^5.3.7",
|
||||||
"ts-loader": "^9.4.2",
|
"ts-loader": "^9.4.2",
|
||||||
"tsify": "^5.0.4",
|
"tsify": "^5.0.4",
|
||||||
"typescript": "^5.0.2",
|
"typescript": "^5.0.2",
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"markdown-it": "^13.0.1",
|
"markdown-it": "^13.0.1",
|
||||||
"markdown-it-container": "^3.0.0",
|
"markdown-it-container": "^3.0.0",
|
||||||
"prettier": "^2.8.2",
|
"prettier": "^2.8.2",
|
||||||
|
"terser-webpack-plugin": "^5.3.7",
|
||||||
"ts-loader": "^9.4.2",
|
"ts-loader": "^9.4.2",
|
||||||
"tsify": "^5.0.4",
|
"tsify": "^5.0.4",
|
||||||
"typescript": "^5.0.2",
|
"typescript": "^5.0.2",
|
||||||
|
|||||||
+31
-31
@@ -6,9 +6,9 @@ window.AprilJokes.settings = {
|
|||||||
shake: {
|
shake: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
chance: 1,
|
chance: 1,
|
||||||
directions: ['top', 'left', 'bottom', 'left'],
|
directions: ["top", "left", "bottom", "left"],
|
||||||
force: 0.5,
|
force: 0.5,
|
||||||
selector: '[id^=pun]',
|
selector: "[id^=pun]",
|
||||||
interval: 100,
|
interval: 100,
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -23,29 +23,29 @@ window.AprilJokes.settings = {
|
|||||||
selector: 'img[src*="/avatars/"]',
|
selector: 'img[src*="/avatars/"]',
|
||||||
variant_chance: 20,
|
variant_chance: 20,
|
||||||
variants: {
|
variants: {
|
||||||
'sepia({0}%)': 100,
|
"sepia({0}%)": 100,
|
||||||
'saturate({0}%)': 100,
|
"saturate({0}%)": 100,
|
||||||
'hue-rotate({0}deg)': 360,
|
"hue-rotate({0}deg)": 360,
|
||||||
'invert({0}%)': 100,
|
"invert({0}%)": 100,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
humanitarian_hell: {
|
humanitarian_hell: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
chance: 20,
|
chance: 20,
|
||||||
selector: '.post-content',
|
selector: ".post-content",
|
||||||
},
|
},
|
||||||
|
|
||||||
crazy_letters: {
|
crazy_letters: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
chance: 20,
|
chance: 20,
|
||||||
selector: '.pa-author a'
|
selector: ".pa-author a",
|
||||||
},
|
},
|
||||||
|
|
||||||
letter_chaos: {
|
letter_chaos: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
chance: 20,
|
chance: 20,
|
||||||
selector: '.post-content',
|
selector: ".post-content",
|
||||||
shuffle_chance: 50,
|
shuffle_chance: 50,
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ window.AprilJokes.settings = {
|
|||||||
"#00FF00",
|
"#00FF00",
|
||||||
"#FFFF00",
|
"#FFFF00",
|
||||||
"#FF7F00",
|
"#FF7F00",
|
||||||
"#FF0000"
|
"#FF0000",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
springy_emoji: {
|
springy_emoji: {
|
||||||
@@ -119,11 +119,11 @@ window.AprilJokes.settings = {
|
|||||||
clock: {
|
clock: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
weight: 50,
|
weight: 50,
|
||||||
dateColor: string = "blue",
|
dateColor: (string = "blue"),
|
||||||
faceColor: string = "black",
|
faceColor: (string = "black"),
|
||||||
secondsColor: string = "red",
|
secondsColor: (string = "red"),
|
||||||
minutesColor: string = "black",
|
minutesColor: (string = "black"),
|
||||||
hoursColor: string = "black",
|
hoursColor: (string = "black"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -135,26 +135,26 @@ window.AprilJokes.settings = {
|
|||||||
rude: false,
|
rude: false,
|
||||||
change_frequency: 5,
|
change_frequency: 5,
|
||||||
schemas: {
|
schemas: {
|
||||||
'{adj} {noun}{p}': 10,
|
"{adj} {noun}{p}": 10,
|
||||||
'{noun} {adj}{p}': 3,
|
"{noun} {adj}{p}": 3,
|
||||||
'{adj}, {adj} {noun}{p}': 10,
|
"{adj}, {adj} {noun}{p}": 10,
|
||||||
'{adj} и очень {adj} {noun}{p}': 10,
|
"{adj} и очень {adj} {noun}{p}": 10,
|
||||||
'{adj} {noun} {verb}{p}': 10,
|
"{adj} {noun} {verb}{p}": 10,
|
||||||
'{adj} {noun} {adv} {verb}{p}': 5,
|
"{adj} {noun} {adv} {verb}{p}": 5,
|
||||||
'{adj} {noun} {verb} {place}{p}': 5,
|
"{adj} {noun} {verb} {place}{p}": 5,
|
||||||
'{adj} {noun} {adv} {verb} {place}{p}': 5,
|
"{adj} {noun} {adv} {verb} {place}{p}": 5,
|
||||||
},
|
},
|
||||||
variants: {
|
variants: {
|
||||||
adj: {
|
adj: {
|
||||||
...window.AprilJokes.settings.stupid_title.variants.adj,
|
...window.AprilJokes.settings.stupid_title.variants.adj,
|
||||||
...BuildStupdiTitleVariant(true, 'скромный, шутливый, !грубый'),
|
...BuildStupdiTitleVariant(true, "скромный, шутливый, !грубый"),
|
||||||
...BuildStupdiTitleVariant(false, 'скромная, шутливая, !грубая'),
|
...BuildStupdiTitleVariant(false, "скромная, шутливая, !грубая"),
|
||||||
},
|
},
|
||||||
noun: { ...window.AprilJokes.settings.stupid_title.variants.noun, },
|
noun: { ...window.AprilJokes.settings.stupid_title.variants.noun },
|
||||||
verb: { ...window.AprilJokes.settings.stupid_title.variants.verb, },
|
verb: { ...window.AprilJokes.settings.stupid_title.variants.verb },
|
||||||
place: { ...window.AprilJokes.settings.stupid_title.variants.place, },
|
place: { ...window.AprilJokes.settings.stupid_title.variants.place },
|
||||||
adv: { ...window.AprilJokes.settings.stupid_title.variants.adv, },
|
adv: { ...window.AprilJokes.settings.stupid_title.variants.adv },
|
||||||
p: { ...window.AprilJokes.settings.stupid_title.variants.p, },
|
p: { ...window.AprilJokes.settings.stupid_title.variants.p },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|||||||
+32
-31
@@ -43,7 +43,7 @@ window.AprilJokes.settings = {
|
|||||||
/**
|
/**
|
||||||
* Направление тряски
|
* Направление тряски
|
||||||
*/
|
*/
|
||||||
directions: ['top', 'left', 'bottom', 'left'],
|
directions: ["top", "left", "bottom", "left"],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Сила тряски
|
* Сила тряски
|
||||||
@@ -53,7 +53,7 @@ window.AprilJokes.settings = {
|
|||||||
/**
|
/**
|
||||||
* Селектор всех элементов, которые будут трястись
|
* Селектор всех элементов, которые будут трястись
|
||||||
*/
|
*/
|
||||||
selector: '[id^=pun]',
|
selector: "[id^=pun]",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Частота тряски
|
* Частота тряски
|
||||||
@@ -98,10 +98,10 @@ window.AprilJokes.settings = {
|
|||||||
* Список фильтров и диапозона случайных параметров.
|
* Список фильтров и диапозона случайных параметров.
|
||||||
*/
|
*/
|
||||||
variants: {
|
variants: {
|
||||||
'sepia({0}%)': 100,
|
"sepia({0}%)": 100,
|
||||||
'saturate({0}%)': 100,
|
"saturate({0}%)": 100,
|
||||||
'hue-rotate({0}deg)': 360,
|
"hue-rotate({0}deg)": 360,
|
||||||
'invert({0}%)': 100,
|
"invert({0}%)": 100,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ window.AprilJokes.settings = {
|
|||||||
/**
|
/**
|
||||||
* Селектор всех элементов, которые будут затронуты.
|
* Селектор всех элементов, которые будут затронуты.
|
||||||
*/
|
*/
|
||||||
selector: '.post-content',
|
selector: ".post-content",
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -136,7 +136,7 @@ window.AprilJokes.settings = {
|
|||||||
/**
|
/**
|
||||||
* Селектор всех элементов, которые будут затронуты.
|
* Селектор всех элементов, которые будут затронуты.
|
||||||
*/
|
*/
|
||||||
selector: '.pa-author a'
|
selector: ".pa-author a",
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -153,7 +153,7 @@ window.AprilJokes.settings = {
|
|||||||
/**
|
/**
|
||||||
* Селектор всех элементов, которые будут затронуты
|
* Селектор всех элементов, которые будут затронуты
|
||||||
*/
|
*/
|
||||||
selector: '.post-content',
|
selector: ".post-content",
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Вероятность того, что буквы будут перемешаны
|
* Вероятность того, что буквы будут перемешаны
|
||||||
@@ -206,7 +206,7 @@ window.AprilJokes.settings = {
|
|||||||
"#00FF00",
|
"#00FF00",
|
||||||
"#FFFF00",
|
"#FFFF00",
|
||||||
"#FF7F00",
|
"#FF7F00",
|
||||||
"#FF0000"
|
"#FF0000",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -355,27 +355,27 @@ window.AprilJokes.settings = {
|
|||||||
/**
|
/**
|
||||||
* Цвет даты
|
* Цвет даты
|
||||||
*/
|
*/
|
||||||
dateColor: string = "blue",
|
dateColor: (string = "blue"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Цвет циферблата
|
* Цвет циферблата
|
||||||
*/
|
*/
|
||||||
faceColor: string = "black",
|
faceColor: (string = "black"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Цвет секундной стрелки
|
* Цвет секундной стрелки
|
||||||
*/
|
*/
|
||||||
secondsColor: string = "red",
|
secondsColor: (string = "red"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Цвет минутной стрелки
|
* Цвет минутной стрелки
|
||||||
*/
|
*/
|
||||||
minutesColor: string = "black",
|
minutesColor: (string = "black"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Цвет часовой стрелки
|
* Цвет часовой стрелки
|
||||||
*/
|
*/
|
||||||
hoursColor: string = "black",
|
hoursColor: (string = "black"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -409,6 +409,7 @@ window.AprilJokes.settings = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Частота смены статусов (в минутах)
|
* Частота смены статусов (в минутах)
|
||||||
|
* Установите значение 0, что бы обновление происходило при каждом обновлении страницы
|
||||||
*/
|
*/
|
||||||
change_frequency: 5,
|
change_frequency: 5,
|
||||||
|
|
||||||
@@ -422,14 +423,14 @@ window.AprilJokes.settings = {
|
|||||||
* {p} - знак препинания
|
* {p} - знак препинания
|
||||||
*/
|
*/
|
||||||
schemas: {
|
schemas: {
|
||||||
'{adj} {noun}{p}': 10,
|
"{adj} {noun}{p}": 10,
|
||||||
'{noun} {adj}{p}': 3,
|
"{noun} {adj}{p}": 3,
|
||||||
'{adj}, {adj} {noun}{p}': 10,
|
"{adj}, {adj} {noun}{p}": 10,
|
||||||
'{adj} и очень {adj} {noun}{p}': 10,
|
"{adj} и очень {adj} {noun}{p}": 10,
|
||||||
'{adj} {noun} {verb}{p}': 10,
|
"{adj} {noun} {verb}{p}": 10,
|
||||||
'{adj} {noun} {adv} {verb}{p}': 5,
|
"{adj} {noun} {adv} {verb}{p}": 5,
|
||||||
'{adj} {noun} {verb} {place}{p}': 5,
|
"{adj} {noun} {verb} {place}{p}": 5,
|
||||||
'{adj} {noun} {adv} {verb} {place}{p}': 5,
|
"{adj} {noun} {adv} {verb} {place}{p}": 5,
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -439,14 +440,14 @@ window.AprilJokes.settings = {
|
|||||||
variants: {
|
variants: {
|
||||||
adj: {
|
adj: {
|
||||||
...window.AprilJokes.settings.stupid_title.variants.adj,
|
...window.AprilJokes.settings.stupid_title.variants.adj,
|
||||||
...BuildStupdiTitleVariant(true, 'скромный, шутливый, !грубый'),
|
...BuildStupdiTitleVariant(true, "скромный, шутливый, !грубый"),
|
||||||
...BuildStupdiTitleVariant(false, 'скромная, шутливая, !грубая'),
|
...BuildStupdiTitleVariant(false, "скромная, шутливая, !грубая"),
|
||||||
},
|
},
|
||||||
noun: { ...window.AprilJokes.settings.stupid_title.variants.noun, },
|
noun: { ...window.AprilJokes.settings.stupid_title.variants.noun },
|
||||||
verb: { ...window.AprilJokes.settings.stupid_title.variants.verb, },
|
verb: { ...window.AprilJokes.settings.stupid_title.variants.verb },
|
||||||
place: { ...window.AprilJokes.settings.stupid_title.variants.place, },
|
place: { ...window.AprilJokes.settings.stupid_title.variants.place },
|
||||||
adv: { ...window.AprilJokes.settings.stupid_title.variants.adv, },
|
adv: { ...window.AprilJokes.settings.stupid_title.variants.adv },
|
||||||
p: { ...window.AprilJokes.settings.stupid_title.variants.p, },
|
p: { ...window.AprilJokes.settings.stupid_title.variants.p },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import $ from "jquery";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Получение всех элементов, являющимися TextNode.
|
||||||
|
* Используется некоторыми шутками для уменьшения влияния на существующее DOM-дерево.
|
||||||
|
*/
|
||||||
|
export function getTextNodes(
|
||||||
|
root: any
|
||||||
|
): JQuery<HTMLElement | Text | Comment | Document> {
|
||||||
|
return $(root)
|
||||||
|
.find("*")
|
||||||
|
.contents()
|
||||||
|
.filter((_, node) => node.nodeType === Node.TEXT_NODE);
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
import {
|
||||||
|
StupidTitleVariants,
|
||||||
|
BuildStupdiTitleVariant,
|
||||||
|
} from "../jokes/stupid_title";
|
||||||
|
export function StupidTitleDefaultVariants(vars: StupidTitleVariants) {
|
||||||
|
vars.adj = {
|
||||||
|
...BuildStupdiTitleVariant(
|
||||||
|
true,
|
||||||
|
"адекватный,$адский,активный,алчный,%ангельский,банальный,безнадёжный,$бесполезный,былой,верный,виртуальный,вкусный,воспитанный,выгодный,выходной,гигантский,$глупый,гордый,грамотный,громадный,грубый,далекий,двуличный,деятельный,доброжелательный,$жалкий,жёсткий,жестокий,$жирный,заинтересованный,запасной,застенчивый,знакомый,иностранный,истинный,конструктивный,креативный,ласковый,любимый,мелочный,^мирный,мстительный,небесный,невозможный,независимый,низкий,нужный,объективный,обыкновенный,опрятный,^оригинальный,особенный,острый,откровенный,открытый,пестрый,повседневный,подземный,пожилой,показательный,последний,посторонний,провинциальный,пышный,робкий,родной,самовлюблённый,северный,седой,семейный,серьёзный,сногсшибательный,^солнечный,спокойный,суровый,терпеливый,уверенный в себе,ударный,^удачливый,формальный,хладнокровный,целый,чистый,чрезвычайный,чужой,южный"
|
||||||
|
),
|
||||||
|
...BuildStupdiTitleVariant(
|
||||||
|
false,
|
||||||
|
"адекватная,$адская,активная,алчная,%ангельская,банальная,безнадёжная,$бесполезная,былая,верная,виртуальная,вкусная,воспитанная,выгодная,выходная,гигантская,$глупая,гордая,грамотная,громадная,грубая,далекая,двуличная,деятельная,доброжелательная,$жалкая,жёсткая,жестокая,$жирная,заинтересованная,запасная,застенчивая,знакомая,иностранная,истинная,конструктивная,креативная,ласковая,любимая,мелочная,^мирная,мстительная,небесная,невозможная,независимая,низкая,нужная,объективная,обыкновенная,опрятная,^оригинальная,особенная,острая,откровенная,открытая,пестрая,повседневная,подземная,пожилая,показательная,последняя,посторонняя,провинциальная,пышная,робкая,родная,самовлюблённая,северная,седая,семейная,серьезная,сногсшибательная,^солнечная,спокаяная,суровая,терпеливая,уверенная в себе,ударная,^удачливая,формальная,хладнокровная,целая,чистая,чрезвычайная,чужая,южная"
|
||||||
|
),
|
||||||
|
...vars.adj,
|
||||||
|
};
|
||||||
|
vars.noun = {
|
||||||
|
...BuildStupdiTitleVariant(
|
||||||
|
true,
|
||||||
|
"актёр,$балбес,бард,басурманин,борец,бродяга,бруталище,волк,дворф,%дед,%дедушка,джентльмен,диван,динозавр,дракон,ёж,%ёжик,жук,зайц,$злоумышленник,зомби,карасик,кентавр,кит,кот,кролик,кулак,лев,ледник,лесоруб,%мальчег,мальчик,манекен,массажист,мачо,монах,монстр,наследник,ниндзя,носорог,одиночка,организм,орёл,отец,принц,проказник,пузырь,$раб,рыцарь,спортсмен,сурикат,сын,%сынок,тигр,товарищ,хоббит,эльф"
|
||||||
|
),
|
||||||
|
...BuildStupdiTitleVariant(
|
||||||
|
false,
|
||||||
|
"актриса,акула,$бабка,бабочка,%бабушка,бактерия,белочка,бусинка,валькирия,$ведьма,волторна,волчица,горгулья,дворфиха,девочка,деревяшка,детка,%деффачка,%дочка,дочь,заноза,$злоумышленница,знаменитость,каруселька,килька,конфетка,косточка,кошка,красотка,крышка,леди,$личинка,львица,мать,машина,милашка,монашка,мышь,наследница,орлица,панда,пиранья,принцесса,простуда,$рабыня,русалочка,рыбка,рыбка,скамеечка,спортсменка,тигрица,травка,черепашка,чертовка,эльфийка"
|
||||||
|
),
|
||||||
|
...vars.noun,
|
||||||
|
};
|
||||||
|
vars.verb = {
|
||||||
|
...BuildStupdiTitleVariant(
|
||||||
|
null,
|
||||||
|
"бежит,берёт и делает,болеет,встаёт,говорит,думает,забывает,замирает,заходит,идёт,%имеет план и придерживается его,ловит,меняется,молчит,нарушает,оглядывается,орёт,освобождает,отвечает,отказаться куда-то идти,отказывается,отказывается вставать,отказывается что-то делать,оформляет,плывёт,поглядывает,поздравляет,поздравляет,получает,прибывает,приказывает,просыпается,прощает,работает,радуется,скрывается,снимает,снимает,снимается в сериале,снимается в фильме,собирается,соединяет,спрашивает,тянет,указывает,учит,читает,что-то скрывает,чувствует опасность,шепчет"
|
||||||
|
),
|
||||||
|
...BuildStupdiTitleVariant(
|
||||||
|
true,
|
||||||
|
"взял и сделал,додумался,женился,женится,заработался,не спал,не успел,обиделся,познал дзен,присел,проснулся,скрылся,смог,успел"
|
||||||
|
),
|
||||||
|
...BuildStupdiTitleVariant(
|
||||||
|
false,
|
||||||
|
"взяла и сделала,выходит замуж,вышла замуж,додумалась,заработалась,не спала,не успела,обиделась,познала дзен,присела,проснулась,скрылась,смогла,успела"
|
||||||
|
),
|
||||||
|
...vars.verb,
|
||||||
|
};
|
||||||
|
vars.place = {
|
||||||
|
...BuildStupdiTitleVariant(
|
||||||
|
null,
|
||||||
|
"в джунглях,в квартире,в космосе,в лесу,в очереди,в пустыне,в театре,%в тёплой и уютной квартире,в филармонии,где-то,на заснеженной вершине,на конференции,на пляже,на форуме,под водой,под дождём,%под проливным дождём"
|
||||||
|
),
|
||||||
|
...vars.place,
|
||||||
|
};
|
||||||
|
vars.adv = {
|
||||||
|
...BuildStupdiTitleVariant(
|
||||||
|
null,
|
||||||
|
"безрассудно,быстро,внезапно,вновь,$грубо,грустно,медленно,%молниеносно,немедленно,опять,осмысленно,позже,предсказуемо,расчётливо,регулярно,счастливо,уже,уныло"
|
||||||
|
),
|
||||||
|
...vars.adv,
|
||||||
|
};
|
||||||
|
}
|
||||||
+26
-26
@@ -1,5 +1,5 @@
|
|||||||
<style class="april-fools__styles">
|
<style class="april-fools__styles">
|
||||||
.april-fools__button {
|
.april-fools__button {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0.2rem;
|
bottom: 0.2rem;
|
||||||
right: 0.2rem;
|
right: 0.2rem;
|
||||||
@@ -10,17 +10,17 @@
|
|||||||
opacity: 0.3;
|
opacity: 0.3;
|
||||||
transition: 0.4s all;
|
transition: 0.4s all;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.april-fools__button:hover {
|
.april-fools__button:hover {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.april-fools__joke-row {
|
.april-fools__joke-row {
|
||||||
border-bottom: 1px solid black;
|
border-bottom: 1px solid black;
|
||||||
}
|
}
|
||||||
.april-fools__joke-row:first-of-type {
|
.april-fools__joke-row:first-of-type {
|
||||||
border-top: 1px solid black;
|
border-top: 1px solid black;
|
||||||
}
|
}
|
||||||
.april-fools__joke {
|
.april-fools__joke {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row wrap;
|
flex-flow: row wrap;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
@@ -29,38 +29,38 @@
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 1ch;
|
gap: 1ch;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.april-fools__joke:hover {
|
.april-fools__joke:hover {
|
||||||
text-shadow: 0 0 black;
|
text-shadow: 0 0 black;
|
||||||
}
|
}
|
||||||
.april-fools__joke:before {
|
.april-fools__joke:before {
|
||||||
display: block;
|
display: block;
|
||||||
content: "";
|
content: "";
|
||||||
flex: 0 0 2ch;
|
flex: 0 0 2ch;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
content: "✔";
|
content: "✔";
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
input.april-fools__joke-input:checked + .april-fools__joke {
|
input.april-fools__joke-input:checked + .april-fools__joke {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
input.april-fools__joke-input:checked + .april-fools__joke:before {
|
input.april-fools__joke-input:checked + .april-fools__joke:before {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.april-fools__joke .april-fools__joke-title {
|
.april-fools__joke .april-fools__joke-title {
|
||||||
flex: 1 auto;
|
flex: 1 auto;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.april-fools__joke .april-fools__joke-description {
|
.april-fools__joke .april-fools__joke-description {
|
||||||
flex: 1 auto;
|
flex: 1 auto;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
.april-fools__joke .april-fools__joke-chance {
|
.april-fools__joke .april-fools__joke-chance {
|
||||||
flex: 0 0 4ch;
|
flex: 0 0 4ch;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
.april-fools__content .april-fools__reset-button {
|
.april-fools__content .april-fools__reset-button {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 10px auto;
|
margin: 10px auto;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
+10
-2
@@ -1,11 +1,19 @@
|
|||||||
<div class="april-fools__content">
|
<div class="april-fools__content">
|
||||||
<div class="april-fools__jokes"></div>
|
<div class="april-fools__jokes"></div>
|
||||||
|
|
||||||
<button class="april-fools__reset-button">Вернуться к настройкам форума (страница будет перезагружена!)</button>
|
<button class="april-fools__reset-button">
|
||||||
|
Вернуться к настройкам форума (страница будет перезагружена!)
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<template class="april-fools__template" id="april-fools__window-row">
|
<template class="april-fools__template" id="april-fools__window-row">
|
||||||
<div class="april-fools__joke-row">
|
<div class="april-fools__joke-row">
|
||||||
<input type="checkbox" class="april-fools__joke-input" name="april-fools__joke-${joke.id}" id="april-fools__joke-${joke.id}" style="display: none;" />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class="april-fools__joke-input"
|
||||||
|
name="april-fools__joke-${joke.id}"
|
||||||
|
id="april-fools__joke-${joke.id}"
|
||||||
|
style="display: none"
|
||||||
|
/>
|
||||||
<label class="april-fools__joke" for="april-fools__joke-${joke.id}">
|
<label class="april-fools__joke" for="april-fools__joke-${joke.id}">
|
||||||
<p class="april-fools__joke-title">${joke.title}</p>
|
<p class="april-fools__joke-title">${joke.title}</p>
|
||||||
<p class="april-fools__joke-description">${joke.description}</p>
|
<p class="april-fools__joke-description">${joke.description}</p>
|
||||||
|
|||||||
+3
-5
@@ -65,8 +65,8 @@ export abstract class Joke {
|
|||||||
* Переключить блокировку шутки
|
* Переключить блокировку шутки
|
||||||
* @param value Новое значение
|
* @param value Новое значение
|
||||||
*/
|
*/
|
||||||
toggle(value: boolean|null = null) {
|
toggle(value: boolean | null = null) {
|
||||||
this.settings.enabled = (value === null) ? !this.settings.enabled : value;
|
this.settings.enabled = value === null ? !this.settings.enabled : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -78,11 +78,9 @@ export abstract class Joke {
|
|||||||
/**
|
/**
|
||||||
* Объект, описывающий шутку, которая может быть остановлена
|
* Объект, описывающий шутку, которая может быть остановлена
|
||||||
*/
|
*/
|
||||||
export abstract class StopableJoke extends Joke
|
export abstract class StopableJoke extends Joke {
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* Остановка шутки, если возможно
|
* Остановка шутки, если возможно
|
||||||
*/
|
*/
|
||||||
abstract stop(): void;
|
abstract stop(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+48
-33
@@ -36,20 +36,24 @@ export class JokerClass {
|
|||||||
* @param handler Метод, выполняющий шутку
|
* @param handler Метод, выполняющий шутку
|
||||||
* @param settings Объект настроек шутки
|
* @param settings Объект настроек шутки
|
||||||
*/
|
*/
|
||||||
addCustom(id: string, handler: Function, settings: JokeSettings|null = null): Joke {
|
addCustom(
|
||||||
const joke = new class extends Joke {
|
id: string,
|
||||||
|
handler: Function,
|
||||||
|
settings: JokeSettings | null = null
|
||||||
|
): Joke {
|
||||||
|
const joke = new (class extends Joke {
|
||||||
id = id;
|
id = id;
|
||||||
|
|
||||||
title = 'Пользовательская шутка';
|
title = "Пользовательская шутка";
|
||||||
|
|
||||||
description = 'Для шутки не определено описание';
|
description = "Для шутки не определено описание";
|
||||||
|
|
||||||
settings: JokeSettings = { chance: 10, enabled: true };
|
settings: JokeSettings = { chance: 10, enabled: true };
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
handler.call(this, this.settings);
|
handler.call(this, this.settings);
|
||||||
}
|
}
|
||||||
};
|
})();
|
||||||
|
|
||||||
Object.assign(joke.settings, settings ?? {});
|
Object.assign(joke.settings, settings ?? {});
|
||||||
|
|
||||||
@@ -64,7 +68,7 @@ export class JokerClass {
|
|||||||
get settings(): SettingsMap {
|
get settings(): SettingsMap {
|
||||||
const result: SettingsMap = {};
|
const result: SettingsMap = {};
|
||||||
|
|
||||||
result['core'] = this.core_settings;
|
result["core"] = this.core_settings;
|
||||||
|
|
||||||
for (const entries of Object.entries(this.jokes)) {
|
for (const entries of Object.entries(this.jokes)) {
|
||||||
const id = entries[0];
|
const id = entries[0];
|
||||||
@@ -85,7 +89,8 @@ export class JokerClass {
|
|||||||
for (const entry of Object.entries(settings)) {
|
for (const entry of Object.entries(settings)) {
|
||||||
const id = entry[0];
|
const id = entry[0];
|
||||||
const jokeSettings = entry[1];
|
const jokeSettings = entry[1];
|
||||||
const targetSettings = (id === 'core') ? this.core_settings : this.jokes[id].settings;
|
const targetSettings =
|
||||||
|
id === "core" ? this.core_settings : this.jokes[id].settings;
|
||||||
|
|
||||||
Object.assign(targetSettings, jokeSettings);
|
Object.assign(targetSettings, jokeSettings);
|
||||||
}
|
}
|
||||||
@@ -147,32 +152,38 @@ export class JokerClass {
|
|||||||
states[key] = this.jokes[key].settings.enabled;
|
states[key] = this.jokes[key].settings.enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch('/api.php?' + $.param({
|
fetch(
|
||||||
method: 'storage.set',
|
"/api.php?" +
|
||||||
user_id: (<any> window).UserID,
|
$.param({
|
||||||
key: 'april-fools',
|
method: "storage.set",
|
||||||
token: (<any> window).ForumAPITicket,
|
user_id: (<any>window).UserID,
|
||||||
|
key: "april-fools",
|
||||||
|
token: (<any>window).ForumAPITicket,
|
||||||
value: JSON.stringify(states),
|
value: JSON.stringify(states),
|
||||||
timer: 24 * 60
|
timer: 24 * 60,
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Загрузка пользовательских настроек
|
* Загрузка пользовательских настроек
|
||||||
*/
|
*/
|
||||||
async loadUserStates() {
|
async loadUserStates() {
|
||||||
const response = await fetch('/api.php?' + $.param({
|
const response = await fetch(
|
||||||
method: 'storage.get',
|
"/api.php?" +
|
||||||
user_id: (<any> window).UserID,
|
$.param({
|
||||||
key: 'april-fools',
|
method: "storage.get",
|
||||||
}));
|
user_id: (<any>window).UserID,
|
||||||
|
key: "april-fools",
|
||||||
|
})
|
||||||
|
);
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
|
|
||||||
if (json.error) {
|
if (json.error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = JSON.parse(json.response.storage.data['april-fools']);
|
const data = JSON.parse(json.response.storage.data["april-fools"]);
|
||||||
|
|
||||||
for (const key of Object.keys(this.jokes)) {
|
for (const key of Object.keys(this.jokes)) {
|
||||||
this.jokes[key].settings.enabled = data[key];
|
this.jokes[key].settings.enabled = data[key];
|
||||||
@@ -180,17 +191,19 @@ export class JokerClass {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async clearUserStates() {
|
async clearUserStates() {
|
||||||
await fetch('/api.php?' + $.param({
|
await fetch(
|
||||||
method: 'storage.delete',
|
"/api.php?" +
|
||||||
user_id: (<any> window).UserID,
|
$.param({
|
||||||
key: 'april-fools',
|
method: "storage.delete",
|
||||||
token: (<any> window).ForumAPITicket,
|
user_id: (<any>window).UserID,
|
||||||
}));
|
key: "april-fools",
|
||||||
|
token: (<any>window).ForumAPITicket,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Запуск шутки
|
* Запуск шутки
|
||||||
*
|
*
|
||||||
@@ -198,12 +211,14 @@ export class JokerClass {
|
|||||||
* @param {boolean} forced
|
* @param {boolean} forced
|
||||||
*/
|
*/
|
||||||
start(id: string, forced: boolean = false) {
|
start(id: string, forced: boolean = false) {
|
||||||
if (!(id in this.jokes))
|
if (!(id in this.jokes)) return;
|
||||||
return;
|
|
||||||
|
|
||||||
const joke = this.jokes[id];
|
const joke = this.jokes[id];
|
||||||
|
|
||||||
if (!forced && (!joke.settings.enabled || !this.check(joke.settings.chance))) {
|
if (
|
||||||
|
!forced &&
|
||||||
|
(!joke.settings.enabled || !this.check(joke.settings.chance))
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +239,7 @@ export class JokerClass {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.core_settings.testers.indexOf((<any> window).UserID) >= 0) {
|
if (this.core_settings.testers.indexOf((<any>window).UserID) >= 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,12 +267,12 @@ export class JokerClass {
|
|||||||
/**
|
/**
|
||||||
* Общие настройки системы
|
* Общие настройки системы
|
||||||
*/
|
*/
|
||||||
core_settings = new CoreSettings;
|
core_settings = new CoreSettings();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Перечисление всех шуток
|
* Перечисление всех шуток
|
||||||
*/
|
*/
|
||||||
jokes: JokeMap = {}
|
jokes: JokeMap = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+16
-11
@@ -10,13 +10,13 @@ import { JokerClass } from "../joker";
|
|||||||
* @author Kozhilya
|
* @author Kozhilya
|
||||||
*/
|
*/
|
||||||
export class CarnivalJoke extends Joke {
|
export class CarnivalJoke extends Joke {
|
||||||
id = 'carnival';
|
id = "carnival";
|
||||||
|
|
||||||
title = 'Карнавал';
|
title = "Карнавал";
|
||||||
|
|
||||||
description = 'Аватарки приобретают интересные цвета';
|
description = "Аватарки приобретают интересные цвета";
|
||||||
|
|
||||||
settings = new CarnivalJokeSettings;
|
settings = new CarnivalJokeSettings();
|
||||||
|
|
||||||
start(): void {
|
start(): void {
|
||||||
$(this.settings.selector).each((_, elem) => {
|
$(this.settings.selector).each((_, elem) => {
|
||||||
@@ -27,11 +27,16 @@ export class CarnivalJoke extends Joke {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
filters.push(entry[0].replace('{0}', Math.round(Math.random() * entry[1]).toString()));
|
filters.push(
|
||||||
|
entry[0].replace(
|
||||||
|
"{0}",
|
||||||
|
Math.round(Math.random() * entry[1]).toString()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filters.length > 0) {
|
if (filters.length > 0) {
|
||||||
$(elem).css({'filter': filters.join(' ')});
|
$(elem).css({ filter: filters.join(" ") });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -56,11 +61,11 @@ export class CarnivalJokeSettings implements JokeSettings {
|
|||||||
* Список фильтров и диапозона случайных параметров
|
* Список фильтров и диапозона случайных параметров
|
||||||
*/
|
*/
|
||||||
variants: CarnivalJokeFilters = {
|
variants: CarnivalJokeFilters = {
|
||||||
'sepia({0}%)': 100,
|
"sepia({0}%)": 100,
|
||||||
'saturate({0}%)': 100,
|
"saturate({0}%)": 100,
|
||||||
'hue-rotate({0}deg)': 360,
|
"hue-rotate({0}deg)": 360,
|
||||||
'invert({0}%)': 100,
|
"invert({0}%)": 100,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CarnivalJokeFilters {
|
export interface CarnivalJokeFilters {
|
||||||
|
|||||||
@@ -9,21 +9,21 @@ import $ from "jquery";
|
|||||||
* @author Kozhilya
|
* @author Kozhilya
|
||||||
*/
|
*/
|
||||||
export class CrazyLettersJoke extends Joke {
|
export class CrazyLettersJoke extends Joke {
|
||||||
id = 'crazy_letters';
|
id = "crazy_letters";
|
||||||
|
|
||||||
title = 'Мама, Я сОшЛа С уМа!';
|
title = "Мама, Я сОшЛа С уМа!";
|
||||||
|
|
||||||
description = 'иМеНа ЗаБоРчИкОм';
|
description = "иМеНа ЗаБоРчИкОм";
|
||||||
|
|
||||||
settings = new CrazyLettersJokeSettings;
|
settings = new CrazyLettersJokeSettings();
|
||||||
|
|
||||||
start(): void {
|
start(): void {
|
||||||
$(this.settings.selector).each((_, elem) => {
|
$(this.settings.selector).each((_, elem) => {
|
||||||
let text = $(this).text();
|
let text = $(this).text();
|
||||||
let result = '';
|
let result = "";
|
||||||
|
|
||||||
for (let i = 0; i < text.length; i++) {
|
for (let i = 0; i < text.length; i++) {
|
||||||
result += text[i][(i % 2) ? 'toLowerCase' : 'toUpperCase']();
|
result += text[i][i % 2 ? "toLowerCase" : "toUpperCase"]();
|
||||||
}
|
}
|
||||||
|
|
||||||
$(this).text(result);
|
$(this).text(result);
|
||||||
@@ -39,5 +39,5 @@ export class CrazyLettersJokeSettings implements JokeSettings {
|
|||||||
/**
|
/**
|
||||||
* Селектор всех элементов, которые будут затронуты
|
* Селектор всех элементов, которые будут затронуты
|
||||||
*/
|
*/
|
||||||
selector: string = '.pa-author a';
|
selector: string = ".pa-author a";
|
||||||
}
|
}
|
||||||
+58
-44
@@ -13,13 +13,13 @@ const cursor_effects = require("cursor-effects");
|
|||||||
* @link https://tholman.com/cursor-effects/
|
* @link https://tholman.com/cursor-effects/
|
||||||
*/
|
*/
|
||||||
export class CursorEffectsJoke extends StopableJoke {
|
export class CursorEffectsJoke extends StopableJoke {
|
||||||
id = 'cursor_effects';
|
id = "cursor_effects";
|
||||||
|
|
||||||
title = 'Красивый курсор';
|
title = "Красивый курсор";
|
||||||
|
|
||||||
description = 'Эффекты, следующие за курсором';
|
description = "Эффекты, следующие за курсором";
|
||||||
|
|
||||||
settings = new CursorEffectsJokeSettings;
|
settings = new CursorEffectsJokeSettings();
|
||||||
|
|
||||||
active_cursor_effect: any;
|
active_cursor_effect: any;
|
||||||
|
|
||||||
@@ -28,7 +28,7 @@ export class CursorEffectsJoke extends StopableJoke {
|
|||||||
*/
|
*/
|
||||||
enableAll() {
|
enableAll() {
|
||||||
for (const key of Object.keys(this.settings.effects)) {
|
for (const key of Object.keys(this.settings.effects)) {
|
||||||
this.settings.effects[<CursorEffectsEnum> key].enabled = true;
|
this.settings.effects[<CursorEffectsEnum>key].enabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ export class CursorEffectsJoke extends StopableJoke {
|
|||||||
*/
|
*/
|
||||||
disableAll() {
|
disableAll() {
|
||||||
for (const key of Object.keys(this.settings.effects)) {
|
for (const key of Object.keys(this.settings.effects)) {
|
||||||
this.settings.effects[<CursorEffectsEnum> key].enabled = false;
|
this.settings.effects[<CursorEffectsEnum>key].enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,8 +47,13 @@ export class CursorEffectsJoke extends StopableJoke {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getRandomEffect(): CursorEffectsEnum {
|
getRandomEffect(): CursorEffectsEnum {
|
||||||
const elements = Object.values(CursorEffectsEnum).map(e => <CursorEffectsEnum>e);
|
const elements = Object.values(CursorEffectsEnum).map(
|
||||||
const totalWeight = elements.reduce((sum, element) => sum + this.weight(element), 0);
|
(e) => <CursorEffectsEnum>e
|
||||||
|
);
|
||||||
|
const totalWeight = elements.reduce(
|
||||||
|
(sum, element) => sum + this.weight(element),
|
||||||
|
0
|
||||||
|
);
|
||||||
const randomWeight = Math.random() * totalWeight;
|
const randomWeight = Math.random() * totalWeight;
|
||||||
|
|
||||||
let currentWeight = 0;
|
let currentWeight = 0;
|
||||||
@@ -75,20 +80,23 @@ export class CursorEffectsJoke extends StopableJoke {
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum CursorEffectsEnum {
|
enum CursorEffectsEnum {
|
||||||
Rainbow = 'rainbow',
|
Rainbow = "rainbow",
|
||||||
FairyDust = 'fairy_dust',
|
FairyDust = "fairy_dust",
|
||||||
SpringyEmoji = 'springy_emoji',
|
SpringyEmoji = "springy_emoji",
|
||||||
Emoji = 'emoji',
|
Emoji = "emoji",
|
||||||
Ghost = 'ghost',
|
Ghost = "ghost",
|
||||||
Trailing = 'trailing',
|
Trailing = "trailing",
|
||||||
TextFlag = 'text_flag',
|
TextFlag = "text_flag",
|
||||||
FollowingDot = 'following_dot',
|
FollowingDot = "following_dot",
|
||||||
Bubbles = 'bubbles',
|
Bubbles = "bubbles",
|
||||||
Snowflake = 'snowflake',
|
Snowflake = "snowflake",
|
||||||
Clock = 'clock'
|
Clock = "clock",
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveCursorEffectsEnum(effect: CursorEffectsEnum|string, options: CursorEffectsSetting): any {
|
function resolveCursorEffectsEnum(
|
||||||
|
effect: CursorEffectsEnum | string,
|
||||||
|
options: CursorEffectsSetting
|
||||||
|
): any {
|
||||||
switch (effect) {
|
switch (effect) {
|
||||||
case CursorEffectsEnum.Rainbow:
|
case CursorEffectsEnum.Rainbow:
|
||||||
return cursor_effects.rainbowCursor(options);
|
return cursor_effects.rainbowCursor(options);
|
||||||
@@ -134,7 +142,8 @@ export class CursorEffectsJokeSettings implements JokeSettings {
|
|||||||
/**
|
/**
|
||||||
* Радужный след за курсором
|
* Радужный след за курсором
|
||||||
*/
|
*/
|
||||||
[CursorEffectsEnum.Rainbow]: new class extends DefaultCursorEffectsSetting {
|
[CursorEffectsEnum.Rainbow]:
|
||||||
|
new (class extends DefaultCursorEffectsSetting {
|
||||||
/**
|
/**
|
||||||
* Длина полосы
|
* Длина полосы
|
||||||
*/
|
*/
|
||||||
@@ -155,49 +164,52 @@ export class CursorEffectsJokeSettings implements JokeSettings {
|
|||||||
"#00FF00",
|
"#00FF00",
|
||||||
"#FFFF00",
|
"#FFFF00",
|
||||||
"#FF7F00",
|
"#FF7F00",
|
||||||
"#FF0000"
|
"#FF0000",
|
||||||
];
|
];
|
||||||
},
|
})(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Цепочка из эмодзи "на резинке" под курсором
|
* Цепочка из эмодзи "на резинке" под курсором
|
||||||
*/
|
*/
|
||||||
[CursorEffectsEnum.SpringyEmoji]: new class extends DefaultCursorEffectsSetting {
|
[CursorEffectsEnum.SpringyEmoji]:
|
||||||
|
new (class extends DefaultCursorEffectsSetting {
|
||||||
/**
|
/**
|
||||||
* Висящий эмодзи
|
* Висящий эмодзи
|
||||||
*/
|
*/
|
||||||
emoji: string = "🤪"
|
emoji: string = "🤪";
|
||||||
},
|
})(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Падающие от курсора эмодзи
|
* Падающие от курсора эмодзи
|
||||||
*/
|
*/
|
||||||
[CursorEffectsEnum.Emoji]: new class extends DefaultCursorEffectsSetting {
|
[CursorEffectsEnum.Emoji]: new (class extends DefaultCursorEffectsSetting {
|
||||||
/**
|
/**
|
||||||
* Падающие эмодзи
|
* Падающие эмодзи
|
||||||
*/
|
*/
|
||||||
emoji: string[] = ["🔥", "🐬", "🦆"]
|
emoji: string[] = ["🔥", "🐬", "🦆"];
|
||||||
},
|
})(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Падающие от курсора пылинки
|
* Падающие от курсора пылинки
|
||||||
*/
|
*/
|
||||||
[CursorEffectsEnum.FairyDust]: new class extends DefaultCursorEffectsSetting {
|
[CursorEffectsEnum.FairyDust]:
|
||||||
|
new (class extends DefaultCursorEffectsSetting {
|
||||||
/**
|
/**
|
||||||
* Цвет пылинок
|
* Цвет пылинок
|
||||||
*/
|
*/
|
||||||
colors: string[] = ["#ff0000", "#00ff00", "#0000ff"];
|
colors: string[] = ["#ff0000", "#00ff00", "#0000ff"];
|
||||||
},
|
})(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* След "зависших" курсоров
|
* След "зависших" курсоров
|
||||||
*/
|
*/
|
||||||
[CursorEffectsEnum.Ghost]: new DefaultCursorEffectsSetting,
|
[CursorEffectsEnum.Ghost]: new DefaultCursorEffectsSetting(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* След курсоров "на резинке"
|
* След курсоров "на резинке"
|
||||||
*/
|
*/
|
||||||
[CursorEffectsEnum.Trailing]: new class extends DefaultCursorEffectsSetting {
|
[CursorEffectsEnum.Trailing]:
|
||||||
|
new (class extends DefaultCursorEffectsSetting {
|
||||||
/**
|
/**
|
||||||
* Количество элементов
|
* Количество элементов
|
||||||
*/
|
*/
|
||||||
@@ -213,12 +225,13 @@ export class CursorEffectsJokeSettings implements JokeSettings {
|
|||||||
* Используйте `null`, что бы использовать картинку курсора по умолчанию
|
* Используйте `null`, что бы использовать картинку курсора по умолчанию
|
||||||
*/
|
*/
|
||||||
baseImageSrc: string | null = null;
|
baseImageSrc: string | null = null;
|
||||||
},
|
})(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Текст, развивающийся флагом от курсора
|
* Текст, развивающийся флагом от курсора
|
||||||
*/
|
*/
|
||||||
[CursorEffectsEnum.TextFlag]: new class extends DefaultCursorEffectsSetting {
|
[CursorEffectsEnum.TextFlag]:
|
||||||
|
new (class extends DefaultCursorEffectsSetting {
|
||||||
/**
|
/**
|
||||||
* Отображаемый текст
|
* Отображаемый текст
|
||||||
*/
|
*/
|
||||||
@@ -248,37 +261,38 @@ export class CursorEffectsJokeSettings implements JokeSettings {
|
|||||||
* Размер... чего-то.
|
* Размер... чего-то.
|
||||||
*/
|
*/
|
||||||
size: number = 3;
|
size: number = 3;
|
||||||
|
})(),
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Точка, преследующая курсор
|
* Точка, преследующая курсор
|
||||||
*/
|
*/
|
||||||
[CursorEffectsEnum.FollowingDot]: new class extends DefaultCursorEffectsSetting {
|
[CursorEffectsEnum.FollowingDot]:
|
||||||
|
new (class extends DefaultCursorEffectsSetting {
|
||||||
/**
|
/**
|
||||||
* Цвет догоняющей точки
|
* Цвет догоняющей точки
|
||||||
*/
|
*/
|
||||||
color: string = "#323232a6";
|
color: string = "#323232a6";
|
||||||
},
|
})(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Пузырьки от курсора
|
* Пузырьки от курсора
|
||||||
*/
|
*/
|
||||||
[CursorEffectsEnum.Bubbles]: new DefaultCursorEffectsSetting,
|
[CursorEffectsEnum.Bubbles]: new DefaultCursorEffectsSetting(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Снежинки, летящие от курсора
|
* Снежинки, летящие от курсора
|
||||||
*
|
*
|
||||||
* Отключено, потому что сейчас не зима :D
|
* Отключено, потому что сейчас не зима :D
|
||||||
*/
|
*/
|
||||||
[CursorEffectsEnum.Snowflake]: new class extends DefaultCursorEffectsSetting {
|
[CursorEffectsEnum.Snowflake]:
|
||||||
|
new (class extends DefaultCursorEffectsSetting {
|
||||||
weight: number = 0;
|
weight: number = 0;
|
||||||
},
|
})(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Циферблат вокруг курсора
|
* Циферблат вокруг курсора
|
||||||
*/
|
*/
|
||||||
[CursorEffectsEnum.Clock]: new class extends DefaultCursorEffectsSetting {
|
[CursorEffectsEnum.Clock]: new (class extends DefaultCursorEffectsSetting {
|
||||||
/**
|
/**
|
||||||
* Цвет даты
|
* Цвет даты
|
||||||
*/
|
*/
|
||||||
@@ -303,7 +317,7 @@ export class CursorEffectsJokeSettings implements JokeSettings {
|
|||||||
* Цвет часовой стрелки
|
* Цвет часовой стрелки
|
||||||
*/
|
*/
|
||||||
hoursColor: string = "black";
|
hoursColor: string = "black";
|
||||||
},
|
})(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Joke, JokeSettings, StopableJoke } from "../joke";
|
import { Joke, JokeSettings, StopableJoke } from "../joke";
|
||||||
|
import { getTextNodes } from "../common";
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -9,19 +10,25 @@ import $ from "jquery";
|
|||||||
* @author Kozhilya
|
* @author Kozhilya
|
||||||
*/
|
*/
|
||||||
export class HumanitarianHellJoke extends Joke {
|
export class HumanitarianHellJoke extends Joke {
|
||||||
id = 'humanitarian_hell';
|
id = "humanitarian_hell";
|
||||||
|
|
||||||
title = 'Ад гуманитария';
|
title = "Ад гуманитария";
|
||||||
|
|
||||||
description = 'Все "тся" заменяются на "ться", а все "ться" на "тся"';
|
description = 'Все "тся" заменяются на "ться", а все "ться" на "тся"';
|
||||||
|
|
||||||
settings = new HumanitarianHellJokeSettings;
|
settings = new HumanitarianHellJokeSettings();
|
||||||
|
|
||||||
|
processText(text: string): string {
|
||||||
|
return text.replace(/(ть?ся)/g, function (fnd) {
|
||||||
|
return fnd.indexOf("ь") > 0 ? "тся" : "ться";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
start(): void {
|
start(): void {
|
||||||
$(this.settings.selector).each(function () {
|
const textNodes = getTextNodes(this.settings.selector);
|
||||||
$(this).html($(this).html().replace(/(ть?ся)/g, function (fnd) {
|
|
||||||
return (fnd.indexOf('ь') > 0) ? 'тся' : 'ться';
|
textNodes.each((_, elem) => {
|
||||||
}));
|
elem.textContent = this.processText(elem.textContent);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,5 +41,5 @@ export class HumanitarianHellJokeSettings implements JokeSettings {
|
|||||||
/**
|
/**
|
||||||
* Селектор всех элементов, которые будут затронуты
|
* Селектор всех элементов, которые будут затронуты
|
||||||
*/
|
*/
|
||||||
selector: string = '.post-content';
|
selector: string = ".post-content";
|
||||||
}
|
}
|
||||||
+23
-12
@@ -1,28 +1,29 @@
|
|||||||
import { Joke, JokeSettings, StopableJoke } from "../joke";
|
import { Joke, JokeSettings, StopableJoke } from "../joke";
|
||||||
|
import { getTextNodes } from "../common";
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
import { JokerClass } from "../joker";
|
import { JokerClass } from "../joker";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **Буквенный хаос**
|
* **Буквенный хаос**
|
||||||
*
|
*
|
||||||
* Все буквы в словах, кроме первой и последней, перемешены.
|
* Все буквы в словах, кроме первой и последней, перемешены
|
||||||
*
|
*
|
||||||
* @author Kozhilya
|
* @author Kozhilya
|
||||||
*/
|
*/
|
||||||
export class LetterChaosJoke extends Joke {
|
export class LetterChaosJoke extends Joke {
|
||||||
id = 'letter_chaos';
|
id = "letter_chaos";
|
||||||
|
|
||||||
title = 'Буквенный хаос';
|
title = "Буквенный хаос";
|
||||||
|
|
||||||
description = 'Все буквы в словах, кроме первой и последней, перемешены.';
|
description = "Все буквы в словах, кроме первой и последней, перемешены";
|
||||||
|
|
||||||
settings = new LetterChaosJokeSettings;
|
settings = new LetterChaosJokeSettings();
|
||||||
|
|
||||||
punctuationSymbols: string[] | null = null;
|
punctuationSymbols: string[] | null = null;
|
||||||
|
|
||||||
private shuffleLetters(word: string): string {
|
private shuffleLetters(word: string): string {
|
||||||
// Check if the word has two or more letters
|
// Check if the word has two or more letters
|
||||||
if ((word.length < 3) || !this.check(this.settings.shuffle_chance)) {
|
if (word.length < 3 || !this.check(this.settings.shuffle_chance)) {
|
||||||
return word;
|
return word;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,21 +34,31 @@ export class LetterChaosJoke extends Joke {
|
|||||||
const middleCharacters = characters.slice(1, -1);
|
const middleCharacters = characters.slice(1, -1);
|
||||||
for (let i = middleCharacters.length - 1; i > 0; i--) {
|
for (let i = middleCharacters.length - 1; i > 0; i--) {
|
||||||
const j = Math.floor(Math.random() * (i + 1));
|
const j = Math.floor(Math.random() * (i + 1));
|
||||||
[middleCharacters[i], middleCharacters[j]] = [middleCharacters[j], middleCharacters[i]];
|
[middleCharacters[i], middleCharacters[j]] = [
|
||||||
|
middleCharacters[j],
|
||||||
|
middleCharacters[i],
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Join the shuffled characters back into a word
|
// Join the shuffled characters back into a word
|
||||||
return [characters[0], ...middleCharacters, characters[characters.length - 1]].join("");
|
return [
|
||||||
|
characters[0],
|
||||||
|
...middleCharacters,
|
||||||
|
characters[characters.length - 1],
|
||||||
|
].join("");
|
||||||
}
|
}
|
||||||
|
|
||||||
private processNode(node: any) {
|
private processNode(node: any) {
|
||||||
node.textContent = node.textContent?.replace(/([А-Яа-яA-Za-z]+)/gm, this.shuffleLetters);
|
node.textContent = node.textContent?.replace(
|
||||||
|
/([А-Яа-яA-Za-z]+)/gm,
|
||||||
|
this.shuffleLetters
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
start(): void {
|
start(): void {
|
||||||
const items = $(this.settings.selector).find('*').contents().filter((_, node) => node.nodeType === Node.TEXT_NODE);
|
const textNodes = getTextNodes(this.settings.selector);
|
||||||
|
|
||||||
items.each((_, node) => this.processNode(node))
|
textNodes.each((_, node) => this.processNode(node));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +70,7 @@ export class LetterChaosJokeSettings implements JokeSettings {
|
|||||||
/**
|
/**
|
||||||
* Селектор всех элементов, которые будут затронуты
|
* Селектор всех элементов, которые будут затронуты
|
||||||
*/
|
*/
|
||||||
selector: string = '.post-content';
|
selector: string = ".post-content";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Вероятность того, что буквы будут перемешаны
|
* Вероятность того, что буквы будут перемешаны
|
||||||
|
|||||||
+12
-8
@@ -9,19 +9,23 @@ import $ from "jquery";
|
|||||||
* @author Kozhilya
|
* @author Kozhilya
|
||||||
*/
|
*/
|
||||||
export class MirrorJoke extends Joke {
|
export class MirrorJoke extends Joke {
|
||||||
id = 'mirror';
|
id = "mirror";
|
||||||
|
|
||||||
title = 'Зеркало';
|
title = "Зеркало";
|
||||||
|
|
||||||
description = 'Элементы форума отражаются (по крайней мере, пытаются)';
|
description = "Элементы форума отражаются (по крайней мере, пытаются)";
|
||||||
|
|
||||||
settings = new MirrorJokeSettings;
|
settings = new MirrorJokeSettings();
|
||||||
|
|
||||||
start(): void {
|
start(): void {
|
||||||
$('.post, .post h3, .post-links, .post-author, .post-content')
|
$(".post, .post h3, .post-links, .post-author, .post-content")
|
||||||
.css('transform', 'scaleX(-1)').css('-moz-transform', 'scaleX(-1)').css('-moz-transform', 'scaleX(-1)').css('filter', 'FlipH').css('-ms-filter', '"FlipH"');
|
.css("transform", "scaleX(-1)")
|
||||||
$('.post-links, .post-links ul, .post h3 span').css('margin-left', '0');
|
.css("-moz-transform", "scaleX(-1)")
|
||||||
$('.post h3 span').css('margin-right', '25em');
|
.css("-moz-transform", "scaleX(-1)")
|
||||||
|
.css("filter", "FlipH")
|
||||||
|
.css("-ms-filter", '"FlipH"');
|
||||||
|
$(".post-links, .post-links ul, .post h3 span").css("margin-left", "0");
|
||||||
|
$(".post h3 span").css("margin-right", "25em");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -9,19 +9,19 @@ import $ from "jquery";
|
|||||||
* @author Kozhilya
|
* @author Kozhilya
|
||||||
*/
|
*/
|
||||||
export class ShakeJoke extends StopableJoke {
|
export class ShakeJoke extends StopableJoke {
|
||||||
id = 'shake';
|
id = "shake";
|
||||||
|
|
||||||
title = 'Форумо-трясение';
|
title = "Форумо-трясение";
|
||||||
|
|
||||||
description = 'Страница форума начинает трястись';
|
description = "Страница форума начинает трястись";
|
||||||
|
|
||||||
settings = new ShakeJokeSettings;
|
settings = new ShakeJokeSettings();
|
||||||
|
|
||||||
private interval_id: NodeJS.Timer;
|
private interval_id: NodeJS.Timer;
|
||||||
|
|
||||||
private items: JQuery;
|
private items: JQuery;
|
||||||
|
|
||||||
private data_name: string = 'april-fools-shake';
|
private data_name: string = "april-fools-shake";
|
||||||
|
|
||||||
rand(a: number): number {
|
rand(a: number): number {
|
||||||
return a + this.settings.force * (Math.random() * 2 - 1);
|
return a + this.settings.force * (Math.random() * 2 - 1);
|
||||||
@@ -33,8 +33,8 @@ export class ShakeJoke extends StopableJoke {
|
|||||||
this.items.each((_, elem) => {
|
this.items.each((_, elem) => {
|
||||||
let data: ShakeJokeMargin = {};
|
let data: ShakeJokeMargin = {};
|
||||||
|
|
||||||
this.settings.directions.forEach(d => {
|
this.settings.directions.forEach((d) => {
|
||||||
data[d] = parseInt($(elem).css('margin-' + d));
|
data[d] = parseInt($(elem).css("margin-" + d));
|
||||||
});
|
});
|
||||||
|
|
||||||
$(elem).data(this.data_name, data);
|
$(elem).data(this.data_name, data);
|
||||||
@@ -45,7 +45,7 @@ export class ShakeJoke extends StopableJoke {
|
|||||||
const data: ShakeJokeMargin = $(elem).data(this.data_name);
|
const data: ShakeJokeMargin = $(elem).data(this.data_name);
|
||||||
|
|
||||||
for (const entry of Object.entries(data)) {
|
for (const entry of Object.entries(data)) {
|
||||||
$(elem).css('margin-' + entry[0], this.rand(entry[1]))
|
$(elem).css("margin-" + entry[0], this.rand(entry[1]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, this.settings.interval);
|
}, this.settings.interval);
|
||||||
@@ -57,8 +57,8 @@ export class ShakeJoke extends StopableJoke {
|
|||||||
this.items.each((_, elem) => {
|
this.items.each((_, elem) => {
|
||||||
let data: ShakeJokeMargin = {};
|
let data: ShakeJokeMargin = {};
|
||||||
|
|
||||||
this.settings.directions.forEach(d => {
|
this.settings.directions.forEach((d) => {
|
||||||
$(elem).css('margin-' + d, data[d]);
|
$(elem).css("margin-" + d, data[d]);
|
||||||
});
|
});
|
||||||
|
|
||||||
$(elem).data(this.data_name, data);
|
$(elem).data(this.data_name, data);
|
||||||
@@ -74,7 +74,7 @@ export class ShakeJokeSettings implements JokeSettings {
|
|||||||
/**
|
/**
|
||||||
* Направление тряски (тряска происходит путём изменения перечисленных направлений margin на значение ±force от стандартного значения)
|
* Направление тряски (тряска происходит путём изменения перечисленных направлений margin на значение ±force от стандартного значения)
|
||||||
*/
|
*/
|
||||||
directions: string[] = ['top', 'left', 'bottom', 'left'];
|
directions: string[] = ["top", "left", "bottom", "left"];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Сила тряски - насколько отклоняется элемент от стандартного значения
|
* Сила тряски - насколько отклоняется элемент от стандартного значения
|
||||||
@@ -84,7 +84,7 @@ export class ShakeJokeSettings implements JokeSettings {
|
|||||||
/**
|
/**
|
||||||
* Селектор всех элементов, которые будут трястись
|
* Селектор всех элементов, которые будут трястись
|
||||||
*/
|
*/
|
||||||
selector: string = '[id^=pun]';
|
selector: string = "[id^=pun]";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Частота тряски
|
* Частота тряски
|
||||||
|
|||||||
+104
-86
@@ -1,35 +1,39 @@
|
|||||||
import { Joke, JokeSettings, StopableJoke } from "../joke";
|
import { Joke, JokeSettings, StopableJoke } from "../joke";
|
||||||
import $ from "jquery";
|
import $ from "jquery";
|
||||||
|
import { StupidTitleDefaultVariants } from "../data/stupid_title_variants";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* **Глупые статусы**
|
* **Глупые статусы**
|
||||||
*
|
*
|
||||||
* Каждому пользователю даётся новый глупый статус.
|
* Каждому пользователю даётся новый глупый статус
|
||||||
*
|
*
|
||||||
* @author Kozhilya
|
* @author Kozhilya
|
||||||
*/
|
*/
|
||||||
export class StupidTitleJoke extends Joke {
|
export class StupidTitleJoke extends Joke {
|
||||||
id = 'stupid_title';
|
id = "stupid_title";
|
||||||
|
|
||||||
title = 'Глупые статусы';
|
title = "Глупые статусы";
|
||||||
|
|
||||||
description = 'Каждому пользователю даётся новый глупый статус.';
|
description = "Каждому пользователю даётся новый глупый статус";
|
||||||
|
|
||||||
settings = new StupidTitleJokeSettings;
|
settings = new StupidTitleJokeSettings();
|
||||||
|
|
||||||
private loadedGenders: any = null;
|
private loadedGenders: any = null;
|
||||||
|
|
||||||
async loadGenders(): Promise<void> {
|
async loadGenders(): Promise<void> {
|
||||||
const names = $('.pa-author a')
|
const names = $(".pa-author a")
|
||||||
.map((_, elem) => elem.innerText).toArray()
|
.map((_, elem) => elem.innerText)
|
||||||
|
.toArray()
|
||||||
.reduce((arr: string[], name: string) => {
|
.reduce((arr: string[], name: string) => {
|
||||||
if (arr.indexOf(name) < 0){
|
if (arr.indexOf(name) < 0) {
|
||||||
arr.push(name);
|
arr.push(name);
|
||||||
}
|
}
|
||||||
return arr
|
return arr;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const url = '/api.php?' + $.param({ method: 'users.get', fields: 'username,sex', username: names });
|
const url =
|
||||||
|
"/api.php?" +
|
||||||
|
$.param({ method: "users.get", fields: "username,sex", username: names });
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
|
|
||||||
@@ -40,11 +44,11 @@ export class StupidTitleJoke extends Joke {
|
|||||||
}
|
}
|
||||||
|
|
||||||
json.response.users.forEach((element: any) => {
|
json.response.users.forEach((element: any) => {
|
||||||
if (element.sex === '0') {
|
if (element.sex === "0") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadedGenders[element.username] = element.sex === '1';
|
this.loadedGenders[element.username] = element.sex === "1";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,16 +62,23 @@ export class StupidTitleJoke extends Joke {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.resetSeed();
|
this.resetSeed();
|
||||||
return this.selectRandom(name, { 'm': 1, 'f': 1 }) === 'm';
|
return this.selectRandom(name, { m: 1, f: 1 }) === "m";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private variantsGenerated = false;
|
||||||
|
|
||||||
async start(): Promise<void> {
|
async start(): Promise<void> {
|
||||||
|
if (!this.variantsGenerated) {
|
||||||
|
StupidTitleDefaultVariants(this.settings.variants);
|
||||||
|
this.variantsGenerated = true;
|
||||||
|
}
|
||||||
|
|
||||||
await this.loadGenders();
|
await this.loadGenders();
|
||||||
|
|
||||||
const cache: any = {};
|
const cache: any = {};
|
||||||
|
|
||||||
$('.post-author').each((_, root) => {
|
$(".post-author").each((_, root) => {
|
||||||
const name = $('.pa-author a', root).text();
|
const name = $(".pa-author a", root).text();
|
||||||
if (!name) {
|
if (!name) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -77,7 +88,7 @@ export class StupidTitleJoke extends Joke {
|
|||||||
cache[name] = this.generatePhrase(name);
|
cache[name] = this.generatePhrase(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.pa-title', root).text(cache[name]);
|
$(".pa-title", root).text(cache[name]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,16 +101,21 @@ export class StupidTitleJoke extends Joke {
|
|||||||
Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity.
|
Largely inspired by MurmurHash2/3, but with a focus on speed/simplicity.
|
||||||
Public domain. Attribution appreciated.
|
Public domain. Attribution appreciated.
|
||||||
*/
|
*/
|
||||||
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
|
let h1 = 0xdeadbeef ^ seed,
|
||||||
|
h2 = 0x41c6ce57 ^ seed;
|
||||||
for (let i = 0, ch; i < name.length; i++) {
|
for (let i = 0, ch; i < name.length; i++) {
|
||||||
ch = name.charCodeAt(i);
|
ch = name.charCodeAt(i);
|
||||||
h1 = Math.imul(h1 ^ ch, 2654435761);
|
h1 = Math.imul(h1 ^ ch, 2654435761);
|
||||||
h2 = Math.imul(h2 ^ ch, 1597334677);
|
h2 = Math.imul(h2 ^ ch, 1597334677);
|
||||||
}
|
}
|
||||||
h1 = Math.imul(h1 ^ (h1>>>16), 2246822507) ^ Math.imul(h2 ^ (h2>>>13), 3266489909);
|
h1 =
|
||||||
h2 = Math.imul(h2 ^ (h2>>>16), 2246822507) ^ Math.imul(h1 ^ (h1>>>13), 3266489909);
|
Math.imul(h1 ^ (h1 >>> 16), 2246822507) ^
|
||||||
|
Math.imul(h2 ^ (h2 >>> 13), 3266489909);
|
||||||
|
h2 =
|
||||||
|
Math.imul(h2 ^ (h2 >>> 16), 2246822507) ^
|
||||||
|
Math.imul(h1 ^ (h1 >>> 13), 3266489909);
|
||||||
|
|
||||||
const value = 4294967296 * (2097151 & h2) + (h1>>>0);
|
const value = 4294967296 * (2097151 & h2) + (h1 >>> 0);
|
||||||
|
|
||||||
return Math.floor(Math.pow(Math.sin(value), 2) * limit) % limit;
|
return Math.floor(Math.pow(Math.sin(value), 2) * limit) % limit;
|
||||||
}
|
}
|
||||||
@@ -108,15 +124,25 @@ export class StupidTitleJoke extends Joke {
|
|||||||
|
|
||||||
private resetSeed(): void {
|
private resetSeed(): void {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
const time = new Date().getUTCHours() * 60 + new Date().getUTCMinutes();
|
const time = date.getUTCHours() * 60 + date.getUTCMinutes();
|
||||||
this.seed = Math.floor(time / this.settings.change_frequency);
|
|
||||||
|
|
||||||
console.log('Seed reset:', time, this.seed);
|
if (this.settings.change_frequency === 0) {
|
||||||
|
this.seed = time * 60 + date.getUTCSeconds();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private selectRandom(name: string, variants: StupidTitleWeightedVariants): string {
|
this.seed = Math.floor(time / this.settings.change_frequency);
|
||||||
|
}
|
||||||
|
|
||||||
|
private selectRandom(
|
||||||
|
name: string,
|
||||||
|
variants: StupidTitleWeightedVariants
|
||||||
|
): string {
|
||||||
const elements = Object.keys(variants);
|
const elements = Object.keys(variants);
|
||||||
const totalWeight = elements.reduce((sum, element) => sum + variants[element], 0);
|
const totalWeight = elements.reduce(
|
||||||
|
(sum, element) => sum + variants[element],
|
||||||
|
0
|
||||||
|
);
|
||||||
const randomWeight = this.prng(name, this.seed++, totalWeight);
|
const randomWeight = this.prng(name, this.seed++, totalWeight);
|
||||||
|
|
||||||
let currentWeight = 0;
|
let currentWeight = 0;
|
||||||
@@ -130,7 +156,10 @@ export class StupidTitleJoke extends Joke {
|
|||||||
throw new Error("Тебя быть тут не должно...");
|
throw new Error("Тебя быть тут не должно...");
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildVariants(type: string, gender: boolean): StupidTitleWeightedVariants {
|
private buildVariants(
|
||||||
|
type: string,
|
||||||
|
gender: boolean
|
||||||
|
): StupidTitleWeightedVariants {
|
||||||
const result: StupidTitleWeightedVariants = {};
|
const result: StupidTitleWeightedVariants = {};
|
||||||
const variants: StupidTitleVariant = this.settings.variants[type];
|
const variants: StupidTitleVariant = this.settings.variants[type];
|
||||||
|
|
||||||
@@ -138,7 +167,7 @@ export class StupidTitleJoke extends Joke {
|
|||||||
const word = iterator[0];
|
const word = iterator[0];
|
||||||
const wordSettings = iterator[1];
|
const wordSettings = iterator[1];
|
||||||
|
|
||||||
if (!wordSettings.enabled || (wordSettings.gender === !gender)) {
|
if (!wordSettings.enabled || wordSettings.gender === !gender) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,11 +189,13 @@ export class StupidTitleJoke extends Joke {
|
|||||||
const gender = this.resolveGender(name);
|
const gender = this.resolveGender(name);
|
||||||
const prhase = this.selectRandom(name, this.settings.schemas);
|
const prhase = this.selectRandom(name, this.settings.schemas);
|
||||||
|
|
||||||
return this.capitalizeFirst(prhase.replace(/\{(.+?)\}/g, (_, type: string) => {
|
return this.capitalizeFirst(
|
||||||
|
prhase.replace(/\{(.+?)\}/g, (_, type: string) => {
|
||||||
const variants = this.buildVariants(type, gender);
|
const variants = this.buildVariants(type, gender);
|
||||||
|
|
||||||
return this.selectRandom(name, variants);
|
return this.selectRandom(name, variants);
|
||||||
}));
|
})
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,6 +221,7 @@ export class StupidTitleJokeSettings implements JokeSettings {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Частота смены статусов (в минутах)
|
* Частота смены статусов (в минутах)
|
||||||
|
* Установите значение 0, что бы обновление происходило при каждом обновлении страницы
|
||||||
*/
|
*/
|
||||||
change_frequency: number = 5;
|
change_frequency: number = 5;
|
||||||
|
|
||||||
@@ -204,14 +236,14 @@ export class StupidTitleJokeSettings implements JokeSettings {
|
|||||||
* {p} - знак препинания
|
* {p} - знак препинания
|
||||||
*/
|
*/
|
||||||
schemas: StupidTitleWeightedVariants = {
|
schemas: StupidTitleWeightedVariants = {
|
||||||
'{adj} {noun}{p}': 10,
|
"{adj} {noun}{p}": 10,
|
||||||
'{noun} {adj}{p}': 3,
|
"{noun} {adj}{p}": 3,
|
||||||
'{adj}, {adj} {noun}{p}': 10,
|
"{adj}, {adj} {noun}{p}": 10,
|
||||||
'{adj} и очень {adj} {noun}{p}': 10,
|
"{adj} и очень {adj} {noun}{p}": 10,
|
||||||
'{adj} {noun} {verb}{p}': 10,
|
"{adj} {noun} {verb}{p}": 10,
|
||||||
'{adj} {noun} {adv} {verb}{p}': 5,
|
"{adj} {noun} {adv} {verb}{p}": 5,
|
||||||
'{adj} {noun} {verb} {place}{p}': 5,
|
"{adj} {noun} {verb} {place}{p}": 5,
|
||||||
'{adj} {noun} {adv} {verb} {place}{p}': 5,
|
"{adj} {noun} {adv} {verb} {place}{p}": 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -219,53 +251,33 @@ export class StupidTitleJokeSettings implements JokeSettings {
|
|||||||
* Смотрите раздел описания скрипта, что бы настроить это поле
|
* Смотрите раздел описания скрипта, что бы настроить это поле
|
||||||
*/
|
*/
|
||||||
variants: StupidTitleVariants = {
|
variants: StupidTitleVariants = {
|
||||||
adj: {
|
adj: {},
|
||||||
...buildVariant(true, 'жесткий,^удачливый,низкий,знакомый,откровенный,^мирный,грамотный,вкусный,виртуальный,пышный,провинциальный,$жирный,заинтересованный,объективный,^оригинальный,пожилой,чистый,особенный,выгодный,громадный,обыкновенный,чужой,ударный,^солнечный,истинный,посторонний,южный,седой,$бесполезный,острый,пестрый,формальный,повседневный,невозможный,$жалкий,целый,$глупый,последний,выходной,серьезный,подземный,небесный,любимый,былой,семейный,далекий,северный,суровый,гигантский,иностранный,родной,конструктивный,показательный,нужный,чрезвычайный,гордый,банальный,открытый,независимый,запасной,мстительный,грубый,алчный,мелочный,хладнокровный,спокойный,терпеливый,креативный,активный,адекватный,застенчивый,опрятный,безнадёжный,уверенный в себе,доброжелательный,ласковый,робкий,воспитанный,самовлюблённый,деятельный,двуличный,верный'),
|
noun: {},
|
||||||
...buildVariant(false, 'жесткая,^удачливая,низкая,знакомая,откровенная,^мирная,грамотная,вкусная,виртуальная,пышная,провинциальная,$жирная,заинтересованная,объективная,^оригинальная,пожилая,чистая,особенная,выгодная,громадная,обыкновенная,чужая,ударная,^солнечная,истинная,посторонняя,южная,седая,$бесполезная,острая,пестрая,формальная,повседневная,невозможная,$жалкая,целая,$глупая,последняя,выходная,серьезная,подземная,небесная,любимая,былая,семейная,далекая,северная,суровая,гигантская,иностранная,родная,конструктивная,показательная,нужная,чрезвычайная,гордая,банальная,открытая,независимая,запасная,мстительная,грубая,алчная,мелочная,хладнокровная,спокаяная,терпеливая,креативная,активная,адекватная,застенчивая,опрятная,безнадёжная,уверенная в себе,доброжелательная,ласковая,робкая,воспитанная,самовлюблённая,деятельная,двуличная,верная'),
|
verb: {},
|
||||||
},
|
place: {},
|
||||||
noun: {
|
adv: {},
|
||||||
...buildVariant(null, ''),
|
|
||||||
|
|
||||||
...buildVariant(true, 'орёл, ниндзя, манекен, пузырь, бродяга, рыцарь, кентавр, зайц, диван, наследник, сын, джентльмен, басурманин, карасик, $злоумышленник, $раб, хоббит, одиночка, отец, кролик, бруталище, дворф, актёр, %дед, спортсмен, $балбес, %мальчег, лев, ёж, организм, монах, хоббит, борец, тигр, монстр, массажист, мачо, эльф, ледник, жук, кот, зомби, проказник, дракон, носорог, волк, лесоруб, кит, %дедушка, динозавр, бард, кулак, принц, %сынок, мальчик, товарищ, ёжик, сурикат'),
|
|
||||||
|
|
||||||
...buildVariant(false, 'заноза, волторна, $личинка, детка, %бабушка, простуда, черепашка, мышь, волчица, деревяшка, пиранья, каруселька, красотка, леди, %дочка, орлица, принцесса, $ведьма, травка, актриса, наследница, %деффачка, горгулья, белочка, акула, машинка, конфетка, знаменитость, косточка, спортсменка, панда, мать, львица, эльфийка, $злоумышленница, чертовка, дворфиха, кошка, $рабыня, скамеечка, дочь, монашка, бактерия, рыбка, бусинка, $бабка, девочка, валькирия, килька, бабочка, милашка, крышка, тигрица, рыбка, русалочка'),
|
|
||||||
},
|
|
||||||
verb: {
|
|
||||||
...buildVariant(null, 'встаёт, снимает, приказывает, указывает, собирается, чувствует опасность, орёт, болеет, поздравляет, освобождает, поздравляет, бежит, берёт и делает, молчит, радуется, прощает, читает, снимает, снимается в фильме, что-то скрывает, думает, имеет план и придерживается его, тянет, работает, меняется, ловит, отказаться куда-то идти, заходит, замирает, оформляет, нарушает, отказывается что-то делать, шепчет, снимается в сериале, скрывается, учит, спрашивает, идёт, отказывается вставать, прибывает, отказывается, забывает, получает, плывёт, отвечает, поглядывает, говорит, просыпается, соединяет, оглядывается'),
|
|
||||||
|
|
||||||
...buildVariant(true, 'женится, женился, успел, не успел, смог, скрылся, заработался, познал дзен, присел, обиделся, проснулся, взял и сделал, додумался, не спал'),
|
|
||||||
|
|
||||||
...buildVariant(false, 'выходит замуж, вышла замуж, успела, не успела, смогла, скрылась, заработалась, познала дзен, присела, обиделась, проснулась, взяла и сделала, додумалась, не спала'),
|
|
||||||
},
|
|
||||||
place: {
|
|
||||||
...buildVariant(null, 'где-то, в пустыне, на пляже, под дождём, %под проливным дождём, в квартире, %в тёплой и уютной квартире, в космосе, в театре, в филармонии, на заснеженной вершине, на конференции, на форуме, в очереди, в лесу, в джунглях, под водой'),
|
|
||||||
},
|
|
||||||
adv: {
|
|
||||||
...buildVariant(null, 'счастливо, уныло, грустно, позже, немедленно, регулярно, вновь, опять, уже, внезапно, предсказуемо, медленно, быстро, %молниеносно, $грубо, безрассудно, осмысленно, расчётливо'),
|
|
||||||
},
|
|
||||||
p: {
|
p: {
|
||||||
'': new StupidTitleSetting({ weight: 10 }),
|
"": new StupidTitleSetting({ weight: 10 }),
|
||||||
'.': new StupidTitleSetting({ weight: 10 }),
|
".": new StupidTitleSetting({ weight: 10 }),
|
||||||
'...': new StupidTitleSetting({ weight: 5 }),
|
"...": new StupidTitleSetting({ weight: 5 }),
|
||||||
'!': new StupidTitleSetting({ weight: 5 }),
|
"!": new StupidTitleSetting({ weight: 5 }),
|
||||||
'!!!': new StupidTitleSetting({ weight: 2 }),
|
"!!!": new StupidTitleSetting({ weight: 2 }),
|
||||||
'?': new StupidTitleSetting({ weight: 2 }),
|
"?": new StupidTitleSetting({ weight: 2 }),
|
||||||
'?!': new StupidTitleSetting({ weight: 1 }),
|
"?!": new StupidTitleSetting({ weight: 1 }),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StupidTitleVariants {
|
export interface StupidTitleVariants {
|
||||||
[key: string]: StupidTitleVariant
|
[key: string]: StupidTitleVariant;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StupidTitleVariant {
|
interface StupidTitleVariant {
|
||||||
[key: string]: StupidTitleSetting
|
[key: string]: StupidTitleSetting;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StupidTitleWeightedVariants {
|
interface StupidTitleWeightedVariants {
|
||||||
[key: string]: number
|
[key: string]: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
class StupidTitleSetting {
|
class StupidTitleSetting {
|
||||||
@@ -275,38 +287,44 @@ class StupidTitleSetting {
|
|||||||
|
|
||||||
rude: boolean = false;
|
rude: boolean = false;
|
||||||
|
|
||||||
gender: boolean|null = null;
|
gender: boolean | null = null;
|
||||||
|
|
||||||
constructor(options: any = new Object) {
|
constructor(options: any = new Object()) {
|
||||||
for (const iterator of Object.entries(options)) {
|
for (const iterator of Object.entries(options)) {
|
||||||
if (iterator[0] in this) {
|
if (iterator[0] in this) {
|
||||||
(<any> this)[iterator[0]] = iterator[1];
|
(<any>this)[iterator[0]] = iterator[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildVariant(gender: boolean|null, input: string): StupidTitleVariant
|
export function BuildStupdiTitleVariant(
|
||||||
{
|
gender: boolean | null,
|
||||||
|
input: string
|
||||||
|
): StupidTitleVariant {
|
||||||
const result: StupidTitleVariant = {};
|
const result: StupidTitleVariant = {};
|
||||||
const words = input.split(',').map(word => word.trim());
|
const words = input.split(",").map((word) => word.trim());
|
||||||
|
|
||||||
words.forEach(word => {
|
words.forEach((word) => {
|
||||||
const clean_word = word.replace(/[^А-ЯЁа-яёA-Za-z\- ]/g, '');
|
const clean_word = word.replace(/[^А-ЯЁа-яёA-Za-z\- ]/g, "");
|
||||||
|
|
||||||
if (clean_word === '') {
|
if (clean_word === "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
result[clean_word] = new StupidTitleSetting({
|
result[clean_word] = new StupidTitleSetting({
|
||||||
gender,
|
gender,
|
||||||
rude: word.indexOf('$') >= 0,
|
rude: word.indexOf("$") >= 0,
|
||||||
enabled: word.indexOf('!') < 0,
|
enabled: word.indexOf("!") < 0,
|
||||||
weight: 10 * ((word.indexOf('$') >= 0) ? 0.5 : 1) * ((word.indexOf('%') >= 0) ? 0.5 : 1) * ((word.indexOf('^') >= 0) ? 2 : 1)
|
weight:
|
||||||
|
10 *
|
||||||
|
(word.indexOf("$") >= 0 ? 0.5 : 1) *
|
||||||
|
(word.indexOf("%") >= 0 ? 0.5 : 1) *
|
||||||
|
(word.indexOf("^") >= 0 ? 2 : 1),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
(window as any).BuildStupdiTitleVariant = buildVariant;
|
(window as any).BuildStupdiTitleVariant = BuildStupdiTitleVariant;
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ import { StupidTitleJoke } from "./jokes/stupid_title";
|
|||||||
(window as any).AprilJokes = ((jokes: JokeClassList): JokerClass => {
|
(window as any).AprilJokes = ((jokes: JokeClassList): JokerClass => {
|
||||||
const cl = new JokerClass();
|
const cl = new JokerClass();
|
||||||
|
|
||||||
jokes.forEach(joke => {
|
jokes.forEach((joke) => {
|
||||||
cl.add(new joke());
|
cl.add(new joke());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import button_html from "./html/button.html";
|
|||||||
import styles_html from "./html/styles.html";
|
import styles_html from "./html/styles.html";
|
||||||
import window_html from "./html/window.html";
|
import window_html from "./html/window.html";
|
||||||
|
|
||||||
|
|
||||||
export class JokerUI {
|
export class JokerUI {
|
||||||
joker: JokerClass;
|
joker: JokerClass;
|
||||||
|
|
||||||
@@ -27,10 +26,10 @@ export class JokerUI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get button() {
|
get button() {
|
||||||
let button = $('.april-fools__button');
|
let button = $(".april-fools__button");
|
||||||
|
|
||||||
if (button.length === 0) {
|
if (button.length === 0) {
|
||||||
button = $(button_html).appendTo('body');
|
button = $(button_html).appendTo("body");
|
||||||
}
|
}
|
||||||
|
|
||||||
return button;
|
return button;
|
||||||
@@ -41,22 +40,25 @@ export class JokerUI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render(): JQuery {
|
render(): JQuery {
|
||||||
const result: JQuery = $('<div></div>').html(window_html);
|
const result: JQuery = $("<div></div>").html(window_html);
|
||||||
const row_template = $('#april-fools__window-row', result).html();
|
const row_template = $("#april-fools__window-row", result).html();
|
||||||
const joke_container = $('.april-fools__jokes', result);
|
const joke_container = $(".april-fools__jokes", result);
|
||||||
|
|
||||||
for (const joke of Object.values(this.joker.jokes)) {
|
for (const joke of Object.values(this.joker.jokes)) {
|
||||||
const row = $(eval('`' + row_template + '`'));
|
const row = $(eval("`" + row_template + "`"));
|
||||||
$('input[type="checkbox"]', row).prop('checked', joke.settings.enabled)
|
$('input[type="checkbox"]', row)
|
||||||
.on('click', e => this.joker.toggleJoke(joke.id, (<any>e).currentTarget.checked));
|
.prop("checked", joke.settings.enabled)
|
||||||
|
.on("click", (e) =>
|
||||||
|
this.joker.toggleJoke(joke.id, (<any>e).currentTarget.checked)
|
||||||
|
);
|
||||||
joke_container.append(row);
|
joke_container.append(row);
|
||||||
}
|
}
|
||||||
|
|
||||||
$('button', result).on('click', async () => {
|
$("button", result).on("click", async () => {
|
||||||
await this.joker.clearUserStates();
|
await this.joker.clearUserStates();
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
});
|
});
|
||||||
|
|
||||||
return $('.april-fools__content', result);
|
return $(".april-fools__content", result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-5
@@ -3,13 +3,10 @@
|
|||||||
"allowSyntheticDefaultImports": true,
|
"allowSyntheticDefaultImports": true,
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"module": "es6",
|
"module": "es6",
|
||||||
"target": "es5",
|
"target": "es2017",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"typeRoots": [
|
"typeRoots": ["./node_modules/@types", "./types"]
|
||||||
"./node_modules/@types",
|
|
||||||
"./types"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"files": ["src/main.ts"]
|
"files": ["src/main.ts"]
|
||||||
}
|
}
|
||||||
+18
-8
@@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const webpack = require("webpack");
|
const webpack = require("webpack");
|
||||||
const BomPlugin = require('webpack-utf8-bom');
|
const BomPlugin = require("webpack-utf8-bom");
|
||||||
const { exec } = require('node:child_process');
|
const { exec } = require("node:child_process");
|
||||||
|
const TerserPlugin = require("terser-webpack-plugin");
|
||||||
|
|
||||||
const isProduction = process.env.NODE_ENV == "production";
|
const isProduction = process.env.NODE_ENV == "production";
|
||||||
|
|
||||||
@@ -11,21 +12,21 @@ const config = {
|
|||||||
entry: "./src/main.ts",
|
entry: "./src/main.ts",
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve(__dirname, "dist"),
|
path: path.resolve(__dirname, "dist"),
|
||||||
filename: () => ('april-fools' + (isProduction ? '.min' : '') + '.js'),
|
filename: () => "april-fools" + (isProduction ? ".min" : "") + ".js",
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new BomPlugin(true),
|
new BomPlugin(true),
|
||||||
{
|
{
|
||||||
apply: (compiler) => {
|
apply: (compiler) => {
|
||||||
compiler.hooks.afterEmit.tap('AfterEmitPlugin', (compilation) => {
|
compiler.hooks.afterEmit.tap("AfterEmitPlugin", (compilation) => {
|
||||||
exec('./upload.sh', (err, stdout, stderr) => {
|
exec("./upload.sh", (err, stdout, stderr) => {
|
||||||
if (stdout) process.stdout.write(stdout);
|
if (stdout) process.stdout.write(stdout);
|
||||||
if (stderr) process.stderr.write(stderr);
|
if (stderr) process.stderr.write(stderr);
|
||||||
console.log("Uploaded.");
|
console.log("Uploaded.");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
// Add your plugins here
|
// Add your plugins here
|
||||||
// Learn more about plugins from https://webpack.js.org/configuration/plugins/
|
// Learn more about plugins from https://webpack.js.org/configuration/plugins/
|
||||||
],
|
],
|
||||||
@@ -52,11 +53,20 @@ const config = {
|
|||||||
extensions: [".tsx", ".ts", ".jsx", ".js", "..."],
|
extensions: [".tsx", ".ts", ".jsx", ".js", "..."],
|
||||||
},
|
},
|
||||||
externals: {
|
externals: {
|
||||||
jquery: 'jQuery',
|
jquery: "jQuery",
|
||||||
},
|
},
|
||||||
watchOptions: {
|
watchOptions: {
|
||||||
aggregateTimeout: 20,
|
aggregateTimeout: 20,
|
||||||
},
|
},
|
||||||
|
optimization: {
|
||||||
|
minimize: isProduction,
|
||||||
|
minimizer: [new TerserPlugin({
|
||||||
|
terserOptions: {
|
||||||
|
compress: true,
|
||||||
|
},
|
||||||
|
minify: TerserPlugin.uglifyJsMinify,
|
||||||
|
})],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = () => {
|
module.exports = () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user