svnno****@sourc*****
svnno****@sourc*****
2010年 9月 29日 (水) 22:54:09 JST
Revision: 2027 http://sourceforge.jp/projects/sie/svn/view?view=rev&revision=2027 Author: dhrname Date: 2010-09-29 22:54:09 +0900 (Wed, 29 Sep 2010) Log Message: ----------- tspan要素の実装を開始 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-09-28 14:31:36 UTC (rev 2026) +++ branches/06x/061/org/w3c/dom/svg.js 2010-09-29 13:54:09 UTC (rev 2027) @@ -3247,13 +3247,14 @@ function SVGTextContentElement() { SVGElement.apply(this); + this._list = []; //文字の位置を格納しておくリスト /*readonly SVGAnimatedLength*/ this.textLength = new SVGAnimatedLength(); /*readonly SVGAnimatedEnumeration*/ this.lengthAdjust = new SVGAnimatedEnumeration(SVGTextContentElement.LENGTHADJUST_UNKNOWN); this._isYokogaki = true; this.addEventListener("DOMNodeInserted", function(evt){ - var tar = evt.target; + var tar = evt.target, cur = evt.currentTarget; if ((evt.eventPhase === Event.CAPTURING_PHASE) && (tar.nodeType === Node.TEXT_NODE) && !!!tar._tar) { - //Textノードにdiv要素を格納したリストをプロパティとして蓄えておく + /*Textノードにdiv要素を格納したリストをプロパティとして蓄えておく*/ tar._tar = []; for (var i=0, tdli=tar.data.length;i<tdli;++i) { var d = document.createElement("div"), dstyle = d.style; @@ -3267,9 +3268,158 @@ d.appendChild(document.createTextNode(tar.data.charAt(i))); tar._tar[tar._tar.length] = d; } + if (cur.parentNode) { + var evtt = cur.ownerDocument.createEvent("MutationEvents"); + evtt.initMutationEvent("DOMNodeInsertedIntoDocument", false, false, null, null, null, null, null); + evtt.target = cur; + evtt.eventPhase = Event.AT_TARGET; + var tce = cur._capter; //tceは登録しておいたリスナーのリスト + for (var j=0,tcli=tce.length;j<tcli;++j){ + if (tce[j]) { + tce[j].handleEvent(evtt); + } + } + evtt = null; + } } evt = tar = null; }, true); + return this; +}; +SVGTextContentElement.constructor = SVGElement; +SVGTextContentElement.prototype = new SVGElement(); + // lengthAdjust Types + /*unsigned short*/ SVGTextContentElement.LENGTHADJUST_UNKNOWN = 0; + /*unsigned short*/ SVGTextContentElement.LENGTHADJUST_SPACING = 1; + /*unsigned short*/ SVGTextContentElement.LENGTHADJUST_SPACINGANDGLYPHS = 2; +/*long*/ SVGTextContentElement.prototype.getNumberOfChars = function() { + return (this._list.length/3); +}; +/*float*/ SVGTextContentElement.prototype.getComputedTextLength = function() { + var l = this.textLength.baseVal; + if (l.unitType === SVGLength.SVG_LENGTHTYPE_UNKNOWN) { + l.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_NUMBER, this.getSubStringLength(0, this.getNumberOfChars())); + } + l = null; + return (this.textLength.baseVal.value); +}; +/*getSubStringLengthメソッド + *charnum番目の文字からnchars+charnum-1番目までの文字列の長さを求めて返す + */ +/*float*/ SVGTextContentElement.prototype.getSubStringLength = function(/*unsigned long*/ charnum, /*unsigned long*/ nchars ) { + if (nchars === 0) { + return 0; + } + var tg = this.getNumberOfChars(); + if (tg < (nchars+charnum)) { + /*ncharsが文字列の長さよりも長くなってしまったときには、 + *文字列の末端までの長さを求めるとする(SVG1.1の仕様より) + */ + nchars = tg - charnum + 1; + } + var end = this.getEndPositionOfChar(nchars+charnum-1), st = this.getStartPositionOfChar(charnum); + if (this._isYokogaki) { + var s = end.x - st.x; + } else { + var s = end.y - st.y; + } + tg = end = st = null; + return s; +} +/*SVGPoint*/ SVGTextContentElement.prototype.getStartPositionOfChar = function (/*unsigned long*/ charnum ) { + if (charnum > this.getNumberOfChars() || charnum < 0) { + throw (new DOMException(DOMException.INDEX_SIZE_ERR)); + } else { + var s = this.ownerDocument.documentElement.createSVGPoint(); + s.x = this._list[charnum*3]; + s.y = this._list[charnum*3 + 1]; + s = s.matrixTransform(this.getScreenCTM()); + return s; + } +}; +/*SVGPoint*/ SVGTextContentElement.prototype.getEndPositionOfChar = function(/*unsigned long*/ charnum ) { + if (charnum > this.getNumberOfChars() || charnum < 0) { + throw (new DOMException(DOMException.INDEX_SIZE_ERR)); + } else { + var s = this.getStartPositionOfChar(charnum); + //アドバンス値(すなわちフォントの大きさ)をCTMの行列式を用いて、算出する + var n = this._list[charnum*3 + 2] * Math.sqrt(Math.abs(this.getScreenCTM()._determinant())); + if (this._isYokogaki) { + s.x += n; + } else { + s.y += n; + } + return s; + } +}; +/*SVGRect*/ SVGTextContentElement.prototype.getExtentOfChar = function(/*unsigned long*/ charnum ) { + +}; +/*float*/ SVGTextContentElement.prototype.getRotationOfChar = function(/*unsigned long*/ charnum ) { + +}; +/*long*/ SVGTextContentElement.prototype.getCharNumAtPosition = function(/*SVGPoint*/ point ) { + +}; +/*void*/ SVGTextContentElement.prototype.selectSubString = function(/*unsigned long*/ charnum,/*unsigned long*/ nchars ) { + +}; + +function SVGTextPositioningElement() { + SVGTextContentElement.apply(this); + /*readonly SVGAnimatedLengthList*/ this.x = new SVGAnimatedLengthList(); + /*readonly SVGAnimatedLengthList*/ this.y = new SVGAnimatedLengthList(); + /*readonly SVGAnimatedLengthList*/ this.dx = new SVGAnimatedLengthList(); + /*readonly SVGAnimatedLengthList*/ this.dy = new SVGAnimatedLengthList(); + /*readonly SVGAnimatedNumberList*/ this.rotate = new SVGAnimatedNumberList(); + this.addEventListener("DOMAttrModified", function(evt){ + var tar = evt.target, name = evt.attrName, tod = tar.ownerDocument.documentElement; + var _parseFloat = parseFloat; + if ((name === "x") || (name === "y") || (name === "dx") || (name === "dy")) { + var enr = evt.newValue.replace(/^\s+|\s+$/g, "").split(/[\s,]+/), teas = tar[name].baseVal; + for (var i=0, tli=enr.length;i<tli;++i) { + var tea = tod.createSVGLength(); + var n = enr[i].match(/\D+$/), type = 0; + if (!!n) { + n = n[0]; + } + if (!n) { + type = SVGLength.SVG_LENGTHTYPE_NUMBER; + } else if (n === "%") { + if ((name === "x") || (name === "dx")) { + tea._percent *= tod.viewport.width; + } else if ((name === "y") || (name === "dy")) { + tea._percent *= tod.viewport.height; + } + type = SVGLength.SVG_LENGTHTYPE_PERCENTAGE; + } else if (n === "em") { + var style = tar.ownerDocument.defaultView.getComputedStyle(tar, null); + tea._percent *= _parseFloat(style.getPropertyValue("font-size")); + style = null; + type = SVGLength.SVG_LENGTHTYPE_EMS; + } else if (n === "ex") { + type = SVGLength.SVG_LENGTHTYPE_EXS; + } else if (n === "px") { + type = SVGLength.SVG_LENGTHTYPE_PX; + } else if (n === "cm") { + type = SVGLength.SVG_LENGTHTYPE_CM; + } else if (n === "mm") { + type = SVGLength.SVG_LENGTHTYPE_MM; + } else if (n === "in") { + type = SVGLength.SVG_LENGTHTYPE_IN; + } else if (n === "pt") { + type = SVGLength.SVG_LENGTHTYPE_PT; + } else if (n === "pc") { + type = SVGLength.SVG_LENGTHTYPE_PC; + } + var s = _parseFloat(enr[i]); + s = isNaN(s) ? 0 : s; + tea.newValueSpecifiedUnits(type, s); + teas.appendItem(tea); + } + } + evt = tar = null; + }, false); this.addEventListener("DOMNodeInserted", function(evt){ if (evt.eventPhase === Event.BUBBLING_PHASE) { return; //強制終了させる @@ -3280,7 +3430,6 @@ if (!(tar instanceof SVGTextContentElement)) { return; } - tar._list = []; //文字の位置を格納しておくリスト var x = 0, y = 0, n = 0; //現在のテキスト位置と順番 var style = tar.ownerDocument.defaultView.getComputedStyle(tar, null); var isYokogaki = ((style.getPropertyValue("writing-mode")) === "lr-tb") ? true : false; @@ -3296,14 +3445,14 @@ /*現在のテキスト位置を、前のノードによって、 *変更する(tspan要素のみ) */ - var tpt = tar, d = 0; - while (tpt.previousSibling) { - if (tpt.previousSibling.nodeType === Node.TEXT_NODE) { - d += tpt.length; - } else if (tpt.previousSibling.localName === "tspan") { - d += tpt.getNumberOfChars(); + var d = 0, tpre = tar.previousSibling; + while (tpre) { + if (tpre.nodeType === Node.TEXT_NODE) { + d += tpre.length; + } else if (tpre.localName === "tspan") { + d += tpre.getNumberOfChars(); } - tpt = tpt.previousSibling; + tpre = tpre.previousSibling; } if (isYokogaki) { x = tp.getSubStringLength(0, d); @@ -3406,136 +3555,22 @@ tar._isYokogaki = isYokogaki //getEndPositionOfCharメソッドなどで使う evt = tar = style = null; }, true); - evt = tar = null; - },false); - return this; -}; -SVGTextContentElement.constructor = SVGElement; -SVGTextContentElement.prototype = new SVGElement(); - // lengthAdjust Types - /*unsigned short*/ SVGTextContentElement.LENGTHADJUST_UNKNOWN = 0; - /*unsigned short*/ SVGTextContentElement.LENGTHADJUST_SPACING = 1; - /*unsigned short*/ SVGTextContentElement.LENGTHADJUST_SPACINGANDGLYPHS = 2; -/*long*/ SVGTextContentElement.prototype.getNumberOfChars = function() { - return (this._list.length/3); -}; -/*float*/ SVGTextContentElement.prototype.getComputedTextLength = function() { - var l = this.textLength.baseVal; - if (l.unitType === SVGLength.SVG_LENGTHTYPE_UNKNOWN) { - l.newValueSpecifiedUnits(SVGLength.SVG_LENGTHTYPE_NUMBER, this.getSubStringLength(0, this.getNumberOfChars())); - } - l = null; - return (this.textLength.baseVal.value); -}; -/*getSubStringLengthメソッド - *charnum番目の文字からnchars+charnum-1番目までの文字列の長さを求めて返す - */ -/*float*/ SVGTextContentElement.prototype.getSubStringLength = function(/*unsigned long*/ charnum, /*unsigned long*/ nchars ) { - if (nchars === 0) { - return 0; - } - var end = this.getEndPositionOfChar(nchars+charnum-1), st = this.getStartPositionOfChar(charnum); - if (this._isYokogaki) { - var s = end.x - st.x; - } else { - var s = end.y - st.y; - } - return s; -} -/*SVGPoint*/ SVGTextContentElement.prototype.getStartPositionOfChar = function (/*unsigned long*/ charnum ) { - if (charnum > this.getNumberOfChars() || charnum < 0) { - throw (new DOMException(DOMException.INDEX_SIZE_ERR)); - } else { - var s = this.ownerDocument.documentElement.createSVGPoint(); - s.x = this._list[charnum*3]; - s.y = this._list[charnum*3 + 1]; - s = s.matrixTransform(this.getScreenCTM()); - return s; - } -}; -/*SVGPoint*/ SVGTextContentElement.prototype.getEndPositionOfChar = function(/*unsigned long*/ charnum ) { - if (charnum > this.getNumberOfChars() || charnum < 0) { - throw (new DOMException(DOMException.INDEX_SIZE_ERR)); - } else { - var s = this.getStartPositionOfChar(charnum); - //アドバンス値(すなわちフォントの大きさ)をCTMの行列式を用いて、算出する - var n = this._list[charnum*3 + 2] * Math.sqrt(Math.abs(this.getScreenCTM()._determinant())); - if (this._isYokogaki) { - s.x += n; - } else { - s.y += n; - } - return s; - } -}; -/*SVGRect*/ SVGTextContentElement.prototype.getExtentOfChar = function(/*unsigned long*/ charnum ) { - -}; -/*float*/ SVGTextContentElement.prototype.getRotationOfChar = function(/*unsigned long*/ charnum ) { - -}; -/*long*/ SVGTextContentElement.prototype.getCharNumAtPosition = function(/*SVGPoint*/ point ) { - -}; -/*void*/ SVGTextContentElement.prototype.selectSubString = function(/*unsigned long*/ charnum,/*unsigned long*/ nchars ) { - -}; - -function SVGTextPositioningElement() { - SVGTextContentElement.apply(this); - /*readonly SVGAnimatedLengthList*/ this.x = new SVGAnimatedLengthList(); - /*readonly SVGAnimatedLengthList*/ this.y = new SVGAnimatedLengthList(); - /*readonly SVGAnimatedLengthList*/ this.dx = new SVGAnimatedLengthList(); - /*readonly SVGAnimatedLengthList*/ this.dy = new SVGAnimatedLengthList(); - /*readonly SVGAnimatedNumberList*/ this.rotate = new SVGAnimatedNumberList(); - this.addEventListener("DOMAttrModified", function(evt){ - var tar = evt.target, name = evt.attrName, tod = tar.ownerDocument.documentElement; - var _parseFloat = parseFloat; - if ((name === "x") || (name === "y") || (name === "dx") || (name === "dy")) { - var enr = evt.newValue.replace(/^\s+|\s+$/g, "").split(/[\s,]+/), teas = tar[name].baseVal; - for (var i=0, tli=enr.length;i<tli;++i) { - var tea = tod.createSVGLength(); - var n = enr[i].match(/\D+$/), type = 0; - if (!!n) { - n = n[0]; + /*tspan要素から先にDONNodeInsertedIntoDocumentイベントを発火させる*/ + if (tar.localName === "tspan") { + var evtt = tar.ownerDocument.createEvent("MutationEvents"); + evtt.initMutationEvent("DOMNodeInsertedIntoDocument", false, false, null, null, null, null, null); + evtt.target = tar; + evtt.eventPhase = Event.AT_TARGET; + var tce = tar._capter; //tceは登録しておいたリスナーのリスト + for (var j=0,tcli=tce.length;j<tcli;++j){ + if (tce[j]) { + tce[j].handleEvent(evtt); } - if (!n) { - type = SVGLength.SVG_LENGTHTYPE_NUMBER; - } else if (n === "%") { - if ((name === "x") || (name === "dx")) { - tea._percent *= tod.viewport.width; - } else if ((name === "y") || (name === "dy")) { - tea._percent *= tod.viewport.height; - } - type = SVGLength.SVG_LENGTHTYPE_PERCENTAGE; - } else if (n === "em") { - var style = tar.ownerDocument.defaultView.getComputedStyle(tar, null); - tea._percent *= _parseFloat(style.getPropertyValue("font-size")); - style = null; - type = SVGLength.SVG_LENGTHTYPE_EMS; - } else if (n === "ex") { - type = SVGLength.SVG_LENGTHTYPE_EXS; - } else if (n === "px") { - type = SVGLength.SVG_LENGTHTYPE_PX; - } else if (n === "cm") { - type = SVGLength.SVG_LENGTHTYPE_CM; - } else if (n === "mm") { - type = SVGLength.SVG_LENGTHTYPE_MM; - } else if (n === "in") { - type = SVGLength.SVG_LENGTHTYPE_IN; - } else if (n === "pt") { - type = SVGLength.SVG_LENGTHTYPE_PT; - } else if (n === "pc") { - type = SVGLength.SVG_LENGTHTYPE_PC; - } - var s = _parseFloat(enr[i]); - s = isNaN(s) ? 0 : s; - tea.newValueSpecifiedUnits(type, s); - teas.appendItem(tea); } + evtt = null; } evt = tar = null; - }, false); + },false); return this; }; SVGTextPositioningElement.constructor = SVGTextContentElement; @@ -3579,6 +3614,7 @@ } tar.addEventListener("DOMNodeInsertedIntoDocument", function(evt) { var tar = evt.target, ti = tar.firstChild, ttp = tar._tar; + ttp.style.cssText = tar.style.cssText; var style = tar.ownerDocument.defaultView.getComputedStyle(tar, null); var n = parseFloat(style.getPropertyValue("font-size")) * Math.sqrt(Math.abs(tar.getScreenCTM()._determinant())); ttp.style.fontSize = n + "px"; @@ -3671,7 +3707,7 @@ SVGTextElement.prototype = new SVGTextPositioningElement(); function SVGTSpanElement() { - SVGTextPositioningElement.apply(this, arguments); + SVGTextElement.apply(this, arguments); return this; }; SVGTSpanElement.constructor = SVGTextPositioningElement;