-
Notifications
You must be signed in to change notification settings - Fork 26
5.3. Tutorial 3 Enhancing an existing IA (Encryption)
In this third tutorial, we are going to enhance an existing IA: the encryption IA!
The Encryption IA is a simple IA that takes a hash algorithm as the keyword (md5, sha1, sha256) and then the string to hash:
{
"runtime": "nodejs",
"template_name": "encryption",
"display_name": "hash",
"images_path": "ia/img/",
"data": {
"result": "87c9b69c9e6b164a2ab9350dfebf4e3a5814e5abb8dcb6c5f9c7df3191b835c0",
"stringToHash": "no tracking",
"hash": "SHA256"
},
"query": "sha256 no tracking",
"status": "success",
"cacheExpirationTime": 200,
"files": [
{
"url": "ia/template/en_gb/encryption.js?deef78e5a4f7bc21f549c05b7038f8508caa9631",
"type": "template"
}
]
}
What we want to achieve is simple: we want to change the template to add a link to copy the hash to the clipboard.
Our IA already exists so we don't have to generate it. We are going to edit a few files and create a new one.
The first file we are going to edit is the template file. This is where we are going to add the link over the hash, to copy the hash to the clipboard:
<div class="ia__encryption">
<span class="ia__encryption__icon icon icon-md5"></span>
<span class="ia__encryption__result">
<a href="#" id="copy-hash" title="{{= _("Copy to clipboard", "encryption") }}">{{= it.data.result }}</a>
</span>
<div class="ia__encryption__description">
{{= _("Hash","encryption") }} {{= it.data.hash }} :
<span class="ia__encryption__description--query">
{{! it.data.stringToHash }}
</span>
</div>
</div>
We added a <a></a> element around our result. This element has its id set to copy-hash so we can add an event listener in our JavaScript file and copy the hash to the clipboard when it's clicked.
The link is inside a span element and is going to need styling, so we will add a rule in our scss file for the a
element:
.ia__encryption__result {
...
a {
color: rgba(48, 52, 58, 0.95);
text-decoration : none;
}
}
In order for our link to actually copy the hash to our clipboard, we are going to need to add a javascript function. So we will need to add a javascript script to our project! Let's edit our main js file to add that option. Anywhere you want inside the module.exports scope, add this line to tell our project that it should use a javascript script:
script: "encryption_script"
By adding that, our project will know we have to include a javascript file. It will look for a file named encryption_script.js in src/modules/encryption/public/javascript/. This file shouldn't exist yet, nor should the public/javascript folder. Create both! And let's edit our new javascript file:
var IARuntime = function() {
function Encryption (iaData) {
// constructor
}
Encryption.prototype.run = function() {
// function that's gonna run at runtime
};
Encryption.prototype.stop = function() {
// function that's gonna run upon exit
};
return Encryption;
}();
As you can see, this javascript file must follow a few rules: it must declare a IARunTime class containing a constructor, a run() function and a stop() function.
The constructor is where we will initialize the important variables we're going to need. The run() function is going to be ran at runtime. This is where we will add the eventListener on our hash. The stop() function is going to be ran upon exit. This is where we will delete everything we created to copy the text to the clipboard.
As usual, we won't explain the actual code much, but here is how your file should look like. Refer to the comments for more information:
var IARuntime = function() {
function Encryption (iaData) {
}
/**
* gets a string, sets it to the fake textarea and copies it to the clipboard
* @param text
*/
Encryption.prototype.copyHash = function(text) {
var it = this;
it.existsTextarea.value = text;
it.existsTextarea.select();
try {
document.execCommand('copy');
} catch (err) {
throw err
}
};
/**
* runs at runtime
*/
Encryption.prototype.run = function() {
var it = this;
// declares our fake textarea
it.textArea_id = "copy-hash-clipboard";
it.existsTextarea = document.getElementById(it.textArea_id);
if(!it.existsTextarea){
// if it doesn't exist, creates it
var textarea = document.createElement("textarea");
textarea.id = it.textArea_id;
// place in top-left corner of screen
textarea.style.position = 'fixed';
textarea.style.top = 0;
textarea.style.left = 0;
// give it a 1px² size so it's not visible, remove borders etc.
textarea.style.width = '1px';
textarea.style.height = '1px';
textarea.style.padding = 0;
textarea.style.border = 'none';
textarea.style.outline = 'none';
textarea.style.boxShadow = 'none';
textarea.style.background = 'transparent';
// append it to the page
document.querySelector("body").appendChild(textarea);
it.existsTextarea = document.getElementById(it.textArea_id);
}
// handling clicks on "copy-hash" link
var hashLink = document.getElementById("copy-hash");
hashLink.addEventListener('click', function(e){
it.copyHash(e.target.innerHTML);
});
};
/**
* runs upon exit
*/
Encryption.prototype.stop = function() {
var it = this;
if (it.existsTextarea){
var elem = document.getElementById(it.textArea_id);
elem.parentNode.removeChild(elem);
}
};
return Encryption;
}();
In the run() method, we created a fake textarea to hold the hash, so we can copy it to our clipboard (execCommand only works on inputs and textareas). We then declared an Event Listener on the link of the hash so when it's clicked, we trigger the function copyHash that we created.
Of course, you can also declare functions outside the IARunTime class, and they will be available for calling in your .dot file. However, you should ALWAYS have a IARunTime class in your script file, even if it's empty.
Now that we made sure that our data is correct, we're going to test how our IA looks like. For that purpose, let's hit the sandbox: http://localhost:3030/?q=sha256 copy to clipboard
Make sure that:
- Your IA is triggered correctly,
- Your IA blends in correctly with Qwant's layout
- Your IA actually gives the right result and works the way you intended (click on the hash!)