I have a SFW embedded in a PHP page. There is also a div on the page with id="target".
I want to access the content of that div (ie: the characters inside it) and hold them as a String variable in AS3. How can I do this?
My attempt so far
import flash.external.ExternalInterface;
var myDivContent = ExternalInterface.call("function(){ return document.GetElementById('target');}");
var myDivContent2:String = myDivContent.toString();
test_vars.text = myDivContent2; //Dynamic text output
I don't think you can define a function in the ExternalInterface.call() method. You have to call a function by name which already exists in the JavaScript.
So I'd create some JavaScript code like this:
function getTargetContent()
{
return document.getElementById('target').innerHTML;
}
And then in your Flash,
var myDivContent = ExternalInterface.call("getTargetContent");
Note that document.getElementById('target') only returns the reference to that div, not the contents within. So if you don't return .innerHTML then the Flash will get an object which may not be usable (although I haven't actually tried doing this).
The easiest way to do this is as Allan describes, write a Javascript function to sit on the page and return the required value to you.
Of course, if you can't edit the page content, only the flash, then you do need to pass the function itself, which will actually have to be forced into the page though JavaScript injection. An example for your case, which I have not tested:
//prepare the JavaSctipt as an XML object for Dom insertion
var injectCode:XML =
<script>
<![CDATA[
function() {
getElementContent = function(elementID) {
return document.getElementById(elementID).innerHTML;
}
}
]]>
</script>;
//inject code
ExternalInterface.call(injectCode);
//get contents of 'divA'
var divAContent:String = ExternalInterface.call('getElementContent','divA') as String;
//get contents of 'spanB'
var spanBContent:String = ExternalInterface.call('getElementContent','spanB') as String;
You're almost there :
var res : String = ExternalInterface.call("function(){return document.getElementById('target').outerHTML}");
If you only want the content of your target, use innerHTML instead of outerHTML.
Related
In an MVC application I have to use #HTML.TextAreaFor to display some text from a database, the trouble is sometimes that text may have HTML tags within it and I can't see a way to remove those for display only.
Is it possible to do this in the view (maybe with CSS?) without having to strip the tags in the controller first?
EDIT
The data coming from the controller contains html tags which I do not want to remove, I just don't want to display them
Normally I would use #HTML.Raw but it has to work in a #HTML.TextAreaFor control.
If you want to decode Html returned from the Controller you can use the following JavaScript method:
This method decodes "Chris' corner" to "Chris' corner".
var decodeEntities = (function () {
// this prevents any overhead from creating the object each time
var element = document.createElement('div');
function decodeHTMLEntities(str) {
if (str && typeof str === 'string') {
// strip script/html tags
str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '');
str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');
element.innerHTML = str;
str = element.textContent;
element.textContent = '';
}
return str;
}
return decodeHTMLEntities;
})();
You can do this by using a razor code in your view.
#Html.Raw(HttpUtility.HtmlDecode(Model.Content))
if I set Model.Content to this string "<strong>This is me</strong><button>click</button>", the code above will render it like HTML code and will have a strong text next to a button as an output like the image below:
There's some nice rich text editors libraries like CK Editor, Quill, or TinyMCE that can display HTML while still maintaining the editor capabilities of being a text editor. All of these libraries have capabilities of being read-only as well if that's necessary.
Example from Quill -
Sorted this by changing TextAreaFor toTextBoxFor and setting a formatted value.
#Html.TextBoxFor(x => Model.MyItem, new { #class = "form-control", #required = "true", Value = Regex.Replace(Model.MyItem, "<.*?>", String.Empty) })
I'm trying to use a script to replace a particular string with a different string. I think the code is right, but I keep getting the error "Object does not allow properties to be added or changed."
Does anyone know what could be going wrong?
function searchAndReplace() {
var teams = SitesApp.getPageByUrl("https://sites.google.com/a/directory/teams");
var list = teams.getChildren();
list.forEach(function(element){
page = element.getChildren();
});
page.forEach(function(element) {
var html = element.getHtmlContent();
html.replace(/foo/, 'bar');
element.setHtmlContent = html;
});
};
Try This:
Javascript reference:
The replace() method returns a new string with some or all matches of a pattern replaced by a replacement.
I think the issue here is that forEach cannot change the array that it is called upon. From developer.mozilla.org "forEach() does not mutate the array on which it is called (although callback, if invoked, may do so)."
Try doing it with a regular loop.
I am using Ace Editor in my web app. Wonder if it's possible to copy the text inside Ace Editor to clipboard with highlight. With default configurations, if I copy the selected text in Ace Editor to clipboard, it seems that only text content is copied with no html styles.
Thanks a lot for your help!
Unfortunately there is no api for this. you'll need to modify https://github.com/ajaxorg/ace/blob/v1.2.5/lib/ace/keyboard/textinput.js#L290 to also set text/html mime type to some html, rendered similar to https://github.com/ajaxorg/ace/blob/v1.2.5/lib/ace/layer/text.js#L442.
Also you'll need to include the css for the theme in the copied html
I know this is late, but this might be helpful for someone like me who stumbled upon this problem this late.
The basic idea is to get the text that is being copied and use Ace's tokenizer to generate HTML from it:
Add an event listener on the copy/cut event on the editor's container.
You can use clipboard object in event to get the data currently being copied: event.clipboardData?.getData('text/plain')
Rest steps are in code below
// get current tokenizer
const tokenizer = aceSession.getMode().getTokenizer();
// get `Text` object from ace , this will help in generating HTML
const Text = ace.require('ace/layer/text').Text;
// create a wrapper div, all your resultant HTML will come inside this
// also this will contain the basic HTML required to initialize the editor
const root = document.createElement('div');
// this is the main magic object
const rootText = new Text(root);
lines.forEach(line => {
// this converts your text to tokens
const tokens = tokenizer.getLineTokens(line, 'start') as any;
const leadingSpacesCount = (line.match(/^\s*/) || [])[0].length;
const lineGroupEl = document.createElement('div');
lineGroupEl.className = 'ace_line_group';
const lineEl = document.createElement('div');
lineEl.className = 'ace_line';
const spaceSpan = document.createElement('span');
if (tokens && tokens.tokens.length) {
//////////////////////////////////////////////////////
// Magic Happens here, this line is responsible for converting our tokens to HTML elements
rootText.$renderSimpleLine(lineEl, tokens.tokens);
//////////////////////////////////////////////////////
// Leading spaces do not get translated to HTML, add them separately
spaceSpan.innerHTML = ' '.repeat(leadingSpacesCount);
lineEl.insertBefore(spaceSpan, lineEl.children[0]);
} else {
spaceSpan.innerHTML = ' ';
lineEl.appendChild(spaceSpan);
}
lineGroupEl.appendChild(lineEl);
// `root` has a wrapper div, inside which our main div (with class "ace_layer ace_text-layer") lies
root.children[0].appendChild(lineGroupEl);
});
return root.innerHTML;
Now finally, in your eventlistener you can wrap this with any div to give your own custom color to it, and put it to clipboardData with text\html mime type:
event.clipboardData?.setData('text/html', htmlContent);
I ran into a strange problem with a content script. The content script is defined as "run_at" : "document_end" in the manifest. After a page is loaded the script inserts an object tag into the page (if the tag with predefined id does not exist yet), and sets some properties in it, such as type, width, height, innerHTML, and title. All works fine here.
function checkForObject()
{
var obj = document.getElementById("unique_id");
if(obj == null)
{
var d = document.createElement("object");
d.id = "unique_id";
d.width = "1";
d.height = "1";
d.type = "application/x-y-z";
d.title = "1000";
d.style.position = "absolute";
d.style.left = "0px";
d.style.top = "0px";
d.style.zIndex = "1";
document.getElementsByTagName("body")[0].appendChild(d);
}
}
checkForObject();
I see the new object in the page html-code with proper values in its properties.
Some time later I need to read the title property of the object in the same content script. The code is simple:
function ReadTitle()
{
var obj = document.getElementById("unique_id");
var value = obj.title; // breakpoint
console.log(value);
// TODO: want to use proper title value here
}
The function is called from background.html page:
chrome.tabs.onActivated.addListener(
function(info)
{
chrome.tabs.executeScript(info.tabId, {code: 'setTimeout(ReadTitle, 250);'});
});
Unfortunately, in ReadTitle I'm getting not what I expect. Instead of current value of the title I see the logged value is:
function title() { [native code] }
If I set a breakpoint at the line marked by // breakpoint comment, I see in the watcher that all object properties including the title are correct. Nevertheless, the variable value gets the abovementioned descriptive string.
Apparently, I have missed something simple, but I can't figure it out.
The answer. It was a bug in the npapi plugin, which hosts the object of used type. My apologies for all who have read the question with intention to help.
The NPAPI plugin used in the object erroneously reported title as supported method.
I wrote code below that is working perfectly for displaying the results of my sales tax calculation into a span tag. But, I am not understanding how to change the "total" value into a variable that I can work with.
<script type="text/javascript">
function doStateTax(){
var grandtotalX = $('#GRANDtotalprice').val();
var statetaxX = $('#ddl').val();
$.post('statetax.php',
{statetaxX:statetaxX, grandtotalX:grandtotalX},
function(data) {
data = $.parseJSON(data);
$('.products-placeholder').html(data.products);
$('.statetax-placeholder').html(data.statetax);
$('.total-placeholder').html(data.total);
// ...
});
return false;
};
</script>
Currently, $('.total-placeholder').html(data.total); is successfully placing the total number into here:
<span class="total-placeholder"></span>
but how would I make the (data.total) part become a variable? With help figuring this out, I can pass that variable into a hidden input field as a "value" and successfully give a proper total to Authorize.net
I tried this and id didn't work (see the testtotal part to see what I'm trying to accomplish)..
function(data) {
data = $.parseJSON(data);
$('.products-placeholder').html(data.products);
$('.statetax-placeholder').html(data.statetax);
$('.total-placeholder').html(data.total);
$testtotal = (data.total);
// ...
If you are using a hidden field inside a form, you could do:
//inside $.post -> success handler.
$('.total-placeholder').html(data.total);
$('input[name=yourHiddenFieldName]', yourForm).val(data.total);
This will now be submitted along with the usual submit. Or if you want to access the data elsewhere:
var dataValue = $('input[name=yourHiddenFieldName]', yourForm).val();
The "data" object you are calling can be used anywhere within the scope after you have a success call. Like this:
$.post('statetax.php',
{statetaxX:statetaxX, grandtotalX:grandtotalX},
function(data) {
data = $.parseJSON(data);
var total = data.total;
var tax = data.total * 0.19;
});
return false;
};
Whenever you get an object back always try to see with an alert() or console.log() what it is.
alert(data); // This would return <object> or <undefined> or <a_value> etc.
After that try to delve deeper (when not "undefined").
alert(data.total); // <a_value>?
If you want 'testotal' to be recognized outside the function scope, you need to define it outside the function, and then you can use it somewhere else:
var $testtotal;
function(data) {
data = $.parseJSON(data);
$('.products-placeholder').html(data.products);
$('.statetax-placeholder').html(data.statetax);
$('.total-placeholder').html(data.total);
$testtotal = (data.total);
EDIT:
The comments are becoming too long so i'll try and explain here:
variables defined in javascript cannot be accessed by PHP and vice versa, the only way PHP would know about your javascript variable is if you pass it that variable in an HTTP request (regular or ajax).
So if you want to pass the $testtotal variable to php you need to make an ajax request(or plain old HTTP request) and send the variable to the php script and then use $_GET/$_POST to retrieve it.
Hope that answers your question, if not then please edit your question so it'll be clearer.