diff --git a/package.json b/package.json
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"ansi_up": "^4.0.3",
"bootstrap": "^4.3.1",
"bootstrap-year-calendar-bs4": "^1.0.0",
+ "chosen-js": "^1.8.7",
"clipboard": "^2.0.4",
"core-js": "^3.1.4",
"d3": "^5.9.7",
diff --git a/swh/web/assets/config/webpack.config.development.js b/swh/web/assets/config/webpack.config.development.js
--- a/swh/web/assets/config/webpack.config.development.js
+++ b/swh/web/assets/config/webpack.config.development.js
@@ -302,6 +302,15 @@
outputPath: 'fonts/'
}
}]
+ }, {
+ test: /\.png$/,
+ use: [{
+ loader: 'file-loader',
+ options: {
+ name: '[name].[ext]',
+ outputPath: 'img/thirdParty/'
+ }
+ }]
}
],
// tell webpack to not parse minified pdfjs file to speedup build process
diff --git a/swh/web/assets/src/bundles/browse/content.css b/swh/web/assets/src/bundles/browse/content.css
--- a/swh/web/assets/src/bundles/browse/content.css
+++ b/swh/web/assets/src/bundles/browse/content.css
@@ -21,3 +21,23 @@
.swh-content svg {
max-width: 100%;
}
+
+.chosen-single {
+ height: 31px !important;
+ border-radius: 0px !important;
+ background-color: #f4f4f4 !important;
+ color: #444 !important;
+ border-color: #ddd !important;
+ background-image:none !important;
+ -webkit-box-shadow: none !important;
+ -moz-box-shadow: none !important;
+ box-shadow: none !important;
+ font-weight: 400 !important;
+ font-size: 14px !important;
+ padding-top: 4px !important;
+ padding-bottom: 4px !important;
+}
+
+.chosen-single:hover {
+ background-color: #e7e7e7 !important;
+}
diff --git a/swh/web/assets/src/bundles/browse/origin-search.js b/swh/web/assets/src/bundles/browse/origin-search.js
--- a/swh/web/assets/src/bundles/browse/origin-search.js
+++ b/swh/web/assets/src/bundles/browse/origin-search.js
@@ -43,7 +43,7 @@
table.append(tableRow);
// get async latest visit snapshot and update visit status icon
let latestSnapshotUrl = Urls.api_1_origin_visit_latest(origin.url);
- latestSnapshotUrl += "?require_snapshot=true";
+ latestSnapshotUrl += '?require_snapshot=true';
fetch(latestSnapshotUrl)
.then(response => response.json())
.then(data => {
diff --git a/swh/web/assets/src/bundles/vendors/index.js b/swh/web/assets/src/bundles/vendors/index.js
--- a/swh/web/assets/src/bundles/vendors/index.js
+++ b/swh/web/assets/src/bundles/vendors/index.js
@@ -31,6 +31,12 @@
import 'datatables.net-responsive-bs4/css/responsive.bootstrap4.css';
import './datatables.css';
+// chosen-js
+import 'chosen-js';
+import 'chosen-js/chosen.min.css';
+import 'chosen-js/chosen-sprite.png';
+import 'chosen-js/chosen-sprite@2x.png';
+
// iframe-resizer
import 'iframe-resizer';
diff --git a/swh/web/browse/views/content.py b/swh/web/browse/views/content.py
--- a/swh/web/browse/views/content.py
+++ b/swh/web/browse/views/content.py
@@ -14,7 +14,7 @@
from swh.model.hashutil import hash_to_hex
-from swh.web.common import query, service
+from swh.web.common import query, service, highlightjs
from swh.web.common.utils import (
reverse, gen_path_info, swh_object_icons
)
@@ -181,6 +181,8 @@
raise_if_unavailable=False)
origin_type = request.GET.get('origin_type', None)
origin_url = request.GET.get('origin_url', None)
+ selected_language = request.GET.get('language', None)
+
if not origin_url:
origin_url = request.GET.get('origin', None)
snapshot_context = None
@@ -218,6 +220,12 @@
language = content_display_data['language']
mimetype = content_display_data['mimetype']
+ # Override language with selected language
+ if selected_language is not None:
+ language = selected_language
+
+ language_select = highlightjs._hljs_languages
+
root_dir = None
filename = None
path_info = None
@@ -303,6 +311,7 @@
'max_content_size': content_display_max_size,
'mimetype': mimetype,
'language': language,
+ 'language_select': language_select,
'breadcrumbs': breadcrumbs,
'top_right_link': {
'url': content_raw_url,
diff --git a/swh/web/templates/includes/content-display.html b/swh/web/templates/includes/content-display.html
--- a/swh/web/templates/includes/content-display.html
+++ b/swh/web/templates/includes/content-display.html
@@ -53,7 +53,25 @@
{% elif swh_object_metadata.filename and swh_object_metadata.filename|default:""|slice:"-5:" == "ipynb" %}
swh.webapp.renderNotebook({{ top_right_link.url|jsonify }}, '.swh-ipynb');
{% elif content %}
+ let codeContainer = $('code');
+ let content = codeContainer.text();
+
swh.webapp.highlightCode();
+
+ function updateLanguage(language) {
+ codeContainer.text(content);
+ codeContainer.removeClass();
+ codeContainer.addClass(language);
+
+ let urlParams = new URLSearchParams(window.location.search);
+ urlParams.set('language', language);
+
+ const newUrl = window.location.pathname + '?' + urlParams.toString() + window.location.hash;
+ window.history.replaceState('', document.title, newUrl);
+
+ swh.webapp.highlightCode();
+ }
+
{% endif %}
{% endif %}
diff --git a/swh/web/templates/includes/top-navigation.html b/swh/web/templates/includes/top-navigation.html
--- a/swh/web/templates/includes/top-navigation.html
+++ b/swh/web/templates/includes/top-navigation.html
@@ -94,6 +94,14 @@
{{ top_right_link.text }}
{% endif %}
+ {% if language_select %}
+
+ {% endif %}
{% if show_actions_menu %}