package { import flash.display.*; import flash.geom.*; import flash.text.*; import flash.events.*; import css.*; import ascsstest.*; public class CSSTest extends Sprite implements IParserListener { public static const SCROLL_SCALE:Number = 5; public static var theInstance:CSSTest; private var mTextOut:TextField; private var mCSS:ASCSS; private var mVLayer:Sprite; private var mWLayer:Sprite; private var mELayer:Sprite; private var mBGLayer:Sprite; private var mBGPtn:BitmapData; private var mProgBar:ProgressBar; private var mPrevX:int; private var mPrevY:int; private var mVisualGeneratedLength:int; private var mTopVisual:StyleListVisual; private var mParserPaused:Boolean; private var mRollbackAnimation:Boolean = false; public static const T_CSS:String = "@charset \"Shift_JIS\"; \n"+ "\n"+ "@import url(../system/html.css);\n"+ "@import url(../system/system.css);\n"+ "@import url(./common.css);\n"+ "\n"+ "/* commented out for Opera\n"+ "@namespace url(http://www.w3.org/1999/xhtml);\n"+ "@namespace xhtml2 url(http://www.w3.org/2002/06/xhtml2);\n"+ "*/\n"+ " \n"+ "/* Block */ \n"+ " \n"+ "html, body \n"+ "{\n"+ " color: white;\n"+ "/* background: #3E5C70;*/\n"+ " background: #6E8CA0 url(./img/body_bg.png) fixed no-repeat right bottom;/*rgb(110, 140, 160)*/\n"+ "}\n"+ " \n"+ "html, \n"+ "html *,\n"+ "html h1,\n"+ "html h2,\n"+ "html h3,\n"+ "html h4,\n"+ "html h5,\n"+ "html h6,\n"+ "#section-root h1,\n"+ "#section-root h2,\n"+ "#section-root h3,\n"+ "#section-root h4,\n"+ "#section-root h5,\n"+ "#section-root h6,\n"+ "#section-root h1 *,\n"+ "#section-root h2 *,\n"+ "#section-root h3 *,\n"+ "#section-root h4 *,\n"+ "#section-root h5 *,\n"+ "#section-root h6 *,\n"+ "#section-root .index dt,\n"+ "#section-root .index dt *,\n"+ "#cover #section-root #sec-contents *\n"+ "{\n"+ " font-family: \"Century Gothic\", Arial, Verdana, \"ヒラギノ丸ゴ Pro W4\", \"MS Pゴシック\", Osaka, sans-serif;\n"+ "}\n"+ "\n"+ "#section-root *\n"+ "{\n"+ " font-family: sans-serif;\n"+ "/* _font-family: Verdana, Arial, \"ヒラギノ丸ゴ Pro W4\", \"MS Pゴシック\", Osaka, sans-serif; */\n"+ " _font-family: \"MS Pゴシック\", sans-serif;\n"+ "}\n"+ " \n"+ "body \n"+ "{\n"+ " line-height: 1.5;\n"+ " margin: 0;\n"+ " padding: 0;\n"+ "}\n"+ " \n"+ "ul, ol \n"+ "{\n"+ " margin: 0 0 1em 0;\n"+ " padding: 0 0 0 10%;\n"+ "}\n"+ " \n"+ "ul li, \n"+ "ol li\n"+ "{\n"+ " margin: 0.1em;\n"+ " padding: 0.1em;\n"+ "}\n"+ " \n"+ "ul \n"+ "{\n"+ " list-style-image: url(./img/marker.jpg);\n"+ "}\n"+ " \n"+ "ol \n"+ "{\n"+ " list-style-image: none;\n"+ "}\n"+ " \n"+ "dl dt \n"+ "{\n"+ " clear: both;\n"+ "}\n"+ "dl.index dt\n"+ "{\n"+ " margin-left: -15px;\n"+ " padding-left: 15px;\n"+ " padding-bottom: 5px;\n"+ " background: url(./img/heading_bg2.png) no-repeat 0 100%;\n"+ "}\n"+ " \n"+ "#gallery dl dt \n"+ "{\n"+ " background: url(./img/thumbnail_bg.jpg) no-repeat 100% 0;\n"+ " border: solid #C8DCF0 0;/*rgb(200, 220, 240)*/\n"+ " border-width: 0.05em 0 0 0;\n"+ " height: 100px;\n"+ " margin: 1.5em 0 -25px 0;\n"+ " min-height: 100px;\n"+ " padding: 0.1em 10px 10px 0;\n"+ "\n"+ " \\62 ackground-image: url(\"./img/thumbnail_bg-alpha.png\");\n"+ " _background-image: url(\"./img/thumbnail_bg.jpg\");\n"+ "}\n"+ " \n"+ "#gallery dl dt img \n"+ "{\n"+ " float: right;\n"+ "}\n"+ " \n"+ "dl dd, dl dd * \n"+ "{\n"+ " clear: none;\n"+ "}\n"+ " \n"+ "h1, h2, h3, h4, h5, h6 \n"+ "{\n"+ " margin-top: 4em;\n"+ "}\n"+ " \n"+ "h1 .sub, \n"+ "h2 .sub,\n"+ "h3 .sub,\n"+ "h4 .sub,\n"+ "h5 .sub,\n"+ "h6 .sub\n"+ "{\n"+ " font-size: 70%;\n"+ " display: block;\n"+ "}\n"+ " \n"+ "h1 \n"+ "{\n"+ "/* background: url(./img/heading.png) no-repeat right;*/\n"+ " font-style: italic;\n"+ " font-size: 150%;\n"+ " border: black solid 0;\n"+ " border-width: 0 0 0.07em 0;\n"+ " margin: -0.4em 0 2em -8%;\n"+ " padding: 0 10% 0.1em 8%;\n"+ "}\n"+ "h1, h2, h3, h4, h5, dt, th {\n"+ " text-shadow: #607384 0.15em 0.15em 0.3em;\n"+ "}\n"+ " \n"+ "#cover h1 \n"+ "{\n"+ " font-size: 220%;\n"+ " margin: -1.5em 0 2em -8%;\n"+ "}\n"+ " \n"+ "h2 \n"+ "{\n"+ " background: url(./img/heading_bg.png) no-repeat 0 0;\n"+ " border-top: 1px solid #AFC0CB;\n"+ " margin-left: -16px;\n"+ " padding-left: 16px;\n"+ " padding-top: 1em;\n"+ " padding-bottom: 1.5em;\n"+ "}\n"+ " \n"+ "h3 \n"+ "{\n"+ " padding-left: 15px;\n"+ " margin-left: -15px;\n"+ " background: url(./img/one-point.png) no-repeat 0 0;\n"+ " padding-top: 5px;\n"+ " padding-bottom: 10px;\n"+ " min-height: 15px;\n"+ "}\n"+ " \n"+ "address \n"+ "{\n"+ " background: black url(./img/address_bg.png) no-repeat right bottom;\n"+ " color: white;\n"+ " font-size: 80%;\n"+ " font-style: normal;\n"+ " margin: 0;\n"+ " padding: 10em 2% 120px 2%;\n"+ " width: 26%;\n"+ " border-left: 1.2em solid #637E91;\n"+ " border-bottom: 1em solid #6E8CA0;\n"+ "\n"+ " _padding: 10em 5% 120px 5%;\n"+ " _width: 30%;\n"+ "}\n"+ " \n"+ "#cover address \n"+ "{\n"+ " background: none;\n"+ " position: static;\n"+ " width: 30%;\n"+ " height: 3em;\n"+ " padding-bottom: 0;\n"+ " margin-top: -8em;\n"+ " border-left: none;\n"+ " border-bottom: none;\n"+ "}\n"+ " \n"+ "#cover #Appendix \n"+ "{\n"+ " background: black url(./img/address_bg.png) no-repeat right bottom;\n"+ " margin: 0 -6.6% 0 -20%;\n"+ " padding: 0 5.5% 120px 10%;\n"+ " width: auto;\n"+ "}\n" ; private var mWireNodes:Array = []; function CSSTest() { mVisualGeneratedLength = 0; mBGPtn = generateBackgroundBitmap(); stage.scaleMode = StageScaleMode.NO_SCALE; mBGLayer = new Sprite(); addChild(mBGLayer); drawBackground(mBGLayer.graphics); var g:Graphics = graphics; mTextOut = new TextField(); mTextOut.width = 600; mTextOut.height = 9999; mTextOut.x = 190; mTextOut.y = 8; mTextOut.textColor = 0x777777; mTextOut.mouseEnabled = false; addChild(mTextOut); theInstance = this; puts(T_CSS); mWLayer = new Sprite(); mWLayer.blendMode = BlendMode.ADD; addChild(mWLayer); mELayer = new Sprite(); addChild(mELayer); mVLayer = new Sprite(); addChild(mVLayer); var pex:PropExt = new PropExt(); mCSS = new ASCSS(T_CSS, CSSTest, true, this); mCSS.propertyExtension = pex; scrollY(120); mParserPaused = true; mProgBar = new ProgressBar(200); mProgBar.x = 300; mProgBar.y = 260; mProgBar.alpha = 0.5; addChild(mProgBar); stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown); stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); stage.addEventListener(Event.ENTER_FRAME, onEnterFrame); } private function updateWire():void { var ln:int = mTextOut.numLines; if (ln == 0) return; var th:Number = mTextOut.textHeight / Number(ln); var tscrollY:int = mTextOut.y; var tscrollX:int = mTextOut.x; var g:Graphics = mWLayer.graphics; g.clear(); for each(var w:Object in mWireNodes) { g.lineStyle(1, 0x2244aa, 0.2); var v:RuleVisual = RuleVisual(w.v); var rx:int = v.x + mVLayer.x + 10; var ry:int = v.anchorY + mVLayer.y; var ty:int = tscrollY + (Number(w.sl)+Number(w.el))/2 * th; var tx:int = tscrollX + 40; g.moveTo(rx, ry); g.lineTo(tx, ty); g.lineTo(rx+2, ry); g.moveTo(rx-2, ry); g.lineTo(tx, ty); g.lineTo(rx, ry-2); g.moveTo(rx, ry+2); g.lineTo(tx, ty); } } private function onMouseDown(e:MouseEvent):void { mRollbackAnimation = false; mPrevX = stage.mouseX; mPrevY = stage.mouseY; } public function scrollY(base:Number):void { mELayer.y += base*SCROLL_SCALE; mVLayer.y += base*SCROLL_SCALE; mTextOut.y = 8 + mVLayer.y/SCROLL_SCALE; mBGLayer.y = int(mTextOut.y/2 + 16000) % 16; } public function scrollAbsoluteY(base:Number):void { mELayer.y = base*SCROLL_SCALE; mVLayer.y = base*SCROLL_SCALE; mTextOut.y = 8 + mVLayer.y/SCROLL_SCALE; mBGLayer.y = int(mTextOut.y/2 + 16000) % 16; } private function onMouseMove(e:MouseEvent):void { if (e.buttonDown) { var dx:int = stage.mouseX - mPrevX; var dy:int = stage.mouseY - mPrevY; if (mELayer != null && mVLayer != null && (dx != 0 || dy != 0)) { mELayer.x += dx*SCROLL_SCALE; mVLayer.x += dx*SCROLL_SCALE; mTextOut.x = 190 + mVLayer.x/SCROLL_SCALE; mBGLayer.x = int(mTextOut.x/2 + 16000) % 16; scrollY(dy); e.updateAfterEvent(); updateWire(); } mPrevX = stage.mouseX; mPrevY = stage.mouseY; } } private function generateStyleListChildren(sl:StyleList, sv:StyleListVisual):void { var ch:StyleBase; var len:uint = sl.length; var children:Array = []; for (var i:uint = mVisualGeneratedLength;i < len;i++) { ch = sl.item(i); if (ch is CSSRule) { var v:RuleVisual = new RuleVisual(CSSRule(ch)); mVLayer.addChild(v); addWire(mTextOut, v, CSSRule(ch)); if (ch is CSSStyleRule) generateStyleRuleChildren(CSSStyleRule(ch), v); children.push(v); } } chain(sv, children); mVisualGeneratedLength = len; } private function addWire(tx:TextField, v:RuleVisual, r:CSSRule):void { mWireNodes.push({sl: r.startLineNo, el: r.endLineNo, v: v}); } private function generateStyleRuleChildren(sr:CSSStyleRule, sv:RuleVisual):void { var v:SelectorVisual; var nx:CSSSelector = sr.selector; var children:Array = []; while(nx != null) { v = new SelectorVisual(nx); mVLayer.addChild(v); children.push(v); generateSelectorChildren(nx, v); nx = nx.next; } if (sr.declaration != null) { var dv:DeclarationVisual = new DeclarationVisual(sr.declaration); mVLayer.addChild(dv); children.push(dv); if (sr.declaration is CSSMutableStyleDeclaration) generateMutableDeclarationChildren(CSSMutableStyleDeclaration(sr.declaration), dv); } chain(sv, children); } private function generateSelectorChildren(ss:CSSSelector, sv:SelectorVisual):void { if (ss.m_tagHistory != null) { var v:SelectorVisual = new SelectorVisual(ss.m_tagHistory); mVLayer.addChild(v); sv.firstChild = v; generateSelectorChildren(ss.m_tagHistory, v); } } private function generateMutableDeclarationChildren(sd:CSSMutableStyleDeclaration, sv:DeclarationVisual):void { var len:uint = sd.length; var children:Array = []; for (var i:uint;i < len;i++) { var v:PropertyVisual = new PropertyVisual(sd.rawItem(i)); mVLayer.addChild(v); children.push(v); generatePropertyChildren(sd.rawItem(i), v); } chain(sv, children); } private function generatePropertyChildren(cp:CSSProperty, pv:PropertyVisual):void { var val:CSSValue = cp.value; if (val == null) return; var v:ValueVisual = new ValueVisual(val); if (val is CSSValueList) generateValueListChildren(CSSValueList(val), v); mVLayer.addChild(v); pv.firstChild = v; } private function generateValueListChildren(cv:CSSValueList, vv:ValueVisual):void { var len:uint = cv.length; var children:Array = []; for (var i:uint;i < len;i++) { var v:ValueVisual = new ValueVisual(cv.item(i)); mVLayer.addChild(v); children.push(v); if (cv.item(i) is ShadowValue) generateShadowValueChildren(ShadowValue(cv.item(i)), v); } chain(vv, children); } private function generateShadowValueChildren(sv:ShadowValue, vv:ValueVisual):void { var v:ValueVisual var children:Array = []; for each(var prop:String in ['x', 'y', 'color', 'blur']) { if (!sv[prop]) continue; v = new ValueVisual(sv[prop]); mVLayer.addChild(v); children.push(v); } chain(vv, children); } private function chain(parent:StyleVisualBase, children:Array /* of StyleVisualBase */):void { var prev:StyleVisualBase = parent.firstChild; if (prev) { for(;prev.nextSibling != null;) prev = prev.nextSibling; } for each(var ch:StyleVisualBase in children) { if (prev == null) parent.firstChild = ch; else prev.nextSibling = ch; prev = ch; } } public static function puts(msg:*):void { if (theInstance != null) theInstance.mTextOut.appendText(msg.toString() + "\n"); } private function generateBackgroundBitmap():BitmapData { var b:BitmapData = new BitmapData(16, 16, false); var rc:Rectangle = new Rectangle(); rc.x = 0; rc.y = 0; rc.width = 16; rc.height = 16; b.fillRect(rc, 0x222222); rc.x = 1; rc.y = 1; rc.width = 3; rc.height = 3; b.fillRect(rc, 0x333333); return b; } private function drawBackground(g:Graphics):void { g.beginBitmapFill(mBGPtn); g.drawRect(-600, -600, 2000, 1800); g.endFill(); } public function cssParserPaused():void { updateVisual(); mProgBar.progress = 1.0 - mCSS.restRatio; mParserPaused = true; } public function cssParserFinished():void { updateVisual(); if (mProgBar) { removeChild(mProgBar); mProgBar = null; } mCSS = null; mRollbackAnimation = true; } public function onEnterFrame(e:Event):void { if (mCSS && mParserPaused) { try{ mCSS.parse(); } catch(e:*) { puts(e); } } if (mRollbackAnimation) { var dy:Number = (mVLayer.y / SCROLL_SCALE) * (-0.3); if (dy < 0.1) mRollbackAnimation = false; if (dy < 3) dy = 3; scrollY(dy); updateWire(); } } public function updateVisual():void { var sheet:StyleList = mCSS.sheet; if (mTopVisual == null) { var sv:StyleListVisual = new StyleListVisual(sheet); sv.edgeLayer = mELayer; mVLayer.addChild(sv); sv.x = 10; sv.y = 10; mTopVisual = sv; } var oldH:Number = mVLayer.height; generateStyleListChildren(sheet, mTopVisual); mTopVisual.calcSize(false); mTopVisual.calcMaxWidth(); mTopVisual.locate(); mELayer.graphics.clear(); mTopVisual.renderEdge(mELayer, 0xffffff); mTopVisual.updateView(); scrollY(-(mVLayer.height - oldH)/SCROLL_SCALE); updateWire(); } } } class PropExt implements css.IPropertyExtension { import css.*; private var mAzimuthPropID:int; function PropExt() { mAzimuthPropID = CSSPropertyID.addExtProp("azimuth"); } public function isColorValue(aPropID:int):Boolean { return false; } public function isValidPrimitiveValue(aPropID:int, aValue:Value, aValueId:int, aHost:IPropertyExtensionHost):Boolean { if (aPropID == mAzimuthPropID) { return true; } return false; } }