how to use modernizr to load ractive legacy - modernizr

I need to work on a project, that needs legacy support.
How would I go about integrating it with modernizr to only load legacy if necessary?
Is that even possible?

The legacy build includes polyfills for a few bits and pieces that aren't in IE8 - Ractive does its own check when it first loads, and throws an error if it detects missing features (and it's the non-legacy build). The detection code is here - so you could just copy that into your app:
function useRactiveLegacy () {
return (
typeof Date.now !== FUNCTION ||
typeof String.prototype.trim !== FUNCTION ||
typeof Object.keys !== FUNCTION ||
typeof Array.prototype.indexOf !== FUNCTION ||
typeof Array.prototype.forEach !== FUNCTION ||
typeof Array.prototype.map !== FUNCTION ||
typeof Array.prototype.filter !== FUNCTION ||
( typeof window !== 'undefined' && typeof window.addEventListener !== FUNCTION )
);
}
// using Modernizr
Modernizr.load({
test: !useRactiveLegacy(),
yep: 'ractive.js',
nope: 'ractive-legacy.js
});
// using AMD
require([ useRactiveLegacy() ? 'ractive-legacy' : 'ractive' ], function ( Ractive ) {
/* code goes here */
});
Bear in mind that these checks could change with future versions of Ractive - for example, there may come a time when we decide to relegate Promises to the legacy version, rather than automatically polyfilling it.

Related

Error localStorage is not defined on refersh (Nuxt Js , Parse server)

Getting the above error on page refresh, but i am not using localStorage in my Code.
Perform operations only possible in the browser within the following if statement:
if (process.client) {
localStorage...
}
See: https://nuxtjs.org/api/context/
another option is to only call it in the beforeMount or mounted functions, since they always happen on the client side.
Your app is running on a server so there is no browser or window, which means you do not have access to the APIs provided by the browser.
You can prevent this error by checking if the window object is available before try to access it. for example:
const token = typeof window !== 'undefined' ? localStorage.getItem('token') : null;
//OR
if (typeof window !== 'undefined') {
const token = typeof window !== 'undefined' ? localStorage.getItem('token') : null;
}
Well What I did was that I created a state like
const thisWindow = useState('thisWindow')
and in app.vue onMounted set window like
onMounted( () => {
thisWindow.value = window
})
and just called it in my function and globally

React onKeyDown/onKeyUp events on non-input elements

I need to capture cmd button up and down events, in order to choose, whether to use concatenation or not in setState. How do i get these events, for example, on table element?
You have to capture the keypress then in body/window level. Table element doesn't have input focus so you can't capture the keys from table (without input element).
var cmdDown = false;
document.body.addEventListener('keydown', function(event) {
var key = event.keyCode || event.charCode || 0;
if ([91,93,224,17].indexOf(key) !== -1) {
cmdDown = true;
}
console.log('CMD DOWN: ' + cmdDown.toString());
});
document.body.addEventListener('keyup', function(event) {
var key = event.keyCode || event.charCode || 0;
if ([91,93,224,17].indexOf(key) !== -1) {
cmdDown = false;
}
console.log('CMD DOWN: ' + cmdDown.toString());
});
Simple Example
I believe best practice here is to add an event listener to document and modify your element (e.x. table) accordingly. Extending u/Hardy's answer with a full React component:
class MyComponent extends React.Component {
// Using an arrow function. Alternatively, could bind() this
// function in the component's constructor
keydownHandler = (event) => {
// Add logic, e.x. check event.keyCode to see
// if CMD is pressed and then update state
}
componentDidMount() {
document.addEventListener("keydown", this.keydownHandler);
}
componentWillUnmount() {
this.removeEventListener("keydown", this.keydownHandler);
}
render() {
<div>Hello World</div>
}
}
Alternative
As others have noted, there are challenges in using keyboard events that are bound to non-input elements, as browsers require those elements to be in focus in order to invoke the bound callbacks. Another approach that seems to work is to set the tabindex property of the component to bring the element in focus. From u/burak's answer:
render() {
<div onKeyDown={this.keydownHandler} tabindex={-1}>Example</div>
}
This has the benefit of connecting into React's Synthetic Events, that is "a cross-browser wrapper around the browser’s native event." However, when modifying the tabindex property it's important to be mindful that this could change the order of focusable elements, and affect a user's ability to navigate your site with their keyboard or accessibility software. Some users report that setting tabindex to -1 resolves this issue (see comments in previous link).

Make Pinterest Profile Widget Secure

I am using the below page to create a Pinterest Profile widget:
https://business.pinterest.com/en/widget-builder#do_embed_user
The problem is that when the widget displays the images use non secure links. I need to display the widget on a secure page so need them to be https://
Any ideas how I can go about this?
Ok so after a bit of research I have made a pretty intense hack to make this work. Pintrest does serve https content, it is just that for some reason they have not included this in their API. So I have stepped through the API and found the attribute setter that sets attributes to any elements the API creates.
Anyway.. here is the fiddle: https://jsfiddle.net/nanff007/1/ (make sure to https)
And here is the code that performs the magic...
This is a workaround/hack or whatever you want to call it. It will not work forever. It may also not work in all countries as the akamai urls may change. The best option would be to raise a request ticket with Pintrest.
(function() {
$('a[data-pin-do]').each(function () {
$(this).attr('data-pin-dont', $(this).attr('data-pin-do'));
$(this).removeAttr('data-pin-do');
});
var timer = setInterval(function () {
for (prop in window) {
if (prop.search(/^PIN_/) > -1 && typeof window[prop] != 'boolean') {
clearInterval(timer);
window[prop].f.set = function (el, att, string) {
if(att == 'src' && el.tagName.toLowerCase() == 'img') {
string = string.replace(/(^http:\/\/)/i, "https://s-");
}
if (typeof el[att] === 'string') {
el[att] = string;
} else {
el.setAttribute(att, string);
}
};
$('a[data-pin-dont]').each(function () {
$(this).attr('data-pin-do', $(this).attr('data-pin-dont'));
$(this).removeAttr('data-pin-dont');
});
window[prop].f.init();
break;
}
}
}, 100);
}());
Just Remove the https: and start with // as the beginning of the link.
For Example:
< a href="//sub-domain.example.com">Acme Widgets
Remove the spaces before > and after < in the above example

isotope cssHooks overwrite jQuery.transit cssHooks

I have a strange issue where, I can not find any simple solution. Using the isotope Plugin and the jQuery.transit Plugin in the same document, makes some of the jQuery.transit plugin supported css3 transitions become unusable (only in FF16).
It looks like the $.cssHooks function in isotope breaks the cssHooks functions from other plugins.
If i disable in isotope.js the line 216
setIsoTransform( elem, 'scale', value );
in this function:
$.cssHooks.scale = {
set: function( elem, value ) {
// uncomment this bit if you want to properly parse strings
// if ( typeof value === 'string' ) {
// value = parseFloat( value );
// }
// alert(elem+" "+value)
setIsoTransform( elem, 'scale', value );
},
get: function( elem, computed ) {
var transform = $.data( elem, 'isoTransform' );
return transform && transform.scale ? transform.scale : 1;
}
};
than the cssHooks function from jQuery transit works well. (In this case the scale function from Isotope does not work any more.)
I don't understand why isotope extend the cssHooks this way, and why this influence any other object on the page, and not just the elements which should be managed via isotope.
I hope you can give me a good direction, or some update.
Cheers,
ThemePunch

Tinymce is (sometimes) undefined

I'm using Tinymce (with jQuery) in a project I'm working at; we use a rich text editor for users to input information; however, sometimes when loading the page Firefox and Chrome will detect a 'tinymce is not defined' error (sometimes at different lines of the code), while other times the page will load just fine. What's weird is that it works perfectly with IE.
Here's a bit of the code I'm using:
view.find('textarea.rich-text').each(function () {
$(this).tinymce( /* ...rules... */);
});
And later on
_variable.find("#summary").tinymce().setContent(content);
This line is where the error (sometimes) gets caught. It seems to me that the problem is a loading issue, even though the tinyMCE plugin is initialized about 5000 lines prior this line.
Update: For now I have managed to 'solve' the problem with a setTimeout, but this seems like a really ugly way to do it.
A few points:
You don't mention whether or not the TinyMCE initialization is done within a jQuery ready event function. It should be of course.
You don't need the each loop. You can just say:
$('textarea.rich-text').tinymce({
script_url : '../js/tinymce/jscripts/tiny_mce/tiny_mce.js',
theme : "advanced",
...
});
You don't need the call to find since you are just selecting by id. Just do:
$("#summary").tinymce().setContent(content);
Your real issue is probably that tinymce has not finished initializing itself when you get the error. You see it has to load a script from the configured script_url. That may take a while. Therefore, you have to make use of a callback such as oninit.
If you do not have control over init method of TinyMCE then, you can follow this solution.
jQuery(document).ready(function($) {
function myCustomSetContent( id, content ) {
// Check if TinyMCE is defined or not.
if( typeof tinymce != "undefined" ) {
var editor = tinymce.get( id );
// Check if TinyMCE is initialized properly or not.
if( editor && editor instanceof tinymce.Editor ) {
editor.setContent( text );
editor.save( { no_events: true } );
} else {
// Fallback
// If TinyMCE is not initialized then directly set the value in textarea.
//TinyMCE will take up this value when it gets initialized.
jQuery( '#'+id ).val( text );
}
return true;
}
return false;
}
function myCustomGetContent( id ) {
// Check if TinyMCE is defined or not.
if( typeof tinymce != "undefined" ) {
var editor = tinymce.get( id );
// Check if TinyMCE is initialized properly or not.
if( editor && editor instanceof tinymce.Editor ) {
return editor.getContent();
} else {
// Fallback
// If TinyMCE is not initialized then directly set the value in textarea.
// TinyMCE will take up this value when it gets initialized.
return jQuery( '#'+id ).val();
}
}
return '';
}
$(".class-to-update-content").on("click", function(e) {
myCustomSetContent( "tinymce-editor-id", "New Content in Editor" );
});
$(".class-to-get-content").on("click", function(e) {
$("div.class-to-display-content").html( myCustomGetContent( "tinymce-editor-id" ) );
});
});
Ref : http://blog.incognitech.in/tinymce-undefined-issue/
EDIT: Solution included

Resources