ipython notebook: how to toggle header invisible by default - jupyter-notebook

I want to save some space for my 14 inch screen. What should I write in e.g. ipython_notebook_config.py to trigger this?

If it doesn't already exist, create a file named custom.js in /Users/YOURUSERNAME/.ipython/profile_default/static/custom/
(You may have to run ipython profile create, if you have never run this command.)
In custom.js, put the following lines of JavaScript
$([IPython.events]).on("app_initialized.NotebookApp", function () {
$('div#header').hide();
});
If you would like to also hide the toolbar by default, use these lines of JavaScript instead
$([IPython.events]).on("app_initialized.NotebookApp", function () {
$('div#header').hide();
$('div#maintoolbar').hide();
});

If you have a recent IPython, like v3.0.0 or higher, and are seeing only sporadic success with this method, you'll need to hook into the RequireJS dependency loader, and put the following in your common.js:
require(['jquery'], function($) {
$('#header-container').hide();
});
common.js is loaded at the bottom of the page, so there's no need to wait for the DOM ready event, i.e., $(function() { ... }).
For further discussion see my answer at Turn off auto-closing parentheses in ipython and its comments.

if you are using Anaconda3, please do:
update your C:\Anaconda3\Lib\site-packages\notebook\static\custom\custom.css
.container{ width:100% !important; }
div#site{ height: 100% !important; }
update your C:\Anaconda3\Lib\site-packages\notebook\static\custom\custom.js, and we add a shortcut ctrl+ for toggle the header
$([IPython.events]).on('notebook_loaded.Notebook',function(){
$('#header').hide();
IPython.keyboard_manager.command_shortcuts.add_shortcut('ctrl-`',function (event) {
if (IPython.notebook.mode == 'command') {
$('#header').toggle();
return false;
}
return true;
});
});

Related

page transitions in meteor - not quite working?

so in the back of the 'discover meteor' book they explain how to do page transitions. i've got it working, however it causes problems with the loading of javascript functions and variables on other pages that its animating into. it seems they're not ready or simply don't exist at the time the page is routed.
Template.layout.onRendered(function() {
this.find('.pos-rel')._uihooks = {
insertElement: function(node, next) {
$(node).hide().insertBefore(next)
.delay(200)
.velocity("transition.slideUpIn", 1000)
},
removeElement: function(node) {
$(node).velocity({
opacity: 0,
},
{
duration: 100,
complete: function() {
$(this).remove();
}
});
}
}
});
if i remove the above code then all my javascript variables and functions work correctly. does anyone have another working solution to page transitions using velocity.js ? i did find this one but its a year old and i couldn't get it to work at all, it just makes the content where '{> yield}' is go blank :(
Just a note for asking questions on stack overflow: "causes problems with the loading of javascript functions and variables" is pretty vague. Its best to give more specifics.
But anyways, you said here that you're using isotope to render items in a grid. I'm assuming you're calling $elements.isotope() within a Template[name].onRendered callback.
This is probably the issue because its trying to compute and rearrange into a grid the elements while they're hidden. Using display: none actually removed the elements, thus isotope can't compute the sizes, etc. for the layout. Try this:
insertElement: function(node, next) {
$(node).css("opacity", 0).insertBefore(next)
.delay(200)
.velocity("transition.slideUpIn", {duration:1000, display:null})
},
opacity: 0 should do what you're looking for. It will make them transparent without removing them from the transition.slideUpIn should animate opacity so you're good there.
Also, velocity transitions mess with the display property. Setting display: null in the animation options prevents it from setting the display to block or whatever it wants to do. This may or may not be necessary, but I pretty much always use it.
You could use:
onAfterAction
onBeforeAction
. The solution should be something like this:
animateContentOut = function() {
$('#content').css('display', 'none');
this.next();
}
fadeContentIn = function() {
$('#content').velocity('transition.fadeIn',1000);
}
Router.onBeforeAction(animateContentOut)
Router.onAfterAction(fadeContentIn)

Creating a TinyMCE inline editor AND making it visible from a button

I'd like to use TinyMCE 4.1.7 in inline mode. When the user right-clicks a DIV and selects Edit, indicating they want to edit the DIV, I execute
var id= g.currentElement$.attr('id');
tinymce.init({
selector: "div#"+id,
inline:true,
});
This adds a TinyMCE editor (I know because I catch an AddEditor event) but it doesn't seem to append the editor elements to the DOM (I can't see them in Chrome DevTools Elements tab). For the editor to appear I have to click inside the DIV.
I want to change this behavior so that when the user right-clicks the DIV and selects Edit, my handler will also trigger whatever is triggered now by clicking in the DIV. So after I've launched the editor, as above, I need to call some other method that will append the editor to the DOM and make it visible, so clicking Edit in the context menu is all I need to bring up the TinyMCE editor.
Could someone tell me what I need to do to accomplish this?
(The reason I can't just click the DIV to bring up the editor is that a click already means something else. A single click selects the DIV, where it can be deleted, duplicated, nudged, etc. A drag on the DIV moves it. And a drag on a DIV corner resizes the DIV. A right-click with an Edit option is all I have left.)
Thanks for your help.
Steve
I got this working as follows.
I first run the tinymce init:
var id= g.currentElement$.attr('id');
tinymce.init({
selector: "div#"+id,
inline:true,
});
That creates an editor for the element but doesn't render or show it. Rendering and showing the editor normally requires a mousedown on the element.
After stepping through a lot of tinymce code I realized that firing a focusin event on the editor instance is what gets the editor rendered and displayed. So I created a callback for AddEditor. The AddEditor event comes in early in the editor create process, though, and I didn't want to fire focusin until the editor was complete, so at the AddEditor event I get the editor instance and create a callback for "NodeChange," which happens at the end of the editor create.
When NodeCreate comes in I fire a "focusin" on the editor and that renders and displays the editor, as I wanted. A single click, now, runs tinymce init and leaves an inline editor displayed and ready on top of the element.
The total code is:
tinymce.on('AddEditor', function(e) {
e.editor.on('NodeChange', function(e) { // now that we know the editor set a callback at "NodeChange."
e.target.fire("focusin"); // NodeChange is at the end of editor create. Fire focusin to render and show it
});
});
If anyone sees anything wrong with this I'd be very grateful for any comments.
Thanks
tinymce.init({
selector: "div#"+id,
inline:true,
setup: function (ed) {
ed.on('init', function(e) {
e.target.fire("focusin");
});
}
});
This will do the trick for the initiating editor instance. Better then globally firing for every single NodeChange event for every single editor instance on the page. (Assuming there multiple editors but also works with single editor.)
BUT WAIT...
There is a better practice using JS Promises. tinymce.init returns a Promise Object.
let tinyMcePromise= tinymce.init({
selector: "div#"+id,
inline:true
});
tinyMcePromise.then(function(editors){
editors[0].focus();
});
Official documentation: https://www.tinymce.com/docs/api/tinymce/root_tinymce/#init
Beware: Some older versions of tinyMce have a bug about init Promise.
**Please first add jquery and tinymce library..**
<script src="latestjquery.js" type="text/javascript" charset="utf-8"></script>
<script src="tinymce.min.js"></script>
<form method="post">
<textarea>here firstly onlciki will show menu and when edit will be selcted then it will be converted into ediotr</textarea>
</form>
<ul class='custom-menu'>
<li data-action = "first">First thing</li>
<li data-action = "second">Second thing</li>
<li data-action = "third">Third thing</li>
</ul>
<script>
//Trigger action when the contexmenu is about to be shown
$("textarea").bind("contextmenu", function (event) {
// Avoid the real one
event.preventDefault();
// Show contextmenu
$(".custom-menu").finish().toggle(100).
// In the right position (the mouse)
css({
top: event.pageY + "px",
left: event.pageX + "px"
});
});
// If the document is clicked somewhere
$("textarea").bind("mousedown", function (e) {
// If the clicked element is not the menu
if (!$(e.target).parents(".custom-menu").length > 0) {
// Hide it
$(".custom-menu").hide(100);
}
});
// If the menu element is clicked
$(".custom-menu li").click(function(){
tinymce.init({
selector: "textarea"
});
// This is the triggered action name
switch($(this).attr("data-action")) {
// A case for each action. Your actions here
case "first": alert("first"); break;
case "second": alert("second"); break;
case "editor": alert("editor will appear");
break;
}
// Hide it AFTER the action was triggered
$(".custom-menu").hide(100);
});
</script>
<style>
.custom-menu {
display: none;
z-index: 1000;
position: absolute;
overflow: hidden;
border: 1px solid #CCC;
white-space: nowrap;
font-family: sans-serif;
background: #FFF;
color: #333;
border-radius: 5px;
}
.custom-menu li {
padding: 8px 12px;
cursor: pointer;
}
.custom-menu li:hover {
background-color: #DEF;
}
</style>

How to watch the size of an element?

I am trying to watch the width of a directive's element (the directive itself). In the demo below I set the element style to 100%, in the real world app the element resizes through media queries.
Here is my approach:
http://jsfiddle.net/fusio/5zgaj79b/
scope.$watch(
function() {
return element.width()
},
function(val) {
console.log(val)
},
true
);
Is .width() not changing?
The reason it is not triggering is that, for the first function to get called, a digest cycle has to be triggered. How to do it? Try adding the following to your fiddle:
angular.module('HelloApp', ['components']).run(function($rootScope) {
$(window).on("resize", function() {
$rootScope.$apply();
});
});
For a real scenario, you may want to limit the scope of the $apply to a specific scope, so as not to cause unnecessary watcher invocations.

Changing mouse cursor on ajaxStart

I have the following scripts which work fairly nicely:
$("#spanLoading").ajaxStart(function () {
$('#spanLoading').empty().append("<img src='/img/loading.gif' />");
});
$("#spanLoading").ajaxComplete(function () {
$('#spanLoading').empty();
});
Is it possible to change these a little, so instead of loading an image on ajaxStart, the mouse cursor changes instead to css cursor wait, and then changes back to normal when ajaxComplete.
Yes, you can do this by changing the cursor property of the body element:
$("#spanLoading").ajaxStart(function () {
$('body').css('cursor', 'wait');
});
$("#spanLoading").ajaxComplete(function () {
$('body').css('cursor', 'auto');
});
Yes:
$('html').css('cursor', 'wait');
On ajaxComplete you change it back.

Wait for fonts to load before rendering web page

I'm using #font-face to embed fonts in my website. First the text renders as the system default, and then (once the font file has loaded presumably) the correct font renders a fraction of a second later. Is there a way to minimise/get rid of this delay, by delaying the page rendering until after fonts have loaded or similar.
Since nobody mentioned that, I believe this question needs an update. The way I managed to solve the problem was using the "preload" option supported by modern browsers.
In case someone does not need to support old browsers.
<link rel="preload" href="assets/fonts/xxx.woff" as="font" type="font/woff" crossorigin>
some useful links with more details:
https://developer.mozilla.org/en-US/docs/Web/HTML/Preloading_content
http://www.bramstein.com/writing/preload-hints-for-web-fonts.html
Edit: The best approach is probably to base64 encode your fonts. This means your font will have to be loaded fully by the time your HTML is parsed and displayed. You can do this with font squirrel's webfont generator https://www.fontsquirrel.com/tools/webfont-generator by clicking "Expert" and then "base64 encode". This is how services like TypeKit work.
Original answer:
Another way to detect if fonts are loaded would be using FontLoader https://github.com/smnh/FontLoader or by copying their strategy.
They bind to the scroll event in the browser, because when the font loads it will resize the text. It uses two containing divs (that will scroll when the height changes) and a separate fallback for IE.
An alternative is to check the DOM periodically with setInterval, but using javascript events is far faster and superior.
Obviously, you might do something like set the opacity of body to 0 and then display it in once the font loads.
This is down to how the browser behaves.
First off where is your #font declared? Is it inline to your HTML, declared in a CSS sheet on the page, or (hopefully) declared in an external CSS sheet?
If it is not in an external sheet, try moving it to one (this is better practice anyway usually).
If this doesn't help, you need to ask yourself is the fraction of a second difference really significantly detrimental to the user experience? If it is, then consider JavaScript, there are a few things you might be able to do, redirects, pauses etc, but these might actually be worse than the original problem. Worse for users, and worse to maintain.
This link might help:
http://paulirish.com/2009/fighting-the-font-face-fout/
Joni Korpi has a nice article on loading fonts before the rest of the page.
http://jonikorpi.com/a-smoother-page-load/
He also uses a loading.gif to alleviate the delay so users won't get frustrated.
This code works very well for me. It uses the Font Loading API which has good support among modern browsers.
<style>
#font-face {
font-family: 'DemoFont';
font-style: normal;
font-weight: 400;
src: url("./fonts/DemoFont.eot");
src: url("./fonts/DemoFont.woff2") format("woff2"),
url("./fonts/DemoFont.woff") format("woff"),
url("./fonts/DemoFont.ttf") format("truetype");
}
.font {
font-family: 'DemoFont';
color: transparent;
}
html.font-loaded .font {
color: inherit; // Override `transparent` from .font
}
</style>
<script>
// Check if API exists
if (document && document.fonts) {
// Do not block page loading
setTimeout(function () {
document.fonts.load('16px "DemoFont"').then(() => {
// Make font using elements visible
document.documentElement.classList.add('font-loaded')
})
}, 0)
} else {
// Fallback if API does not exist
document.documentElement.classList.add('font-loaded')
}
</script>
The trick is to set the CSS color to transparent for elements using the font. Once loaded this is reset by adding font-loaded class to <html> element.
Please replace DemoFont with something meaningful for your project to get it work.
I had a similar problem while rendering to an HTML canvas, and this was my solution. It's based on the FontFace API, and similar to Holtwicks approach. The key differences are that this is a generic approach and that it will work out-of-the-box for external fonts/stylesheets (e.g. google fonts).
A couple of notes;
fonts.load( ... ) will happily resolve with an empty set of fonts if the font isn't known yet. Presumably, this happens if this code is called before the stylesheet declaring the font was added. I added a fonts.check(...) to overcome that.
This will let you await javascript execution until a font is available, so it won't work out of the box for 'normal' HTML content. You can combine this with Holtwicks answer above.
export async function waitForFontLoad(
font: string,
timeout = 1000,
interval = 10
) {
return new Promise((resolve, reject) => {
// repeatedly poll check
const poller = setInterval(async () => {
try {
await document.fonts.load(font);
} catch (err) {
reject(err);
}
if (document.fonts.check(font)) {
clearInterval(poller);
resolve(true);
}
}, interval);
setTimeout(() => clearInterval(poller), timeout);
});
}
Only IE loads first the font and then the rest of the page.
The other browsers load things concurrently for a reason. Imagine that there's a problem with the server hosting the font or with the font downloading.
You will hang your entire site until the font is loaded. On my opinion a flash of unstyled text is better than not seeing the site at all
You can use CSS font-display inside your #font-face.
The keywords for all the available values are:
auto
block
swap
fallback
optional
Giulio Mainardi has written a nice article about all of them, and which you should use where on sitepoint.
You can read it here: https://www.sitepoint.com/css-font-display-future-font-rendering-web/?utm_source=frontendfocus&utm_medium=email
Use https://github.com/typekit/webfontloader
and check the events in the configuration
https://github.com/typekit/webfontloader#configuration
<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
<script>
WebFont.load({
custom: {
families: [ "CustomFont1", "CustomFont2" ]
},
active: function() {
//Render your page
}
});
</script>
while the answer posted by #fluffy works. But the interval function runs after every interval and doesn't wait for fonts.load promise to resolve, better solution would be to use recursive function
function waitForFontLoad(font: string, timeout = 1000, interval = 10) {
const startTime = Date.now();
return new Promise((resolve, reject) => {
const recursiveFn = () => {
const currTime = Date.now();
if (currTime - startTime >= timeout) {
reject("font listener timeout " + font);
} else {
document.fonts
.load(font)
.then((fonts) => {
if (fonts.length >= 1) {
resolve(true);
} else {
setTimeout(recursiveFn, interval);
}
})
.catch((err) => {
reject(err);
});
}
};
recursiveFn();
});
}
reference - webfontloader
Simplest solution
// Single font
FontLoad( ['Font name one'])
// Multiple fonts
FontLoad( ['Font name one','Another font name'])
you can use without CallBack funtion too, callback function is optional incase you want invoked inside when FontLoad function completed.
const FontLoad = async ( fonts=[] , callback=()=>{} ) => {
await fonts;
for (const font of fonts) {
document.fonts.check(`80px ${font}`)
? document.fonts.load(`80px ${font}`).then( () => { console.log( `Font: ${font} loaded ✔️` ) } )
: console.log( `Font: ${font} not founded ❌` )
}
document.fonts.ready.then(() => { console.log("Ready"); callback() })
}
FontLoad( ['Arial','FONT_NOT_FOUNDED'], ()=> console.log("External function") )
(function() {
document.getElementsByTagName("html")[0].setAttribute("class","wf-loading")
document.getElementsByTagName("html")[0].setAttribute("className","wf-loading")
})();
use this method.. use with Webfont.js
Maybe something like this:
$("body").html("<img src='ajax-loader.gif' />");
Then when the page loads, replace body's content with the actual content and hopefully, fully rendered fonts, you may have to play around with this though...

Resources