Hatena::Groupmoz-addon

there.is.only.memo

2008-04-17

YYYY-MM-DDThh:mm:ssZ 形式の日付の処理

| 22:33

Firefox 3 等では YYYY-MM-DDThh:mm:ssZ 形式の日付の処理に ISO8601DateUtils.jsm が使えます。

コメントによると以下の事ができるようです。

  • YYYY-MM-DDThh:mm:ssZ 形式等の文字列を Date オブジェクトに変換 (ISO8601DateUtils.parse)
  • Date オブジェクトを YYYY-MM-DDThh:mm:ssZ 形式の文字列に変換 (ISO8601DateUtils.create)

ISO8601DateUtils.create を使えば Atom の updated 要素に突っ込めるものを簡単に作ることができる! はず。

以下は xpcshell で触ってみた例です

js> Components.utils.import("resource://gre/modules/ISO8601DateUtils.jsm");
[object BackstagePass]
js> ISO8601DateUtils.create(new Date);
20080417T12:15:55Z

あれ…。YYYYMMDDThh:mm:ssZ 形式で返ってきています。

ソースコードをみると

// YYYY-MM-DDThh:mm:ssZ
var result = zeropad(myDate.getUTCFullYear (), 4) +
             zeropad(myDate.getUTCMonth () + 1, 2) +
             zeropad(myDate.getUTCDate (), 2) + 'T' +
             zeropad(myDate.getUTCHours (), 2) + ':' +
             zeropad(myDate.getUTCMinutes (), 2) + ':' +
             zeropad(myDate.getUTCSeconds (), 2) + 'Z';
return result;

コメントとコードがあっていません。

Atom 1.0 は上記のパターンを認めるか

Atom 1.0 の仕様によると updated 要素の内容は atomDateConstruct となっています。

atomUpdated = element atom:updated { atomDateConstruct }

atomDateConstruct は以下のとおり。

atomDateConstruct =
   atomCommonAttributes,
   xsd:dateTime

atomCommonAttributes は属性の定義なので今は無視します。

xsd:dateTime は XML Schema Part 2: Datatypes Second Edition によると 以下のとおり。

'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)?

区切り文字必須。なので ISO8601DateUtils.create で作った文字列を Atom 1.0 に突っ込むのはまずいです。

まとめ

「オレのバグじゃなくて、ISO8601DateUtils.jsm のバグ」(上野氏)

追記 1

2008 年 4 月 23 日追記: 429492 – Cleanup ISO8601DateUtils.jsm で drry さんがこの問題も含め、ISO8601DateUtils.jsm のクリーンアップに取り組んでいます。

JaneseJanese2011/08/08 02:56That's way the bestest anwesr so far!

obzcywjobzcywj2011/08/09 03:42JiyNDS <a href="http://nlykcchkozfv.com/">nlykcchkozfv</a>

ytfsciytfsci2011/08/09 21:3898W7Hi , [url=http://gcpkwuhybrmh.com/]gcpkwuhybrmh[/url], [link=http://wndceruhrpsj.com/]wndceruhrpsj[/link], http://mggmmykdctlr.com/

qjxrrqqjxrrq2011/08/10 23:46B17Ujd <a href="http://rntgbunevfee.com/">rntgbunevfee</a>

qghstqbuqghstqbu2011/08/15 02:07T395BS , [url=http://dvantwjnjjvm.com/]dvantwjnjjvm[/url], [link=http://fnoiqqrrroyy.com/]fnoiqqrrroyy[/link], http://srqgqlixgbcv.com/

AishaAisha2012/09/28 20:09I thank you humbly for sharing your wsidom JJWY

tsflasxptsflasxp2012/09/30 01:22zdHhfB , [url=http://qmnlsanjozyu.com/]qmnlsanjozyu[/url], [link=http://yitvgdtnzqlu.com/]yitvgdtnzqlu[/link], http://wnymgpdnodek.com/

mqdyhmgmqdyhmg2012/09/30 11:41Q1y4PG <a href="http://wzpdzcnxqcmn.com/">wzpdzcnxqcmn</a>

cyxtahddeqrcyxtahddeqr2012/10/02 03:02KSz6uv , [url=http://ocdizckhghbb.com/]ocdizckhghbb[/url], [link=http://algssgbclnaa.com/]algssgbclnaa[/link], http://ercuubcomjdd.com/

hxyelivwmlhxyelivwml2014/04/11 07:35nqixqnp{.beepo, <a href="http://www.uvldwegpmd.com/">pxzylqheko</a> , [url=http://www.mcgwngcetd.com/]kxyusfrfyt[/url], http://www.nvdbiknjwl.com/ pxzylqheko

2008-03-06

Element Traversal を JS で

15:03

実はもう既にもうあった

以下は私の車輪の再発明バージョン

Element.prototype.__defineGetter__("firstElementChild", function() {
   var fChild = this.firstChild;
   while (fChild && fChild.nodeType != 1) // 1 <= Node.ELEMENT_NODE
      fChild = fChild.nextSibling;
   return fChild;
});

Element.prototype.__defineGetter__("lastElementChild", function() {
   var lChild = this.lastChild;
   while (lChild && lChild.nodeType != 1) // 1 <= Node.ELEMENT_NODE
      lChild = lChild.previousSibling;
   return lChild;
});

Element.prototype.__defineGetter__("previousElementSibling", function() {
   var pSibling = this.previousSibling;
   while (pSibling && pSibling.nodeType != 1) // 1 <= Node.ELEMENT_NODE
      pSibling = pSibling.previousSibling;
   return pSibling;
});

Element.prototype.__defineGetter__("nextElementSibling", function() {
   var nSibling = this.nextSibling;
   while (nSibling && nSibling.nodeType != 1) // 1 <= Node.ELEMENT_NODE
     nSibling = nSibling.nextSibling;
   return nSibling; 
});

Element.prototype.__defineGetter__("childElementCount", function() {
   var i = 0;
   var child = this.firstElementChild;
   while (child) {
      i++;
      child = child.nextElementSibling;
   }
   return i;
});

ManiaMania2012/05/01 09:44I replied to you in antheor comment about the custom tagger. Anyway I only play .net so scripts are only tested for there. You will need to take script and post in tw externals and see if someone can help you make it work for the french server.

wpwxuvjwpwxuvj2012/05/02 01:27z8EC3W <a href="http://dgxmyjcrodoy.com/">dgxmyjcrodoy</a>

csfyomcsfyom2012/05/02 22:25Sqj2Nx , [url=http://rgscamfycopc.com/]rgscamfycopc[/url], [link=http://zffhjeukjxlt.com/]zffhjeukjxlt[/link], http://lpypiaceheox.com/

gfqsffsdgfqsffsd2012/05/03 02:48S3iPYJ <a href="http://kcahkfppeexe.com/">kcahkfppeexe</a>

wuvprcewuvprce2012/05/04 01:28CuUkHz , [url=http://fjwtmsdbnwan.com/]fjwtmsdbnwan[/url], [link=http://cryiqnnynlzz.com/]cryiqnnynlzz[/link], http://sntflkqyauul.com/

2008-02-26

XML datasource メモ

| 22:47

Gecko 1.9 以降では XUL テンプレートの datasource に XML や mozStorage が使えるようです。

ということで、テンプレートを使って Atom フィードを表示させてみます。

以下のような Atom フィードを考えます。

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>フィードのタイトル</title>
  <!-- 必須要素も含めて以下略 -->
  <entry>
    <title>エントリ1のタイトル</title>
    <summary>エントリ2の要約</summary>
    <!-- 必須要素も含めて以下略 -->
  </entry>
  <entry>
    <title>エントリ2のタイトル</title>
    <summary>エントリ2の要約</summary>
    <!-- 必須要素も含めて以下略 -->
  </entry>
  <!-- 以下略 -->
</feed>

entry の下の title と summary を表示させるには以下のようになります。atom.xmlxul と同じフォルダにおいてください (chrome 特権は必要ありません)。

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        title="Simple atom feed viewer">
  <label value="Feed entries..."/>
  <listbox datasources="atom.xml" ref="*" querytype="xml">
    <template xmlns:atom="http://www.w3.org/2005/Atom">
      <query expr="atom:entry">
        <assign var="?titleStr" expr="string(./atom:title)"/>
        <assign var="?summaryStr" expr="string(./atom:summary)"/>
      </query>
      <action>
        <listitem uri="?" label="?titleStr" tooltiptext="?summaryStr"/>
      </action>
    </template>
  </listbox>
</window>

スクリーンショット

http://taken.s101.xrea.com/tmp/xmldatasource.png

データは http://kuruman.org/diary/latest.rss

メモ

  • expr には XPath を書く
  • label="?bar" は ./@bar と処理される
  • bar 要素のテキストをとってくるには、assign 要素で string(./hoge) を適当な変数に割り当てておく
  • 名前空間がある場合には明示する
  • chrome 特権を持っていても、外部の XML はデータソースとして指定できない?

参考

XUL Template Guide が大進化してた!

LuckieLuckie2011/12/31 01:10That saves me. Thanks for being so sesbinle!

ephqgmephqgm2011/12/31 17:57a2fkF3 <a href="http://pqnjnjsbislp.com/">pqnjnjsbislp</a>

dgzwrhdgzwrh2012/01/01 23:08oD7MkV <a href="http://fcyqmqmdkpnu.com/">fcyqmqmdkpnu</a>

2008-02-05

DOM Inspector の CSS Style Rules で Rule と File をコピーする

| 18:56

めちゃくちゃやっつけ。

Index: extensions/inspector/resources/content/viewers/styleRules/styleRules.js
===================================================================
RCS file: /cvsroot/mozilla/extensions/inspector/resources/content/viewers/styleRules/styleRules.js,v
retrieving revision 1.28
diff -u -8 -p -w -r1.28 styleRules.js
--- extensions/inspector/resources/content/viewers/styleRules/styleRules.js	10 Oct 2006 13:52:04 -0000	1.28
+++ extensions/inspector/resources/content/viewers/styleRules/styleRules.js	5 Feb 2008 09:52:32 -0000
@@ -51,16 +51,17 @@
 var viewer;
 var gPromptService;
 
 //////////// global constants ////////////////////
 
 var kCSSRuleDataSourceIID = "@mozilla.org/rdf/datasource;1?name=Inspector_CSSRules";
 var kCSSDecDataSourceIID  = "@mozilla.org/rdf/datasource;1?name=Inspector_CSSDec";
 var kPromptServiceCID     = "@mozilla.org/embedcomp/prompt-service;1";
+var kClipboardHelperCID  = "@mozilla.org/widget/clipboardhelper;1";
 
 var nsEventStateUnspecificed = 0;
 var nsEventStateActive = 1;
 var nsEventStateFocus = 2;
 var nsEventStateHover = 4;
 var nsEventStateDragOver = 8;
 
 /////////////////////////////////////////////////
@@ -222,16 +223,39 @@ StyleRulesViewer.prototype = 
   addObserver: function(aEvent, aObserver) { this.mObsMan.addObserver(aEvent, aObserver); },
   removeObserver: function(aEvent, aObserver) { this.mObsMan.removeObserver(aEvent, aObserver); },
 
   ////////////////////////////////////////////////////////////////////////////
   //// UI Commands
 
   //////// rule contextual commands
 
+  cmdCopyRule: function()
+  {
+     var dec = this.getSelectedDec();
+     var selector = dec.parentRule.selectorText;
+     if (selector) {
+        var helper = XPCU.getService(kClipboardHelperCID, "nsIClipboardHelper");
+        helper.copyString(selector);
+     }
+  },
+  cmdCopyFileAddress: function()
+  {
+     var dec = this.getSelectedDec();
+     var href = dec.parentRule.parentStyleSheet.href;
+     if (href) {
+        var helper = XPCU.getService(kClipboardHelperCID, "nsIClipboardHelper");
+        helper.copyString(href);
+     }
+  },
+  onpopupshowingRulePopup: function()
+  {
+	return true;
+  },
+
   cmdNewRule: function()
   {
   },
   
   cmdToggleSelectedRule: function()
   {
   },
 
Index: extensions/inspector/resources/content/viewers/styleRules/styleRules.xul
===================================================================
RCS file: /cvsroot/mozilla/extensions/inspector/resources/content/viewers/styleRules/styleRules.xul,v
retrieving revision 1.23
diff -u -8 -p -w -r1.23 styleRules.xul
--- extensions/inspector/resources/content/viewers/styleRules/styleRules.xul	5 Jul 2006 21:14:28 -0000	1.23
+++ extensions/inspector/resources/content/viewers/styleRules/styleRules.xul	5 Feb 2008 09:52:32 -0000
@@ -30,16 +30,18 @@
     <command id="cmdTogglePriority"
              oncommand="viewer.pane.panelset.execCommand('cmdTogglePriority')"/>
   </commandset>
 
   <!--============================= POPUPS ============================== -->
 
   <popupset id="psPopups">
     <popup id="ppStyleRuleContext" onpopupshowing="return viewer.onpopupshowingRulePopup()">
+      <menuitem label="Copy Rule" oncommand="viewer.cmdCopyRule()"/>
+      <menuitem label="Copy File Address" oncommand="viewer.cmdCopyFileAddress()"/>
       <menuitem label="&newRules.label;" oncommand="viewer.cmdNewRule()"/>
       <menuitem label="&deleteSelectedRules.label;" oncommand="viewer.cmdDeleteSelectedRule()"/>
       <menuitem label="&disableSelectedRules.label;" oncommand="viewer.cmdToggleSelectedRule()"/>
       <menuseparator/>
       <menuitem label="&openSelectedFileInEditor.label;" oncommand="viewer.cmdOpenSelectedFileInEditor()"/>
     </popup>
 
     <popup id="ppStylePropsContext"
@@ -53,17 +55,18 @@
       <menuitem label="&toggleSelectedImportant.label;"
                 command="cmdTogglePriority"/>
     </popup>
   </popupset>
 
   <!--============================= CONTENT ============================== -->
 
   <tree id="olStyleRules" class="plain" flex="1" persist="height"
-        seltype="single" onselect="viewer.onRuleSelect()">
+        seltype="single" onselect="viewer.onRuleSelect()"
+        contextmenu="ppStyleRuleContext">
     <treecols>
       <treecol id="olcRule" label="&styleRule.label;" flex="1"/>
       <splitter class="tree-splitter"/>
       <treecol id="olcFileURL" label="&styleRuleURI.label;" flex="1"/>
       <splitter class="tree-splitter"/>
       <treecol id="olcLine" label="&styleRuleLineNumber.label;"/>
     </treecols>
     <treechildren id="olbStyleRules"
  • http://taken.s101.xrea.com/tmp/domicopycssrule.png

LinxLinx2011/08/07 06:48You're the greteast! JMHO

mdguerstsqmdguerstsq2011/08/07 20:43e68wCS <a href="http://fyibkzrvblki.com/">fyibkzrvblki</a>

ayaajhxayaajhx2011/08/08 01:27EIOGah , [url=http://wetxobogtlmn.com/]wetxobogtlmn[/url], [link=http://xuvpmteynysl.com/]xuvpmteynysl[/link], http://bdymfxegixja.com/

qgnfrsyqgnfrsy2011/08/13 00:47Pzm3c1 , [url=http://wqknozqtdqqr.com/]wqknozqtdqqr[/url], [link=http://mkohfsnamwxi.com/]mkohfsnamwxi[/link], http://wuhujexmexjy.com/

RobyRoby2012/09/28 19:16Redaing this makes my decisions easier than taking candy from a baby.

gvoaaqmeugvoaaqmeu2012/09/30 11:37SCUrTu <a href="http://exmbrlrhtqlk.com/">exmbrlrhtqlk</a>

yasybsyasybs2012/10/02 02:57d0uOQf , [url=http://kwsqwyudxcvp.com/]kwsqwyudxcvp[/url], [link=http://ihngevsduckx.com/]ihngevsduckx[/link], http://luhikijgzhzx.com/

2008-01-27

XPathGenerator

20:07

nsIXPathGeneratorノードXPath を簡単に取得することができます (xpath-generator 付きビルドが必要です)。

const Cc =Components.classes;
const Ci = Components.interfaces;

function getXPath(aNode, aContext) {
    var generator = Cc["@mozilla.org/xpath-generator;1"].createInstance(Ci.nsIXPathGenerator);
    try {
      var xpath = generator.generateXPath(aNode, aContext || aNode.ownerDocument);
    } catch (e) {
      return "";
    }
    return xpath;
}

例えば以下のようなドキュメントについて、考えてみます

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>XHTML + SVG</title>
</head>
<body>
    <p>XHTML + SVG</p>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="150px" height="150px"
        viewBox="0 0 100 100">
        <rect x="0" y="0" width="100" height="100" fill="none" stroke="black"/>
        <circle cx="50" cy="50" r="30" fill="red" />
    </svg>
    <p>XHTML + SVG!</p>
</body>
</html>

rect 要素の XPath を得たい時は以下のように使います。

var rect = document.getElementsByTagNameNS("http://www.w3.org/2000/svg", "rect")[0];
getXPath(rect, document);
// => a1:html/a1:body/a0:svg/a0:rect

名前空間接頭辞がわかりにくいので generateXPath() する前に addNamespace() で接頭辞を設定できます。

function getXPath(aNode, aContext) {
    var generator = Cc["@mozilla.org/xpath-generator;1"].createInstance(Ci.nsIXPathGenerator);
    // 名前空間に対する接頭辞を設定
    generator.addNamespace("http://www.w3.org/1999/xhtml", "html");
    generator.addNamespace("http://www.w3.org/2000/svg", "svg");
    //...
    try {
      var xpath = generator.generateXPath(aNode, aContext || aNode.ownerDocument);
    } catch (e) {
      return "";
    }
    return xpath;
}

上記の例だと、

var rect = document.getElementsByTagNameNS("http://www.w3.org/2000/svg", "rect")[0];
getXPath(rect, document);
// => html:html/html:body/svg:svg/svg:rect

という感じになります。

あと id 属性 *1 があると、デフォルトではそれ以上はたどりません。例えば、先ほどの例で body 要素の id 属性が foo だとすると、以下のようになります。

var rect = document.getElementsByTagNameNS("http://www.w3.org/2000/svg", "rect")[0];
getXPath(rect, document);
// => id('foo')/a0:svg/a0:rect

HTML 文書では、名前空間についてあれこれ考えなくても良いです。

<html>
<head>
    <title>An HTML document</title>
</head>
<body>
    <p>HTML</p>
    <p>HTML!</p>
</body>
</html>

2 つ目の p 要素に対してだと、

var p = document.getElementsByTagName("P")[1];
getXPath(p, document);
// => HTML/BODY/P[2]

という感じになります。

404 (Page Not Found) Error - Ever feel like you’re in the wrong place? では

var generator = new XPathGenerator();

でいけると書いてありますが、手元では失敗しました。

*1:厳密には isIdtrue な属性

DionDion2012/04/29 10:42Yeah, that's the tciket, sir or ma'am

awwazwavlawwazwavl2012/04/29 18:48KX6ezo <a href="http://njwviqmaqcfc.com/">njwviqmaqcfc</a>

xknqldoixknqldoi2012/04/29 23:33olsnYX , [url=http://thnucsymadtn.com/]thnucsymadtn[/url], [link=http://fkmowvcwrxot.com/]fkmowvcwrxot[/link], http://jsnvhbgizgyk.com/

bcxzxiefbcxzxief2012/04/30 22:32Q1q6Nl <a href="http://tscrscngdcnw.com/">tscrscngdcnw</a>

aonprhripqaonprhripq2012/05/02 14:43ApEwPe , [url=http://pgaedyxlvhky.com/]pgaedyxlvhky[/url], [link=http://lwrsiixnrlnn.com/]lwrsiixnrlnn[/link], http://ekenygcfpmzz.com/