CSSNamespaceRule.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. //.CommonJS
  2. var CSSOM = {
  3. CSSRule: require("./CSSRule").CSSRule,
  4. CSSStyleSheet: require("./CSSStyleSheet").CSSStyleSheet
  5. };
  6. ///CommonJS
  7. /**
  8. * @constructor
  9. * @see https://drafts.csswg.org/cssom/#the-cssnamespacerule-interface
  10. */
  11. CSSOM.CSSNamespaceRule = function CSSNamespaceRule() {
  12. CSSOM.CSSRule.call(this);
  13. this.__prefix = "";
  14. this.__namespaceURI = "";
  15. };
  16. CSSOM.CSSNamespaceRule.prototype = Object.create(CSSOM.CSSRule.prototype);
  17. CSSOM.CSSNamespaceRule.prototype.constructor = CSSOM.CSSNamespaceRule;
  18. Object.setPrototypeOf(CSSOM.CSSNamespaceRule, CSSOM.CSSRule);
  19. Object.defineProperty(CSSOM.CSSNamespaceRule.prototype, "type", {
  20. value: 10,
  21. writable: false
  22. });
  23. Object.defineProperty(CSSOM.CSSNamespaceRule.prototype, "cssText", {
  24. get: function() {
  25. return "@namespace" + (this.prefix && " " + this.prefix) + " url(\"" + this.namespaceURI + "\");";
  26. }
  27. });
  28. Object.defineProperty(CSSOM.CSSNamespaceRule.prototype, "prefix", {
  29. get: function() {
  30. return this.__prefix;
  31. }
  32. });
  33. Object.defineProperty(CSSOM.CSSNamespaceRule.prototype, "namespaceURI", {
  34. get: function() {
  35. return this.__namespaceURI;
  36. }
  37. });
  38. /**
  39. * NON-STANDARD
  40. * Rule text parser.
  41. * @param {string} cssText
  42. */
  43. Object.defineProperty(CSSOM.CSSNamespaceRule.prototype, "parse", {
  44. value: function(cssText) {
  45. var newPrefix = "";
  46. var newNamespaceURI = "";
  47. // Remove @namespace and trim
  48. var text = cssText.trim();
  49. if (text.indexOf('@namespace') === 0) {
  50. text = text.slice('@namespace'.length).trim();
  51. }
  52. // Remove trailing semicolon if present
  53. if (text.charAt(text.length - 1) === ';') {
  54. text = text.slice(0, -1).trim();
  55. }
  56. // Regex to match valid namespace syntax:
  57. // 1. [optional prefix] url("...") or [optional prefix] url('...') or [optional prefix] url() or [optional prefix] url(unquoted)
  58. // 2. [optional prefix] "..." or [optional prefix] '...'
  59. // The prefix must be a valid CSS identifier (letters, digits, hyphens, underscores, starting with letter or underscore)
  60. var re = /^(?:([a-zA-Z_][a-zA-Z0-9_-]*)\s+)?(?:url\(\s*(?:(['"])(.*?)\2\s*|([^)]*?))\s*\)|(['"])(.*?)\5)$/;
  61. var match = text.match(re);
  62. if (match) {
  63. // If prefix is present
  64. if (match[1]) {
  65. newPrefix = match[1];
  66. }
  67. // If url(...) form with quotes
  68. if (typeof match[3] !== "undefined") {
  69. newNamespaceURI = match[3];
  70. }
  71. // If url(...) form without quotes
  72. else if (typeof match[4] !== "undefined") {
  73. newNamespaceURI = match[4].trim();
  74. }
  75. // If quoted string form
  76. else if (typeof match[6] !== "undefined") {
  77. newNamespaceURI = match[6];
  78. }
  79. this.__prefix = newPrefix;
  80. this.__namespaceURI = newNamespaceURI;
  81. } else {
  82. throw new DOMException("Invalid @namespace rule", "InvalidStateError");
  83. }
  84. }
  85. });
  86. //.CommonJS
  87. exports.CSSNamespaceRule = CSSOM.CSSNamespaceRule;
  88. ///CommonJS