Fix fontSize values
authorAryeh Gregor <AryehGregor+gitcommit@gmail.com>
Mon, 01 Aug 2011 12:43:25 -0600
changeset 476 78f24fe9ebbf
parent 475 c9ad44506915
child 477 304204457dab
Fix fontSize values

This is a horrible hack, but generalizing it would be pointlessly
complicated.
editing.html
implementation.js
source.html
tests.js
--- a/editing.html	Fri Jul 29 15:08:40 2011 -0600
+++ b/editing.html	Mon Aug 01 12:43:25 2011 -0600
@@ -666,6 +666,13 @@
   seems to return the string "false", and IE9 seems to return boolean false.
   -->
 
+  <li>If <var title="">command</var> is "fontSize" and its <a href=#value-override>value override</a>
+  is set, convert the <a href=#value-override>value override</a> to an integer number of
+  pixels and return the <a href=#legacy-font-size-for>legacy font size for</a> the result.
+  <!-- Yuck.  This is incredibly messy, as are lots of other fontSize-related
+  things, but I don't want to define a whole second notion of value for the
+  sake of a single command . . . -->
+
   <li>If the <a href=#value-override>value override</a> for <var title="">command</var> is set, return
   it.
 
@@ -3686,6 +3693,12 @@
   <li>Add ("fontSize", <var title="">node</var>'s <a href=#effective-command-value>effective command value</a>
   for "fontSize") to <var title="">overrides</var>.
 
+  <p class=XXX>This is wrong: it will convert non-pixel sizes to pixel sizes.
+  But I don't see any way to avoid it.  Hopefully it won't come up too often.
+  font-size is a real problem, because the mapping from specified value to
+  computed value is lossy and not fully defined (e.g., how many px is
+  "small"?).
+
   <li>Return <var title="">overrides</var>.
 </ol>
 
--- a/implementation.js	Fri Jul 29 15:08:40 2011 -0600
+++ b/implementation.js	Mon Aug 01 12:43:25 2011 -0600
@@ -656,6 +656,14 @@
 			return "";
 		}
 
+		// "If command is "fontSize" and its value override is set, convert the
+		// value override to an integer number of pixels and return the legacy
+		// font size for the result."
+		if (command == "fontsize"
+		&& getValueOverride("fontsize") !== undefined) {
+			return getLegacyFontSize(getValueOverride("fontsize"));
+		}
+
 		// "If the value override for command is set, return it."
 		if (typeof getValueOverride(command) != "undefined") {
 			return getValueOverride(command);
@@ -3088,14 +3096,35 @@
 		if (node === undefined) {
 			node = getActiveRange().startContainer;
 		}
-		var pixelSize = parseInt(getEffectiveCommandValue(node, "fontsize"));
+		var pixelSize = getEffectiveCommandValue(node, "fontsize");
 
 		// "Return the legacy font size for pixel size."
 		return getLegacyFontSize(pixelSize);
 	}, relevantCssProperty: "fontSize"
 };
 
-function getLegacyFontSize(pixelSize) {
+function getLegacyFontSize(size) {
+	// For convenience in other places in my code, I handle all sizes, not just
+	// pixel sizes as the spec says.  This means pixel sizes have to be passed
+	// in suffixed with "px", not as plain numbers.
+	size = normalizeFontSize(size);
+
+	if (["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "xxx-large"].indexOf(size) == -1
+	&& !/^[0-9]+(\.[0-9]+)?(cm|mm|in|pt|pc|px)$/.test(size)) {
+		// There is no sensible legacy size for things like "2em".
+		return null;
+	}
+
+	var font = document.createElement("font");
+	document.body.appendChild(font);
+	if (size == "xxx-large") {
+		font.size = 7;
+	} else {
+		font.style.fontSize = size;
+	}
+	var pixelSize = parseInt(getComputedStyle(font).fontSize);
+	document.body.removeChild(font);
+
 	// "Let returned size be 1."
 	var returnedSize = 1;
 
--- a/source.html	Fri Jul 29 15:08:40 2011 -0600
+++ b/source.html	Mon Aug 01 12:43:25 2011 -0600
@@ -612,6 +612,13 @@
   seems to return the string "false", and IE9 seems to return boolean false.
   -->
 
+  <li>If <var>command</var> is "fontSize" and its <span>value override</span>
+  is set, convert the <span>value override</span> to an integer number of
+  pixels and return the <span>legacy font size for</span> the result.
+  <!-- Yuck.  This is incredibly messy, as are lots of other fontSize-related
+  things, but I don't want to define a whole second notion of value for the
+  sake of a single command . . . -->
+
   <li>If the <span>value override</span> for <var>command</var> is set, return
   it.
 
@@ -3680,6 +3687,12 @@
   <li>Add ("fontSize", <var>node</var>'s <span>effective command value</span>
   for "fontSize") to <var>overrides</var>.
 
+  <p class=XXX>This is wrong: it will convert non-pixel sizes to pixel sizes.
+  But I don't see any way to avoid it.  Hopefully it won't come up too often.
+  font-size is a real problem, because the mapping from specified value to
+  computed value is lossy and not fully defined (e.g., how many px is
+  "small"?).
+
   <li>Return <var>overrides</var>.
 </ol>
 
--- a/tests.js	Fri Jul 29 15:08:40 2011 -0600
+++ b/tests.js	Mon Aug 01 12:43:25 2011 -0600
@@ -3757,7 +3757,9 @@
 			value = "#" + value;
 		}
 	} else if (command == "fontsize") {
+		beforeValue = legacySizeToCss(beforeValue);
 		afterValue = legacySizeToCss(afterValue);
+		value = legacySizeToCss(getLegacyFontSize(value));
 	} else if (command == "formatblock") {
 		value = value.replace(/^<(.*)>$/, "$1").toLowerCase();
 	} else if (command == "unlink") {
@@ -3769,6 +3771,12 @@
 		afterDiv.lastChild.className = beforeValue === afterValue
 			? "good-result"
 			: "bad-result";
+	} else if (command == "fontsize"
+	&& value === undefined) {
+		// It should just do nothing.
+		afterDiv.lastChild.className = beforeValue === afterValue
+			? "good-result"
+			: "bad-result";
 	} else if (/^justify(center|full|left|right)$/.test(command)) {
 		// We know there are only four correct values beforehand, and afterward
 		// the value has to be the one we set.