chore: batch improvements

- get april-fool-2021 back
- improve LittlePet
- add special products entries
这个提交包含在:
Dragon-Fish 2023-04-01 05:10:04 +08:00
父节点 d7440bb84d
当前提交 dca9919a36
共有 16 个文件被更改,包括 538 次插入76 次删除

查看文件

@ -36,6 +36,7 @@ skip_render:
# 静态文件
- '**/**.js'
- '**/**.css'
- 'plugins/**/**.html'
# CMS
- 'admin/**/*'

查看文件

@ -51,3 +51,7 @@ InPageEdit.myPreference = {
<script src="assets/js/initPluginsList.js"></script>
## ✨ Special products
- [2021 April Fools' Day (IPE-1977)](./plugins/april-fool-2021/)
- [2023 April Fools' Day (My little IPE)](./plugins/april-fool-2023/)

查看文件

@ -0,0 +1,23 @@
---
layout: page
title: 2021 April Fools' Day
date: 2021-04-01 00:00:00
tags:
---
## IPE-1977
**author**: [@dragon-fish](https://github.com/dragon-fish)
<iframe src="./modal/" style="width:80%;max-width:600px;height:420px" scrolling="no"></iframe>
## 《壹玖柒柒》限定皮肤
**author**: [@leranjun](https://github.com/leranjun)
```js
mw.loader.load(
'https://ipe-plugins.js.org/plugins/april-fool-2021/theme.css',
'text/css'
)
```

查看文件

@ -13,7 +13,7 @@
modal.setContent(
$('<div>').append(
$('<iframe>', {
src: 'https://ipe-plugins.js.org/public/AprilFool2021/index.html',
src: 'https://ipe-plugins.js.org/plugins/april-fool-2021/modal/index.html',
scrolling: 'no',
})
)

二进制文件未显示。

之后

宽度:  |  高度:  |  大小: 18 KiB

二进制文件未显示。

之后

宽度:  |  高度:  |  大小: 9.7 KiB

二进制文件未显示。

之后

宽度:  |  高度:  |  大小: 3.8 KiB

二进制文件未显示。

之后

宽度:  |  高度:  |  大小: 4.1 KiB

二进制文件未显示。

之后

宽度:  |  高度:  |  大小: 27 KiB

二进制文件未显示。

之后

宽度:  |  高度:  |  大小: 21 KiB

查看文件

@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>InPageEdit v1977</title>
<link rel="stylesheet" href="style.css" />
</head>
<body style="height: 420px">
<center style="border: 4px double" width="400">
<marquee behavior="" direction=""
><font size="40">
<img src="./img/new2.gif" alt="" /> 页内编™ 壹玖柒柒
<img src="./img/new2.gif" alt="" /> </font
></marquee>
<br />
<img src="./img/rainbow.gif" alt="" style="width: 98%; height: 4px" />
<br />
<blink
><font color="#00ffB4"></font><font color="#00B4ff"></font
><font color="#0000ff"></font><font color="#A500ff"></font
><font color="#FF00B4"></font></blink
>
<br />
<br />
<img src="./img/为我们的友谊干杯.gif" alt="" />
<br /><br />
<a href="#" onclick="fool()" class="btn btn-primary"
>立即访问 ipe.js.org</a
>
</center>
<script>
function fool() {
alert(
'2021 愚人节快乐,InPageEdit感谢有你一路陪伴。\n点击土味广告的外侧就可以关闭,放心只会弹出这一次哒\n如果还想再看一次的话,可以在页面内按顺序输入“ipeaprilfool2021”~'
)
}
</script>
</body>
</html>

查看文件

@ -0,0 +1,371 @@
body {
background: #00f url('./img/microfab.gif') top left;
font-family: '楷体';
color: #fff;
}
.btn {
display: inline-block;
*display: inline;
padding: 4px 12px;
margin-bottom: 0;
*margin-left: 0.3em;
font-size: 16px;
line-height: 20px;
color: #333;
text-align: center;
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
vertical-align: middle;
cursor: pointer;
background-color: #e6e6e6;
*background-color: #e6e6e6;
background-image: -moz-linear-gradient(top, #e6e6e6, #e6e6e6);
background-image: -webkit-gradient(
linear,
0 0,
0 100%,
from(#e6e6e6),
to(#e6e6e6)
);
background-image: -webkit-linear-gradient(top, #e6e6e6, #e6e6e6);
background-image: -o-linear-gradient(top, #e6e6e6, #e6e6e6);
background-image: linear-gradient(to bottom, #e6e6e6, #e6e6e6);
background-repeat: repeat-x;
border: 1px solid #bbb;
*border: 0;
border-color: #e6e6e6 #e6e6e6 #bfbfbf;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
border-bottom-color: #a2a2a2;
-webkit-border-radius: none;
-moz-border-radius: none;
border-radius: none;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe6e6e6',endColorstr='#ffe6e6e6',GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
*zoom: 1;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
0 1px 2px rgba(0, 0, 0, 0.05);
-moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
0 1px 2px rgba(0, 0, 0, 0.05);
}
.btn:hover,
.btn:focus,
.btn:active,
.btn.active,
.btn.disabled,
.btn[disabled] {
color: #333;
background-color: #e6e6e6;
*background-color: #d9d9d9;
}
.btn:active,
.btn.active {
background-color: #ccc \9;
}
.btn:first-child {
*margin-left: 0;
}
.btn:hover,
.btn:focus {
color: #333;
text-decoration: none;
background-position: 0 -15px;
-webkit-transition: background-position 0.1s linear;
-moz-transition: background-position 0.1s linear;
-o-transition: background-position 0.1s linear;
transition: background-position 0.1s linear;
}
.btn:focus {
outline: thin dotted #333;
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
.btn.active,
.btn:active {
background-image: none;
outline: 0;
-webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),
0 1px 2px rgba(0, 0, 0, 0.05);
-moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),
0 1px 2px rgba(0, 0, 0, 0.05);
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
}
.btn.disabled,
.btn[disabled] {
cursor: default;
background-image: none;
opacity: 0.65;
filter: alpha(opacity=65);
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
.btn-large {
padding: 11px 19px;
font-size: 20px;
-webkit-border-radius: none;
-moz-border-radius: none;
border-radius: none;
}
.btn-large [class^='icon-'],
.btn-large [class*=' icon-'] {
margin-top: 4px;
}
.btn-small {
padding: 2px 10px;
font-size: 13.6px;
-webkit-border-radius: none;
-moz-border-radius: none;
border-radius: none;
}
.btn-small [class^='icon-'],
.btn-small [class*=' icon-'] {
margin-top: 0;
}
.btn-mini [class^='icon-'],
.btn-mini [class*=' icon-'] {
margin-top: -1px;
}
.btn-mini {
padding: 1px 6px;
font-size: 12px;
-webkit-border-radius: none;
-moz-border-radius: none;
border-radius: none;
}
.btn-block {
display: block;
width: 100%;
padding-right: 0;
padding-left: 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.btn-block + .btn-block {
margin-top: 5px;
}
input[type='submit'].btn-block,
input[type='reset'].btn-block,
input[type='button'].btn-block {
width: 100%;
}
.btn-primary.active,
.btn-warning.active,
.btn-danger.active,
.btn-success.active,
.btn-info.active,
.btn-inverse.active {
color: rgba(255, 255, 255, 0.75);
}
.btn-primary {
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
background-color: #0ee;
*background-color: #0ee;
background-image: -moz-linear-gradient(top, #0ee, #0ee);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0ee), to(#0ee));
background-image: -webkit-linear-gradient(top, #0ee, #0ee);
background-image: -o-linear-gradient(top, #0ee, #0ee);
background-image: linear-gradient(to bottom, #0ee, #0ee);
background-repeat: repeat-x;
border-color: #0ee #0ee #00a1a2;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00eeee',endColorstr='#ff00eeee',GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary:active,
.btn-primary.active,
.btn-primary.disabled,
.btn-primary[disabled] {
color: #fff;
background-color: #0ee;
*background-color: #00d4d5;
}
.btn-primary:active,
.btn-primary.active {
background-color: #0bb \9;
}
.btn-warning {
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
background-color: #fa0;
*background-color: #fa0;
background-image: -moz-linear-gradient(top, #fa0, #fa0);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fa0), to(#fa0));
background-image: -webkit-linear-gradient(top, #fa0, #fa0);
background-image: -o-linear-gradient(top, #fa0, #fa0);
background-image: linear-gradient(to bottom, #fa0, #fa0);
background-repeat: repeat-x;
border-color: #fa0 #fa0 #b37700;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffaa00',endColorstr='#ffffaa00',GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
}
.btn-warning:hover,
.btn-warning:focus,
.btn-warning:active,
.btn-warning.active,
.btn-warning.disabled,
.btn-warning[disabled] {
color: #fff;
background-color: #fa0;
*background-color: #e69900;
}
.btn-warning:active,
.btn-warning.active {
background-color: #c80 \9;
}
.btn-danger {
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
background-color: #f00;
*background-color: #f00;
background-image: -moz-linear-gradient(top, #f00, #f00);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f00), to(#f00));
background-image: -webkit-linear-gradient(top, #f00, #f00);
background-image: -o-linear-gradient(top, #f00, #f00);
background-image: linear-gradient(to bottom, #f00, #f00);
background-repeat: repeat-x;
border-color: #f00 #f00 #b30000;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff0000',endColorstr='#ffff0000',GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
}
.btn-danger:hover,
.btn-danger:focus,
.btn-danger:active,
.btn-danger.active,
.btn-danger.disabled,
.btn-danger[disabled] {
color: #fff;
background-color: #f00;
*background-color: #e60000;
}
.btn-danger:active,
.btn-danger.active {
background-color: #c00 \9;
}
.btn-success {
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
background-color: #0f0;
*background-color: #0f0;
background-image: -moz-linear-gradient(top, #0f0, #0f0);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0f0), to(#0f0));
background-image: -webkit-linear-gradient(top, #0f0, #0f0);
background-image: -o-linear-gradient(top, #0f0, #0f0);
background-image: linear-gradient(to bottom, #0f0, #0f0);
background-repeat: repeat-x;
border-color: #0f0 #0f0 #00b300;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ff00',endColorstr='#ff00ff00',GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
}
.btn-success:hover,
.btn-success:focus,
.btn-success:active,
.btn-success.active,
.btn-success.disabled,
.btn-success[disabled] {
color: #fff;
background-color: #0f0;
*background-color: #00e600;
}
.btn-success:active,
.btn-success.active {
background-color: #0c0 \9;
}
.btn-info {
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
background-color: #0ff;
*background-color: #0ff;
background-image: -moz-linear-gradient(top, #0ff, #0ff);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0ff), to(#0ff));
background-image: -webkit-linear-gradient(top, #0ff, #0ff);
background-image: -o-linear-gradient(top, #0ff, #0ff);
background-image: linear-gradient(to bottom, #0ff, #0ff);
background-repeat: repeat-x;
border-color: #0ff #0ff #00b2b3;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff00ffff',endColorstr='#ff00ffff',GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
}
.btn-info:hover,
.btn-info:focus,
.btn-info:active,
.btn-info.active,
.btn-info.disabled,
.btn-info[disabled] {
color: #fff;
background-color: #0ff;
*background-color: #00e5e6;
}
.btn-info:active,
.btn-info.active {
background-color: #0cc \9;
}
.btn-inverse {
color: #fff;
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
background-color: #000;
*background-color: #000;
background-image: -moz-linear-gradient(top, #000, #000);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#000), to(#000));
background-image: -webkit-linear-gradient(top, #000, #000);
background-image: -o-linear-gradient(top, #000, #000);
background-image: linear-gradient(to bottom, #000, #000);
background-repeat: repeat-x;
border-color: #000 #000 #000;
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff000000',endColorstr='#ff000000',GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
}
.btn-inverse:hover,
.btn-inverse:focus,
.btn-inverse:active,
.btn-inverse.active,
.btn-inverse.disabled,
.btn-inverse[disabled] {
color: #fff;
background-color: #000;
*background-color: #000;
}
.btn-inverse:active,
.btn-inverse.active {
background-color: #000 \9;
}
.btn {
border: 6px ridge #bbb;
}
.btn-primary {
background: #000 url('./img/rainbow.gif') top left;
}
blink {
-webkit-animation: blink 1s linear infinite;
-moz-animation: blink 1s linear infinite;
-ms-animation: blink 1s linear infinite;
-o-animation: blink 1s linear infinite;
animation: blink 1s linear infinite;
}
@keyframes blink {
0% {
opacity: 0;
}
40% {
opacity: 0;
}
41% {
opacity: 1;
}
99% {
opacity: 1;
}
100% {
opacity: 0;
}
}

查看文件

@ -1,3 +1,7 @@
/**
* @author @leranjun
*/
/* 土味广告 */
.ipe-af-2021 {
background: rgba(0, 0, 0, 0.8);

查看文件

@ -5,6 +5,14 @@ date: 2023-04-01 00:00:00
tags:
---
## My Little IPE
**author**: [@dragon-fish](https://github.com/dragon-fish)
Collaborate with ChatGPT-3.5
## 安装方法
```js
mw.loader.load('https://ipe-plugins.js.org/plugins/april-fool-2023/main.js')
mw.loader.load(
@ -13,8 +21,10 @@ mw.loader.load(
)
```
- <a href="#?action=edit">EDIT</a>
- <a href="#?action=delete">DELETE</a>
## 测试用例
- <a href="#action=edit">EDIT</a>
- <a href="#action=delete">DELETE</a>
<link rel="stylesheet" href="style.css" />
<script src="https://unpkg.com/jquery@3.2.1/dist/jquery.min.js"></script>

查看文件

@ -1,6 +1,11 @@
;(() => {
'strict mode'
/**
* My Little IPE 小小IPE酱
* @author dragon-fish <xiaoyujundesu@outlook.com>
* @license MIT
*/
'strict mode'
;(() => {
if (window.__IPE_20230401__) return
window.__IPE_20230401__ = true
@ -25,14 +30,19 @@
return this // 支持链式调用
}
function sleep(duration = 0) {
return new Promise((n) => setTimeout(n, duration))
}
// Utils
/** @type {(duration: number) => Promise<unknown>} */
const sleep = (duration = 0) => new Promise((n) => setTimeout(n, duration))
/** @type {<T>(arr: T[]) => T} */
const pick = (arr = []) => arr[Math.floor(Math.random() * arr.length)]
/** @type {(min: number, max: number) => number} */
const randomNum = (min = 0, max = 0) =>
Math.floor(Math.random() * (max - min + 1) + min)
class GirlRole {
dialogCountdown = 0
class LittlePet {
/** @type {(string)[]} */
randomTopics = []
dialogList = []
dialogEndTime = 0
/**
* @param {{name:string}} configs
@ -41,53 +51,57 @@
const self = this
this.configs = configs
this.pet = this.createRole(configs)
this.pet.appendTo('body')
this.role = this.createRole()
this.role.appendTo('body')
this.bindDynamicEffects(this.pet)
this.bindDynamicEffects(this.role)
const dialog = this.role.find('pet-dialog')
dialog.doubleClick(() => {
this.dialogEndTime = Date.now()
})
// Clean up dialog
setInterval(() => {
if (this.dialogCountdown > 0) {
this.dialogCountdown -= 100
}
const dialog = this.pet.find('pet-dialog')
if (this.dialogCountdown <= 0 && dialog.data('show', true)) {
const now = Date.now()
if (now > this.dialogEndTime) {
dialog.fadeOut(240)
dialog.data('show', false)
}
}, 100)
}, 50)
// Random topics
;(async function randomTalk() {
const dialog = self.pet.find('pet-dialog')
if (dialog.data('show') !== true) {
console.info('randomTalk')
self.say({
content: self.pick(self.randomTopics),
content: pick(self.dialogList),
})
}
await sleep(self.randomNum(12 * 1000, 24 * 1000))
await sleep(randomNum(12 * 1000, 24 * 1000))
randomTalk()
})()
// Clicked topics
this.pet.find('pet-body').on('click', function () {
self.say({
content: self.pick(self.randomTopics),
this.role.find('pet-body').on('click', () => {
this.say({
content: pick(this.dialogList),
})
})
// Close
this.pet.find('pet-body').doubleClick(function () {
self.pet.fadeOut(120)
this.role.find('pet-body').doubleClick(() => {
this.say({ content: '我不打扰,我先走了哈~', duration: 1500 })
.then(() => {
this.role.fadeOut(120)
return sleep(120)
})
.then(() => this.role.remove())
})
}
/** @returns {JQuery<HTMLElement>} */
createRole(configs = {}) {
if (this.pet) return this.pet
const self = this
createRole() {
if (this.role) return this.role
const pet = $('<pet>')
@ -159,83 +173,73 @@
return this
}
say({ content = '', duration = 5000, raw = false }) {
async say({ content = '', duration = 5000, raw = false }) {
if (!content) return this
const self = this
const now = Date.now()
const dialog = this.role.find('pet-dialog')
const endTimeOriginal = this.dialogEndTime
this.dialogEndTime = now + duration
const dialog = this.pet.find('pet-dialog')
if (dialog.data('show') === true) {
if (now <= endTimeOriginal + 240) {
dialog.fadeOut(120)
await sleep(120)
}
const name = $('<div>')
.css({ fontWeight: '700' })
.text(this.configs.name + ': ')
dialog.empty()
raw
? dialog.append(name, content)
: dialog.append(name, $('<div>', { text: content }))
dialog.fadeIn(240)
this.dialogShown = true
sleep(dialog.data('show') === true ? 120 : 0).then(() => {
dialog.empty()
raw ? dialog.append(name, content) : dialog.append(name, `${content}`)
this.dialogCountdown = duration
dialog.fadeIn(240)
dialog.data('show', true)
})
return this
await sleep(duration)
return self
}
addDialog({ type = 'random', target = '', event = 'click', content = '' }) {
if (!content) return this
const self = this
if (type === 'random') {
this.randomTopics.push(content)
this.dialogList.push(content)
return this
}
const el = $(target || this.pet.find('pet-body'))
el.on(event, function () {
self.say({ content })
const el = $(target || this.role.find('pet-body'))
el.on(event, () => {
this.say({ content })
})
return this
}
/**
* @type {<T>(arr: T[]) => T}
*/
pick(arr = []) {
return arr[Math.floor(Math.random() * arr.length)]
}
randomNum(min = 0, max = 0) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
}
const girl = new GirlRole({
name: 'IPE',
const chan = new LittlePet({
name: 'My little IPE',
chatInterval: [15 * 1000, 30 * 1000],
})
new Promise((n) => {
girl.say({
// 开场白
const start = Date.now()
chan
.say({
content:
'呦吼——我是由 InPageEdit Technology 开发的全新 AI 助理,名字叫【IPE酱】。我专门为帮助用户进行 MediaWiki 的日常维护而设计,能够让您轻松地管理和编辑您的 Wiki 网站。希望IPE酱能成为您维护 Wiki 网站的得力助手~',
'呦吼~我是由 InPageEdit Technology 开发的全新 AI 助理,你可以叫我【IPE酱】。我专门为帮助用户进行 MediaWiki 的日常维护而设计,能够让您轻松地管理和编辑您的 Wiki 网站。希望IPE酱能成为您维护 Wiki 网站的得力助手~',
duration: 5500,
})
return n()
})
.then(() => sleep(6500))
.then(() => {
if (girl.pet.find('pet-dialog').data('show') !== true) {
girl.say({
if (Date.now() >= chan.dialogEndTime) {
chan.say({
content: '(提示)如果想让我离开的话,双击我就可以了哦~',
})
}
})
girl
// 随机对话
chan
.addDialog({
type: 'random',
content: '哇哇哇,别戳我',
@ -350,6 +354,9 @@
type: 'random',
content: '你知道吗我的源代码有超过一半是由AI生成的……',
})
// 特殊触发器
chan
.addDialog({
type: 'event',
target: $('#ipe-edit-toolbox #edit-btn, a[href*="action=edit"]'),

查看文件

@ -138,10 +138,11 @@ pet-dialog {
padding: 0.8em;
padding-bottom: 2em;
border-radius: 0.5em;
width: 20em;
width: 24em;
max-width: calc(100vw - 10em);
z-index: -2;
font-size: 1.12em;
line-height: 1.6;
z-index: -2;
}
@keyframes pet-breathe {