瀏覽代碼

Add Clipboard copy feature on Search page (#2658)

* add clipboard copy feature 

Co-authored-by: unknown <kazuihitoshi@gmail.com>
Shinsuke Sugaya 3 年之前
父節點
當前提交
d3a6191f1d

+ 3 - 0
src/main/java/org/codelibs/fess/mylasta/action/FessLabels.java

@@ -719,6 +719,9 @@ public class FessLabels extends UserMessages {
     /** The key of the message: Viewed ({0}) */
     /** The key of the message: Viewed ({0}) */
     public static final String LABELS_search_click_count = "{labels.search_click_count}";
     public static final String LABELS_search_click_count = "{labels.search_click_count}";
 
 
+    /** The key of the message: {0} views */
+    public static final String LABELS_search_click_views = "{labels.search_click_views}";
+
     /** The key of the message: more.. */
     /** The key of the message: more.. */
     public static final String LABELS_search_result_more = "{labels.search_result_more}";
     public static final String LABELS_search_result_more = "{labels.search_result_more}";
 
 

+ 8 - 8
src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java

@@ -301,7 +301,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
     /** The key of the configuration. e.g. 0 */
     /** The key of the configuration. e.g. 0 */
     String CRAWLER_HTTP_thread_pool_SIZE = "crawler.http.thread_pool.size";
     String CRAWLER_HTTP_thread_pool_SIZE = "crawler.http.thread_pool.size";
 
 
-    /** The key of the configuration. e.g. 50 */
+    /** The key of the configuration. e.g. 100 */
     String CRAWLER_DOCUMENT_MAX_SITE_LENGTH = "crawler.document.max.site.length";
     String CRAWLER_DOCUMENT_MAX_SITE_LENGTH = "crawler.document.max.site.length";
 
 
     /** The key of the configuration. e.g. UTF-8 */
     /** The key of the configuration. e.g. UTF-8 */
@@ -600,7 +600,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
     /** The key of the configuration. e.g. 50 */
     /** The key of the configuration. e.g. 50 */
     String RESPONSE_MAX_TITLE_LENGTH = "response.max.title.length";
     String RESPONSE_MAX_TITLE_LENGTH = "response.max.title.length";
 
 
-    /** The key of the configuration. e.g. 50 */
+    /** The key of the configuration. e.g. 100 */
     String RESPONSE_MAX_SITE_PATH_LENGTH = "response.max.site.path.length";
     String RESPONSE_MAX_SITE_PATH_LENGTH = "response.max.site.path.length";
 
 
     /** The key of the configuration. e.g. true */
     /** The key of the configuration. e.g. true */
@@ -2494,14 +2494,14 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
 
 
     /**
     /**
      * Get the value for the key 'crawler.document.max.site.length'. <br>
      * Get the value for the key 'crawler.document.max.site.length'. <br>
-     * The value is, e.g. 50 <br>
+     * The value is, e.g. 100 <br>
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      */
      */
     String getCrawlerDocumentMaxSiteLength();
     String getCrawlerDocumentMaxSiteLength();
 
 
     /**
     /**
      * Get the value for the key 'crawler.document.max.site.length' as {@link Integer}. <br>
      * Get the value for the key 'crawler.document.max.site.length' as {@link Integer}. <br>
-     * The value is, e.g. 50 <br>
+     * The value is, e.g. 100 <br>
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      * @throws NumberFormatException When the property is not integer.
      * @throws NumberFormatException When the property is not integer.
      */
      */
@@ -3490,14 +3490,14 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
 
 
     /**
     /**
      * Get the value for the key 'response.max.site.path.length'. <br>
      * Get the value for the key 'response.max.site.path.length'. <br>
-     * The value is, e.g. 50 <br>
+     * The value is, e.g. 100 <br>
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      */
      */
     String getResponseMaxSitePathLength();
     String getResponseMaxSitePathLength();
 
 
     /**
     /**
      * Get the value for the key 'response.max.site.path.length' as {@link Integer}. <br>
      * Get the value for the key 'response.max.site.path.length' as {@link Integer}. <br>
-     * The value is, e.g. 50 <br>
+     * The value is, e.g. 100 <br>
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      * @throws NumberFormatException When the property is not integer.
      * @throws NumberFormatException When the property is not integer.
      */
      */
@@ -10222,7 +10222,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
             defaultMap.put(FessConfig.HTTP_FILEUPLOAD_THRESHOLD_SIZE, "262144");
             defaultMap.put(FessConfig.HTTP_FILEUPLOAD_THRESHOLD_SIZE, "262144");
             defaultMap.put(FessConfig.CRAWLER_DEFAULT_SCRIPT, "groovy");
             defaultMap.put(FessConfig.CRAWLER_DEFAULT_SCRIPT, "groovy");
             defaultMap.put(FessConfig.CRAWLER_HTTP_thread_pool_SIZE, "0");
             defaultMap.put(FessConfig.CRAWLER_HTTP_thread_pool_SIZE, "0");
-            defaultMap.put(FessConfig.CRAWLER_DOCUMENT_MAX_SITE_LENGTH, "50");
+            defaultMap.put(FessConfig.CRAWLER_DOCUMENT_MAX_SITE_LENGTH, "100");
             defaultMap.put(FessConfig.CRAWLER_DOCUMENT_SITE_ENCODING, "UTF-8");
             defaultMap.put(FessConfig.CRAWLER_DOCUMENT_SITE_ENCODING, "UTF-8");
             defaultMap.put(FessConfig.CRAWLER_DOCUMENT_UNKNOWN_HOSTNAME, "unknown");
             defaultMap.put(FessConfig.CRAWLER_DOCUMENT_UNKNOWN_HOSTNAME, "unknown");
             defaultMap.put(FessConfig.CRAWLER_DOCUMENT_USE_SITE_ENCODING_ON_ENGLISH, "false");
             defaultMap.put(FessConfig.CRAWLER_DOCUMENT_USE_SITE_ENCODING_ON_ENGLISH, "false");
@@ -10323,7 +10323,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
             defaultMap.put(FessConfig.RESPONSE_FIELD_url_link, "url_link");
             defaultMap.put(FessConfig.RESPONSE_FIELD_url_link, "url_link");
             defaultMap.put(FessConfig.RESPONSE_FIELD_site_path, "site_path");
             defaultMap.put(FessConfig.RESPONSE_FIELD_site_path, "site_path");
             defaultMap.put(FessConfig.RESPONSE_MAX_TITLE_LENGTH, "50");
             defaultMap.put(FessConfig.RESPONSE_MAX_TITLE_LENGTH, "50");
-            defaultMap.put(FessConfig.RESPONSE_MAX_SITE_PATH_LENGTH, "50");
+            defaultMap.put(FessConfig.RESPONSE_MAX_SITE_PATH_LENGTH, "100");
             defaultMap.put(FessConfig.RESPONSE_HIGHLIGHT_content_title_ENABLED, "true");
             defaultMap.put(FessConfig.RESPONSE_HIGHLIGHT_content_title_ENABLED, "true");
             defaultMap.put(FessConfig.INDEX_DOCUMENT_SEARCH_INDEX, "fess.search");
             defaultMap.put(FessConfig.INDEX_DOCUMENT_SEARCH_INDEX, "fess.search");
             defaultMap.put(FessConfig.INDEX_DOCUMENT_UPDATE_INDEX, "fess.update");
             defaultMap.put(FessConfig.INDEX_DOCUMENT_UPDATE_INDEX, "fess.update");

+ 2 - 2
src/main/resources/fess_config.properties

@@ -197,7 +197,7 @@ http.fileupload.threshold.size=262144
 # common
 # common
 crawler.default.script=groovy
 crawler.default.script=groovy
 crawler.http.thread_pool.size=0
 crawler.http.thread_pool.size=0
-crawler.document.max.site.length=50
+crawler.document.max.site.length=100
 crawler.document.site.encoding=UTF-8
 crawler.document.site.encoding=UTF-8
 crawler.document.unknown.hostname=unknown
 crawler.document.unknown.hostname=unknown
 crawler.document.use.site.encoding.on.english=false
 crawler.document.use.site.encoding.on.english=false
@@ -311,7 +311,7 @@ response.field.content_description=content_description
 response.field.url_link=url_link
 response.field.url_link=url_link
 response.field.site_path=site_path
 response.field.site_path=site_path
 response.max.title.length=50
 response.max.title.length=50
-response.max.site.path.length=50
+response.max.site.path.length=100
 response.highlight.content_title.enabled=true
 response.highlight.content_title.enabled=true
 
 
 # document index
 # document index

+ 1 - 0
src/main/resources/fess_label.properties

@@ -231,6 +231,7 @@ labels.search_result_last_modified=Last Modified:
 labels.search_result_favorite=Like
 labels.search_result_favorite=Like
 labels.search_result_favorited=Liked
 labels.search_result_favorited=Liked
 labels.search_click_count=Viewed ({0})
 labels.search_click_count=Viewed ({0})
+labels.search_click_views={0} views
 labels.search_result_more=more..
 labels.search_result_more=more..
 labels.search_result_cache=Cache
 labels.search_result_cache=Cache
 labels.search_result_similar=Similar Results ({0})
 labels.search_result_similar=Similar Results ({0})

+ 2 - 1
src/main/resources/fess_label_ja.properties

@@ -217,12 +217,13 @@ labels.search_result_sort_click_count_desc=クリック数 (降順)
 labels.search_result_sort_favorite_count_asc=お気に入り数 (昇順)
 labels.search_result_sort_favorite_count_asc=お気に入り数 (昇順)
 labels.search_result_sort_favorite_count_desc=お気に入り数 (降順)
 labels.search_result_sort_favorite_count_desc=お気に入り数 (降順)
 labels.search_result_sort_multiple=複数
 labels.search_result_sort_multiple=複数
-labels.search_result_size={0} バイト
+labels.search_result_size={0}バイト
 labels.search_result_created=登録日時:
 labels.search_result_created=登録日時:
 labels.search_result_last_modified=最終更新日時:
 labels.search_result_last_modified=最終更新日時:
 labels.search_result_favorite=Like
 labels.search_result_favorite=Like
 labels.search_result_favorited=Liked
 labels.search_result_favorited=Liked
 labels.search_click_count=クリック数 ({0})
 labels.search_click_count=クリック数 ({0})
+labels.search_click_views={0}回閲覧
 labels.search_result_more=詳細..
 labels.search_result_more=詳細..
 labels.search_result_cache=キャッシュ
 labels.search_result_cache=キャッシュ
 labels.search_result_similar=類似結果 ({0})
 labels.search_result_similar=類似結果 ({0})

+ 1 - 0
src/main/webapp/WEB-INF/view/search.jsp

@@ -150,6 +150,7 @@
 	<input type="hidden" id="contextPath" value="${contextPath}" />
 	<input type="hidden" id="contextPath" value="${contextPath}" />
 	<script type="text/javascript"
 	<script type="text/javascript"
 		src="${fe:url('/js/jquery-3.4.1.min.js')}"></script>
 		src="${fe:url('/js/jquery-3.4.1.min.js')}"></script>
+	<script type="text/javascript" src="${fe:url('/js/clipboard.min.js')}"></script>
 	<script type="text/javascript" src="${fe:url('/js/bootstrap.min.js')}"></script>
 	<script type="text/javascript" src="${fe:url('/js/bootstrap.min.js')}"></script>
 	<script type="text/javascript" src="${fe:url('/js/suggestor.js')}"></script>
 	<script type="text/javascript" src="${fe:url('/js/suggestor.js')}"></script>
 	<script type="text/javascript" src="${fe:url('/js/search.js')}"></script>
 	<script type="text/javascript" src="${fe:url('/js/search.js')}"></script>

+ 39 - 63
src/main/webapp/WEB-INF/view/searchResults.jsp

@@ -56,76 +56,52 @@
 					<div class="description">${doc.content_description}</div>
 					<div class="description">${doc.content_description}</div>
 				</div>
 				</div>
 				<div class="site text-truncate">
 				<div class="site text-truncate">
+					<i class="far fa-copy url-copy" data-clipboard-text="${doc.url_link}"></i>
 					<cite>${f:h(doc.site_path)}</cite>
 					<cite>${f:h(doc.site_path)}</cite>
-					<c:if test="${doc.has_cache=='true'}">
-						<small class="d-none d-lg-inline-block"> <la:link
-								href="/cache/?docId=${doc.doc_id}${appendHighlightParams}"
-								class="cache">
-								<la:message key="labels.search_result_cache" />
-							</la:link>
-						</small>
-					</c:if>
-					<c:if test="${doc.similar_docs_count!=null&&doc.similar_docs_count>1}">
-						<small class="d-none d-lg-inline-block"> <la:link
-								href="/search?q=${f:u(q)}&ex_q=${f:u(queryEntry.value)}&sdh=${f:u(fe:sdh(doc.similar_docs_hash))}${fe:facetQuery()}${fe:geoQuery()}">
-								<la:message key="labels.search_result_similar"
-											arg0="${fe:formatFileSize(doc.similar_docs_count-1)}" />
-							</la:link>
-						</small>
-					</c:if>
 				</div>
 				</div>
 				<div class="more">
 				<div class="more">
 					<a href="#result${s.index}"><la:message
 					<a href="#result${s.index}"><la:message
 							key="labels.search_result_more" /></a>
 							key="labels.search_result_more" /></a>
 				</div>
 				</div>
 				<div class="info">
 				<div class="info">
-					<small> <c:if
-							test="${doc.created!=null && doc.created!=''}">
-							<c:set var="hasInfo" value="true" />
-							<la:message key="labels.search_result_created" />
-							<fmt:formatDate value="${fe:parseDate(doc.created)}"
-								type="BOTH" pattern="yyyy-MM-dd HH:mm" />
-						</c:if> <c:if
-							test="${doc.last_modified!=null && doc.last_modified!=''}">
-							<c:if test="${hasInfo}">
-								<div class="d-sm-none"></div>
-								<span class="d-none d-sm-inline">-</span>
-							</c:if>
-							<c:set var="hasInfo" value="true" />
-							<la:message key="labels.search_result_last_modified" />
-							<fmt:formatDate value="${fe:parseDate(doc.last_modified)}"
-								type="BOTH" pattern="yyyy-MM-dd HH:mm" />
-						</c:if> <c:if
-							test="${doc.content_length!=null && doc.content_length!=''}">
-							<c:if test="${hasInfo}">
-								<div class="d-sm-none"></div>
-								<span class="d-none d-sm-inline">-</span>
-							</c:if>
-							<c:set var="hasInfo" value="true" />
-							<la:message key="labels.search_result_size"
-								arg0="${fe:formatFileSize(doc.content_length)}" />
-						</c:if> <c:if test="${searchLogSupport}">
-							<c:if test="${hasInfo}">
-								<div class="d-sm-none"></div>
-								<span class="d-none d-sm-inline">-</span>
-							</c:if>
-							<c:set var="hasInfo" value="true" />
-							<la:message key="labels.search_click_count"
-								arg0="${f:h(doc.click_count)}" />
-						</c:if> <c:if test="${favoriteSupport}">
-							<c:if test="${hasInfo}">
-								<div class="d-sm-none"></div>
-								<span class="d-none d-sm-inline">-</span>
-							</c:if>
-							<c:set var="hasInfo" value="true" />
-							<a href="#${doc.doc_id}" class="favorite"><la:message
-									key="labels.search_result_favorite" />
-								(${f:h(doc.favorite_count)})</a>
-							<span class="favorited"><la:message
-									key="labels.search_result_favorited" /> <span
-								class="favorited-count">(${f:h(doc.favorite_count)})</span></span>
-						</c:if>
-					</small>
+					<fmt:formatDate value="${fe:parseDate(doc.last_modified)}" type="BOTH" pattern="yyyy-MM-dd HH:mm" />
+					<c:if test="${doc.last_modified==null || doc.last_modified==''}">
+						<fmt:formatDate value="${fe:parseDate(doc.created)}" type="BOTH" pattern="yyyy-MM-dd HH:mm" />
+					</c:if>
+					<c:if test="${doc.content_length!=null && doc.content_length!=''}">
+						<div class="d-sm-none"></div>
+						<span class="d-none d-sm-inline">&nbsp;</span>
+						<la:message key="labels.search_result_size"
+							arg0="${fe:formatFileSize(doc.content_length)}" />
+					</c:if>
+					<c:if test="${searchLogSupport && doc.click_count!=null && doc.click_count>0}">
+						<div class="d-sm-none"></div>
+						<span class="d-none d-sm-inline">&nbsp;</span>
+						<la:message key="labels.search_click_views"
+							arg0="${f:h(doc.click_count)}" />
+					</c:if>
+					<c:if test="${doc.has_cache=='true'}">
+						<div class="d-sm-none"></div>
+						<span class="d-none d-sm-inline">&nbsp;</span>
+						<la:link href="/cache/?docId=${doc.doc_id}${appendHighlightParams}"
+								class="cache">
+							<la:message key="labels.search_result_cache" />
+						</la:link>
+					</c:if>
+					<c:if test="${doc.similar_docs_count!=null&&doc.similar_docs_count>1}">
+						<div class="d-sm-none"></div>
+						<span class="d-none d-sm-inline">&nbsp;</span>
+						<la:link href="/search?q=${f:u(q)}&ex_q=${f:u(queryEntry.value)}&sdh=${f:u(fe:sdh(doc.similar_docs_hash))}${fe:facetQuery()}${fe:geoQuery()}">
+							<la:message key="labels.search_result_similar"
+										arg0="${fe:formatFileSize(doc.similar_docs_count-1)}" />
+						</la:link>
+					</c:if>
+					<c:if test="${favoriteSupport}">
+						<div class="d-sm-none"></div>
+						<span class="d-none d-sm-inline">&nbsp;</span>
+						<a href="#${doc.doc_id}" class="favorite"><i class="far fa-star"></i></a>
+						<span class="favorited"><i class="fas fa-star"></i></span>
+					</c:if>
 				</div>
 				</div>
 			</li>
 			</li>
 		</c:forEach>
 		</c:forEach>

+ 17 - 1
src/main/webapp/css/style.css

@@ -128,10 +128,26 @@ legend{
 	display: none;
 	display: none;
 }
 }
 
 
+#result .info {
+	font-size: 80%;
+}
+
+#result .url-copy {
+	color: #007bff;
+}
+
+#result .url-copied {
+	color: #146ebe;
+}
+
 #result .favorited {
 #result .favorited {
 	display: none;
 	display: none;
 }
 }
 
 
+#result .favorited i {
+	color: #fab005;
+}
+
 #result .thumbnail {
 #result .thumbnail {
 	width: 100px;
 	width: 100px;
 	min-height: 30px;
 	min-height: 30px;
@@ -159,4 +175,4 @@ legend{
 		text-overflow: ellipsis;
 		text-overflow: ellipsis;
 		white-space: nowrap;
 		white-space: nowrap;
 	}
 	}
-}
+}

文件差異過大導致無法顯示
+ 6 - 0
src/main/webapp/js/clipboard.min.js


+ 15 - 0
src/main/webapp/js/search.js

@@ -260,4 +260,19 @@ $(function() {
     );
     );
     loadImage(this, $(this).attr("data-src"), IMG_LOADING_MAX);
     loadImage(this, $(this).attr("data-src"), IMG_LOADING_MAX);
   });
   });
+  
+  var clipboard = new ClipboardJS(".url-copy");
+  clipboard.on("success", function(e) {
+    e.trigger.classList.remove("url-copy");
+    e.trigger.classList.remove("far");
+    e.trigger.classList.add("url-copied");
+    e.trigger.classList.add("fas");
+    setTimeout(function(){
+      e.trigger.classList.remove("url-copied");
+      e.trigger.classList.remove("fas");
+      e.trigger.classList.add("url-copy");
+      e.trigger.classList.add("far");
+    },3000);
+    e.clearSelection();
+  });
 });
 });

部分文件因文件數量過多而無法顯示