add support for custom js code that will be executed on page load (#1032)

This commit is contained in:
Athou
2023-05-05 18:28:31 +02:00
parent b1b5eeb0e0
commit 3d1a1cd033
41 changed files with 431 additions and 219 deletions

View File

@@ -43,6 +43,7 @@ import com.commafeed.frontend.resource.ServerREST;
import com.commafeed.frontend.resource.UserREST;
import com.commafeed.frontend.servlet.AnalyticsServlet;
import com.commafeed.frontend.servlet.CustomCssServlet;
import com.commafeed.frontend.servlet.CustomJsServlet;
import com.commafeed.frontend.servlet.LogoutServlet;
import com.commafeed.frontend.servlet.NextUnreadServlet;
import com.commafeed.frontend.session.SessionHelperFactoryProvider;
@@ -173,6 +174,7 @@ public class CommaFeedApplication extends Application<CommaFeedConfiguration> {
environment.servlets().addServlet("next", injector.getInstance(NextUnreadServlet.class)).addMapping("/next");
environment.servlets().addServlet("logout", injector.getInstance(LogoutServlet.class)).addMapping("/logout");
environment.servlets().addServlet("customCss", injector.getInstance(CustomCssServlet.class)).addMapping("/custom_css.css");
environment.servlets().addServlet("customJs", injector.getInstance(CustomJsServlet.class)).addMapping("/custom_js.js");
environment.servlets().addServlet("analytics.js", injector.getInstance(AnalyticsServlet.class)).addMapping("/analytics.js");
// WebSocket endpoint

View File

@@ -57,6 +57,11 @@ public class UserSettings extends AbstractModel {
@Type(type = "org.hibernate.type.TextType")
private String customCss;
@Lob
@Column(length = Integer.MAX_VALUE)
@Type(type = "org.hibernate.type.TextType")
private String customJs;
@Column(name = "scroll_speed")
private int scrollSpeed;

View File

@@ -29,6 +29,9 @@ public class Settings implements Serializable {
@ApiModelProperty(value = "user's custom css for the website")
private String customCss;
@ApiModelProperty(value = "user's custom js for the website")
private String customJs;
@ApiModelProperty(value = "user's preferred scroll speed when navigating between entries", required = true)
private int scrollSpeed;

View File

@@ -100,6 +100,7 @@ public class UserREST {
s.setScrollMarks(settings.isScrollMarks());
s.setCustomCss(settings.getCustomCss());
s.setCustomJs(settings.getCustomJs());
s.setLanguage(settings.getLanguage());
s.setScrollSpeed(settings.getScrollSpeed());
} else {
@@ -141,6 +142,7 @@ public class UserREST {
s.setShowRead(settings.isShowRead());
s.setScrollMarks(settings.isScrollMarks());
s.setCustomCss(settings.getCustomCss());
s.setCustomJs(settings.getCustomJs());
s.setLanguage(settings.getLanguage());
s.setScrollSpeed(settings.getScrollSpeed());

View File

@@ -0,0 +1,51 @@
package com.commafeed.frontend.servlet;
import java.io.IOException;
import java.util.Optional;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.SessionFactory;
import com.commafeed.backend.dao.UnitOfWork;
import com.commafeed.backend.dao.UserSettingsDAO;
import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserSettings;
import com.commafeed.frontend.session.SessionHelper;
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
abstract class AbstractCustomCodeServlet extends HttpServlet {
private final SessionFactory sessionFactory;
private final UserSettingsDAO userSettingsDAO;
@Override
protected final void doGet(final HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType(getMimeType());
final Optional<User> user = new SessionHelper(req).getLoggedInUser();
if (!user.isPresent()) {
return;
}
UserSettings settings = UnitOfWork.call(sessionFactory, () -> userSettingsDAO.findByUser(user.get()));
if (settings == null) {
return;
}
String customCode = getCustomCode(settings);
if (customCode == null) {
return;
}
resp.getWriter().write(customCode);
}
protected abstract String getMimeType();
protected abstract String getCustomCode(UserSettings settings);
}

View File

@@ -1,47 +1,27 @@
package com.commafeed.frontend.servlet;
import java.io.IOException;
import java.util.Optional;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.SessionFactory;
import com.commafeed.backend.dao.UnitOfWork;
import com.commafeed.backend.dao.UserSettingsDAO;
import com.commafeed.backend.model.User;
import com.commafeed.backend.model.UserSettings;
import com.commafeed.frontend.session.SessionHelper;
import lombok.RequiredArgsConstructor;
public class CustomCssServlet extends AbstractCustomCodeServlet {
@SuppressWarnings("serial")
@RequiredArgsConstructor(onConstructor = @__({ @Inject }))
@Singleton
public class CustomCssServlet extends HttpServlet {
private final SessionFactory sessionFactory;
private final UserSettingsDAO userSettingsDAO;
@Inject
public CustomCssServlet(SessionFactory sessionFactory, UserSettingsDAO userSettingsDAO) {
super(sessionFactory, userSettingsDAO);
}
@Override
protected void doGet(final HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/css");
final Optional<User> user = new SessionHelper(req).getLoggedInUser();
if (!user.isPresent()) {
return;
}
UserSettings settings = UnitOfWork.call(sessionFactory, () -> userSettingsDAO.findByUser(user.get()));
if (settings == null || settings.getCustomCss() == null) {
return;
}
resp.getWriter().write(settings.getCustomCss());
protected String getMimeType() {
return "text/css";
}
@Override
protected String getCustomCode(UserSettings settings) {
return settings.getCustomCss();
}
}

View File

@@ -0,0 +1,29 @@
package com.commafeed.frontend.servlet;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.hibernate.SessionFactory;
import com.commafeed.backend.dao.UserSettingsDAO;
import com.commafeed.backend.model.UserSettings;
@Singleton
public class CustomJsServlet extends AbstractCustomCodeServlet {
@Inject
public CustomJsServlet(SessionFactory sessionFactory, UserSettingsDAO userSettingsDAO) {
super(sessionFactory, userSettingsDAO);
}
@Override
protected String getMimeType() {
return "application/javascript";
}
@Override
protected String getCustomCode(UserSettings settings) {
return settings.getCustomJs();
}
}