/* * Created by LuaView. * Copyright (c) 2017, Alibaba Group. All rights reserved. * * This source code is licensed under the MIT. * For the full copyright and license information,please view the LICENSE file in the root directory of this source tree. */ package com.taobao.luaview.util; import android.util.Log; import com.facebook.csslayout.CSSAlign; import com.facebook.csslayout.CSSFlexDirection; import com.facebook.csslayout.CSSJustify; import com.facebook.csslayout.CSSNode; import com.facebook.csslayout.CSSPositionType; import com.facebook.csslayout.CSSWrap; import com.facebook.csslayout.Spacing; import com.taobao.luaview.util.DimenUtil; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * Created by xiekaiwei on 16/3/17. */ public class FlexboxCSSParser { private static final String TAG = "FlexboxCSSParser"; private static final String POSITION = "position"; private static final String ABSOLUTE = "absolute"; private static final String TOP = "top"; private static final String LEFT = "left"; private static final String BOTTOM = "bottom"; private static final String RIGHT = "right"; private static final String FLEXDEIRECTION = "flex-direction"; private static final String FLEXDIRECTIONROW = "row"; private static final String FLEXDIRECTIONROWREVERSE = "row-reverse"; private static final String FLEXDIRECTIONCOLUMN = "column"; private static final String FLEXDIRECTIONCOLUMNREVERSE = "column-reverse"; private static final String ALIGNITEMS = "align-items"; private static final String ALIGNCONTENT = "align-content"; private static final String ALIGNSELF = "align-self"; private static final String ALIGNAUTO = "auto"; private static final String ALIGNSTART = "flex-start"; private static final String ALIGNCENTER = "center"; private static final String ALIGNEND = "flex-end"; private static final String ALIGNSTRETCH = "stretch"; private static final String JUSTIFYCONTENT = "justify-content"; private static final String JUSTIFYCONTENTSTART = "flex-start"; private static final String JUSTIFYCONTENTCENTER = "center"; private static final String JUSTIFYCONTENTEND = "flex-end"; private static final String JUSTIFYCONTENTBETWEEN = "space-between"; private static final String JUSTIFYCONTENTAROUND = "space-around"; private static final String FLEX = "flex"; private static final String FLEXWRAP = "flex-wrap"; private static final String WIDTH = "width"; private static final String HEIGHT = "height"; private static final String MINWIDTH = "min-width"; private static final String MINHEIGHT = "min-height"; private static final String MAXWIDTH = "max-height"; private static final String MAXHEIGHT = "max-height"; private static final String MARGIN = "margin"; private static final String MARGINLEFT = "margin-left"; private static final String MARGINTOP = "margin-top"; private static final String MARGINBOTTOM = "margin-bottom"; private static final String MARGINRIGHT = "margin-right"; private static final String PADDING = "padding"; private static final String PADDINGLEFT = "padding-left"; private static final String PADDINGTOP = "padding-top"; private static final String PADDINGBOTTOM = "padding-bottom"; private static final String PADDINGRIGHT = "padding-right"; private static final String SIZETOFIT = "sizetofit"; private static Map<String, String> mInlineMap; private static String mCssString; private static CSSNode mNode; public static void parseFlexNodeCSS(CSSNode node, String cssString) { if (mCssString == cssString || mNode == node) { return; } mCssString = cssString; mNode = node; resetInlineMap(); setPosition(); setDirection(); setAlignItems(); setAlignSelf(); setAlignContent(); setJustfiyContent(); setFlex(); setFlexWrap(); setSize(); setMinSize(); setMaxSize(); setMargin(); setPadding(); setSizeToFit(); } private static float pixelFloat(String num) { float fnum = Float.parseFloat(num); return DimenUtil.dpiToPx(fnum); } private static void setPosition() { String position = mInlineMap.get(POSITION); Log.d(TAG, "setPosition: with postion" + position); if (position != null && position.equals(ABSOLUTE)) { mNode.setPositionType(CSSPositionType.ABSOLUTE); String top = mInlineMap.get(TOP); if (top != null) { mNode.setPositionTop(pixelFloat(top)); } String left = mInlineMap.get(LEFT); if (left != null) { mNode.setPositionLeft(pixelFloat(left)); } String bottom = mInlineMap.get(BOTTOM); if (bottom != null) { mNode.setPositionBottom(pixelFloat(bottom)); } String right = mInlineMap.get(RIGHT); if (right != null) { mNode.setPositionRight(pixelFloat(right)); } } } private static void setDirection() { String direction = mInlineMap.get(FLEXDEIRECTION); if (direction != null) { CSSFlexDirection dir = directionMap.get(direction); if (dir != null) { mNode.setFlexDirection(dir); } } } private static void setAlignItems() { String alignItems = mInlineMap.get(ALIGNITEMS); if (alignItems != null) { CSSAlign align = alignMap.get(alignItems); if (align != null) { mNode.setAlignItems(align); } } } private static void setAlignSelf() { String alignSelf = mInlineMap.get(ALIGNSELF); if (alignSelf != null) { CSSAlign align = alignMap.get(alignSelf); if (align != null) { mNode.setAlignSelf(align); } } } private static void setAlignContent() { String alignContent = mInlineMap.get(ALIGNCONTENT); if (alignContent != null) { CSSAlign align = alignMap.get(alignContent); if (align != null) { mNode.setAlignContent(align); } } } private static void setJustfiyContent() { String justifyContent = mInlineMap.get(JUSTIFYCONTENT); if (justifyContent != null) { CSSJustify juc = justifyMap.get(justifyContent); if (juc != null) { mNode.setJustifyContent(juc); } } } private static void setFlex() { String flex = mInlineMap.get(FLEX); if (flex != null) { mNode.setFlex(pixelFloat(flex)); } } private static void setFlexWrap() { String flexWrap = mInlineMap.get(FLEXWRAP); if (flexWrap != null) { CSSWrap ifWrap = Integer.parseInt(flexWrap) > 0 ? CSSWrap.WRAP : CSSWrap.NOWRAP; mNode.setWrap(ifWrap); } } private static void setSize() { String width = mInlineMap.get(WIDTH); if (width != null) { mNode.setStyleWidth(pixelFloat(width)); } String height = mInlineMap.get(HEIGHT); if (height != null) { mNode.setStyleHeight(pixelFloat(height)); } } private static void setMinSize() { String width = mInlineMap.get(MINWIDTH); if (width != null) { mNode.setStyleMinWidth(pixelFloat(width)); } String height = mInlineMap.get(MINHEIGHT); if (height != null) { mNode.setStyleMinWidth(pixelFloat(height)); } } private static void setMaxSize() { String width = mInlineMap.get(MAXWIDTH); if (width != null) { mNode.setStyleMaxWidth(pixelFloat(width)); } String height = mInlineMap.get(MAXHEIGHT); if (height != null) { mNode.setStyleMaxHeight(pixelFloat(height)); } } private static void setMargin() { String margin = mInlineMap.get(MARGIN); if (margin != null) { Float fMargin = pixelFloat(margin); mNode.setMargin(Spacing.LEFT, fMargin); mNode.setMargin(Spacing.TOP, fMargin); mNode.setMargin(Spacing.BOTTOM, fMargin); mNode.setMargin(Spacing.RIGHT, fMargin); } String marginLeft = mInlineMap.get(MARGINLEFT); if (marginLeft != null) { mNode.setMargin(Spacing.LEFT, pixelFloat(marginLeft)); } String marginTop = mInlineMap.get(MARGINTOP); if (marginTop != null) { mNode.setMargin(Spacing.TOP, pixelFloat(marginTop)); } String marginBottom = mInlineMap.get(MARGINBOTTOM); if (marginBottom != null) { mNode.setMargin(Spacing.BOTTOM, pixelFloat(marginBottom)); } String marginRight = mInlineMap.get(MARGINRIGHT); if (marginRight != null) { mNode.setMargin(Spacing.RIGHT, pixelFloat(marginRight)); } } private static void setPadding() { String padding = mInlineMap.get(PADDING); if (padding != null) { Float mPadding = pixelFloat(padding); mNode.setPadding(Spacing.LEFT, mPadding); mNode.setPadding(Spacing.TOP, mPadding); mNode.setPadding(Spacing.BOTTOM, mPadding); mNode.setPadding(Spacing.RIGHT, mPadding); } String paddingLeft = mInlineMap.get(PADDINGLEFT); if (paddingLeft != null) { mNode.setPadding(Spacing.LEFT, pixelFloat(paddingLeft)); } String paddingTop = mInlineMap.get(PADDINGTOP); if (paddingTop != null) { mNode.setPadding(Spacing.TOP, pixelFloat(paddingTop)); } String paddingBottom = mInlineMap.get(PADDINGBOTTOM); if (paddingBottom != null) { mNode.setPadding(Spacing.BOTTOM, pixelFloat(paddingBottom)); } String paddingRight = mInlineMap.get(PADDINGRIGHT); if (paddingRight != null) { mNode.setPadding(Spacing.RIGHT, pixelFloat(paddingRight)); } } private static void setSizeToFit() { String fit = mInlineMap.get(SIZETOFIT); if (fit != null) { mNode.setSizeToFit(Integer.parseInt(fit) > 0); } } private static Map<String, String> resetInlineMap() { List<String> items = Arrays.asList(mCssString.split("\\s*,\\s*")); Map<String, String> resultMap = new HashMap<String, String>(); for (int i = 0; i < items.size(); i++) { String kv = items.get(i); try { List<String> keyAndValue = Arrays.asList(kv.split("\\s*:\\s*")); String key = keyAndValue.get(0); if (!validCssKeys.contains(key)) { Log.d(TAG, "getInlineMap: with un correct key: " + key + " check in" + validCssKeys); } else { resultMap.put(keyAndValue.get(0), keyAndValue.get(1)); } } catch (Exception e) { Log.e(TAG, "getInlineMap: wrong", e); continue; } } Log.d(TAG, "getInlineMap: " + items + "resultMap: " + resultMap); mInlineMap = resultMap; return mInlineMap; } private static final Set<String> validCssKeys; static { validCssKeys = new HashSet<String>(Arrays.asList( POSITION, TOP, LEFT, RIGHT, BOTTOM, FLEXDEIRECTION, ALIGNITEMS, ALIGNCONTENT, ALIGNSELF, JUSTIFYCONTENT, FLEX, FLEXWRAP, WIDTH, HEIGHT, MINWIDTH, MINHEIGHT, MAXWIDTH, MAXHEIGHT, MARGIN, MARGINLEFT, MARGINTOP, MARGINBOTTOM, MARGINRIGHT, PADDING, PADDINGLEFT, PADDINGTOP, PADDINGBOTTOM, PADDINGRIGHT, SIZETOFIT )); } private static final Map<String, CSSFlexDirection> directionMap; static { directionMap = new HashMap<String, CSSFlexDirection>(); directionMap.put(FLEXDIRECTIONCOLUMN, CSSFlexDirection.COLUMN); directionMap.put(FLEXDIRECTIONROW, CSSFlexDirection.ROW); directionMap.put(FLEXDIRECTIONCOLUMNREVERSE, CSSFlexDirection.COLUMN_REVERSE); directionMap.put(FLEXDIRECTIONROWREVERSE, CSSFlexDirection.ROW_REVERSE); } private static final Map<String, CSSAlign> alignMap; static { alignMap = new HashMap<String, CSSAlign>(); alignMap.put(ALIGNAUTO, CSSAlign.AUTO); alignMap.put(ALIGNCENTER, CSSAlign.CENTER); alignMap.put(ALIGNSTART, CSSAlign.FLEX_START); alignMap.put(ALIGNEND, CSSAlign.FLEX_END); alignMap.put(ALIGNSTRETCH, CSSAlign.STRETCH); } private static final Map<String, CSSJustify> justifyMap; static { justifyMap = new HashMap<String, CSSJustify>(); justifyMap.put(JUSTIFYCONTENTAROUND, CSSJustify.SPACE_AROUND); justifyMap.put(JUSTIFYCONTENTBETWEEN, CSSJustify.SPACE_BETWEEN); justifyMap.put(JUSTIFYCONTENTCENTER, CSSJustify.CENTER); justifyMap.put(JUSTIFYCONTENTSTART, CSSJustify.FLEX_START); justifyMap.put(JUSTIFYCONTENTEND, CSSJustify.FLEX_END); } }