I am trying to set the innerText of the p tag located inside the tinyMCE body here using javaScript but cannot seem to reach the element.
Elements Tab of the Developer Tools.
It looks to me like there is a shadow DOM in the iframe. As when I am running the following in the console I get null as a result.
document.querySelector("#tinymce");
null
However if I switch in the console from "top" to "mce_6_ifr" I can now reach the wanted data:
Console Tab of the Developer Tools
I am unsure how to move forward regarding this.
Any help is much appreciated !
I think it will work
document.getElementById("mce_6_ifr").contentWindow.document.getElementsByTagName("p")[0].innerText
TinyMCE has APIs that allow you to load content into the editor so that you do not have to do manual traversal of the DOM.
Here is a fully working example: http://fiddle.tinymce.com/qigaab
The key code is inside the TinyMCE init:
setup: function (editor) {
editor.on('init', function (e) {
editor.setContent('<p>This is content set via the init function</p>');
});
}
This code uses the setContent() API to load your HTML into the editor.
Manual DOM traversal will work but relies on the HTML that TinyMCE injects ... if that changes in some fashion your DOM-based code can break. Using the APIs ensures that you won't get breakage over time.
#Harold I can’t imagine why that would not work. Perhaps you can make a TinyMCE Fiddle that shows running code?
Related
I'm developing a new Widget for CKEditor 4 and some of its content is generated dynamically by a tool that parses CKEditor content window.
At first, the widget is simply a <span class="my-widget"></span> but then some content will be added on the fly.
When switching to CKEditor's source mode, then all the content inside span is visible and it gets really messy. Moreover, I don't want to save all that content in database but only the outer <span class="my-widget"></span>
I'm pretty sure this is feasible because this is how CKEditor's MathJax plugin works: when inserting a formula using TeX syntax, the plugin generates a <span class="math-tex">[formula here]</span>. Then, Mathjax runs and typesets the formula, producing the nice-looking LaTeX-like formula in CKEditor. However, when inspecting the code, it only shows the outer <span class="math-tex">[formula here]</span>.
I inspected their source code and I saw they were using an iframe inside the widget.
Can someone explain to me how it works and the way to do it without using an iframe if possible?
Thanks!
I actually achieved the desired result using the downcast property of a CKeditor widget. We can register a custom method that will be used to convert a widget into its text-based representation. Also, it is called both when switching from wysiwyg mode to source mode and when calling editor.getData().
Also, reading the docs, you get that:
The downcast function will be executed in the CKEDITOR.plugins.widget context
meaning that this is pointing to your widget. So, essentially, I replaced all my widget's children by a single text node:
downcast: function(element) {
element.children = [new CKEDITOR.htmlParser.text(CKEDITOR.tools.htmlEncode(this.data.text))];
return element;
}
And it does the trick!
The new facebook page plugin has the minimum width at 280px (inserted by a data-width:280px).
However when I inspect the element created by the script with firebug i see an element with id="u_0_0" with the width at 280 but i can modify it from console to be as i need (227px).
I've tried to modify it with a little script made with jquery (i can only work with jquery 1.2...an old version of it...) but it doesent seams to work since the element is inserted dinamicaly into the DOM.
I also tried an method finded by google but also it doesn't work:
jQuery(document).ready(function(){
jQuery('#u_0_0').live('DOMNodeInserted', function(){
alert(jQuery('#u_0_0').html());
});
});
The above method doesn't work and if i dont use live it alerts me with undefined...
So, how can i get the element so i can modify it's css ? Maybe jquery 1.2.1 is too old but maybe i can get and modify it with clasic javascript...
The plugin renders in an iframe which is a separate DOM from yours.
Because of that reason, its not possible to run scripts on the plugin from your website
In your script:
jQuery('#u_0_0') is not able to find the div, since that doesn't exist on your DOM.
I think you can't use javascript or css on an object inside a iframe.
If you look upside on code you will see the iframe.
You can do that only if the location of the iframe target is cross-domain but i'm not sure.
I have a Javascript function that is supposed to insert a string formatted in a certain fashion onto a page for a data analytics tool used by another team. The Javascript executes without error, but whenever I look at the page source of the page, it appears that the comment is not present on the page. Does anyone have any ideas what the issue could be? Has anyone had any experience with writing comments onto the page? I thought maybe jQuery was having any issue with writing HTML comments, but it turns out that using just plan Javascript DOM manipulation functionality doesn't work either.
var test_comment = "<!--This is my comment for data analytics-->";
renderTealeafGrid: function(analyticsString) {
var homePage,
analyticsInfo;
if($('.analyticsInfo').length===0) {
homePage = document.getElementById('homePage');
analyticsInfo = document.createElement('span');
analyticsInfo.setAttribute('class','analyticsInfo');
analyticsInfo.innerHTML = analyticsString;
homePage.appendChild(analyticsInfo);
}
}
renderTealeafGridUsingJQuery: function(analyticsString) {
if($('.analyticsInfo').length===0) {
$('#homePage').after('<span class="analyticsInfo hide">' + analyticsString + '</span>');
}
}
None of the logic that you presented does anything with the test_comment variable.
As others have noted, simply View Source will display the original source code of the page, not any DOM changes after the page has been loaded. You will need to Inspect the source using Firebug or Chrome Dev Tools.
Also, if you want to properly add a comment to the DOM, you would use the document.createComment() method.
// Assuming you are simply viewing source of the page.
Your problem is, jQuery manipulates DOM after it had been built.
And DOM is built based on the source of the page which is what you are seeing through 'view source'.
To view the modified source, either inspect element or use firebug like tool.
You can also get the source through jQuery. Try alerting a .html() of the element you are updating.
If you use the old-fashioned view source tool, you will probably see the original source. You can verify the changes in FF by using the Inspect Element array of tools. They show the current DOM, after updates.
I'm very new to javascript, so this is confusing me. All of the settings charm tutorials only show how to put the controls into the settings charm, but none of them say how to find the information gotten in them.
I tried to do one of these (like I do in the main program):
var muteToggle = document.GetElementById("Mute");
where "Mute" is the id in the separate html file.
muteToggle just ends up being null all of the time. I tried putting it after
WinJS.UI.ProcessAll().then(function completed() {...
but that didn't work either. Everything else is the same as in this page: http://msdn.microsoft.com/en-us/library/windows/apps/hh780611.aspx
Make sure you're doing it in the ready function of the js file that is referenced from your settings HTML. Try opening the JavaScript console or QuickWatch while broken at that line and also look at the DOM Explorer to see if you can find your toggle control. You should be able to access it though. Also, try element.getElementById instead of document.getElementById. Either should work actually, but as long as you're troubleshooting. Good luck.
Your problem is that you are trying to get a reference to the HTML element from the code running during the app activation. Although that piece of code may define the HTML to be loaded for a settings pane, it does Not actually load the HTML into the DOM. You just simply can't get the instance from that location.
What you need to do is have the settings flyout have its own js file that implements IPageControlMembers. In particular, you need to implement the ready method. This method is called once all the HTML and controls are loaded for the page, including your toggle. The link has an example of how to do this.
Also see:
WinJS.UI.Pages.define
Using single page navigation
I am just starting out with Windows 8 development using HTML/JS. I've spent the last few months immersed in jQuery development for apps targeting vehicle head-units and televisions.
Jumping into this, I thought the transition would be simple. I have the design and structure of my site all figured out for the most part and was hoping to follow some of the practices I had been using for my previous work.
That is, I want to essentially create a single page app. The main default.html file will house the top navigation/title and one other div. The other div will be used to load in all the other pages, all separate HTML files within the project.
All of the global functions and major functionality will reside in a javascript file, application.js. Then any page-specific javascript will reside at the top of each HTML file.
I'm quickly realizing that this is a problem. Using jQuery.load() to load in my pages causes security errors in my app.
JavaScript runtime error: Unable to add dynamic content. A script attempted to inject dynamic content, or elements previously modified dynamically, that might be unsafe. For example, using the innerHTML property to add script or malformed HTML will generate this exception. Use the toStaticHTML method to filter dynamic content, or explicitly create elements and attributes with a method such as createElement.
I was really hoping to avoid having to learn a bunch of Microsoft-specific stuff. I think it's great that they've provided a lot of tools and what not, and maybe I just haven't used them enough, but everything just feels too rigid for me and for what I'm trying to do or can already be accomplished with jQuery. I'm one who likes to know EXACTLY what is happening and have full control over it.
Also looking through the templates and sample projects, I really don't like all the repeated code. For instance, every single HTML file declaring all the same references. I want to write my references and sections like my title bar just once, and not have to copy/paste that code all over my project.
Is there a way to do things the way I was hoping, and create a single page app? Do they have their own substitute for jQuery's .load()?
Any help pointing me in the right direction would be much appreciated!
EDIT 8/14/2012:
I have tried using the fix from this question:
Using jQuery with Windows 8 Metro JavaScript App causes security error
This gets rid of the security warning and I can load in HTML using jQuery.load(). However, looking at DOM explorer, my HTML is being stripped of my scripts.
I have also tried wrapping my .load() call inside of MSApp.execUnsafeLocalFunction(), but yet again my file still gets stripped of all scripts. What gives?
I fixed by simply changing the line of jQuery that was causing the error.
jQuery-1.8.0, line 5566:
append: function () {
return this.domManip(arguments, true, function (elem) {
if (this.nodeType === 1 || this.nodeType === 11) {
self.appendChild(elem); // problem line
}
});
},
Changed to:
append: function () {
return this.domManip(arguments, true, function (elem) {
if (this.nodeType === 1 || this.nodeType === 11) {
var self = this;
MSApp.execUnsafeLocalFunction(function () {
self.appendChild(elem);
});
}
});
},
There is a "formal" way to do what you are seeking.
WinJS.Navigation is provided to support "single page apps". For example, the default.html would contain a markup that would represent where the dynamically loaded page content would go:
<div id="contenthost"
data-win-control="Application.PageControlNavigator"
data-win-options="{home: '/pages/home/home.html'}">
</div>
In the example above, the actual content page loaded is at /pages/home/home.html
In event handlers, you can simply do the following to load or navigate to another page:
WinJS.Navigation.nav("/pages/other/page.html");
True, it is not jQuery, but it works great :)
Depending on your app, if you are not intending to access any WinRT components, you can navigate your page to ms-appx-web which will change the security policy around the page, but you can't specify this from start up. You would have to do a navigate, and leverage that new securyt context.
The other option you have it to wrap the calls to JQuery with msWWA.execUnsafeLocalFunction function, which will enable all that unsafe code be pushed into the DOM