Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,24 @@
extension point are removed, so a deployment that configured its own
`AtomHandlerFactory` (for example, for custom authentication) no longer has
that handler. AtomPub clients see no change.
- **Icons and images without a compatible license are gone.** The Gaurav theme
no longer ships Font Awesome 3, and the Gaurav and Fauxcoly themes, the
admin pages and the Emoticons plugin no longer use Silk icons or images of
unknown origin. Bootstrap Icons replace them, drawn inline so they look the
same in a customized copy of a theme. The Emoticons plugin now turns `:-)`
into a Unicode emoji instead of an image from `/images/smileys/`, which is
removed along with `/images/editor/` and most Silk icons in `/images/`.
The standard feed icon, the RSS, Atom and OPML badges, the OpenID logo and
the permalink and launch-link icons in `/images/` are gone too, with feed
links now drawn as a Bootstrap Icons feed icon. The unused admin colour
themes under `/roller-ui/theme/` and three unused images in
`/roller-ui/images/` are removed.
Custom templates that link to those files, or to `font-awesome.min.css` or
the theme icons other than `asf-logo.png`, show broken images until they
are updated. Weblogs already using a customized copy keep their own copies
of the old files. Search term highlighting in both themes now uses a new
`js/search-highlight.js`; customized search pages that load `searchhi.js`
keep working only while their copy of that file remains.

### Build and packaging

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,155 +18,115 @@

package org.apache.roller.weblogger.business.plugins.entry;

import java.util.Enumeration;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.text.StringEscapeUtils;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.text.StringEscapeUtils;
import org.apache.roller.weblogger.WebloggerException;
import org.apache.roller.weblogger.config.WebloggerRuntimeConfig;
import org.apache.roller.weblogger.pojos.WeblogEntry;
import org.apache.roller.weblogger.pojos.Weblog;
import org.apache.roller.weblogger.pojos.WeblogEntry;

/**
* Converts ascii emoticons into HTML image tags.
* Converts ASCII emoticons into Unicode emoji.
*
* <p>Each emoticon listed in <code>smileys.properties</code> becomes
* <code>&lt;span class="smiley" title=":-)"&gt;&amp;#x1F642;&lt;/span&gt;</code>,
* so no image files are needed and the emoji scales with the text around it.
*/
public class SmileysPlugin implements WeblogEntryPlugin {

private static final Log log = LogFactory.getLog(SmileysPlugin.class);

// public for tests
public static Pattern[] smileyPatterns = new Pattern[0];
static String[] imageTags = new String[0];
private static final Properties smileyDefs = new Properties();

private final String name = "Emoticons";
private final String description = "Change ASCII emoticons to graphics. " +
":-) becomes <img src='./images/smileys/smile.gif'>";

private static final String NAME = "Emoticons";
private static final String DESCRIPTION =
"Change ASCII emoticons to emoji. :-) becomes a smiling face.";

/** Matches any of the emoticons, longest first. */
private static final Pattern SMILEY_PATTERN;

/** The markup that replaces each emoticon. */
private static final Map<String, String> REPLACEMENTS;

static {
try {
smileyDefs.load(SmileysPlugin.class.getResourceAsStream("smileys.properties"));
} catch (Exception e) {
Properties smileyDefs = new Properties();
try (InputStream in = SmileysPlugin.class.getResourceAsStream("smileys.properties")) {
if (in == null) {
throw new IOException("smileys.properties is not on the classpath");
}
smileyDefs.load(in);
} catch (IOException e) {
log.error("Unable to load smileys.properties", e);
}

Map<String, String> replacements = new HashMap<>();
for (String smiley : smileyDefs.stringPropertyNames()) {
String codePoint = smileyDefs.getProperty(smiley).trim();
String title = StringEscapeUtils.escapeHtml4(smiley);
replacements.put(smiley, "<span class=\"smiley\" title=\"" + title + "\">&#x"
+ codePoint + ";</span>");
}
REPLACEMENTS = Collections.unmodifiableMap(replacements);

// One pass with the longest emoticons tried first, so that ":))" is
// not read as ":)" followed by ")", and markup that has already been
// inserted is never matched again
List<String> smileys = new ArrayList<>(replacements.keySet());
smileys.sort((a, b) -> b.length() != a.length()
? b.length() - a.length() : a.compareTo(b));
SMILEY_PATTERN = smileys.isEmpty() ? null : Pattern.compile(
smileys.stream().map(Pattern::quote).collect(Collectors.joining("|")));
}


public SmileysPlugin() {
log.debug("SmileysPlugin instantiated.");
}


@Override
public String getName() {
return name;
return NAME;
}


@Override
public String getDescription() {
return StringEscapeUtils.escapeEcmaScript(description);
return StringEscapeUtils.escapeEcmaScript(DESCRIPTION);
}


/*
* Convert the SmileyDefs into RegEx patterns and img tags for
* later use. Need an HttpServletRequest though so that we can
* get the ServletContext Path. But only do it once.
*/


@Override
public synchronized void init(Weblog website) throws WebloggerException {
// don't do this work if Smileys already loaded
if (SmileysPlugin.smileyPatterns.length < 1) {
String baseURL = WebloggerRuntimeConfig.getAbsoluteContextURL();

Pattern[] tempP = new Pattern[SmileysPlugin.smileyDefs.size()];
String[] tempS = new String[SmileysPlugin.smileyDefs.size()];
log.debug("# smileys: " + smileyDefs.size());
int count = 0;
Enumeration<?> enum1 = SmileysPlugin.smileyDefs.propertyNames();
while(enum1.hasMoreElements()) {
String smiley = (String)enum1.nextElement();
String smileyAlt = htmlEscape(smiley);
tempP[count] = Pattern.compile(regexEscape(smiley));
tempS[count] = "<img src=\"" +
baseURL + "/images/smileys/" +
smileyDefs.getProperty(smiley, "smile.gif") +
"\" class=\"smiley\"" +
" alt=\"" + smileyAlt + "\"" +
" title=\"" + smileyAlt +"\" />";
log.debug(smiley + "=" + tempS[count]);
count++;
}
SmileysPlugin.smileyPatterns = tempP;
SmileysPlugin.imageTags = tempS;
}
public void init(Weblog website) throws WebloggerException {
// nothing to do, the emoticons are loaded once when the class loads
}


/**
* Find occurences of ascii emoticons and turn them into HTML image pointers.
* Find occurrences of ASCII emoticons and turn them into emoji.
*/
@Override
public String render(WeblogEntry entry, String text) {
Matcher matcher;
for (int i=0; i<smileyPatterns.length; i++) {
matcher = smileyPatterns[i].matcher(text);
text = matcher.replaceAll(imageTags[i]);
if (SMILEY_PATTERN == null || text == null) {
return text;
}
return text;
}


/*
* To display the smiley 'glyph' certain characters
* must be HTML escaped.
*/
private String htmlEscape(String smiley) {
char[] chars = smiley.toCharArray();
StringBuilder buf = new StringBuilder();
for (int i=0; i<chars.length; i++) {
if (chars[i] == '"') {
buf.append("&quot;");
} else if (chars[i] == '>') {
buf.append("&gt;");
} else if (chars[i] == '<') {
buf.append("&lt;");
} else {
buf.append(chars[i]);
}
}
return buf.toString();
}

/**
* Some characters have to escaped with a backslash before
* being compiled into a Regular Expression.
*
* @param smiley
* @return
*/
private static final char[] escape_regex = new char[]
{'-', '(', ')', '\\', '|', ':', '^', '$', '*', '+', '?',
'{', '}', '!', '=', '<', '>', '&', '[', ']' };

private String regexEscape(String smiley) {
char[] chars = smiley.toCharArray();
StringBuilder buf = new StringBuilder();
for (int i=0; i<chars.length; i++) {
for (int x=0; x<escape_regex.length; x++) {
if (escape_regex[x] == chars[i]) {
buf.append("\\");
break;
}
}
buf.append(chars[i]);
Matcher matcher = SMILEY_PATTERN.matcher(text);
StringBuilder result = new StringBuilder(text.length());
while (matcher.find()) {
matcher.appendReplacement(result,
Matcher.quoteReplacement(REPLACEMENTS.get(matcher.group())));
}
return buf.toString();
matcher.appendTail(result);
return result.toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,43 +14,46 @@
# copyright in this work, please see the NOTICE file in the top level
# directory of this distribution.

\:-)=smile.gif
\:)=smile.gif
;-)=wink.gif
;)=wink.gif
\:-(=sad.gif
\:(=sad.gif
\:-0=surprised.gif
8-)=sunglasses.gif
\:-D=grin.gif
\\-o=bored.gif
\:-P=tongue.gif
O\:-)=angelic.gif
\:-||=angry.gif
%-)=drunk.gif
/\:)=20.gif
\:-S=15.gif
\:|=19.gif
;;)=smirk.gif
\:-B=bucktooth.gif
\=;=hand.gif
[-(=28.gif
(\:|=depressed.gif
\=P~=drool.gif
\:-?=thinker.gif
\=D>=whisper.gif
\:">=blush.gif
\:o)=clown.gif
\:-/=confused.gif
\:((=cry.gif
>\:)=devil.gif
\#-o=doh.gif
\:-*=kiss.gif
\:))=laugh.gif
\:x=love.gif
8-|=rolleyes.gif
\:(\:-$=shush.gif
\:-&=sick.gif
8-}=silly.gif
I-)=sleep.gif
\:->=smug.gif
# Each ASCII emoticon maps to the Unicode code point, in hexadecimal, of the
# emoji that SmileysPlugin puts in its place.

\:-)=1F642
\:)=1F642
;-)=1F609
;)=1F609
\:-(=1F641
\:(=1F641
\:-0=1F62E
8-)=1F60E
\:-D=1F600
\\-o=1F971
\:-P=1F61B
O\:-)=1F607
\:-||=1F620
%-)=1F974
/\:)=1F928
\:-S=1F61F
\:|=1F610
;;)=1F60F
\:-B=1F913
\=;=270B
[-(=1F612
(\:|=1F61E
\=P~=1F924
\:-?=1F914
\=D>=1F92D
\:">=1F60A
\:o)=1F921
\:-/=1F615
\:((=1F622
>\:)=1F608
\#-o=1F926
\:-*=1F618
\:))=1F606
\:x=1F60D
8-|=1F644
\:(\:-$=1F92B
\:-&=1F922
8-}=1F92A
I-)=1F634
\:->=1F60C
6 changes: 3 additions & 3 deletions app/src/main/webapp/WEB-INF/jsps/admin/UserEdit.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -120,23 +120,23 @@
<s:url action="entryAdd" namespace="/roller-ui/authoring" var="newEntry">
<s:param name="weblog" value="#perms.weblog.handle" />
</s:url>
<img src='<s:url value="/images/page_white_edit.png"/>' />
<span class="bi bi-pencil-square" aria-hidden="true"></span>
<a href='<s:property value="newEntry" />'>
<s:text name="userAdmin.newEntry" /></a>
</td>
<td width="%15">
<s:url action="entries" namespace="/roller-ui/authoring" var="editEntries">
<s:param name="weblog" value="#perms.weblog.handle" />
</s:url>
<img src='<s:url value="/images/page_white_edit.png"/>' />
<span class="bi bi-pencil-square" aria-hidden="true"></span>
<a href='<s:property value="editEntries" />'>
<s:text name="userAdmin.editEntries" /></a>
</td>
<td width="%15">
<s:url action="weblogConfig" namespace="/roller-ui/authoring" var="manageWeblog">
<s:param name="weblog" value="#perms.weblog.handle" />
</s:url>
<img src='<s:url value="/images/page_white_edit.png"/>' />
<span class="bi bi-pencil-square" aria-hidden="true"></span>
<a href='<s:property value="manageWeblog" />'>
<s:text name="userAdmin.manage" /></a>
</td>
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/webapp/WEB-INF/jsps/editor/EntryEdit.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
<a id="entry_bean_permalink" href='<s:property value="entry.permalink" />'>
<s:property value="entry.permalink"/>
</a>
<img src='<s:url value="/images/launch-link.png"/>'/>
<span class="bi bi-box-arrow-up-right" aria-hidden="true"></span>
</s:if>
<s:else>
<s:property value="entry.permalink"/>
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/webapp/WEB-INF/jsps/editor/Templates.jsp
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@

<td style="vertical-align:middle">
<s:if test="! #p.hidden">
<img src='<s:url value="/images/page_white.png"/>' border="0" alt="icon"/>
<span class="bi bi-file-earmark" aria-hidden="true"></span>
</s:if>
<s:else>
<img src='<s:url value="/images/page_white_gear.png"/>' border="0" alt="icon"/>
<span class="bi bi-gear" aria-hidden="true"></span>
</s:else>
<s:url var="edit" action="templateEdit">
<s:param name="weblog" value="actionWeblog.handle"/>
Expand Down
Loading
Loading