font_css_property.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. function extend(dest, org) {
  2. for (var key in org) {
  3. dest[key] = org[key];
  4. }
  5. return dest;
  6. }
  7. var FontCssProperty = function() {
  8. this.empty = true;
  9. this.shorthand = false;
  10. this.properties = {};
  11. };
  12. FontCssProperty.TAGS_FOR_PRESENTATION = {
  13. U: { textDecoration: "underline" },
  14. B: { fontWeight: "bold" },
  15. STRONG: { fontWeight: "bold" },
  16. I: { fontStyle: "italic" },
  17. EM: { fontStyle: "italic" },
  18. // SUB: { fontSize: "smaller", verticalAlign: "sub"},
  19. // SUP: { fontSize: "smaller", verticalAlign: "super"},
  20. // BIG: { fontSize: "larger" },
  21. // SMALL: { fontSize: "smaller" },
  22. S: { textDecoration: "line-through" },
  23. STRIKE: { textDecoration: "line-through" },
  24. INS: { textDecoration: "underline" },
  25. DEL: { textDecoration: "line-through" },
  26. FONT: function(attributes) {
  27. var result = {};
  28. if (attributes.face) {
  29. result.fontFamily = attributes.face;
  30. }
  31. if (attributes.color) {
  32. result.color = attributes.color;
  33. }
  34. var fontSizeMap = ["", "x-small", "small", "medium", "large", "x-large", "xx-large"];
  35. if (attributes.size) {
  36. var fontSize = attributes.size;
  37. result.fontSize = isNaN(fontSize) ?
  38. fontSize : fontSizeMap[Math.min(Math.max(1, fontSize), 6)];
  39. }
  40. return result;
  41. }
  42. };
  43. FontCssProperty.FONT_RELATED_CSS_PROPERTIES = {
  44. "font": "font",
  45. "font-style": "fontStyle",
  46. "font-weight": "fontWeight",
  47. "font-size": "fontSize",
  48. "font-family": "fontFamily",
  49. "text-decoration": "textDecoration",
  50. "color": "color",
  51. "background-color": "backgroundColor"
  52. };
  53. FontCssProperty.create = function(nodeName, attributes) {
  54. var fontCssProperty = new FontCssProperty();
  55. var elemStyle = FontCssProperty.TAGS_FOR_PRESENTATION[nodeName];
  56. if (elemStyle) {
  57. var fontTagStyle = (typeof elemStyle == "function") ? elemStyle(attributes) : elemStyle;
  58. for (var name in fontTagStyle) {
  59. fontCssProperty.setProperty(name, fontTagStyle[name]);
  60. }
  61. }
  62. var cssText = attributes.style;
  63. if (cssText) {
  64. cssText = cssText.replace(/[\w-]+:\s?;/g, "");
  65. var properties = cssText.split(/; ?|: ?/);
  66. for (var i = 0; i < properties.length - 1; i += 2) {
  67. var styleName = FontCssProperty.FONT_RELATED_CSS_PROPERTIES[properties[i].toLowerCase()];
  68. if (styleName) {
  69. // block에 지정된 backgroundColor style은 가져오지 않는다.
  70. // TODO font related tags
  71. if (styleName != "backgroundColor" || (FontCssProperty.TAGS_FOR_PRESENTATION[nodeName] || nodeName == "SPAN")) {
  72. fontCssProperty.setProperty(styleName, properties[i + 1]);
  73. }
  74. }
  75. }
  76. }
  77. return fontCssProperty.getComputedStyles();
  78. };
  79. FontCssProperty.FONT_CSS_REGEXP = /(.*?)(\w+)(\/\w+)?\s+(['"]?[\w\uac00-\ud7a3]+['"]?)$/;
  80. FontCssProperty.NORMAL_VALUE = "normal";
  81. FontCssProperty.prototype.isEmpty = function() {
  82. return this.empty;
  83. };
  84. FontCssProperty.prototype.setProperty = function(name, value) {
  85. if (/^font$/i.test(name)) {
  86. // because of opera
  87. var parsedProperties = this.fromShorthand(value);
  88. if (parsedProperties) {
  89. this.shorthand = true;
  90. extend(this.properties, this.fromShorthand(value));
  91. }
  92. } else {
  93. this.properties[name] = value;
  94. }
  95. this.empty = false;
  96. };
  97. FontCssProperty.prototype.getComputedStyles = function() {
  98. if (this.shorthand) {
  99. return this.toShorthand();
  100. } else {
  101. return extend({}, this.properties);
  102. }
  103. };
  104. FontCssProperty.prototype.fromShorthand = function(fontCssText) {
  105. // parse extra font-families
  106. var indexOfComma = fontCssText.indexOf(","), extraFontFamilies = "";
  107. if (indexOfComma > 0) {
  108. extraFontFamilies = fontCssText.substring(indexOfComma);
  109. fontCssText = fontCssText.substring(0, indexOfComma);
  110. }
  111. var splittedProperties = fontCssText.match(FontCssProperty.FONT_CSS_REGEXP);
  112. if (splittedProperties === _NULL) { // invalid font css property value
  113. return _NULL;
  114. }
  115. var NORMAL = FontCssProperty.NORMAL_VALUE;
  116. // parse main properties
  117. var properties = {
  118. fontSize: splittedProperties[2],
  119. lineHeight: (splittedProperties[3] || NORMAL).replace("/", ""),
  120. fontFamily: splittedProperties[4] + extraFontFamilies,
  121. fontWeight: NORMAL,
  122. fontStyle: NORMAL,
  123. fontVariant: NORMAL
  124. };
  125. // parse optional properties
  126. var optionalProperties = splittedProperties[1];
  127. if (/bold|700/i.test(optionalProperties)) {
  128. properties.fontWeight = "bold";
  129. }
  130. if (/italic/i.test(optionalProperties)) {
  131. properties.fontStyle = "italic";
  132. }
  133. if (/small-caps/i.test(optionalProperties)) {
  134. properties.fontVarient = "small-caps";
  135. }
  136. return properties;
  137. };
  138. FontCssProperty.prototype.toShorthand = function() {
  139. var propertiesClone = extend({}, this.properties);
  140. var NORMAL = FontCssProperty.NORMAL_VALUE;
  141. var validFontProperties = [];
  142. ["fontWeight", "fontStyle", "fontVarient"].each(function(name) {
  143. if (propertiesClone[name] != NORMAL) {
  144. validFontProperties.push(propertiesClone[name]);
  145. }
  146. });
  147. if (propertiesClone.lineHeight != NORMAL) {
  148. validFontProperties.push(propertiesClone.fontSize + "/" + propertiesClone.lineHeight);
  149. } else {
  150. validFontProperties.push(propertiesClone.fontSize);
  151. }
  152. validFontProperties.push(propertiesClone.fontFamily);
  153. ["fontWeight", "fontStyle", "fontVarient", "fontSize", "lineHeight", "fontFamily"].each(function(name) {
  154. delete propertiesClone[name];
  155. });
  156. var result = { font: validFontProperties.join(" ") };
  157. result = extend(result, propertiesClone);
  158. return result;
  159. };