From 691cd38c514e44c0fa35f5039de9043fe81a418e Mon Sep 17 00:00:00 2001 From: Takagi <1103069291@qq.com> Date: Thu, 2 Nov 2023 10:54:50 +0800 Subject: [PATCH 01/14] fix: optimize editor performance and resolve freezing issues (#4805) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind bug #### What this PR does / why we need it: 优化了编辑器的性能,并解决了卡死现象。具体措施如下: 1. 编辑器异步加载时,由于其 component 并不会使用响应式,所以也无需进行代理,因此使用 `markRaw` 将其转为普通对象,可以优化 vue 性能。 2. 由于 `DefaultEditor` 有多个根节点导致透传的 attrs 无法设置,因此新增一个 div 节点将其原有节点包裹。参见 https://cn.vuejs.org/guide/components/attrs.html#attribute-inheritance-on-multiple-root-nodes 。 3. 原有编辑器实例在切换路由之后不会释放,此次修改之后,将在 vue 的 `onBeforeUnmount` 时间中手动释放编辑器实例。 #### How to test it? 1. 新建文章,新建一个表格。 2. 不要保存,点击文章路由跳出编辑器界面,再次点击上一次所编辑器的文章,查看是否会卡死。 #### Which issue(s) this PR fixes: Fixes #4798 #### Does this PR introduce a user-facing change? ```release-note 优化编辑器性能并解决切换页面所造成的卡死现象 ``` --- .../src/components/editor/DefaultEditor.vue | 369 +++++++++--------- .../use-editor-extension-points.ts | 14 +- 2 files changed, 196 insertions(+), 187 deletions(-) diff --git a/console/src/components/editor/DefaultEditor.vue b/console/src/components/editor/DefaultEditor.vue index 63235794c..23aff4ab0 100644 --- a/console/src/components/editor/DefaultEditor.vue +++ b/console/src/components/editor/DefaultEditor.vue @@ -86,6 +86,7 @@ import { OverlayScrollbarsComponent } from "overlayscrollbars-vue"; import { usePluginModuleStore } from "@/stores/plugin"; import type { PluginModule } from "@halo-dev/console-shared"; import { useDebounceFn } from "@vueuse/core"; +import { onBeforeUnmount } from "vue"; const { t } = useI18n(); @@ -355,6 +356,10 @@ onMounted(() => { }); }); +onBeforeUnmount(() => { + editor.value?.destroy(); +}); + // image drag and paste upload const { policies } = useFetchAttachmentPolicy(); @@ -491,203 +496,205 @@ const currentLocale = i18n.global.locale.value as diff --git a/console/src/composables/use-editor-extension-points.ts b/console/src/composables/use-editor-extension-points.ts index 0dbbff05d..a1f3ab75a 100644 --- a/console/src/composables/use-editor-extension-points.ts +++ b/console/src/composables/use-editor-extension-points.ts @@ -1,6 +1,6 @@ import { usePluginModuleStore } from "@/stores/plugin"; import type { EditorProvider, PluginModule } from "@halo-dev/console-shared"; -import { onMounted, ref, type Ref, defineAsyncComponent } from "vue"; +import { onMounted, ref, type Ref, defineAsyncComponent, markRaw } from "vue"; import { VLoading } from "@halo-dev/components"; import Logo from "@/assets/logo.png"; import { useI18n } from "vue-i18n"; @@ -18,11 +18,13 @@ export function useEditorExtensionPoints(): useEditorExtensionPointsReturn { { name: "default", displayName: t("core.plugin.extension_points.editor.providers.default"), - component: defineAsyncComponent({ - loader: () => import("@/components/editor/DefaultEditor.vue"), - loadingComponent: VLoading, - delay: 200, - }), + component: markRaw( + defineAsyncComponent({ + loader: () => import("@/components/editor/DefaultEditor.vue"), + loadingComponent: VLoading, + delay: 200, + }) + ), rawType: "HTML", logo: Logo, }, From 2d743123bf6698b5713f76de0019d388b69f1edb Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Thu, 2 Nov 2023 11:47:58 +0800 Subject: [PATCH 02/14] chore: update the waiting time for publishing post (#4810) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement /area core /milestone 2.11.x #### What this PR does / why we need it: 修改发布文章的等待时间以防止因数据库执行延迟较高导致的错误提示 最大等待时间为:`100ms * 2 ^ (retryNum - 1)` = `1600ms` 总共需等待时间为:`100ms * (2 ^ retryNum - 1)` = `3100ms` #### Does this PR introduce a user-facing change? ```release-note 修改发布文章的等待时间以防止因数据库执行延迟较高导致的错误提示 ``` --- .../java/run/halo/app/core/extension/endpoint/PostEndpoint.java | 2 +- .../run/halo/app/core/extension/endpoint/PostEndpointTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/application/src/main/java/run/halo/app/core/extension/endpoint/PostEndpoint.java b/application/src/main/java/run/halo/app/core/extension/endpoint/PostEndpoint.java index c15247bd6..308efecd5 100644 --- a/application/src/main/java/run/halo/app/core/extension/endpoint/PostEndpoint.java +++ b/application/src/main/java/run/halo/app/core/extension/endpoint/PostEndpoint.java @@ -243,7 +243,7 @@ public class PostEndpoint implements CustomEndpoint { }) .switchIfEmpty(Mono.error( () -> new RetryException("Retry to check post publish status")))) - .retryWhen(Retry.fixedDelay(10, Duration.ofMillis(200)) + .retryWhen(Retry.backoff(5, Duration.ofMillis(100)) .filter(t -> t instanceof RetryException)); } diff --git a/application/src/test/java/run/halo/app/core/extension/endpoint/PostEndpointTest.java b/application/src/test/java/run/halo/app/core/extension/endpoint/PostEndpointTest.java index c39792a7c..bd6bcde24 100644 --- a/application/src/test/java/run/halo/app/core/extension/endpoint/PostEndpointTest.java +++ b/application/src/test/java/run/halo/app/core/extension/endpoint/PostEndpointTest.java @@ -170,7 +170,7 @@ class PostEndpointTest { .is5xxServerError(); // Verify WebClient retry behavior - verify(client, times(12)).get(eq(Post.class), eq("post-1")); + verify(client, times(7)).get(eq(Post.class), eq("post-1")); verify(client).update(any(Post.class)); } From a8a5413460786f68d9a008f8ce83ef056f3e42b8 Mon Sep 17 00:00:00 2001 From: Ryan Wang Date: Thu, 2 Nov 2023 15:44:48 +0800 Subject: [PATCH 03/14] refactor: add t parameter for plugin bundle resources (#4804) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /area console /kind improvement /milestone 2.11.x #### What this PR does / why we need it: 为插件的 bundle.css 和 bundle.js 重定向请求添加时间戳参数,防止被浏览器、Nginx、CDN 服务缓存,导致插件的资源不能及时更新。 #### Which issue(s) this PR fixes: Fixes #4803 #### Special notes for your reviewer: 测试方式: 1. 在 Firefox 浏览器测试启动和停止若干插件,观察插件提供的 UI 样式是否正常即可。 #### Does this PR introduce a user-facing change? ```release-note 优化 Console 端插件捆绑资源的请求,防止在操作插件状态之后无法及时更新资源。 ``` --- console/src/setup/setupModules.ts | 4 ++-- console/src/utils/load-style.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/console/src/setup/setupModules.ts b/console/src/setup/setupModules.ts index b38737815..d9d8d3a40 100644 --- a/console/src/setup/setupModules.ts +++ b/console/src/setup/setupModules.ts @@ -21,7 +21,7 @@ export async function setupPluginModules(app: App) { const { load } = useScriptTag( `${ import.meta.env.VITE_API_URL - }/apis/api.console.halo.run/v1alpha1/plugins/-/bundle.js` + }/apis/api.console.halo.run/v1alpha1/plugins/-/bundle.js?t=${Date.now()}` ); await load(); @@ -45,7 +45,7 @@ export async function setupPluginModules(app: App) { await loadStyle( `${ import.meta.env.VITE_API_URL - }/apis/api.console.halo.run/v1alpha1/plugins/-/bundle.css` + }/apis/api.console.halo.run/v1alpha1/plugins/-/bundle.css?t=${Date.now()}` ); } catch (e) { const message = i18n.global.t("core.plugin.loader.toast.style_load_failed"); diff --git a/console/src/utils/load-style.ts b/console/src/utils/load-style.ts index 23ee309bf..07e42479c 100644 --- a/console/src/utils/load-style.ts +++ b/console/src/utils/load-style.ts @@ -2,7 +2,7 @@ export function loadStyle(href: string) { return new Promise(function (resolve, reject) { let shouldAppend = false; let el: HTMLLinkElement | null = document.querySelector( - 'script[src="' + href + '"]' + 'link[href="' + href + '"]' ); if (!el) { el = document.createElement("link"); From 57b24261e70c022bc0e60d162eef9f542c89cd87 Mon Sep 17 00:00:00 2001 From: Takagi <1103069291@qq.com> Date: Thu, 2 Nov 2023 15:50:48 +0800 Subject: [PATCH 04/14] fix: resolve the issue of receiving duplicate key error after deleting metadata (#4815) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind bug /area console /milestone 2.11.x #### What this PR does / why we need it: 重构去重元数据的逻辑,解决删除元数据后仍旧提示 key 不能重复的问题。 #### How to test it? 1. 在文章列表点击设置按钮 2. 添加两个个空的元数据,不保存直接关闭设置框。 3. 再次打开设置框,点击删除空的元数据,查看是否会提示 key 重复。 #### Does this PR introduce a user-facing change? ```release-note 解决删除元数据后仍旧提示 key 不能重复的问题 ``` --- console/src/components/form/AnnotationsForm.vue | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/console/src/components/form/AnnotationsForm.vue b/console/src/components/form/AnnotationsForm.vue index 11cb24005..676686b8a 100644 --- a/console/src/components/form/AnnotationsForm.vue +++ b/console/src/components/form/AnnotationsForm.vue @@ -17,10 +17,12 @@ import { randomUUID } from "@/utils/id"; const themeStore = useThemeStore(); function keyValidationRule(node: FormKitNode) { - return ( - !annotations.value?.[node.value as string] && - !customAnnotationsDuplicateKey.value - ); + const validAnnotations = [ + ...Object.keys(annotations.value), + ...customAnnotationsState.value.map((item) => item.key), + ]; + const count = validAnnotations.filter((item) => item === node.value); + return count.length < 2; } const props = withDefaults( @@ -73,12 +75,6 @@ const annotations = ref<{ }>({}); const customAnnotationsState = ref<{ key: string; value: string }[]>([]); -const customAnnotationsDuplicateKey = computed(() => { - const keys = customAnnotationsState.value.map((item) => item.key); - const uniqueKeys = new Set(keys); - return keys.length !== uniqueKeys.size; -}); - const customAnnotations = computed(() => { return customAnnotationsState.value.reduce((acc, cur) => { acc[cur.key] = cur.value; From b8755ff3b40ed5b398bf3fada8cc2261d4a5f651 Mon Sep 17 00:00:00 2001 From: guqing <38999863+guqing@users.noreply.github.com> Date: Thu, 2 Nov 2023 17:16:05 +0800 Subject: [PATCH 05/14] chore: update the waiting time for publishing post (#4814) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind improvement /area core /milestone 2.11.x #### What this PR does / why we need it: 修改发布文章的等待时间以防止因数据库执行延迟较高导致的错误提示 最大等待时间为:`100ms * 2 ^ (retryNum - 1)` = `25600ms` 总共需等待时间为:`100ms * (2 ^ retryNum - 1)` = `31900ms` = `31.9 s` #### Does this PR introduce a user-facing change? ```release-note None ``` --- .../app/core/extension/endpoint/PostEndpoint.java | 14 +++++++++++--- .../core/extension/endpoint/PostEndpointTest.java | 3 ++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/application/src/main/java/run/halo/app/core/extension/endpoint/PostEndpoint.java b/application/src/main/java/run/halo/app/core/extension/endpoint/PostEndpoint.java index 308efecd5..b888db542 100644 --- a/application/src/main/java/run/halo/app/core/extension/endpoint/PostEndpoint.java +++ b/application/src/main/java/run/halo/app/core/extension/endpoint/PostEndpoint.java @@ -8,7 +8,7 @@ import static org.springdoc.core.fn.builders.requestbody.Builder.requestBodyBuil import io.swagger.v3.oas.annotations.enums.ParameterIn; import java.time.Duration; import java.util.Objects; -import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springdoc.core.fn.builders.schema.Builder; import org.springdoc.webflux.core.fn.SpringdocRouteBuilder; @@ -42,9 +42,10 @@ import run.halo.app.extension.router.QueryParamBuildUtil; */ @Slf4j @Component -@AllArgsConstructor +@RequiredArgsConstructor public class PostEndpoint implements CustomEndpoint { + private int maxAttemptsWaitForPublish = 10; private final PostService postService; private final ReactiveExtensionClient client; @@ -243,7 +244,7 @@ public class PostEndpoint implements CustomEndpoint { }) .switchIfEmpty(Mono.error( () -> new RetryException("Retry to check post publish status")))) - .retryWhen(Retry.backoff(5, Duration.ofMillis(100)) + .retryWhen(Retry.backoff(maxAttemptsWaitForPublish, Duration.ofMillis(100)) .filter(t -> t instanceof RetryException)); } @@ -278,4 +279,11 @@ public class PostEndpoint implements CustomEndpoint { return postService.listPost(postQuery) .flatMap(listedPosts -> ServerResponse.ok().bodyValue(listedPosts)); } + + /** + * Convenient for testing, to avoid waiting too long for post published when testing. + */ + public void setMaxAttemptsWaitForPublish(int maxAttempts) { + this.maxAttemptsWaitForPublish = maxAttempts; + } } diff --git a/application/src/test/java/run/halo/app/core/extension/endpoint/PostEndpointTest.java b/application/src/test/java/run/halo/app/core/extension/endpoint/PostEndpointTest.java index bd6bcde24..8846b2f76 100644 --- a/application/src/test/java/run/halo/app/core/extension/endpoint/PostEndpointTest.java +++ b/application/src/test/java/run/halo/app/core/extension/endpoint/PostEndpointTest.java @@ -50,6 +50,7 @@ class PostEndpointTest { @BeforeEach void setUp() { + postEndpoint.setMaxAttemptsWaitForPublish(3); webTestClient = WebTestClient .bindToRouterFunction(postEndpoint.endpoint()) .build(); @@ -170,7 +171,7 @@ class PostEndpointTest { .is5xxServerError(); // Verify WebClient retry behavior - verify(client, times(7)).get(eq(Post.class), eq("post-1")); + verify(client, times(5)).get(eq(Post.class), eq("post-1")); verify(client).update(any(Post.class)); } From caa4d4490760fdb8bb6f78859226b0425271e027 Mon Sep 17 00:00:00 2001 From: John Niang Date: Sat, 4 Nov 2023 12:48:42 +0800 Subject: [PATCH 06/14] Upgrade to SnakeYAML 2.2 (#4819) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind cleanup #### What this PR does / why we need it: Upgrade to SnakeYAML 2.2. #### Which issue(s) this PR fixes: This PR fixes CVE-2022-1471(High-severity vulnerabilities). image See https://hub.docker.com/layers/halohub/halo/sha-2ccf811/images/sha256-e11fe7550a6b7eef42166b53373b6fe889538db54921fbd83623558286d9270c?context=explore for more. #### Does this PR introduce a user-facing change? ```release-note 升级 SnakeYAML 至 2.2 ``` --- gradle.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/gradle.properties b/gradle.properties index f9face1e9..5fb5d935d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,2 @@ version=2.11.0-SNAPSHOT +snakeyaml.version=2.2 From 4ea20142f5b03c7e6515975670f729061659160f Mon Sep 17 00:00:00 2001 From: John Niang Date: Mon, 6 Nov 2023 10:52:48 +0800 Subject: [PATCH 07/14] Add generator meta into head (#4821) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind feature /area core /milestone 2.11.x #### What this PR does / why we need it: Please see https://html.spec.whatwg.org/multipage/semantics.html#meta-generator for more. This PR add the generator meta into head, so that we can know what sites are using Halo. ```bash http localhost:8090/ | grep generator ``` If someone want to disable the generator meta, they can configure the property `halo.theme.generator-meta-disabled` to `true`. #### Does this PR introduce a user-facing change? ```release-note 添加 Generator 元数据标识 ``` --- .../app/infra/properties/ThemeProperties.java | 5 + .../halo/app/theme/ThemeConfiguration.java | 13 +++ .../theme/dialect/GeneratorMetaProcessor.java | 43 +++++++ .../dialect/GeneratorMetaProcessorTest.java | 59 ++++++++++ .../ThemeMessageResolverIntegrationTest.java | 107 ++++-------------- .../themes/default/templates/index.html | 2 +- .../themes/other/templates/index.html | 2 +- 7 files changed, 143 insertions(+), 88 deletions(-) create mode 100644 application/src/main/java/run/halo/app/theme/dialect/GeneratorMetaProcessor.java create mode 100644 application/src/test/java/run/halo/app/theme/dialect/GeneratorMetaProcessorTest.java diff --git a/application/src/main/java/run/halo/app/infra/properties/ThemeProperties.java b/application/src/main/java/run/halo/app/infra/properties/ThemeProperties.java index b4decf3f3..7f5f11c91 100644 --- a/application/src/main/java/run/halo/app/infra/properties/ThemeProperties.java +++ b/application/src/main/java/run/halo/app/infra/properties/ThemeProperties.java @@ -9,6 +9,11 @@ public class ThemeProperties { @Valid private final Initializer initializer = new Initializer(); + /** + * Indicates whether the generator meta needs to be disabled. + */ + private boolean generatorMetaDisabled; + @Data public static class Initializer { diff --git a/application/src/main/java/run/halo/app/theme/ThemeConfiguration.java b/application/src/main/java/run/halo/app/theme/ThemeConfiguration.java index 1a921761b..08e81cbeb 100644 --- a/application/src/main/java/run/halo/app/theme/ThemeConfiguration.java +++ b/application/src/main/java/run/halo/app/theme/ThemeConfiguration.java @@ -8,7 +8,10 @@ import java.io.IOException; import java.nio.file.Path; import java.time.Instant; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.web.WebProperties; +import org.springframework.boot.info.BuildProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.FileSystemResource; @@ -21,8 +24,10 @@ import org.thymeleaf.extras.springsecurity6.dialect.SpringSecurityDialect; import reactor.core.publisher.Mono; import run.halo.app.infra.ThemeRootGetter; import run.halo.app.infra.utils.FileUtils; +import run.halo.app.theme.dialect.GeneratorMetaProcessor; import run.halo.app.theme.dialect.HaloSpringSecurityDialect; import run.halo.app.theme.dialect.LinkExpressionObjectDialect; +import run.halo.app.theme.dialect.TemplateHeadProcessor; /** * @author guqing @@ -86,4 +91,12 @@ public class ThemeConfiguration { ServerSecurityContextRepository securityContextRepository) { return new HaloSpringSecurityDialect(securityContextRepository); } + + @Bean + @ConditionalOnProperty(name = "halo.theme.generator-meta-disabled", + havingValue = "false", + matchIfMissing = true) + TemplateHeadProcessor generatorMetaProcessor(ObjectProvider buildProperties) { + return new GeneratorMetaProcessor(buildProperties); + } } diff --git a/application/src/main/java/run/halo/app/theme/dialect/GeneratorMetaProcessor.java b/application/src/main/java/run/halo/app/theme/dialect/GeneratorMetaProcessor.java new file mode 100644 index 000000000..ca2ee56cd --- /dev/null +++ b/application/src/main/java/run/halo/app/theme/dialect/GeneratorMetaProcessor.java @@ -0,0 +1,43 @@ +package run.halo.app.theme.dialect; + +import static org.thymeleaf.model.AttributeValueQuotes.DOUBLE; + +import java.util.Map; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.info.BuildProperties; +import org.springframework.core.annotation.Order; +import org.thymeleaf.context.ITemplateContext; +import org.thymeleaf.model.IModel; +import org.thymeleaf.processor.element.IElementModelStructureHandler; +import reactor.core.publisher.Mono; + +/** + * Processor for generating generator meta. + * Set the order to 0 for removing the meta in later TemplateHeadProcessor. + * + * @author johnniang + */ +@Order(0) +public class GeneratorMetaProcessor implements TemplateHeadProcessor { + + private final String generatorValue; + + public GeneratorMetaProcessor(ObjectProvider buildProperties) { + this.generatorValue = "Halo " + buildProperties.stream().findFirst() + .map(BuildProperties::getVersion) + .orElse("Unknown"); + } + + @Override + public Mono process(ITemplateContext context, IModel model, + IElementModelStructureHandler structureHandler) { + return Mono.fromRunnable(() -> { + var modelFactory = context.getModelFactory(); + var generatorMeta = modelFactory.createStandaloneElementTag("meta", + Map.of("name", "generator", "content", generatorValue), + DOUBLE, false, true); + model.add(generatorMeta); + }); + } + +} diff --git a/application/src/test/java/run/halo/app/theme/dialect/GeneratorMetaProcessorTest.java b/application/src/test/java/run/halo/app/theme/dialect/GeneratorMetaProcessorTest.java new file mode 100644 index 000000000..a732d7aec --- /dev/null +++ b/application/src/test/java/run/halo/app/theme/dialect/GeneratorMetaProcessorTest.java @@ -0,0 +1,59 @@ +package run.halo.app.theme.dialect; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +import java.io.FileNotFoundException; +import java.net.URISyntaxException; +import java.nio.file.Path; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.util.ResourceUtils; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; +import run.halo.app.infra.InitializationStateGetter; +import run.halo.app.theme.ThemeContext; +import run.halo.app.theme.ThemeResolver; + +@SpringBootTest +@AutoConfigureWebTestClient +class GeneratorMetaProcessorTest { + + @Autowired + WebTestClient webClient; + + @MockBean + InitializationStateGetter initializationStateGetter; + + @MockBean + ThemeResolver themeResolver; + + @BeforeEach + void setUp() throws FileNotFoundException, URISyntaxException { + when(initializationStateGetter.userInitialized()).thenReturn(Mono.just(true)); + var themeContext = ThemeContext.builder() + .name("default") + .path(Path.of(ResourceUtils.getURL("classpath:themes/default").toURI())) + .active(true) + .build(); + when(themeResolver.getTheme(any(ServerWebExchange.class))) + .thenReturn(Mono.just(themeContext)); + } + + @Test + void requestIndexPage() { + webClient.get().uri("/") + .exchange() + .expectStatus().isOk() + .expectBody() + .consumeWith(System.out::println) + .xpath("/html/head/meta[@name=\"generator\"][starts-with(@content, \"Halo \")]") + .exists(); + } + +} diff --git a/application/src/test/java/run/halo/app/theme/message/ThemeMessageResolverIntegrationTest.java b/application/src/test/java/run/halo/app/theme/message/ThemeMessageResolverIntegrationTest.java index dc63f6b44..6948c4e96 100644 --- a/application/src/test/java/run/halo/app/theme/message/ThemeMessageResolverIntegrationTest.java +++ b/application/src/test/java/run/halo/app/theme/message/ThemeMessageResolverIntegrationTest.java @@ -68,21 +68,9 @@ public class ThemeMessageResolverIntegrationTest { .exchange() .expectStatus() .isOk() - .expectBody(String.class) - .isEqualTo(""" - - - - - Title - - - index -
zh
-
欢迎来到首页
- - - """); + .expectBody() + .xpath("/html/body/div[1]").isEqualTo("zh") + .xpath("/html/body/div[2]").isEqualTo("欢迎来到首页"); } @Test @@ -92,21 +80,9 @@ public class ThemeMessageResolverIntegrationTest { .exchange() .expectStatus() .isOk() - .expectBody(String.class) - .isEqualTo(""" - - - - - Title - - - index -
en
-
Welcome to the index
- - - """); + .expectBody() + .xpath("/html/body/div[1]").isEqualTo("en") + .xpath("/html/body/div[2]").isEqualTo("Welcome to the index"); } @Test @@ -116,21 +92,9 @@ public class ThemeMessageResolverIntegrationTest { .exchange() .expectStatus() .isOk() - .expectBody(String.class) - .isEqualTo(""" - - - - - Title - - - index -
foo
-
欢迎来到首页
- - - """); + .expectBody() + .xpath("/html/body/div[1]").isEqualTo("foo") + .xpath("/html/body/div[2]").isEqualTo("欢迎来到首页"); } @Test @@ -140,21 +104,11 @@ public class ThemeMessageResolverIntegrationTest { .exchange() .expectStatus() .isOk() - .expectBody(String.class) - .isEqualTo(""" - - - - - Title - - - index -
zh
-
欢迎来到首页
- - - """); + .expectBody() + .xpath("/html/head/title").isEqualTo("Title") + .xpath("/html/body/div[1]").isEqualTo("zh") + .xpath("/html/body/div[2]").isEqualTo("欢迎来到首页") + ; // For other theme when(themeResolver.getTheme(any(ServerWebExchange.class))) @@ -162,35 +116,16 @@ public class ThemeMessageResolverIntegrationTest { webTestClient.get() .uri("/index?language=zh") .exchange() - .expectBody(String.class) - .isEqualTo(""" - - - - - Other theme title - - -

Other 首页

- - - """); + .expectBody() + .xpath("/html/head/title").isEqualTo("Other theme title") + .xpath("/html/body/p").isEqualTo("Other 首页"); + webTestClient.get() .uri("/index?language=en") .exchange() - .expectBody(String.class) - .isEqualTo(""" - - - - - Other theme title - - -

other index

- - - """); + .expectBody() + .xpath("/html/head/title").isEqualTo("Other theme title") + .xpath("/html/body/p").isEqualTo("other index"); } ThemeContext createDefaultContext() throws URISyntaxException { diff --git a/application/src/test/resources/themes/default/templates/index.html b/application/src/test/resources/themes/default/templates/index.html index 441ad470c..7d38411c4 100644 --- a/application/src/test/resources/themes/default/templates/index.html +++ b/application/src/test/resources/themes/default/templates/index.html @@ -1,7 +1,7 @@ - + Title diff --git a/application/src/test/resources/themes/other/templates/index.html b/application/src/test/resources/themes/other/templates/index.html index ca476f69c..2ecf09eaf 100644 --- a/application/src/test/resources/themes/other/templates/index.html +++ b/application/src/test/resources/themes/other/templates/index.html @@ -1,7 +1,7 @@ - + Other theme title From ee52adf24c95f4e1d7580c84ff2cd8c139f7db71 Mon Sep 17 00:00:00 2001 From: John Niang Date: Sun, 12 Nov 2023 12:30:08 +0800 Subject: [PATCH 08/14] Fix the problem where some Windows developers are unable to build project (#4844) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind bug /area core #### What this PR does / why we need it: Currently, some Windows developers using GBK as character encoding are unable to build project, please see https://github.com/halo-dev/halo/issues/4771 for more. Because the source code are using UTF-8 character encoding, the `javadoc`, `compileJava`, `compileTestJava` and `delombok` tasks will use the default character encoding GBK to handle the sources, which prevents the `:api:javadoc` task from running properly. At the same time, we thank to @DaiYuANg for his first proposed solution in https://github.com/halo-dev/halo/pull/4517. #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/4771 #### Special notes for your reviewer: Validate the result by executing command `./gradlew clean build -x check` on Windows environment. #### Does this PR introduce a user-facing change? ```release-note 修复在部分 Windows 开发者无法正常构建 Halo 的问题 ``` --- api/build.gradle | 4 ++++ application/build.gradle | 2 ++ 2 files changed, 6 insertions(+) diff --git a/api/build.gradle b/api/build.gradle index 4e8a5c6cd..7063a3c60 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -7,6 +7,10 @@ plugins { group = 'run.halo.app' description = 'API of halo project, connecting by other projects.' +compileJava.options.encoding = "UTF-8" +compileTestJava.options.encoding = "UTF-8" +javadoc.options.encoding = "UTF-8" + repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } diff --git a/application/build.gradle b/application/build.gradle index 71baa8060..988b82a3c 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -11,6 +11,8 @@ plugins { group = "run.halo.app" sourceCompatibility = JavaVersion.VERSION_17 +compileJava.options.encoding = "UTF-8" +compileTestJava.options.encoding = "UTF-8" checkstyle { toolVersion = "9.3" From 9963ad359ced85f240296cedcbee6c3e8387b77e Mon Sep 17 00:00:00 2001 From: John Niang Date: Mon, 13 Nov 2023 11:06:08 +0800 Subject: [PATCH 09/14] Upgrade to Gradle 8.4 (#4848) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind cleanup /area core /milestone 2.11.x #### What this PR does / why we need it: Upgrade to Gradle 8.4 by executing command `./gradlew wrapper --gradle-version 8.4 --distribution-type all`. See https://docs.gradle.org/8.4/release-notes.html for more. #### Does this PR introduce a user-facing change? ```release-note 升级 Gradle 至 8.4 ``` --- gradle/wrapper/gradle-wrapper.jar | Bin 61574 -> 61608 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 943f0cbfa754578e88a3dae77fce6e3dea56edbf..ccebba7710deaf9f98673a68957ea02138b60d0a 100644 GIT binary patch delta 5094 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 delta 5107 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 I6Xdi10eY*&F8}}l diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bdc9a83b1..309b4e18d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 65dcd68d6..79a61d421 100755 --- a/gradlew +++ b/gradlew @@ -144,7 +144,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac From 841aa96e59d581f6b982e54a5c79c0c21a15a6d7 Mon Sep 17 00:00:00 2001 From: John Niang Date: Mon, 13 Nov 2023 11:08:09 +0800 Subject: [PATCH 10/14] Upgrade to Lombok gradle plugin 8.4 (#4849) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind cleanup /area core /milestone 2.11.x #### What this PR does / why we need it: Upgrade to Lombok gradle plugin 8.4. See https://docs.freefair.io/gradle-plugins/8.4/reference/#_installation and https://docs.freefair.io/gradle-plugins/8.4/reference/#_system_requirements for more. #### Does this PR introduce a user-facing change? ```release-note 升级 Lombok Gradle 插件至 8.4 ``` --- api/build.gradle | 2 +- application/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/build.gradle b/api/build.gradle index 7063a3c60..33f5a47ed 100644 --- a/api/build.gradle +++ b/api/build.gradle @@ -1,7 +1,7 @@ plugins { id 'java-library' id 'halo.publish' - id "io.freefair.lombok" version "8.0.0-rc2" + id "io.freefair.lombok" version "8.4" } group = 'run.halo.app' diff --git a/application/build.gradle b/application/build.gradle index 988b82a3c..206647803 100644 --- a/application/build.gradle +++ b/application/build.gradle @@ -6,7 +6,7 @@ plugins { id 'java' id 'jacoco' id "de.undercouch.download" version "5.3.1" - id "io.freefair.lombok" version "8.0.0-rc2" + id "io.freefair.lombok" version "8.4" } group = "run.halo.app" From 4a6ce88b7fdbf30993351fdf542a9aafdcf9fc57 Mon Sep 17 00:00:00 2001 From: inkslab <111865683+Thematrixofink@users.noreply.github.com> Date: Mon, 13 Nov 2023 12:06:08 +0800 Subject: [PATCH 11/14] feat: add devices mock preview for post and single page (#4846) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What type of PR is this? /kind feature /area console #### What this PR does / why we need it: 为文章以及页面预览增加终端切换功能,类似于预览主题的终端切换 #### Which issue(s) this PR fixes: Fixes #4789 #### Special notes for your reviewer: 测试方式: 本地运行halo,预览文章和页面,切换不同终端,各个界面正常显示且功能正常。 #### Does this PR introduce a user-facing change? ```release-note 文章预览支持模拟不同设备尺寸。 ``` --- .../components/preview/UrlPreviewModal.vue | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/console/src/components/preview/UrlPreviewModal.vue b/console/src/components/preview/UrlPreviewModal.vue index 08fd413eb..2ae8a9792 100644 --- a/console/src/components/preview/UrlPreviewModal.vue +++ b/console/src/components/preview/UrlPreviewModal.vue @@ -1,5 +1,13 @@