We use a closed source knowledge base solution currently, and the WYSIWYG to create articles is TinyMCE (looks like it may be a modified/simplified).
They do not currently allow changing it at all (adding plugins, etc, unless you can inject plugins somehow).
I do have full access to the header and can use javascript, so the question is, is there a way to remove the existing tinymce instance and replace it with my own on page load?
...is there a way to remove the existing tinymce instance and replace
it with my own on page load?
Indeed there is but it may be more work than you want to take on.
If you cannot modify the code that the app uses to load TinyMCE the best you could do would be to...
Wait for the page to load and TinyMCE to initialize
Manually remove TinyMCE from the page using the remove() API
Initialize a new TinyMCE instance on that same textarea using the init() API
Remove API: https://www.tinymce.com/docs/api/tinymce/root_tinymce/#remove
Init API: https://www.tinymce.com/docs/api/tinymce/root_tinymce/#init
You can play with these APIs on http://fiddle.tinymce.com/ to see how they work before you try to mess with the app's codebase. This should get you started: http://fiddle.tinymce.com/kpgaab
Related
I'm building a Chrome Extension.
The extension injects some CSS and JavaScript when .html files on the users local drive are loaded in the browser (file:///).
My extension adds an extensive UI to the page that allows the user to modify and manipulate the original source code from their .html file.
The primary purpose of the extension is debugging and QAing HTML email newsletters. Here's just a few things that it does:
Checking links for the appropriate parameters.
Toggling images off and on to simulate popular email clients.
Displaying the source code side-by-side to show a desktop view and multiple mobile sized views.
A function that takes the original HTML and generates a plain text version.
A function that toggles <style> blocks off and on to simulate popular email clients ignoring them.
Email files are backed up via Dropbox and the Dropbox API is integrated to allow for quick sharing right from the email newsletter.
Until now I've been using javascript in my injected content script like this to create all of my menu items.
var debugOrb = document.createElement("div");
debugOrb.id = "borders-orb";
debugOrb.className = "borders-orb orb glyph";
debugOrb.addEventListener("click", toggleBorders, false);
orbsBottom.appendChild(debugOrb);
Here's an extended view of the code I've written to create all of these toggles/menu items: http://pastebin.com/LQTkNhpP
My problem is that now I'm going to be adding a LOT more clickable menu items like this. And it feels like if I do, it's going to get out of hand really quick. Especially since I'll be nesting a lot of divs to make the whole thing look organized and using JavaScript to create lots of text nodes too.
My first thought was what if I could just create my entire menu in regular HTML, then just inject that file into the page with the javascript in my content script. I'm barely intermediate level with JavaScript though. And as I understand it, if I did this, I'd lose my ability to use onclick handlers for all of these divs I'm creating.
Is there an efficient way to handle my goal that I'm not aware of?
Notes:
I'm not using any framework/plugins like React, Angular, or jQuery.
Once the html is added you can always get the element by id and then add an event listener to that element. You can have functions relate to the divs and then onload create the event listeners. element.addEventListener ('click', function);
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
I was trying to write a global JavaScriptfunction which overrides any HTML object (img, iframe, links and so on) before it being loaded by the page. The purpose of the overiding action was to to change the SRC and HREF of these objects using the DOM to any other link.
Unfortunately I didn't find any solution to that without firstly loading the object and only then changing it by the onload event.
My second option was to change the SRC and HREF by matching these attributes with a regular expression and replacing the resultant values. I prefer not to do so because it's slow and consumes a lot of time.
I would be glad if someone can share with his/her experience and help me solve this out.
JavaScript only works within the DOM.
You could however, load the page via AJAX, get the content and do any string manipulation on it.
If you are trying to modify items that exist in the static HTML of the page, you cannot modify them with javascript until they are successfully loaded by the browser. There is no way to modify them before that. They may or may not be visible to the viewer before you have a chance to modify them.
To solve this issue, there are a couple of options.
Put CSS style rules in the page that causes all items that you want to modify to initially be hidden and then your javascript can modify them and then show them so they will not be seen before your modification.
Don't put the items that you want to modify in the static part of your HTML page. You can either create them programmatically with javascript and insert them into the page or you can load them via ajax, modify them after loading them via ajax and then insert them into the page.
For both of these scenarios, you will have to devise a fallback plan if javascript is not enabled.
Let's say I want to create a website that contains one page. All the content is dynamic and generated using JavaScript with DOM replacement. The good thing about this is that it creates a better user experience, especially for applications that contain catalogues (online stores, galleries, etc). The problem now comes with linking. Let's say I'm browsing the site and I feel like sharing that particular thing I'm looking at with someone, but the problem is the link is always the same since it's JavaScript that's doing the magic. So the question comes: how can I create a fully JavaScript run website while maintaining the ability to link?
Now there's hash linking, but I'm failing miserably. I've tried overriding all <a> tags, changing the hash, and preventing the default action like so
$("a").click( function(){
window.location.hash = $(this).attr("id");
processHash();
return false;
});
Yet, it will randomly scroll my body for no reason.
I'd like some insights on the restrictions of linking in a fully dynamic website. Thanks.
Here is one simple thing you can do:
window.onload = function () {
processHash();
}
or it can be using jquery $(function () {...});
what happens here is when the page is loaded example http://www.example.com/#some-link
the page content is loaded first then your function that handle links processHash(); will do its work
not even the new and shiny jQuery mobile library is 100% ajax, but it's close. Obviously with a very modern browser, checkout this doc site done in jQuery mobile: http://jquerymobile.com/test/
If you dig in the docs a little you see how they use hash linking with the framework and html5 data-content="page"
each <div data-content="page">Is an independent page, if I remember right</div>
http://dy-verse.blogspot.com/2009/08/screen-scraping-with-javascript-firebug.html[link text][1]
outlines a strategy to parse a page and submit contents to a Google spreadsheet that depends on Greasemonkey. I'd like to adapt this approach to a simple bookmarklet where, instead of hardcoding in the page address to be parsed, i would manually navigate to the page in question to execute the bookmarklet.
I need help coding the entry point and assigning the elements to be parsed. My page has 3 (un-nested) tables at the top-level of the document - it has no classnames. How do I go about passing those tables into the start() function?
thx
If you load your page with a bookmarklet you have free hands to use any of your javascript command inside that page.
You can use document.getElementsByTagName('TABLE') or load a JS library that will help you do the job.
And if you are using a modern browser you can use as well the document.querySelectorAll with a CSS selector.