[Sie-announce] SIEコード [2061] text2svg機能を実装

Back to archive index

svnno****@sourc***** svnno****@sourc*****
2010年 10月 16日 (土) 21:40:29 JST


Revision: 2061
          http://sourceforge.jp/projects/sie/svn/view?view=rev&revision=2061
Author:   dhrname
Date:     2010-10-16 21:40:29 +0900 (Sat, 16 Oct 2010)

Log Message:
-----------
text2svg機能を実装

Modified Paths:
--------------
    branches/06x/061/org/w3c/dom/svg.js

Modified: branches/06x/061/org/w3c/dom/svg.js
===================================================================
--- branches/06x/061/org/w3c/dom/svg.js	2010-10-15 14:30:45 UTC (rev 2060)
+++ branches/06x/061/org/w3c/dom/svg.js	2010-10-16 12:40:29 UTC (rev 2061)
@@ -1072,6 +1072,9 @@
    *随時、属性の値をDOMプロパティに変換しておくリスナー登録
    */
   this.addEventListener("DOMAttrModified", function(evt){
+    if (evt.eventPhase === Event.BUBBLING_PHASE) {
+      return; //強制終了させる
+    }
     var tar = evt.target, name = evt.attrName;
     if (name === "viewBox") {
       tar._cacheScreenCTM = null;
@@ -1116,6 +1119,11 @@
       }
       tp.align = sa;
       tp.meetOrSlice = mos;
+    } else if (name === "width") {
+      /*viewportを更新する*/
+      tar.viewport.width = tar.width.baseVal.value;
+    } else if (name === "height") {
+      tar.viewport.height = tar.height.baseVal.value;
     }
     evt = name = null;
   }, false);  
@@ -1471,6 +1479,8 @@
 SVGSwitchElement.constructor = SVGElement;
 SVGSwitchElement.prototype = new SVGElement();
 
+//bookmarkletから呼び出されたらtrue
+var sieb_s;
 function GetSVGDocument(ele) {
   this._tar = ele;
   this._next = null;
@@ -1482,7 +1492,7 @@
    */
   _init : function() {
   /*objeiはobject要素かembed要素*/
-  var xmlhttp = NAIBU.xmlhttp, objei = this._tar, thistar = this;
+  var xmlhttp = NAIBU.xmlhttp, objei = this._tar, ca = this._ca;
   if (this._tar.nodeName === "OBJECT") {
     var data = "data";
   } else {
@@ -1491,13 +1501,23 @@
   xmlhttp.open("GET", objei.getAttribute(data), true);
   objei.style.display = "none";
   xmlhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
-  xmlhttp.onreadystatechange = function() {
-    if ((xmlhttp.readyState === 4)  &&  (xmlhttp.status === 200)) {
+  this.xmlhttp = xmlhttp;
+  /*クロージャを利用しないと、_caはwindowの元で実行される*/
+  (function(te, ta) {
+    ta.onreadystatechange = function() {
+      te._ca();
+    };
+  })(this, xmlhttp);
+  xmlhttp.send(null);
+  },
+  /*コール関数。全処理を担う*/
+  _ca : function() {
+    if ((this.xmlhttp.readyState === 4)  &&  (this.xmlhttp.status === 200)) {
       /*responseXMLを使うと、時々、空のデータを返すことがあるため(原因は不明)、
        *ここでは、responseTextを用いる
        */
       var dew = new Date();
-      str = xmlhttp.responseText;
+      str = this.xmlhttp.responseText;
       NAIBU.doc.async = false;
       /*下記のプロパティについては、Microsoftのサイトを参照
        *ResolveExternals Property [Second-level DOM]
@@ -1508,6 +1528,7 @@
       NAIBU.doc.validateOnParse = false;
       NAIBU.doc.resolveExternals = false;
       NAIBU.doc.loadXML(str);
+      var objei = this._tar;
       if (/&[^;]+;/.test(str)) {
         /*以下の処理は、実体参照を使ったとき
          *代替の処理を用いて、実体参照を処理するもの
@@ -1531,11 +1552,9 @@
       var objw = objei.getAttribute("width"), objh = objei.getAttribute("height");
       if (objw) {
         tar.setAttributeNS(null, "width", objw);
-        tar.viewport.width = tar.width.baseVal.value;
       }
       if (objh) {
         tar.setAttributeNS(null, "height", objh);
-        tar.viewport.height = tar.height.baseVal.value;
       }
       var fi = NAIBU.doc.documentElement.firstChild, n;
       var attr = NAIBU.doc.documentElement.attributes, att;
@@ -1622,16 +1641,14 @@
       s.defaultView._cache = s.defaultView._cache_ele = null;
       s = evt = null;
       alert((new Date()).getTime() - dew.getTime());
-      if (thistar._next) {
-        thistar._next._init();
+      if (this._next) {
+        this._next._init();
       } else {
         /*全要素の読み込みが終了した場合*/
         NAIBU.Time.start();
         delete NAIBU.doc;
       }
     }
-  };
-  xmlhttp.send(null);
   },
   /*SVGDocument*/  getSVGDocument : function() {
     return (this._document);
@@ -3317,22 +3334,23 @@
     if ((evt.eventPhase === Event.CAPTURING_PHASE) && (tar.nodeType === Node.TEXT_NODE) && !!!tar._tars) {
       /*Textノードにdiv要素を格納したリストをプロパティとして蓄えておく*/
       tar._tars = [];
-      tar.data = tar.data.replace(/^\s+/, "").replace(/\s+$/, "");
-      for (var i=0, tdli=tar.data.length;i<tdli;++i) {
+      var data = tar.data.replace(/^\s+/, "").replace(/\s+$/, "");
+      for (var i=0, tdli=data.length;i<tdli;++i) {
         var d = document.createElement("div"), dstyle = d.style;
         dstyle.position = "absolute";
         dstyle.marginLeft = dstyle.marginRight = dstyle.marginTop = "0px";
         dstyle.paddingTop = dstyle.paddingLeft = "0px";
         dstyle.whiteSpace = "nowrap";
         dstyle.textIndent = "0px";
-        d.appendChild(document.createTextNode(tar.data.charAt(i)));
+        d.appendChild(document.createTextNode(data.charAt(i)));
         tar._tars[tar._tars.length] = d;
       }
+      data = null;
       cur._length += tar._tars.length;
     } else if ((evt.eventPhase === Event.CAPTURING_PHASE) && (tar instanceof SVGTextContentElement) && !!!tar._tars) {
       cur._length += tar._length;
     }
-    evt = tar = null;
+    evt = tar = cur = null;
   }, true);
  return this;
 };
@@ -5051,6 +5069,10 @@
   } else {
     window['on'+evt] = lis;
   }
+  //Sieb用
+  if (sieb_s) {
+    lis();
+  }
 };
 function unsvgtovml() {
   try {
@@ -5078,7 +5100,8 @@
     }
   }
   NAIBU.xmlhttp = xmlhttp;
-  NAIBU.doc = new ActiveXObject("MSXML2.DomDocument")
+  NAIBU.doc = new ActiveXObject("MSXML2.DomDocument");
+  var nd = NAIBU.doc;
   if (!document.namespaces["v"]) {
     document.namespaces.add("v","urn:schemas-microsoft-com:vml");
     document.namespaces.add("o","urn:schemas-microsoft-com:office:office");
@@ -5089,9 +5112,39 @@
       + "v\\:group{text-indent:0px;position:relative;width:100%;height:100%;" +vmlUrl
       + "v\\:shape{width:100%;height:100%;" +vmlUrl;
   }
-  //IEならばtrue
-  var isMSIE = /*@cc_on!@*/false;
-  if (xmlhttp && isMSIE) {
+  var ary = document.getElementsByTagName("script");
+  //全script要素をチェックして、type属性がimage/svg+xmlならば、中身をSVGとして処理する
+  for (var i=0; i < ary.length; ++i) {
+    var hoge = ary[i].type;
+    if (ary[i].type === "image/svg+xml") {
+      var ait = ary[i].text;
+      if (sieb_s && ait.match(/&lt;svg/)) {
+        //ソース内のタグを除去
+        ait = ait.replace(/<.+?>/g, "");
+        //エンティティを文字に戻す
+        ait = ait.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&amp;/g, "&");
+      }
+      if (NAIBU.isMSIE) {
+        var gsd = new GetSVGDocument(ary[i]);
+        gsd.xmlhttp = {
+          readyState : 4,
+          status : 200,
+          responseText : ait.replace(/\shref=/g, " target='_top' xlink:href=")
+        }
+        gsd._ca();
+      } else {
+        var base = location.href.replace(/\/[^\/]+?$/,"/"); //URIの最後尾にあるファイル名は消す。例: /n/sie.js -> /n/
+        ait = ait.replace(/\shref=(['"a-z]+?):\/\//g, " target='_top' xlink:href=$1://").replace(/\shref=(.)/g, " target='_top' xlink:href=$1"+base);
+        var s = textToSVG(ait,ary[i].getAttribute("width"),ary[i].getAttribute("height"));
+        ary[i].parentNode.insertBefore(s,ary[i]);
+      }
+      ait = null;
+    }
+    hoge = null;
+  }
+  NAIBU.doc = nd;
+  nd = ary = null;
+  if (xmlhttp && NAIBU.isMSIE) {
     if (!!document.createElementNS) { //IE9ならば
       if (!!document.createElementNS( "http://www.w3.org/2000/svg", "svg").createSVGRect) {
       }
@@ -5119,4 +5172,30 @@
     }
   }
 }) );
-NAIBU.addEvent("unload", unsvgtovml);
\ No newline at end of file
+NAIBU.utf16 = function ( /*string*/ s)  {
+  return unescape(s);
+}
+NAIBU.unescapeUTF16 = function ( /*string*/ s) {
+  return s.replace(/%u\w\w\w\w/g,  NAIBU.utf16);
+}
+//Text2SVG機能。SVGのソース(文章)をSVG画像に変換できる。
+NAIBU.textToSVG = function ( /*string*/ source, /*float*/ w, /*float*/ h) {
+  /*Safari3.xでは、DOMParser方式だと、文字が表示されないバグがあるため、
+   *dataスキーム方式を採用する
+   */
+  if (navigator.userAgent.indexOf('WebKit') > -1 || navigator.userAgent.indexOf('Safari') > -1) { //WebKit系ならば
+    var data = 'data:image/svg+xml;charset=utf-8,' + NAIBU.unescapeUTF16(escape(source));
+    var ob = document.createElement("object");
+    ob.setAttribute("data",data);
+    ob.setAttribute("width",w);
+    ob.setAttribute("height",h);
+    ob.setAttribute("type","image/svg+xml");
+    return ob;
+  } else {
+    var doc = (new DOMParser()).parseFromString(source, "text/xml");
+    return (document.importNode(doc.documentElement, true));
+  }
+};
+NAIBU.addEvent("unload", unsvgtovml);
+//IEならばtrue
+NAIBU.isMSIE = /*@cc_on!@*/false;




Sie-announce メーリングリストの案内
Back to archive index