はてなリンク記法を展開
by
yanbe
2018-02-23 [2018/02/23 09:23:15]
はてなリンク記法をa要素に展開します。つまり [http://b.hatena.ne.jp/:title=hoge] 等を <a href="http://b.hatena.ne.jp/">hoge</a> に変換します。
@@ -3,7 +3,7 @@
* @description はてなリンク記法をa要素に展開します。つまり [http://b.hatena.ne.jp/:title=hoge] 等を <a href="http://b.hatena.ne.jp/">hoge</a> に変換します。
* @include http://blog.hatena.ne.jp/*
* @license MIT License
- * @require
+ * @require
*/
function getHatenaLinkNotationOnCursor(textarea) {
@@ -107,26 +107,28 @@
textarea.value = textarea.value.replace(notation, replaceHTML);
}
-var textarea = document.getElementsByTagName('textarea')[0];
-var notation = getHatenaLinkNotationOnCursor(textarea);
-if (notation) {
+function main() {
+ var textarea = document.getElementsByTagName('textarea')[0];
+ var notation = getHatenaLinkNotationOnCursor(textarea);
+ if (!notation) return;
var result = parseHatenaLinkNotation(notation);
- if (!result['url']) return;
if (typeof(result['title']) == 'string') {
expandHatenaLinkNotation(result);
} else if (location.hostname == 'blog.hatena.ne.jp') {
var syntax = '[' + result['url'] + ':title]';
- $.ajax({ url: 'http://blog.hatena.ne.jp/api/external/json?url='+encodeURIComponent('http://d.hatena.ne.jp/api/syntax?syntax=' + encodeURIComponent(syntax)) }).done(function(json) {
- var div = document.createElement('div');
- div.innerHTML = json[syntax];
- result['title'] = div.firstChild.innerHTML;
+ $.ajax({
+ url: 'http://blog.hatena.ne.jp/api/external/json?url='+encodeURIComponent('http://d.hatena.ne.jp/api/syntax?syntax=' + encodeURIComponent(syntax))
+ }).done(function(json) {
+ var div = document.createElement('div');
+ div.innerHTML = json[syntax];
+ result['title'] = div.firstChild.innerHTML;
}).fail(function() {
- result['title'] = 'ここにタイトルを入力';
+ result['title'] = 'ここにタイトルを入力';
}).always(function () {
- expandHatenaLinkNotation(result);
+ expandHatenaLinkNotation(result);
});
} else {
- result['title'] = typeof(result['title']) == 'boolean' || result['embed'] ? 'ここにタイトルを入力' : result['url'];
- expandHatenaLinkNotation(result);
+ result['title'] = typeof(result['title']) == 'boolean' || result['embed'] ? 'ここにタイトルを入力' : result['url'];
+ expandHatenaLinkNotation(result);
}
}
/*
* @title はてなリンク記法を展開
* @description はてなリンク記法をa要素に展開します。つまり [http://b.hatena.ne.jp/:title=hoge] 等を <a href="http://b.hatena.ne.jp/">hoge</a> に変換します。
* @include http://blog.hatena.ne.jp/*
* @license MIT License
* @require
*/
function getHatenaLinkNotationOnCursor(textarea) {
var text = textarea.value;
var caret = textarea.selectionStart;
var start = text.lastIndexOf('[', caret);
var end = text.indexOf(']', caret-1);
var notation = text.substring(start, end+1);
return notation.indexOf('\n') != -1 ? undefined : notation;
}
function parseHatenaLinkNotation(notation) {
var result = {};
var m_url = notation.match(/https?:\/\/[^:\]]+/);
if (m_url) {
result['url'] = m_url[0];
}
var m_title = notation.match(/:title(?:=([^:\]]+))?/); // [http://b.hatena.ne.jp/:title=hoge]
if (m_title) {
result['title'] = m_title[1] ? m_title[1] : true;
}
var m_bookmark = notation.match(/:bookmark]/); // [http://b.hatena.ne.jp/:title=hoge:bookmark]
if (m_bookmark) {
result['bookmark'] = true;
}
var m_embed = notation.match(/:embed(:cite)?]$/); // [http://b.hatena.ne.jp/:embed:cite]
if (m_embed) {
result['embed'] = true;
if (m_embed[1]) {
result['cite'] = true;
}
}
return result;
}
function expandSimpleHatenaLinkNotation(result) {
var a = document.createElement('a');
a.setAttribute('data-snf-link', 'keep');
a.href = result['url'];
if (result['title']) {
if (typeof(result['title']) == 'string') {
a.innerHTML = result['title'];
} else {
a.innerHTML = result['title'];
}
} else {
a.innerHTML = result['url'];
}
var frag = document.createDocumentFragment();
frag.appendChild(a);
if (result['bookmark']) {
var bookmarkLink = document.createElement('a');
bookmarkLink.href = 'http://b.hatena.ne.jp/entry/' + result['url'];
bookmarkLink.className = 'http-bookmark';
var bookmarkCount = document.createElement('img');
bookmarkCount.src = '//b.hatena.ne.jp/entry/image/' + result['url'];
bookmarkCount.className = 'http-bookmark';
bookmarkLink.appendChild(bookmarkCount);
frag.appendChild(bookmarkLink);
}
return frag;
}
function expandEmbedHatenaLinkNotation(result) {
var iframe = document.createElement('iframe');
iframe.setAttribute('data-snf-link', 'keep');
iframe.src = 'https://hatenablog-parts.com/embed?url=' + encodeURIComponent(result['url']);
iframe.title = result['title'];
iframe.className = 'embed-card embed-blogcard';
iframe.scrolling = 'no';
iframe.style.display = 'block';
iframe.style.width = '100%';
iframe.style.height = '190px';
iframe.style.maxWidth = '500px';
iframe.style.margin = '10px 0px';
var frag = document.createDocumentFragment();
frag.appendChild(iframe);
if (result['cite']) {
var cite = document.createElement('cite');
cite.className = 'hatena-citation';
var citeLink = document.createElement('a');
citeLink.href = result['url'];
citeLink.innerHTML = result['title'];
cite.appendChild(citeLink);
frag.appendChild(cite);
}
return frag;
}
function expandHatenaLinkNotation(result) {
var expanded = result['embed'] ? expandEmbedHatenaLinkNotation(result) : expandSimpleHatenaLinkNotation(result);
var comment = document.createComment(notation);
var div = document.createElement('div');
div.appendChild(comment);
div.appendChild(expanded);
var replaceHTML = div.innerHTML;
textarea.value = textarea.value.replace(notation, replaceHTML);
}
function main() {
var textarea = document.getElementsByTagName('textarea')[0];
var notation = getHatenaLinkNotationOnCursor(textarea);
if (!notation) return;
var result = parseHatenaLinkNotation(notation);
if (typeof(result['title']) == 'string') {
expandHatenaLinkNotation(result);
} else if (location.hostname == 'blog.hatena.ne.jp') {
var syntax = '[' + result['url'] + ':title]';
$.ajax({
url: 'http://blog.hatena.ne.jp/api/external/json?url='+encodeURIComponent('http://d.hatena.ne.jp/api/syntax?syntax=' + encodeURIComponent(syntax))
}).done(function(json) {
var div = document.createElement('div');
div.innerHTML = json[syntax];
result['title'] = div.firstChild.innerHTML;
}).fail(function() {
result['title'] = 'ここにタイトルを入力';
}).always(function () {
expandHatenaLinkNotation(result);
});
} else {
result['title'] = typeof(result['title']) == 'boolean' || result['embed'] ? 'ここにタイトルを入力' : result['url'];
expandHatenaLinkNotation(result);
}
}
- Permalink
- このページへの個別リンクです。
- RAW
- 書かれたコードへの直接のリンクです。
- Packed
- 文字列が圧縮された書かれたコードへのリンクです。
- Userscript
- Greasemonkey 等で利用する場合の .user.js へのリンクです。
- Loader
- @require やソースコードが長い場合に多段ロードする Loader コミのコードへのリンクです。
- Metadata
- コード中にコメントで @xxx と書かれたメタデータの JSON です。