#### What type of PR is this?
/area core
/kind cleanup
/milestone 2.20.x
#### What this PR does / why we need it:
重新生成 OpenAPI 定义和 API Client,在 https://github.com/halo-dev/halo/pull/6488 中忘了重新生成。
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/area core
/kind improvement
/milestone 2.20.x
#### What this PR does / why we need it:
移除在 Edge 浏览器中,为密码输入框添加显示密码明文按钮。
<img width="406" alt="image" src="https://github.com/user-attachments/assets/49801c25-d8dc-46db-9cba-302653af1951">
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.20.x
#### What this PR does / why we need it:
将索引构建状态添加到就绪检测的指标中
#### Which issue(s) this PR fixes:
Fixes#6632
#### Does this PR introduce a user-facing change?
```release-note
将索引构建状态添加到就绪检测的指标中以优化就绪时访问出现索引不可用的问题
```
#### What type of PR is this?
/milestone 2.20.x
/area core
#### What this PR does / why we need it:
将内容管理相关的数据更新类归档到 content 包下,如访问量和评论量统计
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.20.x
#### What this PR does / why we need it:
修复文章封面图链接包含空格时主题端会因为生成缩略图错误而无法访问的问题
这是由于 URI string 中包含空格无法创建 URI 对象,目前将忽略这种非法参数,如果生成失败则直接返回原始 URI string
#### Which issue(s) this PR fixes:
Fixes#6690
#### Does this PR introduce a user-facing change?
```release-note
修复文章封面图链接包含空格时主题端会因为生成缩略图错误而无法访问的问题
```
#### What type of PR is this?
/area ui
/kind bug
/milestone 2.20.x
#### What this PR does / why we need it:
修复在 FireFox 浏览器下的编辑器中无法通过粘贴文件上传的问题。
#### Which issue(s) this PR fixes:
Fixes#6684
#### Special notes for your reviewer:
在 FireFox 浏览器中,复制一张本地的图片,尝试在编辑器中粘贴,观察是否上传成功。
#### Does this PR introduce a user-facing change?
```release-note
修复在 FireFox 浏览器下的编辑器中无法通过粘贴文件上传的问题。
```
#### What type of PR is this?
/area ui
/kind improvement
/milestone 2.20.x
#### What this PR does / why we need it:
取消异步加载默认编辑器,在之前的版本中,由于编辑器体积较大,所以做了异步加载的处理,但近期的版本中,为了让插件可以使用编辑器或者扩展编辑器,已经将编辑器依赖作为全局加载,如果这个时候还是异步加载编辑器组件的话,进入编辑页面的时候出现短暂的灰屏闪烁。
#### Does this PR introduce a user-facing change?
```release-note
优化默认编辑器的加载方式,防止出现灰屏闪烁的问题。
```
#### What type of PR is this?
/kind improvement
/area ui
/milestone 2.20.x
#### What this PR does / why we need it:
简化页面回收站的页面标题。
#### Does this PR introduce a user-facing change?
```release-note
简化页面回收站的页面标题。
```
#### What type of PR is this?
/area ui
/kind improvement
/milestone 2.20.x
#### What this PR does / why we need it:
统一空状态界面中操作按钮的风格。
#### Does this PR introduce a user-facing change?
```release-note
统一空状态界面中操作按钮的风格。
```
#### What type of PR is this?
/kind feature
/area core
/milestone 2.20.x
#### What this PR does / why we need it:
This PR registers a ServerWebExchangeContextFilter to make ServerWebExchange available under ContextView. The usage example is as follows:
```java
Mono.deferContextual(contextView -> {
var exchange = ServerWebExchangeContextFilter.getExchange(contextView);
assertTrue(exchange.isPresent());
return mono;
})
```
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/area ui
/kind improvement
/milestone 2.20.x
#### What this PR does / why we need it:
升级 UI 项目的 Vue 版本至 3.5.x。
#### Does this PR introduce a user-facing change?
```release-note
升级 UI 项目的 Vue 版本至 3.5.x。
```
#### What type of PR is this?
/kind bug
/area core
/milestone 2.20.x
#### What this PR does / why we need it:
修复文件上传时类型校验失效的问题
此问题由 #6390 导致
#### Does this PR introduce a user-facing change?
```release-note
修复文件上传时类型校验失效的问题
```
#### What type of PR is this?
/kind cleanup
/area core
/milestone 2.20.x
#### What this PR does / why we need it:
This PR upgrades to [Spring Boot 3.4.0-M3](https://github.com/spring-projects/spring-boot/releases/tag/v3.4.0-M3).
1. Fix the compilation error of OptimalPropertyAccess because the class has been privated in [this commit](b431594021).
2. Fix exception `org.mockito.exceptions.misusing.UnnecessaryStubbingException` for some unit tests after upgrading.
3. Replace deprecated annotations `@MockBean` and `@SpyBean` with `@MockitoBean` and `@MockitoSpyBean` respectively.
#### Does this PR introduce a user-facing change?
```release-note
升级 Spring Boot 至 3.4.0-M3
```
#### What type of PR is this?
/area ui
/kind cleanup
/milestone 2.20.x
#### What this PR does / why we need it:
清理 UI 中关于获取 system configmap 的无用代码,目前观察到已经没有任何地方在使用这个数据。
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
/area theme
#### What this PR does / why we need it:
This PR removes ReactivePropertyAccessor because it use `AstUtils#getPropertyAccessorsToTry` which is already hidden in [the commit](33fbd7141d (diff-deaf3517fbd66f40a8717877a8328dee0fb2581dfb6be487f327dc73ea33b5b5)). If we upgraded to Spring Boot 3.4.0-M3, the code in ReactivePropertyAccessor would be broken.
More importantly, I believe there is one issue with the current implementation although it can resolve the reactive issue.
- The PropertyAccessor modified the process flow of SPEL
This PR provides some wrappers to wrap existing PropertyAccessor and MethodResolver to evaluate reactive return value.
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
/area plugin
/milestone 2.20.x
#### What this PR does / why we need it:
Plugins can implement their own RouterFunctions and ControllerMappings, but those might expose root ApplicationContext for plugins, which is not expected.
So this PR fixes the insecure access to root ApplicationContext.
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
/area plugin
/milestone 2.20.x
#### What this PR does / why we need it:
This PR disables access to ApplicationContext using ITemplateContext.
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.20.x
#### What this PR does / why we need it:
This PR adds chunked transfer support for rendering templates, which means that the max memory used by rendering template will be max chunk size instead of size of rendering result.
Users can define the max chunk size like below:
```yaml
spring:
thymeleaf:
reactive:
maxChunkSize: 8KB # Setting to 0 will disable the chunked response.
```
#### Special notes for your reviewer:
1. Try to start Halo instance
2. Execute the command like below and see if the response headers contain `transfer-encoding: chunked`:
```bash
http http://localhost:8090/ -p h
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Language: en-CN
Content-Type: text/html
Expires: 0
Pragma: no-cache
Referrer-Policy: strict-origin-when-cross-origin
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 0
content-encoding: gzip
set-cookie: XSRF-TOKEN=1e677724-ce82-4b63-911c-f78b22cd9169; Path=/
transfer-encoding: chunked
```
#### Does this PR introduce a user-facing change?
```release-note
优化模板渲染时所需的内存
```
#### What type of PR is this?
/milestone 2.20.x
/area core
#### What this PR does / why we need it:
替换 Version 过时方法的引用为新 API
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind feature
/milestone 2.20.x
/area theme
#### What this PR does / why we need it:
主题支持通过 `${site.version}` 得到 Halo 版本号
#### Which issue(s) this PR fixes:
Fixes#6676
#### Does this PR introduce a user-facing change?
```release-note
主题支持通过 `${site.version}` 得到 Halo 版本号
```
#### What type of PR is this?
/kind feature
/area plugin
#### What this PR does / why we need it:
This PR provides an interface ElementTagProcessor to make plugin handle element tag easily. e.g.:
```java
public class ImgTagProcessor implements ElementTagPostProcessor {
@Override
public Mono<Void> process(ITemplateContext context, IProcessableElementTag tag,
IElementTagStructureHandler structureHandler) {
var elementName = tag.getElementDefinition().getElementName();
if (!Objects.equals("img", elementName.getElementName())) {
return Mono.empty();
}
var srcAttr = tag.getAttribute("src");
if (srcAttr == null) {
return Mono.empty();
}
var newSrc = srcAttr.getValue();
// TODO rewrite src
structureHandler.setAttribute("src", newSrc);
return Mono.empty();
}
}
```
After PR merged, plugins https://github.com/webp-sh/halo-plugin-webp-cloud and https://github.com/guqing/plugin-cloudinary can be refined with new method.
#### Does this PR introduce a user-facing change?
```release-note
支持在插件中操作渲染结果
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.20.x
#### What this PR does / why we need it:
If we are running Halo instance in machine with small memory available, the JS/CSS bundle might not be accessible.
This RP refactors generation of JS and CSS bundle with fixed buffer size rather than length of original resources.
```java
2024-09-02T15:01:27.667+08:00 WARN 62039 --- [boundedElastic-3] reactor.core.Exceptions : throwIfFatal detected a jvm fatal exception, which is thrown and logged below:
java.lang.OutOfMemoryError: Java heap space
at java.base/java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:64) ~[na:na]
at java.base/java.nio.ByteBuffer.allocate(ByteBuffer.java:363) ~[na:na]
at org.springframework.core.io.buffer.DefaultDataBuffer.allocate(DefaultDataBuffer.java:234) ~[spring-core-6.1.12.jar:6.1.12]
at org.springframework.core.io.buffer.DefaultDataBuffer.setCapacity(DefaultDataBuffer.java:196) ~[spring-core-6.1.12.jar:6.1.12]
at org.springframework.core.io.buffer.DefaultDataBuffer.ensureWritable(DefaultDataBuffer.java:228) ~[spring-core-6.1.12.jar:6.1.12]
at org.springframework.core.io.buffer.DefaultDataBuffer.write(DefaultDataBuffer.java:296) ~[spring-core-6.1.12.jar:6.1.12]
at org.springframework.core.io.buffer.DefaultDataBuffer.write(DefaultDataBuffer.java:289) ~[spring-core-6.1.12.jar:6.1.12]
at org.springframework.core.io.buffer.DefaultDataBuffer.write(DefaultDataBuffer.java:43) ~[spring-core-6.1.12.jar:6.1.12]
at run.halo.app.core.extension.service.impl.PluginServiceImpl.lambda$uglifyJsBundle$17(PluginServiceImpl.java:257) ~[classes/:na]
at run.halo.app.core.extension.service.impl.PluginServiceImpl$$Lambda$4661/0x000000c80214e298.accept(Unknown Source) ~[na:na]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onNext(FluxPeekFuseable.java:196) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxUsing$UsingFuseableSubscriber.onNext(FluxUsing.java:353) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxGenerate$GenerateSubscription.next(FluxGenerate.java:178) ~[reactor-core-3.6.9.jar:3.6.9]
at org.springframework.core.io.buffer.DataBufferUtils$ReadableByteChannelGenerator.accept(DataBufferUtils.java:1002) ~[spring-core-6.1.12.jar:6.1.12]
at org.springframework.core.io.buffer.DataBufferUtils$ReadableByteChannelGenerator.accept(DataBufferUtils.java:974) ~[spring-core-6.1.12.jar:6.1.12]
at reactor.core.publisher.FluxGenerate.lambda$new$1(FluxGenerate.java:58) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxGenerate$$Lambda$4155/0x000000c802069228.apply(Unknown Source) ~[na:na]
at reactor.core.publisher.FluxGenerate$GenerateSubscription.slowPath(FluxGenerate.java:271) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxGenerate$GenerateSubscription.request(FluxGenerate.java:213) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxUsing$UsingFuseableSubscriber.request(FluxUsing.java:320) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxFlatMap$FlatMapInner.onSubscribe(FluxFlatMap.java:968) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxUsing$UsingFuseableSubscriber.onSubscribe(FluxUsing.java:347) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxGenerate.subscribe(FluxGenerate.java:85) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxUsing.subscribe(FluxUsing.java:102) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.Flux.subscribe(Flux.java:8848) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:430) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.tryOnNext(FluxHandleFuseable.java:135) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxIterable$IterableSubscriptionConditional.slowPath(FluxIterable.java:664) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxIterable$IterableSubscriptionConditional.request(FluxIterable.java:623) ~[reactor-core-3.6.9.jar:3.6.9]
at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.request(FluxHandleFuseable.java:260) ~[reactor-core-3.6.9.jar:3.6.9]
2024-09-02T15:01:27.681+08:00 DEBUG 62039 --- [boundedElastic-3] a.w.r.e.AbstractErrorWebExceptionHandler : [131a559b-102] Resolved [OutOfMemoryError: Java heap space] for HTTP GET /apis/api.console.halo.run/v1alpha1/plugins/-/bundle.js
2024-09-02T15:01:27.681+08:00 ERROR 62039 --- [boundedElastic-3] a.w.r.e.AbstractErrorWebExceptionHandler : [131a559b-102] 500 Server Error for HTTP GET "/apis/api.console.halo.run/v1alpha1/plugins/-/bundle.js?v=1725260408176"
java.lang.OutOfMemoryError: Java heap space
at java.base/java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:64) ~[na:na]
```
#### Does this PR introduce a user-facing change?
```release-note
优化在内存紧张时 Console 端无法加载插件资源的问题
```
#### What type of PR is this?
/kind cleanup
/area core
/milestone 2.20.x
#### What this PR does / why we need it:
删除 SubscriptionServiceIntegrationTest 类。因为当前测试类不经常性出错,暂时无法排查原因。
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.20.x
#### What this PR does / why we need it:
修复 external-url 配置带了尾部斜杠导致邮件通知的查看通知链接无法访问的问题
#### Which issue(s) this PR fixes:
Fixes#6655
#### Does this PR introduce a user-facing change?
```release-note
修复 external-url 配置带了尾部斜杠导致邮件通知的查看通知链接无法访问的问题
```
#### What type of PR is this?
/kind feature
/area theme
/sig docs
/milestone 2.20.x
#### What this PR does / why we need it:
After this PR, we can define i18n message files next to the template file.
```yaml
i18n:
default.properties
templates:
index.html
index.properties # Higher properties than default.properties
index_zh.properties # Higher properties than index.properties
index_zh_CN.properties # Higher priority than index_zh.properties
```
It's convenient for plugins that define the template files.
See https://www.thymeleaf.org/doc/tutorials/3.1/usingthymeleaf.html#standard-message-resolver for more.
#### Does this PR introduce a user-facing change?
```release-note
支持在主题中通过 Thymeleaf 默认行为实现国际化
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.20.x
#### What this PR does / why we need it:
This PR adds support changing locale using query `language`. After passing the query, we will automatically respond a cookie `language` back to browser.
Please see the result below:
```bash
http http://localhost:8090/\?language\=zh-CN Accept:text/html -p h
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Language: zh-CN
Content-Type: text/html
Expires: 0
Pragma: no-cache
Referrer-Policy: strict-origin-when-cross-origin
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 0
content-encoding: gzip
content-length: 4765
set-cookie: language=zh-CN; Path=/; Secure
set-cookie: XSRF-TOKEN=f0f2c972-0024-4575-aef2-0609356b4757; Path=/
```
#### Does this PR introduce a user-facing change?
```release-note
支持利用参数 language 切换地域语言
```
#### What type of PR is this?
/area ui
/kind bug
/milestone 2.20.x
#### What this PR does / why we need it:
修复编辑器中有序列表的样式问题。
#### Which issue(s) this PR fixes:
Fixes#6615
#### Does this PR introduce a user-facing change?
```release-note
修复编辑器中有序列表的样式问题。
```
#### What type of PR is this?
/kind improvement
/area theme
/milestone 2.20.x
#### What this PR does / why we need it:
This PR simplifies ThemeLocaleContextResolver by removing unused attributes.
In another PR <https://github.com/halo-dev/halo/pull/6647>, fixed locale resolution for query parameter `language`. This PR fixes locale resolution for cookie `language` as well.
Please see the results below:
```bash
http https://www.halo.run/ Cookie:language=zh-CN -p h
HTTP/1.1 200 OK
Content-Language: und
```
```bash
http http://localhost:8090 Cookie:language=zh-CN -p h
HTTP/1.1 200 OK
Content-Language: zh-CN
```
#### Does this PR introduce a user-facing change?
```release-note
None
```
#### What type of PR is this?
/kind improvement
/area ui
/milestone 2.20.x
#### What this PR does / why we need it:
优化了 Formkit 中的 selec 组件,使得其使用快捷键与鼠标选中的预选状态始终只有一个。且在多选状态下按回车时,不再预选跳转至第一个选项。
#### How to test it?
在多选状态下测试使用键盘进行预选及使用鼠标 hover 进行预选的状态是否符合预期。
#### Which issue(s) this PR fixes:
Fixes#6600
#### Does this PR introduce a user-facing change?
```release-note
优化 Formkit select 组件在多选状态下的待选中状态。
```
#### What type of PR is this?
/kind improvement
/area core
/milestone 2.20.x
#### What this PR does / why we need it:
不允许回复未通过审核的评论
#### Does this PR introduce a user-facing change?
```release-note
禁止非管理员回复未通过审核的评论
```