as Web Components, I mean AngularJs's directives here.
I am trying to use special characters as a tag's name, especially asiatic ones (korean even more specifically).
Here's a plunker so you'll get a better grasp on what I try to achieve.
// library
(function (angular) {
angular.module('molecules', [])
.directive('헐', function () { return {
template: 'ㅎㅓㄹ'
}});
})(window.angular);
// main module
(function (angular) {
angular.module('lab', ['molecules']);
})(window.angular);
<div ng-controller="monitor1">
<헐></헐>
</div>
It seems to have to do with how the browser is interpreting the DOM. If you append an alphabet character to the foreign character (in the directive and the start and end tags), it works as expected i.e.
<a헐></a헐>
Note - check out the DOM while you are at it (I was checking in IE11) - notice that the tag is closed with . With <헐> notice that the IE has taken it upon itself to make some modifications. There is also the console error HTML1407: Invalid tag name. First character should match [a-zA-Z].
Related
I noticed something very strange about Angular 1.5.6 components. I have a component called scale. I call it:
<scale x-scale="xScale"></scale>
And in my controller:
$scope.xScale = 'lin'.
And my component definition:
angular
.module('myapp')
.component('scale', {
templateUrl: 'analyse/components/scales/scale.tpl.html',
controller: function(){
console.log('in controller and this is ', this);
},
bindings: {
xScale: '='
},
});
The console log outputs undefined.
But if i change x-scale to r-scale in my template and xScale in the binding to rScale, suddenly it works. In fact it seems that if i replace the x with any other letter, it works. Why is this?
It's in the documentation for directives
Normalization
Angular normalizes an element's tag and attribute name
to determine which elements match which directives.
We typically refer to directives by their case-sensitive camelCase normalized name (e.g. ngModel).
However, since HTML is case-insensitive, we refer to
directives in the DOM by lower-case forms, typically using
dash-delimited attributes on DOM elements (e.g. ng-model).
The normalization process is as follows:
Strip x- and data- from the front of the element/attributes.
Convert the :, -, or _ -delimited name to camelCase.
So Angular strips of x- from the front of any attribute name to normalize it, this is done because both regular data-attributes, starting with data-, and x-attributes, starting with x- is valid in HTML 5.
The HTML5 specification states that
Attribute names beginning with the two characters "x-" are reserved
for user agent use and are guaranteed to never be formally added to
the HTML language.
It also states that
For markup-level features that are intended for use with the HTML
syntax, extensions should be limited to new attributes of the form
"x-vendor-feature", where vendor is a short string that identifies the
vendor responsible for the extension, and feature is the name of the
feature.
The x- attributes aren't used very often, but as noted above they are reserved for browser vendors, and you shouldn't be using them, instead you should be using data-attributes, where incidentally, Angular will also remove the data- part for you, so these
<scale data-scale="scale"></scale>
<scale x-scale="scale"></scale>
<scale scale="scale"></scale>
are all the "same" when you do
$scope.scale = 'lin'.
In our project a lot of angular unit tests contain following syntax:
inject(['dependency1', 'dependency2', function(_dependency1_, _dependency2_) {
dependency1 = _dependency1_;
dependency2 = _dependency2_;
}]);
In tests the array which lists the dependencies with string values is obsolete, since this is only useful when using minification. So we issued a coding convention to change this syntax to:
inject(function(_dependency1_, _dependency2_) {
dependency1 = _dependency1_;
dependency2 = _dependency2_;
});
Now I've been replacing a couple of these in existing code when I came across them, but I've gotten really tired of doing this manually. So I'm trying to solve this in IntelliJ by using structural search and replace. This is my search template so far:
inject([$injection$, function($argument$) {
$statement$;
}]);
with occurrences:
$injection$: 1 to infinite
$argument$: 1 to infinite
$statement$: 1 to infinite
The replace template is defined as follows:
inject(function($argument$) {
$statement$;
});
This does not work for the example I defined in the beginning however, it only matches and replaces correctly for a single line statement in the function body, so following example is replaced correctly:
inject(['dependency1', 'dependency2', function(_dependency1_, _dependency2_) {
dependency1 = _dependency1_;
}]);
Am I missing something? When I check out the simple if-else example on the Jetbrains website I get the feeling that this should work.
I have tried removing the semicolon behind the $statement$ variable, this didn't match multiple lines and resulted in the semicolons being removed after replacement. I've also tried applying a regex expressions to the $statement$ variable, but these didn't help either.
((.*)=(.*);\n)+
didn't match, probably because the semicolon is filtered out by the IntelliJ structural search before the actual regex matching is performed.
(.*)=(.*)
matched, but it replaced with the same behaviour as without the regex.
Matching multiple statements with a variable in JavaScript is currently broken because of a bug.
I have a page that I am using ng-include to pull in a file as rendered HTML. I would like to include that same file as code, next to it.
Is there a way to do this in Angular, or jQuery? I want to be able to include HTML, CSS and potentially JS files as code that would be run through a code-renderer, like Prism or something similar.
This is similar to jsfiddle or codepen, in that you can see the code and rendered view in the same window, but I do not need them to be connected (ie. edit the code to see the rendered result.) I just want to pull both views from the same file.
I am currently using an Angular directive to loop through a JSON file and push out blocks of HTML according to what is listed in the JSON. My directive is:
app.directive('patterns', function() {
return {
restrict: 'E',
require: ['^ngType', 'ngTemplate'],
scope: {
ngType: '#',
ngTemplate: '#'
},
templateUrl: 'patterns.html',
controller: function($scope, $http, $sanitize) {
var theType = $scope.ngType;
$http.get('indexes/json/' + theType + '.json')
.then(function(result) {
$scope.patterns = result.data;
});
},
controllerAs: 'patterns',
link: function(scope, iElement, iAttrs, ctrl) {
scope.getType(iAttrs.ngType);
}
}
});
And I want to add something that also uses pattern.anchor (based off an "anchor" key I have in my JSON) to grab a particular file and output only the code. I can currently use pattern.anchor with ng-include to output rendered HTML, but not only code.
Yes, with angular you can use ngSanitize or the $sanitize service.
There's a simple example available here: http://codepen.io/tipsoftheday/pen/jthks
angular.module('expressionsEscaping', ['ngSanitize'])
.controller('ExpressionsEscapingCtrl', function ($scope, $sanitize) {
$scope.msg = 'Hello, <b>World</b>!';
$scope.safeMsg = $sanitize($scope.msg);
});
and a more complex example available in the Angular documentation here: https://docs.angularjs.org/api/ngSanitize/service/$sanitize.
Ampersand-Delineated Character Entity
In the code, replace all angle brackets < and > with a character entity code < and >. The entity codes get rendered as angle brackets but don't get processed as such. Unfortunately, this doesn't preserve the formatting of your file (read on to see how to do that), since all whitespace gets compressed to a single non-breaking space.
<strong> The strong tag is shown rather
than rendered, but all whitespace characters
still get compressed into a single space.
However, this <br /> break tag gets rendered rather
than shown. </strong>
HTML provides a block-level element called pre. Anything inside the pre tag is considered pre-rendered and the browser displays it as-is. Whitespace in this block does not get condensed. This will preserve the formatting of your code.
<pre>
<strong> In this block, if I add extra spaces, they are shown.
If I move to a newline, that is shown as well.
HTML tags still need to have<br />their angle brackets replaced
in order to be shown rather than rendered.</strong>
</pre>
If you are using JavaScript/AJAX to include the file, you can first do a string replace function to replace the angle brackets with the character entity codes. If you are doing server-side includes, you can do something similar with your server-side language of choice.
If you want to do all of this automatically, Mike Feltman suggested a method using Angular.
This filter is operating on a field that's being loaded from a REST service. It's converting new line characters to <br/> tags and they're getting escaped.
angular.module('myMod').filter('convertBreaks', function($sce) {
return function(input) {
return $sce.trustAsHtml(input.replace(/[\n]/g, "<br/>"));
};
});
It's called like this:
<p>{{data.x.y.z | convertBreaks}}</p>
The <br/> tags are coming out escaped. Any suggestions why?
Update
Forgot to mention that this is being executed by a directive that uses the $compile service.
Try using ng-bind-html
<p ng-bind-html="data.x.y.z | convertBreaks"></p>
Angular has some built in security mechanisms that will cause those kinds of shenanigans.
I'm trying to replace an ASP.NET (C#) server-sided method by an javascript/Jquery method. I'm fairly new to Jquery but all went well until I began with regular expressions.
my code in ASP.NET C#
if ((Regex.Match(postcode.Trim(), #"^[1-9]\d{3} ?[a-zA-Z]{2}$")).Success)
{
return Regex.Replace(postcode.Trim(), #"(^[1-9]\d{3})( ?)([a-zA-Z]{2}$)", "$1$3").ToUpper();
}
else
{
throw new Exception("Postcode incorrect");
}
in Jquery I'm only focussing to replace for the moment by manually input the right strings.
I've created a function like:
function FormatDutchPostalCode() {
var postcode = $("#Text1").val();
postcode = postcode.replace(/(^[1-9]\d{3})( ?)([a-zA-Z]{2}$)/, $1$3);
$("#Text1").val(postcode);
}
I'm getting the value from the textbox, so far so good. But when replacing it seems the browsers exits the function (tested in IE9 and FF10.0.1)
What I'm i doing wrong and is it possible to troubleshoot Jquery/Javascript. I've seen firebug could set breakpoints but I can't find if (and if so which) errors occur.
Here is a port of your C# function to JS. It uses an IIFE in order to cache the regex without polluting the current execution scope.
jsFiddle
var FormatDutchPostalCode = (function() {
var reg = /^([1-9]\d{3})\s?([a-z]{2})$/i;
return function(){
var postcode = $.trim($("#Text1").val());
if (postcode && postcode.match(reg) )
{
return postcode.replace(reg, "$1$2").toUpperCase();
}
else
{
throw new Error("Postcode incorrect");
}
};
}());
You need to use '$1$3' or /$1$3/ for the replacement pattern. Currently you've placed the replacement pattern in without using it as a string or regex pattern.
Check out this jsFiddle link showing a working solution.
You could also simplify your pattern by removing the capture group for the optional space, then you can perform the replace using the existing capture groups:
Pattern: /^([1-9]\d{3}) ?([a-zA-Z]{2})$/
Replacement: '$1$2' (only 2 groups exist)
To use Firebug or developer tools, you should be able to bring the tool up using the F12 key. You can test your replacement directly in the console window, or debug your script from the script tab (select the relevant JavaScript file) and place a breakpoint on the line you're interested in by right clicking and adding it or clicking on the line number on the left.
Check out this article for more details: JavaScript debugging for beginners.