4 * @copyright 2009 FeedBlog Project (http://sourceforge.jp/projects/feedblog/)
5 * @author Kureha Hisame (http://lunardial.sakura.ne.jp/) & Yui Naruse (http://airemix.com/)
9 // Feex XMLの<content>要素で、<br>を使用しているか?
10 var inputValidateMode = 1;
11 // 出力時に<content>要素に<br>を付加するか否かを格納する変数
12 var outputValidateMode = 1;
13 // ログのリストが書かれたXMLのファイルパスを記入してください
14 var logXmlUrl = "./xml/loglist.xml";
22 // feedblogの設置アドレスを格納する変数
30 function applyChange(){
31 feedInfo = applyFeedinfo();
32 pageAddr = feedInfo.alternate;
34 if (document.getElementById("entry_title").value == "" || document.getElementById("entry_stdin").value == "") {
35 if (confirm("タイトルか記事が空白です!FeedBlogでの表示時にエラーが出ますがよろしいですか?") == false) {
41 var entry = new Object();
42 var dateRfc3339 = getDate();
43 entry.id = pageAddr + "?" + dateRfc3339;
44 entry.title = document.getElementById("entry_title").value;
46 entry.published = dateRfc3339;
47 entry.updated = dateRfc3339;
48 entry.link = pageAddr + "#" + entry.id;
49 entry.content = document.getElementById("entry_stdin").value.replace(/\r\n/g, "\n");
50 entryList.unshift(entry);
53 refleshEntrylistBox();
55 // 更新後、選択されている項目を、先刻追加した日記に移動する
56 document.getElementById("logBox").selectedIndex = 1;
60 entryList[editIndex].title = document.getElementById("entry_title").value;
61 entryList[editIndex].updated = getDate();
62 entryList[editIndex].content = document.getElementById("entry_stdin").value.replace(/\r\n/g, "\n");
64 document.getElementById("logBox").options[editIndex + 1].text = entryList[editIndex].title;
67 document.getElementById("stdout").value = toXml(feedInfo, entryList);
69 // プレビューエリアにHTMLを表示します
70 document.getElementById("previewArea").innerHTML = entryList[editIndex].content.replace(/\n/g, "<br>");
75 * @param {int} index entryListから削除される記事のインデックス
77 function removeEntry(index){
79 entryList.splice(editIndex, 1);
80 refleshEntrylistBox();
83 document.getElementById("stdout").value = ""
84 document.getElementById("entry_title").value = "";
85 document.getElementById("entry_stdin").value = "";
88 var prevIndex = document.getElementById("logBox").selectedIndex - 1;
89 entryList.splice(editIndex, 1);
90 refleshEntrylistBox();
91 document.getElementById("logBox").selectedIndex = prevIndex;
92 editIndex = editIndex - 1;
94 entryLoader(editIndex);
98 document.getElementById("previewArea").innerHTML = "";
104 function allRemoveEntry(){
108 refleshEntrylistBox();
110 document.getElementById("stdout").value = ""
111 document.getElementById("entry_title").value = "";
112 document.getElementById("entry_stdin").value = "";
116 * 全DOMが使用可能になり次第、自動的に呼ばれる関数
119 if (outputValidateMode == 1) {
120 document.getElementById("addContentBr").checked = true;
123 document.getElementById("addContentBr").checked = false;
130 * ログファイル選択用のコンボボックスをid名:logSelecterに生成します
132 function logXMLLoader(){
137 success: function(xmlData){
138 var separateTag = xmlData.getElementsByTagName("file");
139 var fileList = new Array(separateTag.length);
142 // 読み込んだ要素をStoreに格納して表示
144 boxBuffer.push("<form name='logform'><select name='logbox' style='width: " + comboWidth + "px' onchange='xmlLoader(this.options[this.selectedIndex].value)'>");
145 for (var i = 0; i < separateTag.length; i++) {
147 initUrl = separateTag[i].getElementsByTagName("path")[0].firstChild.nodeValue;
149 boxBuffer.push("<option value='" + separateTag[i].getElementsByTagName("path")[0].firstChild.nodeValue + "'/>" + separateTag[i].getElementsByTagName("display")[0].firstChild.nodeValue + " (" + separateTag[i].getElementsByTagName("path")[0].firstChild.nodeValue + ")" + "</option>");
151 boxBuffer.push("</select></form>");
154 document.getElementById("logSelecter").innerHTML = boxBuffer.join("");
164 * URLを指定し、指定されたFeedXmlを読み込み、解析を行います
165 * @param {String} url
167 function xmlLoader(url){
169 var loader = new jQuery.ajax({
172 success: analyzeTargetXml,
178 * 引数に存在するXMLデータを解析し、画面に反映します
179 * @param {Object} xmlData
181 function analyzeTargetXml(xmlData){
182 var rootTag = xmlData.getElementsByTagName("feed");
183 var entryTag = xmlData.getElementsByTagName("entry");
189 feedInfo = new FeedInfo(rootTag[0]);
190 for (var i = 0; i < entryTag.length; i++) {
191 entryList.push(new Entry(entryTag[i]));
194 feedinfoLoader(feedInfo);
195 pageAddr = feedInfo.alternate;
197 refleshEntrylistBox();
198 document.getElementById("entry_title").value = "";
199 document.getElementById("entry_stdin").value = "";
200 document.getElementById("stdout").value = "";
204 document.getElementById("previewArea").innerHTML = "";
208 * feedInfo変数の内容をHTMLに反映します
209 * @param {FeedInfo} finfo 反映するfeedInfo変数
211 function feedinfoLoader(finfo){
212 document.getElementById("feed_title").value = finfo.title;
213 document.getElementById("feed_subtitle").value = finfo.subtitle;
214 document.getElementById("feed_self").value = finfo.self;
215 document.getElementById("feed_alternate").value = finfo.alternate;
216 document.getElementById("feed_id").value = finfo.id;
217 document.getElementById("feed_rights").value = finfo.rights;
218 document.getElementById("feed_authorname").value = finfo.authorname;
219 document.getElementById("feed_authoremail").value = finfo.authoremail;
223 * HTMLの内容をFeedInfoに変換します
225 function applyFeedinfo(){
226 var finfo = new Object();
227 finfo.title = document.getElementById("feed_title").value;
228 finfo.subtitle = document.getElementById("feed_subtitle").value;
229 finfo.self = document.getElementById("feed_self").value;
230 finfo.alternate = document.getElementById("feed_alternate").value;
231 finfo.id = document.getElementById("feed_id").value;
232 finfo.rights = document.getElementById("feed_rights").value;
233 finfo.authorname = document.getElementById("feed_authorname").value;
234 finfo.authoremail = document.getElementById("feed_authoremail").value;
240 * 指定したEntryList上のインデックスの記事をロードします
243 function entryLoader(index){
245 document.getElementById("entry_title").value = "";
246 document.getElementById("entry_stdin").value = "";
250 document.getElementById("entry_title").value = entryList[index].title;
251 document.getElementById("entry_stdin").value = entryList[index].content;
256 document.getElementById("previewArea").innerHTML = "";
260 * 記事一覧の情報を表示するセレクトボックスにentryListの情報を反映させます
262 function refleshEntrylistBox(){
263 var stringBuffer = [];
264 stringBuffer.push("<form name='logform'><select id='logBox' style='width: " + comboWidth + "px' onchange='entryLoader(this.options[this.selectedIndex].value)'>");
265 stringBuffer.push("<option value='-1'>新規作成</option>");
266 for (var i = 0; i < entryList.length; i++) {
267 stringBuffer.push("<option value='" + i + "'/>" + entryList[i].title + "</option>");
269 stringBuffer.push("</select></form>");
271 document.getElementById("entrySelect").innerHTML = stringBuffer.join("");
276 * @param {Object} obj
278 function FeedInfo(obj){
279 this.title = $("title:first", obj).text();
280 this.subtitle = $("subtitle:first", obj).text();
281 this.self = $("link[rel=self]", obj).attr("href");
282 this.alternate = $("link[rel=alternate]", obj).attr("href");
283 this.updated = $("updated:first", obj).text();
284 this.id = $("id:first", obj).text();
285 this.rights = $("rights:first", obj).text();
286 this.authorname = $("author>name", obj).text();
287 this.authoremail = $("author>email", obj).text();
292 * @param {Object} obj entry 要素の DOM オブジェクト
295 this.id = $("id:first", obj).text();
296 this.title = $("title:first", obj).text();
297 this.summary = $("summary:first", obj).text();
298 this.published = $("published:first", obj).text();
299 this.updated = $("updated:first", obj).text();
300 this.link = $("link:first", obj).attr("href");
301 this.content = $("content:first", obj).text();
303 if (inputValidateMode == 1) {
304 this.content = this.content.replace(/[\r\n]|\r\n/g, "");
305 this.content = this.content.replace(/<br[ \/]*>/ig, "\n");
306 this.content = this.content.replace(/^[ \t]*/mg, "");
311 * グローバル変数からXMLを生成し、返却します
312 * @param {FeedInfo} finfo
313 * @param {Entry[]} elist
315 function toXml(finfo, elist){
316 var stringBuffer = [];
318 stringBuffer.push('<?xml version="1.0" encoding="utf-8"?>');
319 stringBuffer.push('<feed xml:lang="ja-jp" xmlns="http://www.w3.org/2005/Atom">');
320 stringBuffer.push('');
322 stringBuffer.push('<title type="text">' + finfo.title + '</title>');
323 stringBuffer.push('<subtitle type="text">' + finfo.subtitle + '</subtitle>');
324 stringBuffer.push('<link rel="self" type="application/atom+xml" href="' + finfo.self + '" />');
325 stringBuffer.push('<link rel="alternate" type="text/html" href="' + finfo.alternate + '" />');
326 stringBuffer.push('<updated>' + getDate() + '</updated>');
327 stringBuffer.push('<id>' + finfo.id + '</id>');
328 stringBuffer.push('<rights type="text">' + finfo.rights + '</rights>');
329 stringBuffer.push('<author>');
330 stringBuffer.push(' <name>' + finfo.authorname + '</name>');
331 stringBuffer.push(' <email>' + finfo.authoremail + '</email>');
332 stringBuffer.push('</author>');
333 stringBuffer.push('');
335 for (var i = 0; i < elist.length; i++) {
337 if (document.getElementById("addContentBr").checked) {
338 temp_content = xmlAttrContentEscape(convertContent(elist[i].content));
341 temp_content = xmlAttrContentEscape(elist[i].content);
344 stringBuffer.push('<entry>');
345 stringBuffer.push('<id>' + elist[i].id + '</id>');
346 stringBuffer.push('<title>' + elist[i].title + '</title>');
347 stringBuffer.push('<summary>' + elist[i].summary + '</summary>');
348 stringBuffer.push('<published>' + elist[i].published + '</published>');
349 stringBuffer.push('<updated>' + elist[i].updated + '</updated>');
350 stringBuffer.push('<link href="' + elist[i].link + '" />');
351 stringBuffer.push('<content type="html">' + temp_content + '</content>');
352 stringBuffer.push('</entry>');
353 stringBuffer.push('');
356 stringBuffer.push('</feed>');
358 return stringBuffer.join("\n");
362 * <content>要素の変換を行います
363 * @param {String} content
365 function convertContent(content){
366 if (document.getElementById("addContentBr").checked) {
367 content = content.replace(/[\n\r]|\r\n/g, "<br>\n");
370 content = content.replace(/<br>/ig, "\n");
378 * @param {String} str エスケープを行う文字列
380 function xmlAttrContentEscape(str){
381 return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/^[ ]+/mg, " ").replace(/^[\t]+/mg, "");
386 * @param {String} str 逆エスケープを行う文字列
388 function xmlAttrContentUnescape(str){
389 return str.replace(/^[\t]+/mg, "").replace(/^[ ]+/mg, " ").replace(/"/g, '"').replace(/>/g, ">").replace(/</g, "<").replace(/&/g, "&");
393 * jQueryでのパネル開閉を制御します
394 * @param {String} id 開閉するオブジェクトのid
396 function closePanel(id){
397 $("#" + id).slideToggle();
403 function showError(){
404 alert("XMLファイルのローディング中にエラーが発生しました!");
411 var dNow = new Date();
412 var sYear = dNow.getFullYear();
413 var sMonth = dNow.getMonth() + 1;
414 var sDate = dNow.getDate();
415 var sHour = dNow.getHours();
416 var sMinute = dNow.getMinutes();
417 var sSecond = dNow.getSeconds();
421 sMonth = "0" + sMonth;
427 sMinute = "0" + sMinute;
429 sSecond = "0" + sSecond;
431 return sYear + "-" + sMonth + "-" + sDate + "T" + sHour + ":" + sMinute + ":" + sSecond + "+09:00";