add text metrics to the metrics harvester

This commit is contained in:
Elm UI Automation 2020-05-04 22:38:55 -04:00
parent 80e267c890
commit 4ea86ab0d8
2 changed files with 129 additions and 57 deletions

View File

@ -46,7 +46,7 @@ program tests =
cur :: remaining ->
( Just cur, remaining )
in
Browser.document
Browser.element
{ init =
always
( { current = current
@ -136,8 +136,9 @@ type Msg
(List
{ id : String
, bbox : Testable.BoundingBox
, isVisible : Bool
, style : List ( String, String )
, isVisible : Bool
, textMetrics : List TextMetrics
}
)
@ -225,70 +226,61 @@ update msg model =
)
view : Model Msg -> Browser.Document Msg
view : Model Msg -> Html.Html Msg
view model =
case model.current of
Nothing ->
if List.isEmpty model.upcoming then
{ title = "tests finished"
, body =
[ case model.finished of
[] ->
Element.layout [] <|
Element.column
case model.finished of
[] ->
Element.layout [] <|
Element.column
[ Element.spacing 20
, Element.padding 20
, Element.width (Element.px 800)
]
[ Element.none ]
finished :: remaining ->
Element.layout
[ Font.size 16
, Element.inFront (Element.html (viewElementHighlight model))
]
<|
Element.row [ Element.width Element.fill ]
[ Element.el
[ Element.width Element.fill
]
(Element.el
[ Element.centerX
, Element.padding 100
, Border.dashed
, Border.width 2
, Border.color palette.lightGrey
, Font.size 20
, Element.inFront
(Element.el
[ Font.size 14
, Font.color palette.lightGrey
]
(Element.text "test case")
)
]
(Testable.toElement finished.element)
)
, Element.column
[ Element.spacing 20
, Element.padding 20
, Element.width (Element.px 800)
, Element.width Element.fill
]
[ Element.none ]
finished :: remaining ->
Element.layout
[ Font.size 16
, Element.inFront (Element.html (viewElementHighlight model))
(List.map viewResult (finished :: remaining))
]
<|
Element.row [ Element.width Element.fill ]
[ Element.el
[ Element.width Element.fill
]
(Element.el
[ Element.centerX
, Element.padding 100
, Border.dashed
, Border.width 2
, Border.color palette.lightGrey
, Font.size 20
, Element.inFront
(Element.el
[ Font.size 14
, Font.color palette.lightGrey
]
(Element.text "test case")
)
]
(Testable.toElement finished.element)
)
, Element.column
[ Element.spacing 20
, Element.padding 20
, Element.width Element.fill
]
(List.map viewResult (finished :: remaining))
]
]
}
else
{ title = "tests finished"
, body = []
}
Html.text ""
Just ( label, current ) ->
{ title = "running"
, body =
[ Testable.toHtml current ]
}
Testable.toHtml current
viewElementHighlight model =
@ -492,7 +484,17 @@ port styles :
, bbox : Testable.BoundingBox
, style : List ( String, String )
, isVisible : Bool
, textMetrics : List TextMetrics
}
-> msg
)
-> Sub msg
type alias TextMetrics =
{ actualBoundingBoxAscent : Float
, actualBoundingBoxDescent : Float
, actualBoundingBoxLeft : Float
, actualBoundingBoxRight : Float
, width : Float
}

View File

@ -6,10 +6,45 @@
<script type="text/javascript" src="./elm.js"></script>
</head>
<style></style>
<body id="root"></body>
<body id="root">
<div id="elm-home"></div>
<canvas id="canvas"></canvas>
</body>
<script type="text/javascript">
var app = Elm.WeirdCentering.init();
// Calculations for canvas
var PIXEL_RATIO = (function () {
var ctx = document.createElement("canvas").getContext("2d"),
dpr = window.devicePixelRatio || 1,
bsr =
ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio ||
1;
return dpr / bsr;
})();
function createHiDPICanvas(w, h, id, ratio) {
if (!ratio) {
ratio = PIXEL_RATIO;
}
let can = document.getElementById(id);
can.width = w * ratio;
can.height = h * ratio;
can.style.width = w + "px";
can.style.height = h + "px";
can.getContext("2d").setTransform(ratio, 0, 0, ratio, 0, 0);
return can;
}
// create a canvas for text measurements
let canvas = createHiDPICanvas(200, 100, "canvas");
// Starting Elm App,
var app = Elm.WeirdCentering.init({
node: document.getElementById("elm-home"),
});
var test_results = "waiting..";
@ -29,10 +64,17 @@
}
var style = getStyle(element);
var bbox = getBoundingBox(element);
var metrics = getTextMetrics(element);
var visible = isVisible(id, bbox);
var result = { bbox: bbox, style: style, id: id, isVisible: visible };
var result = {
textMetrics: metrics,
bbox: bbox,
style: style,
id: id,
isVisible: visible,
};
results.push(result);
}
app.ports.styles.send(results);
@ -100,5 +142,33 @@
padding: padding,
};
}
function getTextMetrics(element) {
// Given our element, we want to return the text metrics on the text within.
// If it is an element we want to measure:
// we want to get the font family
// and the font size.
// We're going to presume that the font is loaded.
let childrenTextMetrics = [];
for (i = 0; i < element.children.length; i++) {
if (element.children[i].classList.contains("t")) {
let style = window.getComputedStyle(element, null);
let fontSize = style.getPropertyValue("font-size");
let fontFamily = style.getPropertyValue("font-family");
let ctx = canvas.getContext("2d");
ctx.font = fontSize + " " + fontFamily; //"16px Roboto";
let text = ctx.measureText(element.children[i].innerText);
childrenTextMetrics.push({
actualBoundingBoxAscent: text.actualBoundingBoxAscent,
actualBoundingBoxDescent: text.actualBoundingBoxDescent,
actualBoundingBoxLeft: text.actualBoundingBoxLeft,
actualBoundingBoxRight: text.actualBoundingBoxRight,
width: text.width,
});
}
}
return childrenTextMetrics;
}
</script>
</html>