HTA Self-Modifying Code? - vbscript

I'd like to try to make an HTA that holds some data between sessions. The file might move from one computer to another, so I don't want to depend on cookies, and it won't have some remote server to save data to, so my hope is to find a way to use scripting like vbscript to write the save data back to the HTA itself, so that the next time the application runs, it already has the latest information.
What I'd likely do is dedicate a run of lines in the code as a list of variable declarations that will be used to initialize the application. There would be some kind of "save" button in the application that will read the current state of those variables and edit the hta file's source code, specifically on those lines and replace the values with whatever the current values are.
Since an HTA file is essentially just a text file with a different extension, I would assume there's a way to have the HTA edit itself like any other file...but I don't actually know how to do it, or how to isolate the lines of code where the variables will reside and edit them without having to load the entire file into memory and save the entire thing each time I want to save something... I'd like to keep things completely self-contained, so I don't want to depend on external files like an XML or CSV to store settings between sessions, so I'd like to be able to embed the data into the HTA.

You can indeed modify an HTA file while it's running because it's interpreted code. Same way you can modify an HTML file while you're viewing in your browser.
However, I would not do it that way unless there is some compelling reason you must keep everything in 1 file. If there is a problem writing to the HTA, you will end up with a blank file and lose everything. Therefore, I recommend using a plain text file to store your data and include that with your HTA.
MyApp.hta:
<!doctype html>
<HTA:APPLICATION
APPLICATIONNAME="MyApp"
SINGLEINSTANCE="yes"
CONTEXTMENU="no"
ICON=""
ID="HTA"
INNERBORDER="no"
NAVIGABLE="no"
SCROLL="yes"
SHOWINTASKBAR="yes"
VERSION="0.0.1"
/>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<title>MyApp</title>
<style type="text/css">
body { font-family: Calibri, Arial; font-size: 20px; }
label { font-weight: bold; }
.settings__container { position: relative; height: 200px; border: 2px dashed #ccc; overflow: hidden; padding-right: 2px; }
#settings { width: 100%; height: 100%; border: 0; }
</style>
</head>
<body>
<label>Settings:</label>
<div class="settings__container">
<textarea id="settings"></textarea>
</div>
<button id="save-settings__button">Save Now</button>
<script type="text/javascript">
(function() {
var settingsElement = document.getElementById('settings'),
settingsFile = "MyApp.settings.txt",
io = new ActiveXObject('Scripting.FileSystemObject');
function loadSettings() {
try {
var file = io.OpenTextFile(settingsFile, 1),
data = file.ReadAll();
file.Close();
settingsElement.value = data;
} catch(e) {
// Failed to load settings; settings file may not exist yet.
}
}
function saveSettings(data) {
var file = io.OpenTextFile(settingsFile, 2, true);
file.Write(data);
file.Close();
}
// Assuming IE9+
document.getElementById('save-settings__button').addEventListener('click', function(e) {
saveSettings(settingsElement.value);
});
// Load the settings file
addEventListener('load', function(e) {
loadSettings();
});
// Save the settings on exit
addEventListener('unload', function(e) {
saveSettings(settingsElement.value);
});
})();
</script>
</body>
</html>

Have a look at the FileSystemObject. If you're using vbscript, you would need to
Open the HTA file with OpenTextFile
Read the file
Modify the lines you want changed
Write the new contents to the file with CreateTextFile (Overwrite set to True)
For using Javascript the procedure is the same, the methods are slightly different.

Related

Line spacing in CKeditor

apologies but I am an absolute noob on this. I have implemented a CKeditor on my website using the below HTML:
<!doctype html>
<html>
<head>
<!--Define the character set for the HTML element -->
<meta charset="utf-8">
<!--Call the external script to use the CDN CKEditor in your page-->
<script src="//cdn.ckeditor.com/4.6.2/standard/ckeditor.js"></script>
<script type="text/javascript">
//Define an init function that sends the rich text editor contents to the page code
function init() {
//onMessage runs when the HTML element receives a message from the page code
window.onmessage = (event) => {
if (event.data == "x") {
CKEDITOR.instances.CK1.setData( '<p></p>' );
console.log(event.data,"ok");
} else {
//postMessage sends the contents of the CKEDITOR back to the page code
window.parent.postMessage(CKEDITOR.instances.CK1.getData(),"*");
console.log(event.data,"okd");
}
}
}
</script>
</head>
<body onload="init();">
<!--Define the HTML element as a textarea-->
<textarea name="editor1" id="CK1"></textarea>
<script>
//Use the CKEditor replace() function to turn our textarea into a CKEditor rich text editor
CKEDITOR.replace("editor1");
</script>
</body>
</html>
It works great but I have a line spacing issue where it looks like there is a line in between the paragraphs, but when it displays later on it is on top of each other. Is there anyway to reduce the spacing so the user realises they need to press enter again?
Image attached, first test is 1 press of enter after text (which looks like it has a line between but doesn't), second is 2 enters.
My issue is also that I am using Wix, so I can't host the config or whatever files to change. So it all needs to be from the html link.....
Thanks!
enter image description here
These lines of code will remove extra space
:host ::ng-deep .ck-editor__editable_inline p {
margin: 0;
}
Do you need to force the user to press Enter twice for a new paragraph? If so, try this:
CKEDITOR.addCss('.cke_editable p { margin: 0 !important; }');
CKEDITOR.replace('editor1');

Cannot print this document yet, it is still being loaded - Firefox Printer Error

My API generates dynamic HTML document and dumps it into a popup window like so:
var popup = window.open('', "_blank", 'toolbar=0,location=0,menubar=1,scrollbars=1');
popup.document.write(result);
After the document is reviewed by a user, they can print it calling
window.print();
Chrome handles it without any problems, but Firefox shows a Printer error:
"Cannot print this document yet, it is still being loaded"
Printer window opens only if I hit Ctrl+R.
It appears that $(document).ready() never happens in firefox and it keeps waiting for something to load.
Status bar in popup says Read fonts.gstatic.com
Here's a brief content of a document:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="https://fonts.googleapis.com/css?family=Orbitron|Jura|Prompt" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<title>Invoice #15001</title>
<style>
...
</style>
</head>
<body>
<div id="invoice_body" >
...
</div><!-- Invoice body -->
</body>
</html>
I have a feeling it has something to do with Google fonts. Any help is appreciated
When you pass "" as the URL to window.open, Firefox loads 'about:blank' at which point script security is likely preventing you from pulling in external resources via http or https ...
I am able to reproduce your problem and have it popup with the same error when I try to print-- I was able to get it working by using a data url when calling window.open ...
Based on your example, result is a string containing the HTML for the popup, so you would call window.open like this, and no longer use document.write for anything:
var popup = window.open("data:text/html;charset=utf-8,"+result, "printPopup", "toolbar=0,location=0,menubar=0,scrollbars=1");
I tested this with result being a string containing:
<html><head>
<link rel="stylesheet"href="https://fonts.googleapis.com/css?family=Tangerine">
<style> body { font-family: 'Tangerine', serif; font-size: 48px; } </style>
<title>Test</title></head>
<body>
<div>Testing testing</div>
<div>Print</div>
</body>
</html>
And clicking the print link worked as expected...
I had to go an extra mile, but:
I added server side code that would save a html file and pass a link to that file instead of html content:
ob_start();
include('ezts_invoice_template.php');
$dom = ob_get_clean();
$ezts_file_path = EZTS_PLUGIN_PATH.'kernel/tmp/'.session_id().'_tmp.html';
$ezts_file = fopen($ezts_file_path, 'w+');
$result = fwrite($ezts_file, $dom);
fclose($ezts_file);
print_r('{"result":"success", "file":"'.plugin_dir_url(__FILE__).'tmp/'.session_id().'_tmp.html"}');
in JS I open a popup by a link passed from PHP:
var popup = window.open(result.file, "_blank", 'toolbar=0,location=0,menubar=0,scrollbars=1');
and, finally, in template file I added event listener to request deletion of temporary file when the window is closed
window.addEventListener('beforeunload', function(event) {
window.opener.eztsApiRequest('deleteTempFile',
'',
function(result, status){ console.log(result); });
}, false);
It's not as easy, but it works great.

Is it possible generated from local file image from html5-canvas

My canvas has image which programly generated from local file or from images from internet. When I try to save it using toDataURl function I get secure error. How can I save result (without server, using only js ) and is it possible?
I know about security rule but maybe there is some solution to bypass this rule
All my code is in github if need
Shame! Don't bypass rules built to provide security for our users.
The key to satisfying CORS security and still getting what you need is to let the user select the image file you need to load into canvas.
If the user selects the file, CORS security is satisfied and you can use the canvas as you need (including using canvas.toDataURL to save the canvas).
Here are the steps to let a user select a file from their local drive:
Add an html input element with type="file"
The user clicks browse on this element and selects their file
When the user clicks OK, use window.URL.createObjectURL to create a URL from their selected file.
Create a new Image and set its source to the URL you created in #3.
Use context.drawImage to draw your new image on the canvas.
The resulting canvas is CORS compliant so canvas.toDataURL will work.
Here's example code:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
$("#fileInput").change(function(e){
var URL = window.webkitURL || window.URL;
var url = URL.createObjectURL(e.target.files[0]);
var img = new Image();
img.onload = function() {
canvas.width=img.width;
canvas.height = img.height;
ctx.drawImage(img,0,0);
ctx.fillStyle="black";
ctx.fillRect(0,canvas.height-30,canvas.width,30);
ctx.fillStyle="white";
ctx.font="18px verdana";
ctx.fillText("I'm OK with CORS!",5,canvas.height-8);
}
img.src = url;
});
$("#save").click(function(){
var html="<p>Right-click on image below and Save-Picture-As</p>";
html+="<img src='"+canvas.toDataURL()+"' alt='from canvas'/>";
var tab=window.open();
tab.document.write(html);
});
}); // end $(function(){});
</script>
</head>
<body>
<input type="file" id="fileInput">
<button id="save">Save</button><br>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

What are the requirements for /mode/html in Ace editor?

I can get mode/javascript working with:
JS
https://github.com/ajaxorg/ace-builds/blob/master/src-noconflict/ace.js
Theme
https://github.com/ajaxorg/ace-builds/blob/master/src-noconflict/theme-tomorrow.js
Mode
https://github.com/ajaxorg/ace-builds/blob/master/src-noconflict/mode-javascript.js
Worker
https://raw.github.com/ajaxorg/ace-builds/master/src-noconflict/worker-javascript.js
HTML
<script src="/static/js/ace/ace.js"></script>
<div class="my_ace_editor">
function foo(items) {
var x = "All this is syntax highlighted";
return x;
}
</div>
CSS
#my_ace_editor {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
jQuery
$(document).ready(function() {
var editor = ace.edit("my_ace_editor");
editor.setTheme("ace/theme/tomorrow");
editor.getSession().setMode("ace/mode/javascript");
});
But am not having any luck when attempting to display HTML with:
HTML
<div id="my_ace_editor"><p>test</p></div>
jQuery
$(document).ready(function() {
var editor = ace.edit("my_ace_editor");
editor.setTheme("ace/theme/tomorrow");
editor.getSession().setMode("ace/mode/html");
});
and have added:
https://raw.github.com/ajaxorg/ace-builds/master/src-noconflict/mode-html.js
If I type in the HTML editor, the tags and content have syntax highlighting applied.
But it is not showing the actual HTML when it loads - all it shows is test.
There are no Firebug errors and I can see the actual HTML that should be highlighted in Firebug.
Is another file or setting required?
Edit: I can get the HTML content within Ace editor showing correctly if I use:
editor.setValue("<html>test</html>",-1);
But I need to be able to set the value from the HTML itself and not in the jQuery.
The content is being loaded from a database (ie it is 'dynamic content'), i'm not sure if that makes a difference?
You need to escape html, that is instead of
<div id="my_ace_editor"><p>html&test</p></div>
it should be
<div id="my_ace_editor"><p>html&test</p></div>
This is true for all modes not just html
If you do not want to escape the HTML code just use the script tag with the following type and style set
<script type="text/plain" style="display: block;" id="ace-1">
hello world
test test
</script>

Creating a fast and simple image search with Google Images (iframe)

I am doing a university project involving a sort of social network for recipes.
In order to have the database populated by ingredients, I have written a simple form that may add them to the db. Ingredients contain an image which I'd like people to add.
In order not to have my website flooded with uploads, I was thinking about a small google images iframe in which people click on the image they want, so that I can display it by its link (I expect every ingredient to be within the very first results in google images).
My problem is that Google's toolbar (the one they introduced with Google+) is quite annoying, and it takes a lot of the space I want the iframe to occupy.
Are there any workarounds? :-)
That's kind of a "Forever alone" question (I have even got the Tumbleweed achievement on this one :V ).
I arranged something myself, so I'll share :-)
<!DOCTYPE html>
<html>
<head>
<style>img{ height: 100px; float: left; }</style>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$.getJSON("https://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=tex&callback=?",
{
unescapedUrl: "any"
},
function(data) {
$.each(data.responseData.results, function(i,results){
$("<img/>").attr("src", results.unescapedUrl).attr("id", "img"+i).appendTo("#images");
$("#img"+i).wrap($("<a/>").attr("href", results.unescapedUrl));
if ( i == 1 ) $("#images").append("<br />");
});
return false;
});
</script>
</head>
<body>
<table id="images">
</table>
</body>
</html>

Resources