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 hidden or 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'; | |
| })); |
Author
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
contentrule in CSS stylesheet file.translate-valuesinterpolate parameters to pass dynamic values through translation.translatewith valuenoneto prevent translation of current CSS rule-set.not-translateparameter 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
translateto enable translation of stylesheet file.You can use an optional attribute
translate-valuesto pass dynamic values through translation.Also you can use an optional CSS property
translatewith valuenoneto 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