How to style blockquotes in a WYSIWYG editor - javascript

I'm kind of new to Javascript and have been doing small projects to get myself acquainted with the language. I've done things like draggable boxes, a calculator, etc., and now I'm working on a small WYSIWYG editor for practice and possibly a future site.
In this project I'm using an iframe as the text box using this snippet of code:
<!-- images as buttons -->
<iframe id='reply'></iframe>
<script>
var doc;
doc = document.getElementById('reply');
doc = doc.contentDocument || document.frames.reply.document;
doc.designMode = 'on';
</script>
to access the document of the iframe. After accessing the document I use various calls to doc.execCommand('someCommand', false, null); to create the editing interface. I've gotten several buttons to work (bold, italic, underline, strikethrough, sub and superscript, etc.) but I'm having trouble with block quotes. This is for a theoretical message board and the editor needs to be able to make long quotations recognizable, much like how the blockquote button on Stack Overflow operates.
To make this work, so far I've used doc.execCommand('formatblock', false, '<blockquote>');. This method will indent the text properly, but my CSS doesn't effect it. I assume this is because the CSS on that document doesn't apply inside the iframe . . . but I don't know how to style the stuff inside of it. Is there a way to insert a stylesheet inside the iframe? Am I going about this all wrong? Should I perhaps try a textarea over an iframe? Thanks for the help!

You would be better off outputting the results to a div as it forms part of the dom for the page you're viewing. Iframes are for loading independant urls and pages therefore you'd need to style the page within the iframe or link to the same stylesheet as the page containing the iframe.
How about a div like this you can set the oveflow property in the css to overflow: scroll; and get a similar effect to the iframe whilst keeping all your elements in the same page?
<div id='reply'></div>
Css for the div
#reply {
width: 200px;
height: 150px;
overflow: scroll;
/* additional properties */
}
I hope this helps...

Related

Getting an element to share a background with another element?

I have a document that is styled like so:
<div class = 'page'>
<header class = 'site-header'>
<div class = 'main-navigation-container'>
...
</div>
</header>
</div>
where the header has a nice background-image. However, as soon as the header ends we reach the navigation bar, which has a stock blue option. I want to have the header background "spill over" into the
.main-navigation-container, so that it appears as if the .main-navigation-container is contained within the header.
Here's the idea:
Before
As you can see in the before, the navigation container (menu) does not share the background with the header. However, after the change it should look like this:
After
Notice that the menu is now changed to be located within the header. The issue lies in the fact that I am using Wordpress for the backend, so I had to add javscript to the body as opposed to redefining the html elements manually:
<script>
var nav = document.getElementsByClassName("main-navigation-container")[0];
document.getElementsByClassName("site-header")[0].appendChild(nav);
</script>
This approach worked when I used a test document on my local machine, but it does not work in Wordpress. Does anyone have any suggestions as to how I could solve my problem with either the approach I'm currently using, or an entirely different one?
Thanks.
EDIT:
SOLVED: It was an issue with the flow of the document. When you add custom javascript in wordpress they give you two options for script location: Body and Footer. I assumed I needed to put the script in the body, but when I tried moving the script to the footer it worked.
You can make the background of your nav transparent. You can add a custom class 'bg-custom' to the 'main-navigation-container', then in your CSS style sheet add:
.bg-custom: {
background-color: transparent;
}
or add it inline with a 'style' tag:
style="background-color: transparent;"

Change css property of a widget added via the google tag manager and loaded aynchronously in an iframe

I have added a widget on my web site that shows on the lower-right corner of the screen, but I'd rather it appeared on the bottom-left side. The google tag is a script like this
<script src="https://leadbooster-chat.pipedrive.com/assets/loader.js" async></script>
And after loading the script generates an iframe with appropriate css positioning
HTML
<iframe role="complementary" scrolling="no" id="LeadboosterContainer" class="proactiveChat" style="height:100px !important"></iframe>
CSS
#media (min-width: 576px)
<style>
html body #LeadboosterContainer {
bottom: 28px !important;
right: 28px !important;
}
It turns out the widget is not configurable via their interface to appear on the left hand screen (I'll send them a suggestion), but I have discovered that simply changing the right: 28px !important; to a left is enough to produce a quite acceptable behavior.
I'm aware that the developers may change this property in the future, and that the solution I'm thinking of would be a bit dirty, but is it possible to accurately target the CSS generated AFTER the widget is loaded via the script, and change the right to a left ? As you can see, the challenges here
The script is loading the HTML asynchronously
There is is a media query (and actually there are several rules that would need changing)
there is a !important flag which makes it harder to override this CSS rule in a brand new stylesheet
this is an iframe on another website... so we cannot do anything we want since security policies apply inside the iframe, and we only have the control on the iframe element itself for positioning
How can I do this ? I need to trigger an event after an async script has started, and then find a way to target media queries.
An example of what I'm thinking of adding to my google tag
// TODO : find a way to fire this code after the script has loaded / implement runAfterChatBotHasLoaded
runAfterChatBotHasLoaded( function() {
var pipedriveBot = document.getElementById("LeadboosterContainer");
// TODO : find a way to target each media query
position = pipedriveBot.getAttribute('right');
pipedriveBot.setAttribute('left', position)
pipedriveBot.removeProperty('right'));
});
I have also tried
Adding rules via https://davidwalsh.name/add-rules-stylesheets (I run into a Uncaught DOMException: Failed to execute 'insertRule' on 'CSSStyleSheet': The index provided (1) is larger than the maximum index (0).
Various ideas from Find all CSS rules that apply to an element
If the widget is in the iframe then you require either:
GTM in the iframe, not just the parent window
The post message api to securely call functions between the iframe and parent window (the parent window being where GTM is loading)
If the css you are targeting is in the iframe then you need to treat it as a different website that doesn't have your GTM container loaded on it.
If you're trying to move the iframe to the bottom left then this is working for me in a jsfiddle:
var pipedriveBot = document.getElementById("LeadboosterContainer");
// remove the styling
pipedriveBot.style.setProperty('bottom', '0', 'important');
// Add your own
pipedriveBot.style.position = "fixed";
pipedriveBot.style.left = "0px";
See also this article on removing css properties that are set with !important: How can you remove an important CSS property?
Let me know if I have understood correctly. If you need to wait until the DOM contains LeadboosterContainer then you can set a function to check the DOM periodically and then fire a function.

How to disable Evernote web view "max-width" with JavaScript?

Evernote places a max-width limit on web view content, and I have identified its location in Chrome developer tool(F12). Evidence: Unticking the checkbox beside "max-width" will stretch the table to full window width.
My question is, how can I remove that css statement with JavaScript code?
I have tried this:
document.getElementById("container").style.removeProperty("max-width")
but in vain.
The above web page can be reached at http://www.evernote.com/l/ABXYD6q6bM9MyaAfRs78hQnq6VMINfVJODg/
Given that this statement isn't set as inline style, you won't be able to remove it.
However, you could change its value and set it to none by adding an inline style declaration, which will override the current value.
Demo:
var elem = document.getElementById('container');
elem.style.maxWidth = 'none';
Not sure how webview works, but could you try using javascript to add a new class to it that added a max-width of 100%?
document.getElementById("container").classList.add('no-max-width');
then in the styles.css put
.no-max-width {
max-width: 100%; }
If that's not possible, then try
document.getElementById("container").style.maxWidth('100%');
Though I sometimes have trouble with .styles so not sure if that is exactly right, plus I've read it's better to add classes rather than play with css styles in JS, but also not sure how accurate that is.

Treat div as a nonexistent element in HTML

Is adding a display:inline all that is needed for the browser display to treat the <div> as a nonexistent element (do want to consider everything inside the div though) in HTML?
I was thinking of having this div simply as a placeholder to put content into it from javascript and I was wondering whether it would be a good idea to make it display:inline
NOTE By nonexistent I mean that if the user says he wants to display the following on the page
<something here>
<something else here />
....
</something here>
Then the end result on the UI would be exactly what he wanted. Putting a div around it currently is adding a newline between this and other things.
I add this divs around something the user (the user being the programmer that is using the functionality I write) outputs in a function. I want to keep this divs completely invisible to the user. Currently there is a new line injected at times. For example there is a newline in between the two buttons
<div>
<button>Something</button>
<div>
<button>Else</button>
</div>
</div>
As long as you haven't styled the div with any width, height, margin, or padding you can leave it as is. No need to add "display: inline;". It's natural display: block; is just fine and won't take up any space as long as it is empty.
Then, if you inject content with, say, javascript the div will grow to fit the inside content.
Apparently a div has some display properties by default in the browser. Using a tag like <placeholder> seems like a good alternative that does not affect the UI at all.

Why is my TinyMCE hidden textarea acting up?

I have about 7 textareas on a web page, all of them are rich text editors using TinyMCE. However at page load only 1 of them is visible and the rest of them hidden. The user can click a 'show' link which would display the remaining textareas one by one.
However, I have a weird problem. All the textareas are setup like this:
<textarea cols="40" rows="20"></textarea>
However, only the textarea displayed on page load is the full size I want it to be. The remaining textareas are really small when I show them. So I'm thinking that perhaps they aren't rendered because they are hidden on page load.
How can I remedy this?
Try adding some CSS to textareas that are hidden.
For example, use
<textarea cols="40" rows="20" style="width: 40em; height: 20em"></textarea>
I think I ran into this, where TinyMCE's CSS overrides some of the default CSS behaviour. I ended up having to "re-override" it, and eventually edited the TinyMCE's css pages.
I think this is an MCE bug, or at least a feature that MCE lacks.
Since I wanted to style my input box in CSS, not in HTML (yuck) I tried
visibility: hidden;
instead of
display: none;
and everything worked again.
I believe that the latter causes the element to take up no space, which trips up the MCE code which detects the width and height of the element.
When loading TinyMCE with jQuery, this problem can be solved as such:
1- On your textarea, specify a height in the inline style attribute:
<textarea style="height:200px;" class="tinymce" name="myfield"></textarea>
2- add a callback function when instantiating a TinyMCE editor. e.g. tinymceLoaded
$('textarea.tinymce').tinymce({
// Location of TinyMCE script
script_url : 'PATH_TO_TINYMCE.js',
// General options ...
// Theme options...
// callback function
init_instance_callback : "tinymceLoaded"
});
3- Set the height of your Editors in the tinymceLoaded function:
function tinymceLoaded(inst){
// get the desired height of the editor
var height = $('#' + inst.editorId).height();
// when the editor is hidden, the height calculated is 0
// Lets use the inline style text to solve this problem
if(height == 0){
height = $('#' + inst.editorId).css('height'); // 200px
height = height.replace(/[^0-9]/g, ""); // remove all non-numeric characters to isolate the '200'
}
// set the height of the hidden TinyMCE editor
$('#' + inst.editorId + '_ifr').css({height: height + 'px'});
}
Without having a few more specifics about your actual setup and how you're doing the vaious display/hide functionality it's hard to give a definitive answer.
I can throw a few general thoughts out though:
Do they render properly when you don't hide them on page load? That would give a definative answer for at what point the bug's occuring.
When you toggle the view of the textarea can you explicity set the row/col attributes at the same time?
Can you use css (maybe with !important) to set textarea width and height than to test if that has an effect?
From TinyMCE inside hidden div are not displayed as enabled when we put the div visible, user's slolife answer helped me:
Try calling tinyMCE.init(...) after you unhide the containing div.
I've been having the same issue where the height of the hidden textarea controls that were converted into TinyMCE editors were too small. Setting visibility to none worked but leaves a big empty space in its place.
The following solution worked well for me:
Do not hide your textarea controls initially on page load
Instead, set all of your TinyMCE's init config as follows:
tinyMCE.init({
...
init_instance_callback : "onInstanceInit"
});
In your onInstanceInit function, hide the initialized TinyMCE editor dynamically
If you show this editor afterwards, the height will be normal again just like it was never hidden
If you use production version of TinyMCE, you probably forgot to copy folders that tinymce.min.js needs. You need to have folders langs, plugins, skins and themes in the same folder as your tinymce.min.js file.
Another reason for the hidden thing is when you remove elements from the dom with tinymce initialized on them. You need to remove tinymce from this element first, so you will avoid weird behaviour when initialize new tinymce elements.
So for exemple :
removeElementWithTinymce = function(elementToRemove){
var parent = elementToRemove.parentNode;
tinymce.remove(elementToRemove.getAttribute('id'));
parent.removeChild(elementToRemove);
};
That's it.

Categories