Last active
May 19, 2016 13:01
-
-
Save w3core/1417a245ca42559d8cb9c45dc2740da6 to your computer and use it in GitHub Desktop.
Translates all textual parts of "content" rule in CSS stylesheet file. Accepts an optional `translate-values` interpolate parameters to pass dynamized values though translation.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* angular-translate - v2.10.0 - 2016-02-28 | |
* | |
* Copyright (c) 2016 The angular-translate team, Pascal Precht; Licensed MIT | |
*/ | |
(function (root, factory) { | |
if (typeof define === 'function' && define.amd) { | |
// AMD. Register as an anonymous module unless amdModuleId is set | |
define([], function () { | |
return (factory()); | |
}); | |
} else if (typeof exports === 'object') { | |
// Node. Does not work with strict CommonJS, but | |
// only CommonJS-like environments that support module.exports, | |
// like Node. | |
module.exports = factory(); | |
} else { | |
factory(); | |
} | |
}(this, function () { | |
angular.module('pascalprecht.translate') | |
/** | |
* @ngdoc object | |
* @name pascalprecht.translate.$translateStylesheetFiles | |
* @requires $compile | |
* @requires $http | |
* | |
* @description | |
* Complete manual: https://gist.github.com/w3core/1417a245ca42559d8cb9c45dc2740da6 | |
* Translates all textual parts of "content" rule in CSS stylesheet file. | |
* Accepts an optional `translate-values` interpolate parameters to pass | |
* dynamized values though translation. | |
* | |
* @param {string=} translate-values Values to pass into translation id. Can be passed as object literal string or interpolated object. | |
* | |
* @example | |
<example> | |
<file name="index.html"> | |
<link translate rel="stylesheet" href="style.css" /> | |
<link translate translate-values="{{values}}" rel="stylesheet" href="style.css" /> | |
<link translate translate-values="{value: 5}" rel="stylesheet" href="style.css" /> | |
</file> | |
<file name="style.css"> | |
.selector-1:before { | |
content: "TRANSLATION_ID"; | |
display: block; | |
color: red; | |
} | |
.selector-2:after { | |
content: "Not translatable value because 'translate:none' property defined"; | |
translate: none; | |
} | |
.selector-3:before { | |
content: attr(attribute-A) "Some translation ID" attr(attribute-B); | |
} | |
</file> | |
</example> | |
* | |
* @author Max Chuhryaev | |
*/ | |
.directive('link', $translateStylesheetFiles); | |
function $translateStylesheetFiles ($compile, $http) { | |
function clearHREF (href, base) { | |
var s = (typeof href == 'string') ? href.replace(/([?#].*)$/i, '') : ''; | |
if (base) s = s.replace(/[^\/]+$/i, ''); | |
return s; | |
} | |
function extractContentProps (string) { | |
var array = []; | |
string | |
.replace(/\/\*[\s\S]*?\*\//g, ' ') | |
.replace(/@[-a-zA-Z]*?keyframes[^{]+\{[\s\S]+?}\s*}/g, ' ') | |
.replace(/(@media[^{]+)\{([\s\S]+?})\s*}/g, function ($0, $1, $2){ | |
var list = extractContentProps($2); | |
for (var i=0; i<list.length; i++) { | |
list[i].media = $1; | |
array.push(list[i]); | |
} | |
return ' '; | |
}) | |
.replace(/[^}]+{[^}]*?translate\s*\:\s*none\s*[;\r\n\t]+?[^}]*?}/g, ' ') | |
.replace(/([^}]+){[^}]*?content[: ]+([^;}\r\n\t]+)[;\r\n\t]*?[^}]*?}/g, function($0, $1, $2){ | |
if (!hasTranslatableContent($2)) return; | |
array.push({ selector:$1, content:$2 }); | |
}); | |
return array; | |
} | |
function hasTranslatableContent (string) { | |
var result = false; | |
string.replace(/(["'])((?:(?!\1)[^\\]|(?:\\\\)*\\[^\\])*)\1/g, function(string, quote, value){ | |
if (value.trim().length) result = true; | |
}); | |
return result; | |
} | |
function prepareContentProperty (string, vars) { | |
var $var, $obj; | |
if (typeof vars == "string" && vars.trim()) { | |
var values = /^\s*\{\{\s*([^{}]+?)\s*\}\}\s*$/.exec(vars); | |
if (values && values[1].trim()) $var = values[1].trim(); | |
else if (/^\s*\{[^{].+[^}]\}\s*$/.exec(vars)) $obj = vars.trim(); | |
} | |
return string.replace(/(["'])((?:(?!\1)[^\\]|(?:\\\\)*\\[^\\])*)\1/g, function(string, quote){ | |
var antiquote = quote == '"' ? "'" : '"'; | |
var vars = $var ? (":" + $var) | |
: $obj ? (":" + antiquote + $obj + antiquote) | |
: ''; | |
return quote + "{{" + string + "|translate"+vars+"}}" + quote; | |
}); | |
} | |
function insertAfter (newNode, referenceNode) { | |
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); | |
} | |
return { | |
restrict: 'E', | |
compile: function ($element, $attr) { | |
if (typeof $attr.notTranslate != 'undefined') return; | |
if (typeof $attr.translate != 'undefined' && clearHREF($attr.href).match(/\.css$/i)) { | |
return function ($scope, $element, $attr) { | |
var node = document.createElement("style"); | |
node.setAttribute("translation-href", $attr.href); | |
insertAfter(node, $element[0]); | |
$http.get($attr.href).success(function(string){ | |
var css = "", array = extractContentProps(string); | |
for (var i=0; i<array.length; i++) { | |
if (array[i].media && array[i].media.trim()) css+= array[i].media + "{\n"; | |
css += array[i].selector.trim() | |
+ "{content:" | |
+ prepareContentProperty(array[i].content, $attr.translateValues).replace(/(\\)/g, "\\\\") | |
+ ";}\n" | |
; | |
if (array[i].media && array[i].media.trim()) css+= "}\n"; | |
} | |
if (!css.length) return (!node.parentNode.removeChild(node)); | |
if (node.styleSheet) node.styleSheet.cssText = css; | |
else node.appendChild(document.createTextNode(css)); | |
$compile(node)($scope); | |
}); | |
}; | |
} | |
} | |
}; | |
} | |
$translateStylesheetFiles.$inject = ['$compile', '$http']; | |
$translateStylesheetFiles.displayName = '$translateStylesheetFiles'; | |
return 'pascalprecht.translate'; | |
})); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Angular Translate Stylesheet Files
Translates all textual parts of
content
rule in CSS stylesheet file.translate-values
interpolate parameters to pass dynamic values through translation.translate
with valuenone
to prevent translation of current CSS rule-set.not-translate
parameter to prevent translation of stylesheet file.Quick Start
Dependencies
Make sure to embed it in your HTML document.
Make sure that generic logic for angular-translate was integrated and then you can start working with CSS.
Add attribute
translate
to enable translation of stylesheet file.You can use an optional attribute
translate-values
to pass dynamic values through translation.Also you can use an optional CSS property
translate
with valuenone
to prevent translation of any CSS rule-set inside CSS file.An example of some stylesheet file:
Voila
Known conflicts
This library working correctly witn
<link>
tags and does not replaces it. It creates another one<style>
tag that extends an original stylesheets. But make sure that you have not using any CSS preprocessing javascript libraries which can to remove<link>
node that leads to prevent of translation logic. For example -prefix-free javascript library replaces<link>
node to compiled<style>
node. In this case you should implement delayed loading logic for all libraries like this. Following code demonstrates how to implement delayed loading logic in your AngularJS application:-- Have a nice day