Utilize an Angular regular expression as a replacement for the href attribute

I am in search of a filter that can replace the "href" attribute within a TextEntity from an API. The "text" may contain 3 different types of URLs. Once the replacement is done, I want to open the corrected URLs in a new separate window.

Here is the information I receive from the text value:

1. <a href="http://someurl.tdl">link</a> - this example includes all kinds of external links such as mysite.com/mypage.html or any other valid URL starting with http://, https://, ftp://.
2. <a href="singpage.html">internal page</a> - This may include various files like mypdf.pdf or mydoc.doc without a full domain in the URL.
3. <a href="mailto: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="177a6e7a767e7b5773787a767e793963737b">[email protected]</a>"><a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="204d594d41494c60444f4d41494e0e54444c">[email protected]</a></a>

I have attempted something but it did not work.

.filter('parseText', function ($sce, $sanitize) {
var mydomain = 'http://www.mydomain.tdl';
return function (text) {
    var newStringUrlReplace = $sanitize(text).replace('href="','href="'+mydomain);
    var regex = /href="([\S]+)"/g;
    var newString = newStringUrlReplace.replace(regex, "class=\"externalURL\" onClick=\"cordova.InAppBrowser.open('$1', '_blank', 'location=yes')\"");
    return $sce.trustAsHtml(newString);
    }
});

I need the output of the filtered "text" to be as follows:

1. <a href="http://someurl.tdl" class="externalURL" onClick="cordova.InAppBrowser.open('http://someurl.tdl', '_blank', 'location=yes')">link</a>
2. <a href="http://www.mydomain.tdl/singpage.html" onClick="cordova.InAppBrowser.open('http://www.mydomain.tdl/singpage.html', '_blank', 'location=yes')">internal page</a>
3. <a href="mailto: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="660b1f0b070f0a2602090b070f084812020a">[email protected]</a>"><a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="4e2337232f27220e2a21232f2720603a2a22">[email protected]</a></a>

To clarify further:

I require a function that transforms these types of URLs.

<a href="http://someurl.tdl/whichcanincludeanything.html?bar=foo">URL TO A EXTERNAL PAGE</a>

<a href="singpage.html">internal page of the CMS</a> 

into

<a href="http://someurl.tdl/whichcanincludeanything.html?bar=foo" class="externalURL" onClick="cordova.InAppBrowser.open('http://someurl.tdl/whichcanincludeanything.html?bar=foo', '_blank', 'location=yes')">URL TO AN EXTERNAL PAGE</a>

<a href="http://www.mydomain.tdl/singpage.html" onClick="cordova.InAppBrowser.open('http://www.mydomain.tdl/singpage.html', '_blank', 'location=yes')">internal page</a>

Answer №1

Here is an improved version that functions based on your original code:

(function() {
  angular
    .module('app', ['ngSanitize'])
    .controller('MainCtrl', MainCtrl)
    .filter('parseText', parseText);

  function MainCtrl($scope) {
    $scope.array = [
      '<a href="http://someurl.tdl">link</a>',
      '<a href="singpage.html">internal page</a>',
      '<a href="mailto: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="93feeafef2faffd3f7fcfef2fafdbde7f7ff">[email protected]</a>"><a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="ed8094808c8481ad8982808c8483c3998981">[email protected]</a></a>',
      '<a href="http://someurl.tdl/whichcanincludeanything.html?bar=foo">URL TO A  EXTERNAL PAGE</a>',
      '<a href="singpage.html">internal page of the CMS</a>'
    ];
  }

  function parseText($sce) {
    var myDomain = 'http://www.mydomain.tdl/';
    var externalRegex = /([http|https|ftp]+:\/\/[^"]*)/g;
    var internalRegex = /(href=)"([^"]*)/g;
    return function(input) {
      if (!input) return;
      if (input.indexOf('mailto: ') !== -1) return input;
      var url = '';
      if (externalRegex.test(input)) {
        url = input.replace(externalRegex, '$1" class="externalURL" onClick="cordova.InAppBrowser.open(\'$1\', \'_blank\', \'location=yes\')');
      } else {
        url = input.replace(internalRegex, '$1 ' + myDomain + '$2' + ' class="externalURL" onClick="cordova.InAppBrowser.open(\'' + myDomain + '$2' + '\', \'_blank\', \'location=yes\')');
      }
      return $sce.trustAsHtml(url);
    }
  }
})();
<!DOCTYPE html>
<html ng-app="app" >

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-sanitize.min.js"></script>
</head>

<body ng-controller="MainCtrl">
  <p ng-repeat="url in array track by $index">
    <span ng-bind-html="url | parseText"></span>
  </p>
</body>

</html>

Answer №2

Oh, I finally found a working solution!

.filter('modifyText', function ($sce, $sanitize) {
return function ( content ) {
var website = 'http://www.mywebsite.tdl';
content = $sanitize(content);
var source,sear,replacement;
var newContent;
var regex = /href="([\S]+)"/g;
var extMatch = /http|https|\/\//g;
var mtMatch = /mailto:/g;

var divElem = document.createElement("div");
divElem.innerHTML = content;
var anchorList = divElem.getElementsByTagName("a")
var updatedAnchorList = new Array();
var hrefAttr,tag;

if(anchorList.length > 0){

for(var j = 0; j < anchorList.length; j++ ){
  hrefAttr = anchorList[j].getAttribute("href");
  tag = anchorList[j].outerHTML;
  tag = $sanitize(tag);

  if(hrefAttr.match(extMatch) != null){
    newContent = tag.replace(regex, "class=\"externalURL\" onClick=\"cordova.InAppBrowser.open('$1', '_blank', 'location=yes')\"");

  } else if(hrefAttr.match(mtMatch) != null){
    newContent = tag;
  } else{
    newContent = tag.replace(regex, "class=\"externalURL\" onClick=\"cordova.InAppBrowser.open('" + website + "$1', '_blank', 'location=yes')\"");
  }

  source = content;
  sear = tag;
  replacement = newContent;
  content = content.replace(tag,newContent);
   }  
}
 return $sce.trustAsHtml(content);
     };
 });

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The method OnJSAlert in WebChromeClient is failing to execute

I am currently working with a JS script in a WebView, where the script triggers an alert message to the WebView that I want to capture in my app. However, I am facing an issue where the onJSAlert method is not being called and I am unable to use the @Overr ...

Display various v-dialog boxes with distinct contents in a vue.js environment

Hello there! I am currently working on customizing a Vue.js template and I have encountered an issue with displaying dynamic v-dialogs using a looping statement. Currently, the dialog shows all at once instead of individually. Here is the structure of my ...

Display contents while scrolling

Currently, I am working with a "ul" element that contains several "li" items. My goal is to find a solution that will allow me to automatically load additional items every time I reach the 10th item in the list. The idea is to trigger the loading functio ...

obtain the specific attributes of the button that was clicked using jQuery

My goal is to preview an image before uploading it to the server, and this is the HTML code I am using: <html> <script> function readURL(input) { if (input.files && input.files[0]) {.......}} $("#selectedFile").change(functio ...

Mastering the Art of Loading "Please wait" Messages with jQuery BlockUI on Your Website

I'm seeking assistance with implementing jQuery blockUI in my application. Below is the code I currently have: $.blockUI({ css: { border: 'none', padding: '15px', backgroundColor: '#000 ...

Removing data from firestore/storage does not follow the expected pathway

I have created an image gallery for users using Firebase Storage and React, allowing them to upload and delete images. However, I am facing an issue where the deletion process is taking longer than expected. Expected flow: User clicks on the trashcan ico ...

Issues with Express routes - encountered POST 404 (Not Found) error

I'm having trouble with my routing setup in login.js for login.component.js. It seems that when I try to use routes specified within login.js, such as axios.post('http://localhost:5000/login/add3', user), it's not connecting properly. H ...

Checkbox fails to display as checked

I am currently working on implementing checkbox inputs in React JS. I have encountered an issue where the checkboxes do not visually show as checked when clicked, but I am still able to retrieve the value of the checkbox. Here is my code: Simple Checkbox I ...

Take a sequence of multiple words and combine them into a single string with hyphens in between

I've been working on a WordPress website and I created a JavaScript function that adds a class to the body tag, allowing for different backgrounds based on the category. It works perfectly fine when the category is a single word, but encounters issues ...

How to display a video with full height and width using CSS or JavaScript

I am trying to incorporate an html5 video (using the video tag) with 100% width and 100% height to play in the background. I have seen an example using an image, but I want to achieve the same effect with a video. Here is the code I have so far: #video { ...

Establishing data information on dynamically generated HTML

When I receive a JSON response from the server, it contains an array with 32 objects. Here's an example: [{object1}, { object2}, { object3}, etc]. To populate an HTML template with information from each object, I use a simple loop like this: for (v ...

What is the most effective way to send a Json array of objects from a child class component to its parent class component in a React application

Within the component Trivia, I have a state variable called currentQuestion that serves as an index. I've also created another class component called Questions which reads from a JSON file, and I want to pass it to Trivia like this: ... questions = & ...

tips for setting the value of a checkbox to true in React Material-UI with the help of React Hooks

<FormControlLabel onChange={handleCurrentProjectChange} value="end" control={<Checkbox style={{ color: "#C8102E" }} />} label={ <Typography style={{ fontSize: 15 }}> C ...

Tips for adjusting the number of rows in a textarea using Bootstrap

I currently have a textarea in my project that allows users to input text using Bootstrap. However, the height of the textarea is fixed at 3 rows by default. I want to make it dynamic so that as the user types beyond 3 rows, the textarea expands instead of ...

The issue with ReactJS Flask is that a specific webpage link continuously defaults to port 5000 on localhost instead of the intended port 3000

I am struggling with an issue on my website that has a ReactJS frontend and Python-Flask backend. The main page is accessed through a link like http://localhost:3000/. I have 4 pages on the website, and for 3 of them, clicking on the links takes me to the ...

Retrieving information from a JSON file using AngularJS

Hello, I am a beginner in Angularjs and I am facing an issue while trying to retrieve data from a JSON file. The output I am getting is quite strange. Below are snippets from my controller.js and services.js files: angular .module('app') .contro ...

Reducing the size of XML files in ASP.NET 3.5 returned from WebMethods: Available solutions

Recently, I've come into possession of an ASP.NET web app built on .NET 3.5, along with its C# client components and a related JavaScript client. The server-side components currently use the default [WebMethod] serialization method, but due to the la ...

Find the target node within the Angular UI Tree

I'm currently utilizing Angular UI Tree to create a user interface for a file system. My goal is to enable users to drop items into folders while preventing them from dropping into files. To achieve this, I have assigned a "file" or "folder" value to ...

What is the best way to automatically show the last two digits of a phone number in a second text field?

Is there a way to automatically display the last 2 digits of a phone number input into the first text field onto the second text field using AJAX, JavaScript, or jQuery? I am looking for a script for my website similar to what was shown in this video. I ...

Using jQuery to submit a form and update values

I am currently working with a datatable that includes a detail column with an edit button. Upon clicking the edit button, I pass the ID as a parameter and fetch all the values associated with that ID to display in a form. However, when I edit the values an ...