Як написати свій букмарклет?
Букмарклет (bookmark) – це слово створене поєднанням слів bookmark (закладка) і applet (application (застосунок) + зменшувальний суфікс -let). Таким чином правильним перекладом bookmarklet було б “закластуночок” (чи “застокладочка”), але ви цього краще не кажіть Юрку Зеленому. Але я відхиляюсь. Отож, букмарклет, це маленька програма що міститься в закладці.
Як її туди помістили? Ну, виявляється браузери крім протоколів http, ftp, ітп, розуміють такий протокол як javascript. І коли отримують посилання з цим протоколом, при кліку по ньому не змінюють сторінку, а виконують його href
як код JavaScript. Щоб побачити приклад простого букмарклету, створіть документ bookmarklet.htm
, і помістіть в нього такий код:
<html> <head><meta charset="utf-8" /></head> <body> <a href="javascript: alert('Привіт!') ">Мій букмарклет</a> </body> </html>
Якщо відкрити його в браузері, ви побачите чисту сторінку з єдиним посиланням Мій букмарклет, яке при кліку буде показувати повідомлення “Привіт!”. Якщо перетягнути це посилання на панель закладок в браузері, то тепер ви зможете в будь-який момент отримати привітання на будь-якій сторінці яку дивитесь, досить лише натиснути букмарклет.
Але це не дуже корисний букмарклет. Щоб він робив щось корисніше, досить замінити код в рядку 5, на якийсь корисніший.
Наприклад є такий сайт – lib.rus.ec. Вони хоч мають домен еквадору – але москалі, і коли відкрити їх сайт, то вискакує повідомлення, яке блокує доступ до сторінки, і просить грошей за чужі книжки. Я переконаний що в цьому випадку дозволяється використати принцип “грабуй награбоване”, і додати в букмарклет такий код:
document.getElementsByClassName('lsp-overlay')[0].remove()
І тоді при кліку по букмарклету це вікно пропадатиме. Клас, правда? (Не забудьте забрати виклик alert()
який ми написали там раніше)
Але давайте зробимо ще щось складніше і корисніше. Давайте зробимо букмарклет, який оформлює посилання на веб-сторінку в форматі вікіпедії cite web, і дає її нам в якомусь вікні. Це такий шаблон, який гарно оформлює посилання, але заповнювати його руками – ще та морока.
Для букмарклетів є кілька правил. Їх код все таки міститься всередині атрибуту елемента HTML, і повинен відповідати стандартам цієї мови. Наприклад всі подвійні лапки """
(ну ви зрозуміли), повинні бути заміненими HTML-кодом "
. Крім того, перехід на новий рядок вважається еквівалентним пробілу, тому однорядкові коментарі можливі лише в кінці скрипта:
alert('Це вискочить'); // alert('Це не вискочить бо закоментовано'); alert('Це теж не вискочить бо коментар продовжується');
Ну і тому що ввесь скрипт здається браузеру написаним на одному рядку – бажано шанувати крапки з комою.
Якщо ми хочемо написати великий букмарклет, який можливо використовуватиме jQuery, та інші бібліотеки, нам захочеться їх якось підвантажувати. Але, віднедавна в адміністраторів серверів з’явилась нова можливість збільшувати безпеку вводячи обмеження на джерела з яких на сайт завантажуються ресурси – Content Security Policy, тому такі букмарклети можуть працювати не всюди. Можливо доведеться все переписати, мініфікувати і запакувати, але на всяк випадок, ось вам код підвантаження скрипта:
(function () { var script = document.createElement('script'); script.src='https://gist.githubusercontent.com/bunyk/6ae97e5c3de490cfb4a1/raw/b7fcfde5c40314262893761418a6a25dd6ed0ce8/cite_web.js'; document.body.appendChild(script); }());
Подібним чином вже з того скрипта ми можемо підвантажити jQuery та наприклад CSS.
Я тут наковбасив трохи JavaScript, який можливо не на всіх сайтах працює, і не всі дані статті витягує, але на моєму блозі він дає щось подібне до цього:
Щоб поставити собі такий, перенесіть оце посилання в закладки: “{{cite web|…“, а тоді в контекстному меню закладки натисніть “Властивості”, чи “Редагувати”, і замініть текст поля “Location” на
javascript:(function () { var script = document.createElement('script'); script.src='https://gist.githubusercontent.com/bunyk/6ae97e5c3de490cfb4a1/raw/3102c3e285c6e24a9aed98d1bc7f0b7abeda20fc/cite_web.js'; document.body.appendChild(script); }());
Ось код:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.log('Почато завантаження букмарклета'); | |
(function(){ | |
var get_meta_property = function(name) { | |
var element = document.querySelector('meta[property="' + name + '"]'); | |
return element && element.getAttribute("content") || ''; | |
}; | |
var get_article_time = function() { | |
var text = get_meta_property('article:modified_time'); | |
if(text) { | |
return format_date(new Date(text)); | |
} else { | |
return ''; | |
}; | |
}; | |
var get_author = function() { | |
return document.querySelector('a[rel=author] [itemprop=name]').innerHTML; | |
}; | |
/** Now we can create new site handlers that will reuse functionality of the default site handler. */ | |
function SiteHandler(params) { | |
this.get_title = params.get_title || function () { return document.title; }; | |
this.get_website = params.get_website || function () { return get_meta_property('og:site_name'); }; | |
this.get_publisher = params.get_publisher || function () { return get_meta_property('article:publisher'); }; | |
this.get_date = params.get_date || function () { return get_article_time(); }; | |
this.get_author = params.get_author || function () { return get_author(); }; | |
} | |
var siteHandlers = { | |
'na.mil.gov.ua' : new SiteHandler ({ | |
get_website : function () { return 'Народна Армія'; }, | |
get_publisher : function () { return 'Міністерство Оборони України'; } | |
}) | |
}; | |
var get_template_text = function () { | |
var domain = window.location.hostname; | |
var handler = ( siteHandlers[domain] || new SiteHandler({}) ); | |
return '<ref name="">{{cite web\n' + | |
'|url = ' + window.location.href + '\n' + | |
'|title = ' + handler.get_title() + '\n' + | |
'|author = ' + handler.get_author() + '\n' + | |
'|date = ' + handler.get_date() + '\n' + | |
'|website = ' + handler.get_website() + '\n' + | |
'|publisher = ' + handler.get_publisher() + '\n' + | |
'|accessdate = ' + format_date(new Date()) + '\n' + | |
'}}</ref>' | |
.replace('|', '|') // escape template delimiters | |
.replace('\n|', '\n|') // but undo delimiters at the beginning of line | |
.replace('&', '&') // escape html | |
.replace('<', '<'); | |
}; | |
var init = function () { | |
console.log('Очікування завантаження сторінки'); | |
jQuery(function($){ | |
console.log('Створюємо вікно'); | |
$(css_style).appendTo("head"); | |
var panel = $('<div class="cite_web_panel"></div>'); | |
var header = $('<div class="header">Ctrl+C щоб скопіювати</div>'); | |
var close = $('<a href="#">Закрити</span>').click(function() { | |
panel.remove(); | |
}); | |
var content = $('<textarea>' + get_template_text() + '</textarea>'); | |
header.append(close); | |
panel.append(header); | |
panel.append(content); | |
$('body').append(panel); | |
SelectText(content[0]); | |
wikiBookmarkletDone(); // remove style with wait cursor | |
console.log('Готово!') | |
}); | |
}; | |
var SelectText = function (element) { | |
// http://stackoverflow.com/a/987376/816449 | |
var doc = document, range, selection; | |
if (doc.body.createTextRange) { | |
range = document.body.createTextRange(); | |
range.moveToElementText(element); | |
range.select(); | |
} else if (window.getSelection) { | |
selection = window.getSelection(); | |
range = document.createRange(); | |
range.selectNodeContents(element); | |
selection.removeAllRanges(); | |
selection.addRange(range); | |
} | |
}; | |
var monthNames = [ | |
"січня", "лютого", | |
"березня", "квітня", "травня", | |
"червня", "липня", "серпня", | |
"вересня", "жовтня", "листопада", | |
"грудня" | |
]; | |
var format_date = function(date) { | |
var day = date.getDate(); | |
var monthIndex = date.getMonth(); | |
var year = date.getFullYear(); | |
return day + ' ' + monthNames[monthIndex] + ' ' + year; | |
}; | |
console.log('Очікуємо завантаження jQuery'); | |
if (window.jQuery === undefined) { | |
var script = document.createElement("script"); | |
script.src = "https://code.jquery.com/jquery-1.12.0.min.js"; | |
script.onload = init; | |
document.body.appendChild(script); | |
} else { | |
init(); | |
}; | |
var css_style = '' + | |
'<style type="text/css">' + | |
'.cite_web_panel {' + | |
' position: fixed;' + | |
' left: 20%;' + | |
' top: 10%;' + | |
' width: 60%;' + | |
' height: 80%;' + | |
' overflow: auto;' + | |
' border: 1px solid black;' + | |
' background: white;' + | |
' z-index: 9999;' + | |
'}' + | |
'.cite_web_panel .header {' + | |
' width: 100%;' + | |
' background: lightblue;' + | |
' border: 1px solid black;' + | |
' box-sizing: border-box;' + | |
' padding: 2px;' + | |
' font-family: sans-serif;' + | |
' font-weight: bold;' + | |
'}' + | |
'.cite_web_panel .header a {' + | |
' float: right;' + | |
'}' + | |
'.cite_web_panel textarea {' + | |
' width: 100%;' + | |
' margin: 0px;' + | |
' padding: 15px;' + | |
' box-sizing: border-box;' + | |
' font-family: monospace;' + | |
'}' + | |
'</style>'; | |
})(); |
Букмарклети дійсно корисна штука, користуюсь деякими для seo. Ось їх приклади – http://www.searchengines.ru/articles/69_poleznykh_bu.html , http://www.lucky-seo.com/services/bookmarklets
Ivan
11 Березня, 2016 at 10:58
та, букмарклети цікава штука, не знав, що є букмарклет який пише посилання в вікі. В мене особисто недавно була якась біда з посиланнями. Пробував перекладати одну статтю, а посилання скопіювати, але таке враження, що при копіюванні ті посилання якось пошкодились, а я не до кінця знаю, як їх виправити – і в тій статті пише “Помилка цитування: Некоректний теґ ; назва «PRL-20160211» визначена кілька разів з різним вмістом Помилка цитування: Некоректний теґ ; назва «PRL-20160211» визначена кілька разів з різним вмістом”
patlatus
12 Березня, 2016 at 15:48
Не було такого букмарклета, я ото вчора його зробив. 🙂
Щодо помилки, то коли ми визначаємо зноску на зразок
<ref name="a">[посилаємо на A]</ref>
, то далі можемо вставляти її лише за іменем<ref name="a" />
. А в описаному випадку хтось намагається описати два різні посилання для одного name.bunyk
12 Березня, 2016 at 15:53
Кинь посилання на статтю, то легше показати ніж пояснити. 🙂
bunyk
12 Березня, 2016 at 15:54
https://uk.wikipedia.org/wiki/Відкриття_гравітаційних_хвиль
patlatus
12 Березня, 2016 at 17:25
Охохох, що це було? Візуальний редактор?
Ось я виправив перше посилання, всі інші треба так само: https://uk.wikipedia.org/w/index.php?title=%D0%92%D1%96%D0%B4%D0%BA%D1%80%D0%B8%D1%82%D1%82%D1%8F_%D0%B3%D1%80%D0%B0%D0%B2%D1%96%D1%82%D0%B0%D1%86%D1%96%D0%B9%D0%BD%D0%B8%D1%85_%D1%85%D0%B2%D0%B8%D0%BB%D1%8C&type=revision&diff=17755201&oldid=17755163
bunyk
12 Березня, 2016 at 17:39
Так, я пробував користуватись візуальним редактором, хоча спочатку вперше мені було його легко знайти, а вже в наступні рази не так просто.
patlatus
12 Березня, 2016 at 18:13
Там внизу в шаблоні “{{reflist|refs=” Вже описані всі зноски як {{cite journal| ….}}, тому далі треба лише посилатись на їх опис отак:
bunyk
12 Березня, 2016 at 17:43
гм, а нема якогось бота або не можна написати якогось бота, який би таке міг зробити?
patlatus
12 Березня, 2016 at 18:14
Можна спробувати. Але надалі краще зразу писати правильну вікірозмітку, бо патрульних на всіх не стане. 😉
bunyk
12 Березня, 2016 at 20:00
До речі, якщо відкрити консоль браузера на сторінці редагування статті, то в змінній
document.editform.wpTextbox1.value
буде вміст редактора, і його можна змінювати засобами JavaScript. Якщо не я один тут програміст і знаю JavaScript, то може з’являться ще якісь корисні букмарклети? 😉bunyk
12 Березня, 2016 at 20:32
Отако: https://uk.wikipedia.org/w/index.php?title=%D0%9A%D0%BE%D1%80%D0%B8%D1%81%D1%82%D1%83%D0%B2%D0%B0%D1%87%3ABunyk%2Fwikifixer.js&type=revision&diff=17756723&oldid=17756123
bunyk
12 Березня, 2016 at 22:42
о, прикольно
дякую. а як його самостійно заюзати? хоча вже потреби нема, ти вже все пофіксав
patlatus
12 Березня, 2016 at 23:49
гм. тепер я помітив, що раніше у статті в кожному посиланні була назва статті чи не в кожному, але принаймні в одному з них була, наприклад, ‘ Naeye, Robert (11 February 2016). Gravitational Wave Detection Heralds New Era of Science. Sky and Telescope. Процитовано 11 February 2016. ‘ a тепер пише просто Naeye, Robert
patlatus
12 Березня, 2016 at 23:53
Ну то треба руками довиправляти. Посилання – це ж головне що є в статті. І якщо їх правильно робити – можна зекономити мало не 10 кб тексту на 7 джерелах.
bunyk
13 Березня, 2016 at 01:03
[…] ще щойно подумав що мій букмарклет cite web, при застосуванні на сайті Google Books повинен був би […]
Знову повертаючись до університету | Блоґ одного кібера
13 Березня, 2016 at 04:55
Можливо той букмарклет для cite web міг би запитувати у користувача ім’я автора і все інше в одній формі з деякими полями вже заповненими. Тільки це мало б бути не модальне вікно.
harmyder
13 Березня, 2016 at 18:17
Там стоїть content editable, тобто можна дописати прямо в тексті. А не модальне це яке?
Думаю я з цим проектом продовжу, бо бачу що не одному мені воно може знадобитись. 🙂
bunyk
13 Березня, 2016 at 19:20
може у вебі такого немає, та з моїх давніх запасів знань модальне – це таке, що головне вікно стає не доступним поки ти це не закриєш.
harmyder
17 Березня, 2016 at 19:22
Твоя маленька цукерка для cite-web дуже корисна, коли треба накидати нового на ВП:ППВ 🙂 Тільки дату створення воно майже ніколи не визначає. Чого так?
Vira Motorko
27 Вересня, 2016 at 11:21
Бо воно працює лише на сайтах о підтримують Open Graph Protocol (http://ogp.me/), а саме містять тег meta property=”article:modified_time”. А на яких найчастіше треба дату визначати? Може додати код який її знаходить?
bunyk
27 Вересня, 2016 at 17:02
Всілякі новинні сайти. (Якщо твоя ласка, то погортай ВП:ППВ).
Vira Motorko
29 Вересня, 2016 at 14:43