|
1 | | -import {DOM} from 'angular2/src/core/dom/dom_adapter'; |
2 | 1 | import {ListWrapper} from 'angular2/src/core/facade/collection'; |
3 | 2 | import { |
4 | 3 | StringWrapper, |
@@ -144,8 +143,7 @@ export class ShadowCss { |
144 | 143 | * Shim a style element with the given selector. Returns cssText that can |
145 | 144 | * be included in the document via WebComponents.ShadowCSS.addCssToDocument(css). |
146 | 145 | */ |
147 | | - shimStyle(style: string, selector: string, hostSelector: string = ''): string { |
148 | | - var cssText = DOM.getText(style); |
| 146 | + shimStyle(cssText: string, selector: string, hostSelector: string = ''): string { |
149 | 147 | return this.shimCssText(cssText, selector, hostSelector); |
150 | 148 | } |
151 | 149 |
|
@@ -231,8 +229,7 @@ export class ShadowCss { |
231 | 229 | cssText = this._convertColonHostContext(cssText); |
232 | 230 | cssText = this._convertShadowDOMSelectors(cssText); |
233 | 231 | if (isPresent(scopeSelector)) { |
234 | | - _withCssRules(cssText, |
235 | | - (rules) => { cssText = this._scopeRules(rules, scopeSelector, hostSelector); }); |
| 232 | + cssText = this._scopeSelectors(cssText, scopeSelector, hostSelector); |
236 | 233 | } |
237 | 234 | cssText = cssText + '\n' + unscoped; |
238 | 235 | return cssText.trim(); |
@@ -347,50 +344,37 @@ export class ShadowCss { |
347 | 344 |
|
348 | 345 | // change a selector like 'div' to 'name div' |
349 | 346 | /** @internal */ |
350 | | - _scopeRules(cssRules, scopeSelector: string, hostSelector: string): string { |
351 | | - var cssText = ''; |
352 | | - if (isPresent(cssRules)) { |
353 | | - for (var i = 0; i < cssRules.length; i++) { |
354 | | - var rule = cssRules[i]; |
355 | | - if (DOM.isStyleRule(rule) || DOM.isPageRule(rule)) { |
356 | | - cssText += this._scopeSelector(rule.selectorText, scopeSelector, hostSelector, |
357 | | - this.strictStyling) + |
358 | | - ' {\n'; |
359 | | - cssText += this._propertiesFromRule(rule) + '\n}\n\n'; |
360 | | - } else if (DOM.isMediaRule(rule)) { |
361 | | - cssText += '@media ' + rule.media.mediaText + ' {\n'; |
362 | | - cssText += this._scopeRules(rule.cssRules, scopeSelector, hostSelector); |
363 | | - cssText += '\n}\n\n'; |
364 | | - } else { |
365 | | - // KEYFRAMES_RULE in IE throws when we query cssText |
366 | | - // when it contains a -webkit- property. |
367 | | - // if this happens, we fallback to constructing the rule |
368 | | - // from the CSSRuleSet |
369 | | - // https://connect.microsoft.com/IE/feedbackdetail/view/955703/accessing-csstext-of-a-keyframe-rule-that-contains-a-webkit-property-via-cssom-generates-exception |
370 | | - try { |
371 | | - if (isPresent(rule.cssText)) { |
372 | | - cssText += rule.cssText + '\n\n'; |
373 | | - } |
374 | | - } catch (x) { |
375 | | - if (DOM.isKeyframesRule(rule) && isPresent(rule.cssRules)) { |
376 | | - cssText += this._ieSafeCssTextFromKeyFrameRule(rule); |
377 | | - } |
378 | | - } |
| 347 | + _scopeSelectors(cssText: string, scopeSelector: string, hostSelector: string): string { |
| 348 | + var parts = splitCurlyBlocks(cssText); |
| 349 | + var result = []; |
| 350 | + for (var i = 0; i < parts.length; i += 2) { |
| 351 | + var selectorTextWithCommands = parts[i]; |
| 352 | + var selectorStart = selectorTextWithCommands.lastIndexOf(';') + 1; |
| 353 | + var selectorText = |
| 354 | + selectorTextWithCommands.substring(selectorStart, selectorTextWithCommands.length); |
| 355 | + var ruleContent = parts[i + 1]; |
| 356 | + var selectorMatch = RegExpWrapper.firstMatch(_singleSelectorRe, selectorText); |
| 357 | + if (isPresent(selectorMatch) && ruleContent.length > 0) { |
| 358 | + var selPrefix = selectorMatch[1]; |
| 359 | + var selAt = isPresent(selectorMatch[2]) ? selectorMatch[2] : ''; |
| 360 | + var selector = selectorMatch[3]; |
| 361 | + var selSuffix = selectorMatch[4]; |
| 362 | + if (selAt.length === 0 || selAt == '@page') { |
| 363 | + var scopedSelector = |
| 364 | + this._scopeSelector(selector, scopeSelector, hostSelector, this.strictStyling); |
| 365 | + selectorText = `${selPrefix}${selAt}${scopedSelector}${selSuffix}`; |
| 366 | + } else if (selAt == '@media' && ruleContent[0] == OPEN_CURLY && |
| 367 | + ruleContent[ruleContent.length - 1] == CLOSE_CURLY) { |
| 368 | + var scopedContent = this._scopeSelectors(ruleContent.substring(1, ruleContent.length - 1), |
| 369 | + scopeSelector, hostSelector); |
| 370 | + ruleContent = `${OPEN_CURLY}${scopedContent}${CLOSE_CURLY}`; |
379 | 371 | } |
380 | 372 | } |
| 373 | + result.push(selectorTextWithCommands.substring(0, selectorStart)); |
| 374 | + result.push(selectorText); |
| 375 | + result.push(ruleContent); |
381 | 376 | } |
382 | | - return cssText; |
383 | | - } |
384 | | - |
385 | | - /** @internal */ |
386 | | - _ieSafeCssTextFromKeyFrameRule(rule): string { |
387 | | - var cssText = '@keyframes ' + rule.name + ' {'; |
388 | | - for (var i = 0; i < rule.cssRules.length; i++) { |
389 | | - var r = rule.cssRules[i]; |
390 | | - cssText += ' ' + r.keyText + ' {' + r.style.cssText + '}'; |
391 | | - } |
392 | | - cssText += ' }'; |
393 | | - return cssText; |
| 377 | + return result.join(''); |
394 | 378 | } |
395 | 379 |
|
396 | 380 | /** @internal */ |
@@ -477,36 +461,6 @@ export class ShadowCss { |
477 | 461 | selector = StringWrapper.replaceAll(selector, _colonHostRe, _polyfillHost); |
478 | 462 | return selector; |
479 | 463 | } |
480 | | - |
481 | | - /** @internal */ |
482 | | - _propertiesFromRule(rule): string { |
483 | | - var cssText = rule.style.cssText; |
484 | | - // TODO(sorvell): Safari cssom incorrectly removes quotes from the content |
485 | | - // property. (https://bugs.webkit.org/show_bug.cgi?id=118045) |
486 | | - // don't replace attr rules |
487 | | - var attrRe = /['"]+|attr/g; |
488 | | - if (rule.style.content.length > 0 && |
489 | | - !isPresent(RegExpWrapper.firstMatch(attrRe, rule.style.content))) { |
490 | | - var contentRe = /content:[^;]*;/g; |
491 | | - cssText = |
492 | | - StringWrapper.replaceAll(cssText, contentRe, 'content: \'' + rule.style.content + '\';'); |
493 | | - } |
494 | | - // TODO(sorvell): we can workaround this issue here, but we need a list |
495 | | - // of troublesome properties to fix https://github.com/Polymer/platform/issues/53 |
496 | | - // |
497 | | - // inherit rules can be omitted from cssText |
498 | | - // TODO(sorvell): remove when Blink bug is fixed: |
499 | | - // https://code.google.com/p/chromium/issues/detail?id=358273 |
500 | | - // var style = rule.style; |
501 | | - // for (var i = 0; i < style.length; i++) { |
502 | | - // var name = style.item(i); |
503 | | - // var value = style.getPropertyValue(name); |
504 | | - // if (value == 'initial') { |
505 | | - // cssText += name + ': initial; '; |
506 | | - // } |
507 | | - //} |
508 | | - return cssText; |
509 | | - } |
510 | 464 | } |
511 | 465 | var _cssContentNextSelectorRe = |
512 | 466 | /polyfill-next-selector[^}]*content:[\s]*?['"](.*?)['"][;\s]*}([^{]*?){/gim; |
@@ -539,13 +493,34 @@ var _polyfillHostRe = RegExpWrapper.create(_polyfillHost, 'im'); |
539 | 493 | var _colonHostRe = /:host/gim; |
540 | 494 | var _colonHostContextRe = /:host-context/gim; |
541 | 495 |
|
542 | | -function _cssToRules(cssText: string) { |
543 | | - return DOM.cssToRules(cssText); |
| 496 | +var _singleSelectorRe = /^(\s*)(@\S+)?(.*?)(\s*)$/g; |
| 497 | + |
| 498 | +var _curlyRe = /([{}])/g; |
| 499 | +var OPEN_CURLY = '{'; |
| 500 | +var CLOSE_CURLY = '}'; |
| 501 | + |
| 502 | +export function splitCurlyBlocks(cssText:string):string[] { |
| 503 | + var parts = StringWrapper.split(cssText, _curlyRe); |
| 504 | + var result = []; |
| 505 | + var bracketCount = 0; |
| 506 | + var currentCurlyParts = []; |
| 507 | + for (var partIndex = 0; partIndex<parts.length; partIndex++) { |
| 508 | + var part = parts[partIndex]; |
| 509 | + currentCurlyParts.push(part); |
| 510 | + if (part == OPEN_CURLY) { |
| 511 | + bracketCount++; |
| 512 | + } else if (part == CLOSE_CURLY) { |
| 513 | + bracketCount--; |
| 514 | + } |
| 515 | + if (bracketCount === 0) { |
| 516 | + result.push(currentCurlyParts.join('')); |
| 517 | + currentCurlyParts = []; |
| 518 | + } |
| 519 | + } |
| 520 | + result.push(currentCurlyParts.join('')); |
| 521 | + if (result.length >= 2 && result[result.length-1] == '' && result[result.length-2] == '') { |
| 522 | + result = result.slice(0, result.length-2); |
| 523 | + } |
| 524 | + return result; |
544 | 525 | } |
545 | 526 |
|
546 | | -function _withCssRules(cssText: string, callback: Function) { |
547 | | - // Difference from webcomponentjs: remove the workaround for an old bug in Chrome |
548 | | - if (isBlank(callback)) return; |
549 | | - var rules = _cssToRules(cssText); |
550 | | - callback(rules); |
551 | | -} |
0 commit comments