forked from wallabag/wallabag
Compare commits
18 Commits
1.9.1beta2
...
1.9.1beta3
| Author | SHA1 | Date | |
|---|---|---|---|
| c0d4c895a4 | |||
| 4687c44602 | |||
| c56d1f21e3 | |||
| 22a46267be | |||
| 63fc40ff84 | |||
| 900f2a9160 | |||
| f9c8087f78 | |||
| ddbb2308a3 | |||
| 3a690fad55 | |||
| 12b97d6757 | |||
| f0a819a968 | |||
| d31766300a | |||
| 9730853564 | |||
| 7106983464 | |||
| 2c83940270 | |||
| 251fa4af94 | |||
| 727c35d809 | |||
| 090957fe3e |
@ -323,6 +323,21 @@ class Database {
|
||||
return $entries;
|
||||
}
|
||||
|
||||
public function retrieveAllWithTags($user_id)
|
||||
{
|
||||
$entries = $this->retrieveAll($user_id);
|
||||
$count = count($entries);
|
||||
for ($i = 0; $i < $count; $i++) {
|
||||
$tag_entries = $this->retrieveTagsByEntry($entries[$i]['id']);
|
||||
$tags = [];
|
||||
foreach ($tag_entries as $tag) {
|
||||
$tags[] = $tag[1];
|
||||
}
|
||||
$entries[$i]['tags'] = implode(',', $tags);
|
||||
}
|
||||
return $entries;
|
||||
}
|
||||
|
||||
public function retrieveOneById($id, $user_id)
|
||||
{
|
||||
$entry = NULL;
|
||||
|
||||
@ -278,7 +278,7 @@ class Poche
|
||||
}
|
||||
Tools::logm($msg);
|
||||
}
|
||||
Tools::redirect('?');
|
||||
Tools::redirect();
|
||||
break;
|
||||
case 'toggle_fav' :
|
||||
$this->store->favoriteById($id, $this->user->getId());
|
||||
@ -732,23 +732,45 @@ class Poche
|
||||
$html->load_file($_FILES['file']['tmp_name']);
|
||||
$data = array();
|
||||
$read = 0;
|
||||
foreach (array('ol','ul') as $list) {
|
||||
foreach ($html->find($list) as $ul) {
|
||||
foreach ($ul->find('li') as $li) {
|
||||
$tmpEntry = array();
|
||||
$a = $li->find('a');
|
||||
$tmpEntry['url'] = $a[0]->href;
|
||||
$tmpEntry['tags'] = $a[0]->tags;
|
||||
$tmpEntry['is_read'] = $read;
|
||||
if ($tmpEntry['url']) {
|
||||
$data[] = $tmpEntry;
|
||||
|
||||
if (Tools::get_doctype($html)->innertext == "<!DOCTYPE NETSCAPE-Bookmark-file-1>") {
|
||||
// Firefox-bookmarks HTML
|
||||
foreach (array('DL','ul') as $list) {
|
||||
foreach ($html->find($list) as $ul) {
|
||||
foreach ($ul->find('DT') as $li) {
|
||||
$tmpEntry = array();
|
||||
$a = $li->find('A');
|
||||
$tmpEntry['url'] = $a[0]->href;
|
||||
$tmpEntry['tags'] = $a[0]->tags;
|
||||
$tmpEntry['is_read'] = $read;
|
||||
if ($tmpEntry['url']) {
|
||||
$data[] = $tmpEntry;
|
||||
}
|
||||
}
|
||||
}
|
||||
# the second <ol/ul> is for read links
|
||||
$read = ((sizeof($data) && $read)?0:1);
|
||||
# the second <ol/ul> is for read links
|
||||
$read = ((sizeof($data) && $read)?0:1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// regular HTML
|
||||
foreach (array('ol','ul') as $list) {
|
||||
foreach ($html->find($list) as $ul) {
|
||||
foreach ($ul->find('li') as $li) {
|
||||
$tmpEntry = array();
|
||||
$a = $li->find('a');
|
||||
$tmpEntry['url'] = $a[0]->href;
|
||||
$tmpEntry['tags'] = $a[0]->tags;
|
||||
$tmpEntry['is_read'] = $read;
|
||||
if ($tmpEntry['url']) {
|
||||
$data[] = $tmpEntry;
|
||||
}
|
||||
}
|
||||
# the second <ol/ul> is for read links
|
||||
$read = ((sizeof($data) && $read)?0:1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for readability structure
|
||||
|
||||
@ -766,7 +788,7 @@ class Poche
|
||||
$urlsInserted = array(); //urls of articles inserted
|
||||
foreach($data as $record) {
|
||||
$url = trim(isset($record['article__url']) ? $record['article__url'] : (isset($record['url']) ? $record['url'] : ''));
|
||||
if ($url and !in_array($url, $urlsInserted)) {
|
||||
if (filter_var($url, FILTER_VALIDATE_URL) and !in_array($url, $urlsInserted)) {
|
||||
$title = (isset($record['title']) ? $record['title'] : _('Untitled - Import - ') . '</a> <a href="./?import">' . _('click to finish import') . '</a><a>');
|
||||
$body = (isset($record['content']) ? $record['content'] : '');
|
||||
$isRead = (isset($record['is_read']) ? intval($record['is_read']) : (isset($record['archive']) ? intval($record['archive']) : 0));
|
||||
@ -874,7 +896,7 @@ class Poche
|
||||
$filename = "wallabag-export-".$this->user->getId()."-".date("Y-m-d").".json";
|
||||
header('Content-Disposition: attachment; filename='.$filename);
|
||||
|
||||
$entries = $this->store->retrieveAll($this->user->getId());
|
||||
$entries = $this->store->retrieveAllWithTags($this->user->getId());
|
||||
echo $this->tpl->render('export.twig', array(
|
||||
'export' => Tools::renderJson($entries),
|
||||
));
|
||||
|
||||
@ -141,7 +141,7 @@ class Routing
|
||||
$pdf->producePDF();
|
||||
} elseif (isset($_GET['import'])) {
|
||||
$import = $this->wallabag->import();
|
||||
$tplVars = array_merge($this->vars, $import);
|
||||
$this->vars = array_merge($this->vars, $import);
|
||||
} elseif (isset($_GET['empty-cache'])) {
|
||||
Tools::emptyCache();
|
||||
} elseif (isset($_GET['export'])) {
|
||||
|
||||
@ -420,4 +420,23 @@ final class Tools
|
||||
return str_replace('+', '', $token);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns the doctype for an HTML document (used for Mozilla Bookmarks)
|
||||
* @param simple_html_dom $doc
|
||||
* @return doctype $el
|
||||
*
|
||||
*/
|
||||
|
||||
public static function get_doctype($doc)
|
||||
{
|
||||
$els = $doc->find('unknown');
|
||||
|
||||
foreach ($els as $e => $el)
|
||||
if ($el->parent()->tag == 'root')
|
||||
return $el;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -36,8 +36,6 @@ if (isset($_SERVER['HTTP_COOKIE'])) {
|
||||
if (isset($_SESSION['poche_user'])) {
|
||||
unset($_SESSION['poche_user']);
|
||||
}
|
||||
session_destroy();
|
||||
|
||||
|
||||
if (isset($_GET['clean'])) {
|
||||
if (is_dir('install')){
|
||||
|
||||
Binary file not shown.
@ -106,8 +106,11 @@ msgstr "Read the documentation"
|
||||
msgid "download the extension"
|
||||
msgstr "Download the extension"
|
||||
|
||||
msgid "Firefox Add-On"
|
||||
msgstr "Firefox Add-On"
|
||||
msgid "Standard Firefox Add-On"
|
||||
msgstr "Standard Firefox Add-On"
|
||||
|
||||
msgid "Mozilla Services (Social API) Extension"
|
||||
msgstr "Mozilla Services (Social API) Extension"
|
||||
|
||||
msgid "Chrome Extension"
|
||||
msgstr "Chrome Extension"
|
||||
|
||||
Binary file not shown.
@ -200,8 +200,11 @@ msgstr "lisez la documentation"
|
||||
msgid "download the extension"
|
||||
msgstr "téléchargez l'extension"
|
||||
|
||||
msgid "Firefox Add-On"
|
||||
msgstr "Add-On Firefox"
|
||||
msgid "Standard Firefox Add-On"
|
||||
msgstr "Add-On Firefox classique"
|
||||
|
||||
msgid "Mozilla Services (Social API) Extension"
|
||||
msgstr "Extension Mozilla Services (Social API)"
|
||||
|
||||
msgid "Chrome Extension"
|
||||
msgstr "Extension Chrome"
|
||||
@ -948,7 +951,7 @@ msgstr ""
|
||||
|
||||
msgid "The new user %1$s has been sent an email at %2$s. You may have to check spam folder."
|
||||
msgstr ""
|
||||
"Un email a été envoyé au nouvel utiliateur %1$s à l'adresse %2$s. Il peut être nécessaire de vérifier "
|
||||
"Un email a été envoyé au nouvel utilisateur %1$s à l'adresse %2$s. Il peut être nécessaire de vérifier "
|
||||
"le dossier des spams."
|
||||
|
||||
msgid "A problem has been encountered while sending the confirmation email"
|
||||
|
||||
BIN
themes/_global/img/appicon/firefox-service-icon-16.png
Normal file
BIN
themes/_global/img/appicon/firefox-service-icon-16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 337 B |
BIN
themes/_global/img/appicon/firefox-service-icon-32.png
Normal file
BIN
themes/_global/img/appicon/firefox-service-icon-32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 675 B |
BIN
themes/_global/img/appicon/firefox-service-icon-64.png
Normal file
BIN
themes/_global/img/appicon/firefox-service-icon-64.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
@ -1,14 +1,29 @@
|
||||
/**
|
||||
* @desc Navigate with Keyboard from an article to another on an article's page
|
||||
* @param string leftURL - URL of the article on the left
|
||||
* @param string rightURL - URL of the article on the right
|
||||
*/
|
||||
|
||||
function navigateKeyboard(leftURL, rightURL) {
|
||||
window.addEventListener("keydown", function (event) {
|
||||
var key = event.which || event.keyCode; // event.keyCode is used for IE8 and earlier versions
|
||||
switch (key) {
|
||||
case 37:
|
||||
goLeft(leftURL);
|
||||
goLeft(leftURL); // left arrow
|
||||
break;
|
||||
case 72:
|
||||
goLeft(leftURL); // h letter (vim style)
|
||||
break;
|
||||
|
||||
case 39:
|
||||
goRight(rightURL);
|
||||
goRight(rightURL); // right arrow
|
||||
break;
|
||||
case 76:
|
||||
goRight(rightURL); // l letter (vim style)
|
||||
break;
|
||||
case 8:
|
||||
window.history.back();
|
||||
|
||||
}
|
||||
|
||||
}, false);
|
||||
@ -25,3 +40,115 @@ function goRight(rightURL) {
|
||||
window.location = window.location.origin + window.location.pathname + rightURL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @desc Do actions with Keyboard on an article's page
|
||||
* @param number id - ID of the current article
|
||||
*/
|
||||
|
||||
function actionArticle(id) {
|
||||
window.addEventListener("keydown", function (event) {
|
||||
var key = event.which || event.keyCode; // event.keyCode is used for IE8 and earlier versions
|
||||
switch (key) {
|
||||
case 46:
|
||||
deleteArticle(id); // delete key
|
||||
break;
|
||||
case 68:
|
||||
deleteArticle(id); // d key letter
|
||||
break;
|
||||
case 70:
|
||||
favoriteArticle(id); // f key letter
|
||||
break;
|
||||
case 77:
|
||||
markReadArticle(id); // m key letter
|
||||
break;
|
||||
}
|
||||
|
||||
}, false);
|
||||
}
|
||||
|
||||
function deleteArticle(id) {
|
||||
if (id) {
|
||||
window.location = window.location.origin + window.location.pathname + '?action=delete&id=' + id;
|
||||
}
|
||||
}
|
||||
|
||||
function favoriteArticle(id) {
|
||||
if (id) {
|
||||
window.location = window.location.origin + window.location.pathname + '?action=toggle_fav&id=' + id;
|
||||
}
|
||||
}
|
||||
|
||||
function markReadArticle(id) {
|
||||
if (id) {
|
||||
window.location = window.location.origin + window.location.pathname + '?action=toggle_archive&id=' + id;
|
||||
}
|
||||
}
|
||||
|
||||
function homeNavigation() {
|
||||
selectedArticle = $('.entrie:first');
|
||||
console.log("selected first article");
|
||||
window.addEventListener("keydown", function (event) {
|
||||
var key = event.which || event.keyCode; // event.keyCode is used for IE8 and earlier versions
|
||||
switch (key) {
|
||||
case 37: // left arrow
|
||||
selectedArticle = goSelectPrev(selectedArticle,1);
|
||||
break;
|
||||
case 72: // h letter (vim style)
|
||||
selectedArticle = goSelectPrev(selectedArticle,1);
|
||||
break;
|
||||
|
||||
case 39: // right arrow
|
||||
selectedArticle = goSelectNext(selectedArticle,1);
|
||||
break;
|
||||
case 76: // l letter (vim style)
|
||||
selectedArticle = goSelectNext(selectedArticle,1);
|
||||
break;
|
||||
case 13: // enter into article
|
||||
enterArticle(selectedArticle);
|
||||
break;
|
||||
case 74: // j letter key
|
||||
selectedArticle = goSelectNext(selectedArticle,3);
|
||||
break;
|
||||
case 40: // down arrow
|
||||
selectedArticle = goSelectNext(selectedArticle,3);
|
||||
break;
|
||||
case 75: // k letter key
|
||||
selectedArticle = goSelectNext(selectedArticle,3);
|
||||
break;
|
||||
case 38: // up arrow
|
||||
selectedArticle = goSelectNext(selectedArticle,3);
|
||||
break;
|
||||
}
|
||||
|
||||
}, false);
|
||||
}
|
||||
|
||||
function goSelectNext(selectedArticle,number) {
|
||||
if (selectedArticle.next().length) {
|
||||
selectedArticle.removeClass("eselected");
|
||||
selectedArticle = selectedArticle.next();
|
||||
selectedArticle.addClass("eselected");
|
||||
console.log("Changed selected to next");
|
||||
console.log("selectedArticle is now " + selectedArticle.attr("id"));
|
||||
}
|
||||
return selectedArticle;
|
||||
}
|
||||
|
||||
|
||||
function goSelectPrev(selectedArticle,number) {
|
||||
if (selectedArticle.prev().length) {
|
||||
selectedArticle.removeClass("eselected");
|
||||
selectedArticle = selectedArticle.prev();
|
||||
selectedArticle.addClass("eselected");
|
||||
console.log("Changed selected to previous");
|
||||
console.log("selectedArticle is now " + selectedArticle.attr("id"));
|
||||
|
||||
}
|
||||
return selectedArticle;
|
||||
}
|
||||
|
||||
function enterArticle(selectedArticle) {
|
||||
window.location = selectedArticle.find('a:first').attr('href');
|
||||
}
|
||||
@ -39,3 +39,33 @@
|
||||
<script src="{{ poche_url }}themes/_global/js/popupForm.js"></script>
|
||||
<script src="{{ poche_url }}themes/_global/js/keyboard.js"></script>
|
||||
<script src="{{ poche_url }}themes/{{theme}}/js/closeMessage.js"></script>
|
||||
|
||||
<!-- Enable Firefox Social Services
|
||||
script put there because of the call to poche_url -->
|
||||
|
||||
<script>
|
||||
var baseurl = "{{ poche_url }}";
|
||||
console.log(baseurl);
|
||||
var data = {
|
||||
|
||||
"name": "wallabag",
|
||||
"iconURL": baseurl + "/themes/_global/img/appicon/firefox-service-icon-16.png",
|
||||
"icon32URL": baseurl + "/themes/_global/img/appicon/firefox-service-icon-32.png",
|
||||
"icon64URL": baseurl + "/themes/_global/img/appicon/firefox-service-icon-64.png",
|
||||
|
||||
"shareURL": baseurl + "/index.php?action=add&plainurl=%{url}",
|
||||
|
||||
"description": "wallabag Extension for Firefox - The (soon to become) best way to save articles, videos and more",
|
||||
"author": "Thomas Citharel",
|
||||
"homepageURL": "http://doc.wallabag.org/en/User/save_your_first_article.html#firefox-social-api-service",
|
||||
"origin": "https://wallabag.org",
|
||||
"postActivationURL": "http://doc.wallabag.org/en/User/save_your_first_article.html#firefox-social-api-service",
|
||||
|
||||
"version": "0.1"
|
||||
};
|
||||
function activateSocialFeature(node) {
|
||||
var event = new CustomEvent("ActivateSocialFeature");
|
||||
node.setAttribute("data-service", JSON.stringify(data));
|
||||
node.dispatchEvent(event);
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -16,7 +16,8 @@
|
||||
</p>
|
||||
<h3>{% trans "Browser Addons" %}</h3>
|
||||
<ul>
|
||||
<li><a href="https://addons.mozilla.org/firefox/addon/wallabag/" target="_blank">{% trans "Firefox Add-On" %}</a></li>
|
||||
<li><a href="https://addons.mozilla.org/firefox/addon/wallabag/" target="_blank">{% trans "Standard Firefox Add-On" %}</a></li>
|
||||
<li><button onclick="activateSocialFeature(this)">{% trans "Mozilla Services (Social API) Extension" %}</button></li>
|
||||
<li><a href="https://chrome.google.com/webstore/detail/wallabag/bepdcjnnkglfjehplaogpoonpffbdcdj" target="_blank">{% trans "Chrome Extension" %}</a></li>
|
||||
</ul>
|
||||
<h3>{% trans "Mobile Apps" %}</h3>
|
||||
|
||||
@ -399,19 +399,19 @@ footer a {
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.entrie:hover {
|
||||
.entrie:hover, .eselected {
|
||||
box-shadow: 0 3px 10px rgba(0,0,0,1);
|
||||
}
|
||||
|
||||
.entrie:hover:after {
|
||||
.entrie:hover:after, .eselected:after {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.entrie:hover:before {
|
||||
.entrie:hover:before, .eselected:before {
|
||||
bottom: 2.4em;
|
||||
}
|
||||
|
||||
.entrie:hover h2 a {
|
||||
.entrie:hover h2 a, .eselected h2 a {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
@ -421,9 +421,9 @@ footer a {
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.entrie h2:after {
|
||||
content: none;
|
||||
}
|
||||
.entrie h2:after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
|
||||
.entrie h2 a {
|
||||
@ -437,16 +437,6 @@ footer a {
|
||||
-o-transition: all 0.5s ease;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
/*
|
||||
.entrie h2 a:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
}
|
||||
*/
|
||||
|
||||
.entrie p {
|
||||
color: #666;
|
||||
@ -454,12 +444,8 @@ footer a {
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.entrie h2 a:first-letter {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.entrie:hover .tools {
|
||||
bottom: 0;
|
||||
.entrie h2 a:first-letter {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.entrie .tools {
|
||||
@ -477,20 +463,25 @@ footer a {
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.entrie .tools a {
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
padding: 0.4em;
|
||||
}
|
||||
.entrie:hover .tools, .eselected .tools {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.entrie .tools a:hover {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.entrie .tools li {
|
||||
display: inline-block;
|
||||
}
|
||||
.entrie .tools a {
|
||||
color: #666;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
.entrie .tools a:hover {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.entrie .tools li {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.entrie:nth-child(3n+1) {
|
||||
margin-left: 0;
|
||||
|
||||
@ -107,4 +107,8 @@
|
||||
{% if constant('PDF') == 1 %}<a title="{% trans "Download the articles from this category in a pdf file" %}" href="./?pdf&method=category&value={{ view }}">{% trans "Download as PDF" %}</a>{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<script type="text/javascript">
|
||||
homeNavigation();
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@ -111,6 +111,9 @@
|
||||
// Use left and right arrow to navigate on with keyboard
|
||||
navigateKeyboard('?view=view&id={{ navigate.nextid|e }}','?view=view&id={{ navigate.previousid|e }}');
|
||||
|
||||
// use keyboard to do actions
|
||||
actionArticle('{{ entry.id|e }}');
|
||||
|
||||
// swipe to right or left on mobile to navigate
|
||||
$('article').on("swiperight", function(){
|
||||
goLeft('?view=view&id={{ navigate.nextid|e }}');
|
||||
|
||||
@ -36,3 +36,33 @@
|
||||
<script src="{{ poche_url }}themes/_global/js/saveLink.js"></script>
|
||||
<script src="{{ poche_url }}themes/_global/js/keyboard.js"></script>
|
||||
<script src="{{ poche_url }}themes/_global/js/popupForm.js"></script>
|
||||
|
||||
<!-- Enable Firefox Social Services
|
||||
script put there because of the call to poche_url -->
|
||||
|
||||
<script>
|
||||
var baseurl = "{{ poche_url }}";
|
||||
console.log(baseurl);
|
||||
var data = {
|
||||
|
||||
"name": "wallabag",
|
||||
"iconURL": baseurl + "/themes/_global/img/appicon/firefox-service-icon-16.png",
|
||||
"icon32URL": baseurl + "/themes/_global/img/appicon/firefox-service-icon-32.png",
|
||||
"icon64URL": baseurl + "/themes/_global/img/appicon/firefox-service-icon-64.png",
|
||||
|
||||
"shareURL": baseurl + "/index.php?action=add&plainurl=%{url}",
|
||||
|
||||
"description": "wallabag Extension for Firefox - The (soon to become) best way to save articles, videos and more",
|
||||
"author": "Thomas Citharel",
|
||||
"homepageURL": "http://doc.wallabag.org/en/User/save_your_first_article.html#firefox-social-api-service",
|
||||
"origin": "https://wallabag.org",
|
||||
"postActivationURL": "http://doc.wallabag.org/en/User/save_your_first_article.html#firefox-social-api-service",
|
||||
|
||||
"version": "0.1"
|
||||
};
|
||||
function activateSocialFeature(node) {
|
||||
var event = new CustomEvent("ActivateSocialFeature");
|
||||
node.setAttribute("data-service", JSON.stringify(data));
|
||||
node.dispatchEvent(event);
|
||||
}
|
||||
</script>
|
||||
@ -2,11 +2,13 @@
|
||||
<!--
|
||||
$(document).ready(function() {
|
||||
$("body").css("cursor", "wait");
|
||||
$("#content").css("display", "none");
|
||||
|
||||
setTimeout(function(){
|
||||
window.location = './?import';
|
||||
}, {{ import.delay }} );
|
||||
});
|
||||
|
||||
//-->
|
||||
</script>
|
||||
<div class="messages warning">
|
||||
|
||||
@ -16,7 +16,8 @@
|
||||
</p>
|
||||
<h3>Browser Plugins</h3>
|
||||
<ul>
|
||||
<li><a href="https://addons.mozilla.org/firefox/addon/wallabag/" target="_blank">{% trans "Firefox Add-On" %}</a></li>
|
||||
<li><a href="https://addons.mozilla.org/firefox/addon/wallabag/" target="_blank">{% trans "Standard Firefox Add-On" %}</a></li>
|
||||
<li><button onclick="activateSocialFeature(this)">{% trans "Mozilla Services (Social API) Extension" %}</button></li>
|
||||
<li><a href="https://chrome.google.com/webstore/detail/wallabag/bepdcjnnkglfjehplaogpoonpffbdcdj" target="_blank">{% trans "Chrome Extension" %}</a></li>
|
||||
</ul>
|
||||
<h3>Mobile Apps</h3>
|
||||
|
||||
Reference in New Issue
Block a user