Commit 1fedc9df authored by vcjmhg's avatar vcjmhg Committed by GitHub

Merge pull request #1 from 88250/dev

Dev
parents 62e165d1 298f85dd
......@@ -8676,17 +8676,17 @@
}
},
"vcmt": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/vcmt/-/vcmt-1.1.6.tgz",
"integrity": "sha512-gWD+HZDuFrx7YFVtBBAVqGGh68HrjrV/qQaUOiXfmR1yTO6yeoyQPoAm1vnS4ux8fDDXdu8++yIOFQG9DLAQYA==",
"version": "1.1.10",
"resolved": "https://registry.npmjs.org/vcmt/-/vcmt-1.1.10.tgz",
"integrity": "sha512-zx04s0R1vYN92zjFhDZbeWi/lapxl3KyeVtV6ccnRIPxYY4yteOFGcw82qTCTvehRjDL+x7zH8BBF5eDw9fv7g==",
"requires": {
"jquery": "^3.4.1"
}
},
"vditor": {
"version": "3.1.12",
"resolved": "https://registry.npmjs.org/vditor/-/vditor-3.1.12.tgz",
"integrity": "sha512-PuGnHtC3hDM8vxGWv01+jzCLT+sC4UeeGyDtQNtUJbj8TrFmqTKKVlM8NLfeGx80nHan+xByrNF4FxntUGuAfw==",
"version": "3.1.20",
"resolved": "https://registry.npmjs.org/vditor/-/vditor-3.1.20.tgz",
"integrity": "sha512-M1z9xIcjpP2mHyKJ9+a+5GaKXx0cNPyf58yMoJOJBSljGLVO3YNkMhqHUMfoZWiz9Ohf7DZTc4LctYPeGFsl5w==",
"requires": {
"diff-match-patch": "^1.0.4"
}
......
......@@ -54,7 +54,7 @@
"jquery": "^3.4.1",
"nprogress": "^0.2.0",
"uvstat": "^1.0.7",
"vcmt": "^1.1.6",
"vditor": "^3.1.12"
"vcmt": "^1.1.10",
"vditor": "^3.1.20"
}
}
......@@ -73,7 +73,7 @@
</scm>
<properties>
<org.b3log.latke.version>3.3.3</org.b3log.latke.version>
<org.b3log.latke.version>3.3.4</org.b3log.latke.version>
<jsoup.version>1.12.1</jsoup.version>
<flexmark.version>0.50.40</flexmark.version>
......
......@@ -49,7 +49,7 @@ import java.util.concurrent.atomic.AtomicInteger;
* Server.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 3.0.1.4, Apr 2, 2020
* @version 3.0.1.5, Apr 30, 2020
* @since 1.2.0
*/
public final class Server extends BaseServer {
......@@ -246,12 +246,6 @@ public final class Server extends BaseServer {
}
}
Dispatcher.startRequestHandler = new BeforeRequestHandler();
Dispatcher.HANDLERS.add(1, new SkinHandler());
Dispatcher.HANDLERS.add(2, new InitCheckHandler());
Dispatcher.HANDLERS.add(3, new PermalinkHandler());
Dispatcher.endRequestHandler = new AfterRequestHandler();
routeProcessors();
final Latkes.RuntimeDatabase runtimeDatabase = Latkes.getRuntimeDatabase();
......@@ -410,6 +404,12 @@ public final class Server extends BaseServer {
}
public static void routeProcessors() {
Dispatcher.startRequestHandler = new BeforeRequestHandler();
Dispatcher.HANDLERS.add(1, new SkinHandler());
Dispatcher.HANDLERS.add(2, new InitCheckHandler());
Dispatcher.HANDLERS.add(3, new PermalinkHandler());
Dispatcher.endRequestHandler = new AfterRequestHandler();
routeConsoleProcessors();
routeIndexProcessors();
Dispatcher.mapping();
......@@ -634,6 +634,9 @@ public final class Server extends BaseServer {
final Dispatcher.RouterGroup staticSiteConsoleGroup = Dispatcher.group();
staticSiteConsoleGroup.middlewares(consoleAdminAuthMidware::handle);
staticSiteConsoleGroup.put("/console/staticsite", staticSiteConsole::genSite);
final FetchUploadProcessor fetchUploadProcessor = beanManager.getReference(FetchUploadProcessor.class);
Dispatcher.post("/upload/fetch", fetchUploadProcessor::fetchUpload, consoleAuthMidware::handle);
}
/**
......
......@@ -16,21 +16,11 @@ package org.b3log.solo.model;
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="https://hacpai.com/member/e">Dongxu Wang</a>
* @version 1.7.0.8, Jan 18, 2020
* @version 1.7.0.9, Apr 30, 2020
* @since 0.3.1
*/
public final class Common {
/**
* Key of skin cookie name.
*/
public static final String COOKIE_NAME_SKIN = "skin";
/**
* Key of mobile skin cookie name.
*/
public static final String COOKIE_NAME_MOBILE_SKIN = "mobile-skin";
/**
* Key of favicon URL.
*/
......
/*
* Solo - A small and beautiful blogging system written in Java.
* Copyright (c) 2010-present, b3log.org
*
* Solo is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.b3log.solo.processor;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.net.MimeTypes;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.b3log.latke.Keys;
import org.b3log.latke.http.RequestContext;
import org.b3log.latke.ioc.Singleton;
import org.b3log.latke.util.Strings;
import org.b3log.solo.model.Common;
import org.b3log.solo.util.Images;
import org.b3log.solo.util.Solos;
import org.json.JSONObject;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* File fetch upload processor. 第三方图床自动替换为社区图床 https://github.com/88250/solo/issues/114
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.0, Apr 30, 2020
* @since 4.1.0
*/
@Singleton
public class FetchUploadProcessor {
/**
* Logger.
*/
private static final Logger LOGGER = LogManager.getLogger(FetchUploadProcessor.class);
/**
* Fetches the remote file and upload it.
*
* @param context the specified context
*/
public void fetchUpload(final RequestContext context) {
final JSONObject result = Solos.newFail();
context.renderJSONPretty(result);
final JSONObject data = new JSONObject();
final JSONObject requestJSONObject = context.requestJSON();
final String originalURL = requestJSONObject.optString(Common.URL);
if (!Strings.isURL(originalURL) || !StringUtils.startsWithIgnoreCase(originalURL, "http")) {
return;
}
if (Images.uploaded(originalURL)) {
return;
}
final JSONObject upload = Solos.getUploadToken(context);
if (null == upload) {
final String msg = "Gets upload token failed";
LOGGER.log(Level.ERROR, msg);
result.put(Keys.MSG, msg);
return;
}
String url;
byte[] bytes;
String contentType;
try {
final HttpRequest req = HttpRequest.get(originalURL).header("User-Agent", Solos.USER_AGENT);
final HttpResponse res = req.connectionTimeout(3000).timeout(5000).send();
res.close();
if (200 != res.statusCode()) {
result.put(Keys.MSG, "Fetch upload return status code is [" + res.statusCode() + "]");
return;
}
bytes = res.bodyBytes();
contentType = res.contentType();
} catch (final Exception e) {
LOGGER.log(Level.ERROR, "Fetch file [url=" + originalURL + "] failed", e);
result.put(Keys.MSG, "Fetch file [url=" + originalURL + "] failed");
return;
}
final String uploadURL = upload.optString(Common.UPLOAD_URL);
final String uploadToken = upload.optString(Common.UPLOAD_TOKEN);
try {
final String suffix = "." + getSuffix(contentType);
final Path imgFilePath = Files.createTempFile("solo-fetchupload-", suffix);
final File file = imgFilePath.toFile();
FileUtils.writeByteArrayToFile(file, bytes);
final HttpRequest req = HttpRequest.post(uploadURL).
header("User-Agent", Solos.USER_AGENT).header("X-Upload-Token", uploadToken).
connectionTimeout(3000).timeout(5000).form(
"file[]", file);
final HttpResponse res = req.send();
res.close();
if (200 != res.statusCode()) {
result.put(Keys.MSG, "Upload file to community OSS return status code is [" + res.statusCode() + "]");
return;
}
res.charset("UTF-8");
final JSONObject uploadResult = new JSONObject(res.bodyText());
final JSONObject succMap = uploadResult.optJSONObject("data").optJSONObject("succMap");
final String key = succMap.keys().next();
url = succMap.optString(key);
} catch (final Exception e) {
final String msg = "Upload file to community OSS [url=" + originalURL + "] failed";
LOGGER.log(Level.ERROR, msg, e);
result.put(Keys.MSG, msg);
return;
}
data.put(Common.URL, url);
data.put("originalURL", originalURL);
result.put(Common.DATA, data);
result.put(Keys.CODE, 0);
result.put(Keys.MSG, "");
}
/**
* Gets suffix (for example jpg) with the specified content type.
*
* @param contentType the specified content type
* @return suffix
*/
public static String getSuffix(final String contentType) {
String ret;
final String[] exts = MimeTypes.findExtensionsByMimeTypes(contentType, false);
if (null != exts && 0 < exts.length) {
ret = exts[0];
} else {
ret = StringUtils.substringAfter(contentType, "/");
ret = StringUtils.substringBefore(ret, ";");
}
return ret;
}
}
......@@ -17,10 +17,8 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.http.Cookie;
import org.b3log.latke.http.Request;
import org.b3log.latke.http.RequestContext;
import org.b3log.latke.http.Response;
import org.b3log.latke.http.renderer.AbstractFreeMarkerRenderer;
import org.b3log.latke.ioc.Inject;
import org.b3log.latke.ioc.Singleton;
......@@ -49,7 +47,7 @@ import java.util.Map;
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="https://hacpai.com/member/DASHU">DASHU</a>
* @author <a href="http://vanessa.b3log.org">Vanessa</a>
* @version 2.0.0.1, Apr 18, 2020
* @version 2.0.0.2, Apr 30, 2020
* @since 0.3.1
*/
@Singleton
......@@ -92,34 +90,12 @@ public class IndexProcessor {
*/
public void showIndex(final RequestContext context) {
final Request request = context.getRequest();
final Response response = context.getResponse();
final AbstractFreeMarkerRenderer renderer = new SkinRenderer(context, "index.ftl");
final Map<String, Object> dataModel = renderer.getDataModel();
try {
final int currentPageNum = Paginator.getPage(request);
final JSONObject preference = optionQueryService.getPreference();
// 前台皮肤切换 https://github.com/b3log/solo/issues/12060
String specifiedSkin = Skins.getSkinDirName(context);
if (StringUtils.isBlank(specifiedSkin)) {
final JSONObject skinOpt = optionQueryService.getSkin();
specifiedSkin = Solos.isMobile(request) ?
skinOpt.optString(Option.ID_C_MOBILE_SKIN_DIR_NAME) :
skinOpt.optString(Option.ID_C_SKIN_DIR_NAME);
}
request.setAttribute(Keys.TEMAPLTE_DIR_NAME, specifiedSkin);
Cookie cookie;
if (!Solos.isMobile(request)) {
cookie = new Cookie(Common.COOKIE_NAME_SKIN, specifiedSkin);
} else {
cookie = new Cookie(Common.COOKIE_NAME_MOBILE_SKIN, specifiedSkin);
}
cookie.setMaxAge(60 * 60); // 1 hour
cookie.setPath("/");
response.addCookie(cookie);
Skins.fillLangs(preference.optString(Option.ID_C_LOCALE_STRING), (String) context.attr(Keys.TEMAPLTE_DIR_NAME), dataModel);
dataModelService.fillIndexArticles(context, dataModel, currentPageNum, preference);
......
......@@ -33,7 +33,7 @@ import org.json.JSONObject;
* Skin handler.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.0, Nov 3, 2019
* @version 1.0.0.1, Apr 30, 2020
* @since 3.6.7
*/
public class SkinHandler implements Handler {
......@@ -62,11 +62,12 @@ public class SkinHandler implements Handler {
/**
* Resolve skin (template) for the specified HTTP request.
* 前台皮肤切换 https://github.com/b3log/solo/issues/12060
* 调整前台动态皮肤预览逻辑 https://github.com/88250/solo/issues/116
*
* @param request the specified HTTP request
*/
private void resolveSkinDir(final Request request) {
String skin = Skins.getSkinDirNameFromCookie(request);
String skin = Skins.getQuerySkin(request);
if (StringUtils.isBlank(skin)) {
final BeanManager beanManager = BeanManager.getInstance();
final OptionQueryService optionQueryService = beanManager.getReference(OptionQueryService.class);
......@@ -85,7 +86,6 @@ public class SkinHandler implements Handler {
}
}
}
request.setAttribute(Keys.TEMAPLTE_DIR_NAME, skin);
}
......
......@@ -16,15 +16,12 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.http.Cookie;
import org.b3log.latke.http.RequestContext;
import org.b3log.latke.http.Response;
import org.b3log.latke.http.renderer.JsonRenderer;
import org.b3log.latke.ioc.Inject;
import org.b3log.latke.ioc.Singleton;
import org.b3log.latke.service.LangPropsService;
import org.b3log.latke.service.ServiceException;
import org.b3log.solo.model.Common;
import org.b3log.solo.model.Option;
import org.b3log.solo.service.OptionQueryService;
import org.b3log.solo.service.SkinMgmtService;
......@@ -39,7 +36,7 @@ import java.util.Set;
* Skin console request processing.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 2.0.0.0, Feb 9, 2020
* @version 2.1.0.0, Apr 30, 2020
* @since 3.5.0
*/
@Singleton
......@@ -157,16 +154,6 @@ public class SkinConsole {
skinMgmtService.updateSkin(skin);
final Response response = context.getResponse();
final Cookie skinDirNameCookie = new Cookie(Common.COOKIE_NAME_SKIN, skin.getString(Option.ID_C_SKIN_DIR_NAME));
skinDirNameCookie.setMaxAge(60 * 60); // 1 hour
skinDirNameCookie.setPath("/");
response.addCookie(skinDirNameCookie);
final Cookie mobileSkinDirNameCookie = new Cookie(Common.COOKIE_NAME_MOBILE_SKIN, skin.getString(Option.ID_C_MOBILE_SKIN_DIR_NAME));
mobileSkinDirNameCookie.setMaxAge(60 * 60); // 1 hour
mobileSkinDirNameCookie.setPath("/");
response.addCookie(mobileSkinDirNameCookie);
ret.put(Keys.STATUS_CODE, true);
ret.put(Keys.MSG, langPropsService.get("updateSuccLabel"));
......@@ -179,18 +166,4 @@ public class SkinConsole {
jsonObject.put(Keys.MSG, langPropsService.get("updateFailLabel"));
}
}
/**
* Checks whether the specified input is a non-negative integer.
*
* @param input the specified input
* @return {@code true} if it is, returns {@code false} otherwise
*/
private boolean isNonNegativeInteger(final String input) {
try {
return 0 <= Integer.valueOf(input);
} catch (final Exception e) {
return false;
}
}
}
......@@ -47,7 +47,7 @@ import java.util.List;
* Solo initialization service.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.5.2.39, Apr 6, 2020
* @version 1.5.2.40, Apr 30, 2020
* @since 0.4.0
*/
@Service
......@@ -133,7 +133,7 @@ public class InitService {
/**
* Flag of init status.
*/
private static boolean inited;
public static boolean inited;
/**
* Flag of printed init prompt.
......
......@@ -29,7 +29,7 @@ import java.util.concurrent.ThreadLocalRandom;
* Image utilities.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.2.0, Apr 12, 2020
* @version 1.2.0.0, Apr 30, 2020
* @since 2.7.0
*/
public final class Images {
......@@ -44,6 +44,16 @@ public final class Images {
*/
public static String COMMUNITY_FILE_URL = "https://img.hacpai.com";
/**
* Checks whether the specified URL has uploaded.
*
* @param url the specified URL
* @return {@code true} if it has uploaded, returns {@code false} otherwise
*/
public static boolean uploaded(final String url) {
return StringUtils.startsWith(url, COMMUNITY_FILE_URL);
}
/**
* Qiniu image processing.
*
......
......@@ -20,7 +20,6 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.b3log.latke.Keys;
import org.b3log.latke.Latkes;
import org.b3log.latke.http.Cookie;
import org.b3log.latke.http.Request;
import org.b3log.latke.http.RequestContext;
import org.b3log.latke.ioc.BeanManager;
......@@ -28,7 +27,6 @@ import org.b3log.latke.service.LangPropsService;
import org.b3log.latke.service.ServiceException;
import org.b3log.latke.util.Locales;
import org.b3log.latke.util.Stopwatchs;
import org.b3log.solo.model.Common;
import org.b3log.solo.model.Option;
import java.io.File;
......@@ -43,7 +41,7 @@ import java.util.stream.Stream;
* Skin utilities.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.7.0, Jan 14, 2020
* @version 1.2.0.0, Apr 30, 2020
* @since 0.3.1
*/
public final class Skins {
......@@ -232,62 +230,19 @@ public final class Skins {
/**
* Gets skin directory name from the specified request.
* Refers to <a href="https://github.com/b3log/solo/issues/12060">前台皮肤切换</a> for more details.
* Refers to <a href="https://github.com/b3log/solo/issues/12060">前台皮肤切换</a> and
* <a href="https://github.com/88250/solo/issues/116">调整前台动态皮肤预览逻辑</a> for more details.
*
* @param context the specified request context
* @param request the specified request
* @return directory name, or {@code null} if not found
*/
public static String getSkinDirName(final RequestContext context) {
// 1. Get skin from query
final String specifiedSkin = context.param(Option.CATEGORY_C_SKIN);
public static String getQuerySkin(final Request request) {
final String specifiedSkin = request.getParameter(Option.CATEGORY_C_SKIN);
if (StringUtils.isNotBlank(specifiedSkin)) {
final Set<String> skinDirNames = Skins.getSkinDirNames();
if (skinDirNames.contains(specifiedSkin)) {
return specifiedSkin;
} else {
return null;
}
}
// 2. Get skin from cookie
return getSkinDirNameFromCookie(context.getRequest());
}
/**
* Gets skin directory name from the specified request's cookie.
*
* @param request the specified request
* @return directory name, or {@code null} if not found
*/
public static String getSkinDirNameFromCookie(final Request request) {
final Set<String> skinDirNames = Skins.getSkinDirNames();
boolean isMobile = Solos.isMobile(request);
String skin = null, mobileSkin = null;
final Set<Cookie> cookies = request.getCookies();
if (!cookies.isEmpty()) {
for (final Cookie cookie : cookies) {
if (Common.COOKIE_NAME_SKIN.equals(cookie.getName()) && !isMobile) {
final String s = cookie.getValue();
if (skinDirNames.contains(s)) {
skin = s;
break;
}
}
if (Common.COOKIE_NAME_MOBILE_SKIN.equals(cookie.getName()) && isMobile) {
final String s = cookie.getValue();
if (skinDirNames.contains(s)) {
mobileSkin = s;
break;
}
}
}
}
if (StringUtils.isNotBlank(skin)) {
return skin;
}
if (StringUtils.isNotBlank(mobileSkin)) {
return mobileSkin;
}
return null;
......
......@@ -18,6 +18,7 @@ import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.b3log.latke.http.RequestContext;
import org.b3log.solo.model.Option;
import org.b3log.solo.processor.SkinRenderer;
import java.io.ByteArrayInputStream;
......
......@@ -15,7 +15,7 @@
<#if isLoggedIn && commentable>
<div style="position: fixed;bottom: -300px;width: 100%;opacity: 0;background-color: #f1f7fe;padding: 20px 0;transition: all .15s ease-in-out;z-index: 100;left: 0;"
id="soloEditor">
<div style="max-width: 768px;margin: 0 auto;padding: 0 10px;">
<div style="max-width: 920px;margin: 0 auto;padding: 0 10px;">
<div id="soloEditorComment"></div>
<div style="display: flex;margin-top: 10px;line-height: 30px">
<div style="flex: 1;" id="soloEditorReplyTarget"></div>
......
This diff is collapsed.
......@@ -14,7 +14,7 @@
*
* @author <a href="http://vanessa.b3log.org">Liyuan Li</a>
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.6.0.0, Apr 16, 2020
* @version 1.6.0.1, Apr 30, 2020
*/
admin.editors = {}
......@@ -81,6 +81,7 @@ $.extend(SoloEditor.prototype, {
upload: {
max: 10 * 1024 * 1024,
url: Label.uploadURL,
linkToImgUrl: Label.servePath + '/upload/fetch',
token: Label.uploadToken,
filename: function (name) {
return name.replace(/[^(a-zA-Z0-9\u4e00-\u9fa5\.)]/g, '').
......@@ -116,10 +117,20 @@ $.extend(SoloEditor.prototype, {
'emoji',
'link',
'upload',
'insert-after',
'edit-mode',
'preview',
'code-theme',
'content-theme',
{
name: 'more',
toolbar: [
'insert-after',
'fullscreen',
'preview',
'format',
'info',
'help',
],
},
]
options.resize.enable = false
options.toolbarConfig.pin = true
......
......@@ -23,7 +23,7 @@ window.Vcomment = Vcomment
*
* @author <a href="http://vanessa.b3log.org">Liyuan Li</a>
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 2.2.0.1, Feb 23, 2020
* @version 2.2.1.0, Apr 30, 2020
*/
/**
......@@ -109,7 +109,14 @@ window.Util = {
return true
},
callback: function () {
try {
// TODO vditor@3.1.21 移除 try cache
Util.parseMarkdown()
} catch (e) {
}
if (typeof Util.uvstat === 'undefined') {
Util.uvstat = new Uvstat()
}
Util.uvstat.addStat()
Util.uvstat.renderStat()
Util.uvstat.renderCmtStat(
......@@ -303,7 +310,7 @@ window.Util = {
loadVditor: function (cb) {
$.ajax({
method: 'GET',
url: 'https://cdn.jsdelivr.net/npm/vditor@3.1.12/dist/index.min.js',
url: 'https://cdn.jsdelivr.net/npm/vditor@3.1.20/dist/index.min.js',
dataType: 'script',
cache: true,
success: () => {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -14,7 +14,7 @@
*
* @author <a href="http://vanessa.b3log.org">Liyuan Li</a>
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 2.8.0.0, Apr 16, 2020
* @version 2.8.0.1, Apr 30, 2020
*/
window.Page = function (tips) {
this.currentCommentId = ''
......@@ -95,7 +95,8 @@ $.extend(Page.prototype, {
value: shareURL,
size: 99,
})
$qrCode.css('background-image', `url(${qr.toDataURL('image/jpeg')})`).show()
$qrCode.css('background-image', `url(${qr.toDataURL('image/jpeg')})`).
show()
} else {
$qrCode.slideToggle()
}
......@@ -132,6 +133,7 @@ $.extend(Page.prototype, {
if (!$('#soloEditorComment').hasClass('vditor')) {
var that = this
var resizeEnable = true
var toolbar = [
'emoji',
'headings',
......@@ -153,29 +155,44 @@ $.extend(Page.prototype, {
'table',
'insert-before',
'insert-after',
'|',
'undo',
'redo',
'|',
'fullscreen',
'edit-mode',
{
name: 'more',
toolbar: [
'both',
'code-theme',
'content-theme',
'export',
'outline',
'preview',
'format',
'|',
'fullscreen',
'devtools',
'info',
'help',
], resizeEnable = true
],
}]
if ($(window).width() < 768) {
toolbar = [
'emoji',
'link',
'upload',
'insert-after',
'edit-mode',
'preview',
'code-theme',
'content-theme',
{
name: 'more',
toolbar: [
'insert-after',
'fullscreen',
'preview',
'format',
'info',
'help',
],
},
]
resizeEnable = false
}
......@@ -214,7 +231,7 @@ $.extend(Page.prototype, {
position: 'top',
},
lang: Label.langLabel,
toolbar: toolbar,
toolbar,
after: () => {
vditor.focus()
},
......
This diff is collapsed.
This diff is collapsed.
......@@ -14,7 +14,7 @@
*
* @author <a href="http://vanessa.b3log.org">Liyuan Li</a>
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 3.3.0.2, Feb 9, 2020
* @version 3.3.1.0, Apr 30, 2020
*/
@import "reset";
@import "function";
......@@ -960,6 +960,10 @@ button#submitArticle:hover {
border-radius: 0 0 3px 3px;
}
.solo-kanbanniang {
z-index: 1;
}
@media (max-width: 768px) {
#top > a {
display: none;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -19,7 +19,6 @@ import org.b3log.latke.http.Dispatcher;
import org.b3log.latke.http.Request;
import org.b3log.latke.http.Response;
import org.b3log.latke.ioc.BeanManager;
import org.b3log.latke.ioc.Discoverer;
import org.b3log.latke.model.User;
import org.b3log.latke.repository.jdbc.util.Connections;
import org.b3log.latke.repository.jdbc.util.JdbcRepositories;
......@@ -40,13 +39,12 @@ import org.testng.annotations.BeforeMethod;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.Collection;
/**
* Abstract test case.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 4.0.0.0, Feb 9, 2020
* @version 4.0.0.1, Apr 30, 2020
* @since 2.9.7
*/
public abstract class AbstractTestCase {
......@@ -56,6 +54,11 @@ public abstract class AbstractTestCase {
*/
private BeanManager beanManager;
static {
Latkes.init();
Server.routeProcessors();
}
/**
* Before class.
* <ol>
......@@ -67,10 +70,7 @@ public abstract class AbstractTestCase {
*/
@BeforeClass
public void beforeClass() throws Exception {
Latkes.init();
final Collection<Class<?>> classes = Discoverer.discover("org.b3log.solo");
BeanManager.start(classes);
System.out.println("before class");
beanManager = BeanManager.getInstance();
final Connection connection = Connections.getConnection();
......@@ -78,6 +78,7 @@ public abstract class AbstractTestCase {
connection.close();
JdbcRepositories.initAllTables();
InitService.inited = false;
initSolo();
}
......@@ -147,8 +148,6 @@ public abstract class AbstractTestCase {
*/
public MockDispatcher mockDispatcher(final Request request, final Response response) {
final MockDispatcher ret = new MockDispatcher();
ret.init();
Server.routeProcessors();
ret.handle(request, response);
return ret;
......
......@@ -25,5 +25,6 @@ public class MockRequest extends Request {
public MockRequest(final FullHttpRequest req) {
super(null, req);
req.headers().set("X-Forwarded-For", "127.0.0.1");
}
}
\ No newline at end of file
......@@ -22,7 +22,7 @@ import org.testng.annotations.Test;
* {@link ErrorProcessor} test case.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.1.3, Feb 22, 2019
* @version 1.0.1.4, Apr 30, 2020
* @since 1.7.0
*/
@Test(suiteName = "processor")
......@@ -33,11 +33,11 @@ public class ErrorProcessorTestCase extends AbstractTestCase {
*/
public void showErrorPage() {
final MockRequest request = mockRequest();
request.setRequestURI("/error/403");
request.setRequestURI("/notfound");
final MockResponse response = mockResponse();
mockDispatcher(request, response);
final String content = response.getString();
Assert.assertTrue(StringUtils.contains(content, "<title>403 Forbidden! - Solo 的个人博客</title>"));
Assert.assertTrue(StringUtils.contains(content, "<title>404 Not Found! - Solo 的个人博客</title>"));
}
}
......@@ -14,32 +14,16 @@ package org.b3log.solo.processor;
import org.b3log.latke.http.Dispatcher;
import org.b3log.latke.http.Request;
import org.b3log.latke.http.Response;
import org.b3log.latke.http.function.Handler;
import org.b3log.latke.http.handler.InvokeHandler;
import org.b3log.latke.http.handler.RouteHandler;
import java.util.ArrayList;
import java.util.List;
/**
* Mock dispatcher for unit tests.
*
* @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 2.0.0.0, Feb 9, 2020
* @version 2.0.0.1, Apr 30, 2020
* @since 1.7.0
*/
public class MockDispatcher {
/**
* Handlers
*/
private static final List<Handler> HANDLERS = new ArrayList<>();
public void init() {
HANDLERS.add(new RouteHandler());
HANDLERS.add(new InvokeHandler());
}
public void handle(final Request req, final Response resp) {
Dispatcher.handle(req, resp);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment