pdfjs with magento 2 - javascript

I could integrate pdfjs with magento 2 requireJS.
have downloaded files from here: https://cdnjs.com/libraries/pdf.js and placed them in my_theme/web/js/ folder
added pdfjs to requirejs script:
my_theme/web/js/requirejs-config.js
var config = {
paths: {
'pdfjs-dist/build/pdf': 'js/pdf.min',
'pdfjs-dist/build/pdf.worker': 'js/pdf.worker.min'
}
};
add script to page :
require(["js/pdf", "js/pdf.worker"],function(pdfjsLib, pdfWorker){
//define url other parts of script..
pdfjsLib.getDocument(url).promise.then(function(pdfDoc_) {
pdfDoc = pdfDoc_;
document.getElementById('page_count').textContent = pdfDoc.numPages;
// Initial/first page rendering
renderPage(pageNum);
});
});
script is loaded i can see that both pdf.min.js and pdf.worker.min.js where loaded with magento.
but still getting following error: Cannot read property 'getDocument' of undefined.
from test both variables are undefined: pdfjsLib, pdfWorker
any idea what is wrong here ?
if we use :
require(["pdfjs-dist/build/pdf", "pdfjs-dist/build/pdf.worker"],function(pdfjsLib, pdfWorker){
we get 404 since it will try to load script from website/pub/static/vendor/theme/pdfjs-dist/build/pdf.min.js
but file is located at website/pub/static/vendor/theme/js/pdf.min.js

I do not have Magento2 setup but I did a simple HTML setup and it is working:
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
<script>
var config = {
paths: {
'pdfjs-dist/build/pdf': 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.6.347/pdf.min',
'pdfjs-dist/build/pdf.worker': 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/2.6.347/pdf.worker.min'
}
};
requirejs.config(config);
require(["pdfjs-dist/build/pdf", "pdfjs-dist/build/pdf.worker"],function(pdfjsLib, pdfWorker){
console.log(pdfjsLib, pdfWorker);
});
</script>
Maybe this will help you :)

Related

How to add fallback for a failing CDN

I want to include jQuery from CDN into my code. I also want to create a fallback. My original solution was to check if CDN has failed, and if so use document.write to insert the fallback <script> into the DOM.
Now Google is saying not to use document.write so instead I have changed my fallback function to dynamically insert the local <script> path into the DOM:
<script>
function fallback(id, localScript) {
fallBackNode = document.getElementById(id);
// insert local jQuery path, right after fallback (does not work)
fallBackNode.insertAdjacentHTML("afterend", "<script src='" + localScript + "'><\/script>");
// insert local jQuery path, (works)
//document.write('<script src="' + localPath + '"><\/script>');
}
</script>
// jQuery CDN
<script src="https://code.jquery.com/jquery-3.6.0.9-INVALID_CDN.min.js"></script>
// jQuery fallback
<script id="jqueryfallback">window.jQuery || fallback('jqueryfallback', '/Scripts/jquery-3.6.0.min.js');
// jQuery ui CDN
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script></script>
Both of the above options (i.e. using document.write and using fallBackNode.insertAdjacentHTML) produce exactly the same result, they insert my local path right after the fallback check, as shown below:
<script id="jqueryfallback">window.jQuery || fallback('jqueryfallback', '/Scripts/jquery-3.6.0.min.js');</script>
<script src="/Scripts/jquery-3.6.0.min.js"></script> // <-- both solutions insert this line here
However when I use document.write everything works fine and the local jQuery gets loaded before jQuery.ui... but if I use the fallBackNode.insertAdjacentHTML option, I get the following error in jQuery.ui:
It seems like, jQuery.ui which is the next library, does not wait for the local jQuery to be inserted into DOM, and throws error... how can I resolve this issue?
I was interested in this idea, so I tried a simple script loading sequence. You set up the array of main/fallback scripts in the sequence you want them to load. Not sure how production ready it is, but let me know if it helps.
const scripts = [{
main: "https://badlink.com/nothing.js",
fallback: "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"
},
{
main: "https://badlink.com/nothing.js",
fallback: "https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
}
];
let scriptcounter = 0;
function loadScripts() {
if (scriptcounter < scripts.length) {
loadScript(scriptcounter);
}
}
function loadScript(index, fallback) {
let thescript = fallback ? scripts[index].fallback : scripts[index].main
let myScript = document.createElement("script");
myScript.setAttribute("src", thescript);
document.body.appendChild(myScript);
myScript.addEventListener("load", scriptLoaded, false);
myScript.addEventListener("error", scriptError, false);
function scriptError() {
console.log("Script error for ", thescript);
if (fallback) console.log("Fallback failed, stopping");
else loadScript(index, true)
}
function scriptLoaded() {
console.log("Script loaded - ", thescript);
scriptcounter++;
loadScripts()
}
}
window.onload = function() {
loadScripts()
}

TinyMCE editor : Uncaught TypeError: Cannot set property 'isMSIE' of null

I'm using TinyMCE (v3.5.8) and integrated iBrowser plugin (v1.4.5) with Codeigniter 2.1.3 and i'm getting the JavaScript error Uncaught TypeError: Cannot set property 'isMSIE' of null
Please help me to solve this.
Thanks.
EDIT
Error is in iBrowser plugin.
I didn't changed anything as from the downloaded file.
Error occurring in editor_plugin.js in iBrowser plugin folder.
iBrowser plugin url : http://seoroot.com/blog/computing/programming/tinymce-ibrowser-plugin.html
editor_plugin.js contains below code.
ib = null;
(function() {
tinymce.create('tinymce.plugins.IBrowserPlugin', {
init : function(ed, url) {
// load common script
tinymce.ScriptLoader.load(url + '/interface/common.js');
// Register commands
ed.addCommand('mceIBrowser', function() {
var e = ed.selection.getNode();
// Internal image object like a flash placeholder
if (ed.dom.getAttrib(ed.selection.getNode(), 'class').indexOf('mceItem') != -1) {return}
ib.isMSIE = tinymce.isIE;
ib.isGecko = tinymce.isGecko;
ib.isWebKit= tinymce.isWebKit;
ib.oEditor = ed;
ib.editor = ed;
ib.selectedElement = e;
ib.baseURL = url + '/ibrowser.php';
iBrowser_open();
});
// Register buttons
ed.addButton('ibrowser', {
title : 'iBrowser',
cmd : 'mceIBrowser',
image: url + '/interface/images/tinyMCE/ibrowser.gif'
});
// Add a node change handler, selects the button in the UI when a image is selected
ed.onNodeChange.add(function(ed, cm, n) {
cm.setActive('ibrowser', n.nodeName == 'IMG');
});
},
getInfo : function() {
return {
longname : 'iBrowser',
author : 'net4visions.com',
authorurl : 'http://net4visions.com',
infourl : 'http://net4visions.com/ibrowser.html',
version : '1.4.0'
};
}
});
// Register plugin
tinymce.PluginManager.add('ibrowser', tinymce.plugins.IBrowserPlugin);
})();
Sorry. Its a long code.
NOTE : TinyMCE is working well but this plugin has some errors.
The culprit is the first line of the code:
ib = null;
null cannot be accessed as an object. That will throw a TypeError as you've seen. The fix, I assume, would be to change this line to:
ib = {};
That way it is an object and can have its isMSIE property set.
However, I'm a little puzzled why this was explicitly set to null. I'd try changing that line of code and seeing if that breaks something, because there possibly could've been a reason for ib to initially be null.
In the file editor_plugin.js (located in ibrowser root plugin folder) commented out the line:
tinymce.ScriptLoader.load(url + '/interface/common.js');
and add this
$.getScript(url+'/interface/common.js');
Do the same for editor_plugin_src.js as well.
Should be fixed.
The fix by #PhpMyCoder will work too. :)

Common data between js modules in IE8

I have a web app made of several jsp files, several of which make use of common jscript modules. My problem is that I am having difficulties accessing common data between the jscript modules in IE8.
For example - In a jsp file:
<script for="window" event="onload">
// My globals.
myGlobals = new Object();
// Attach it to the window for maximum availability.
window.myGlobals = myGlobals;
// Add some fields to it.
// List is actually built from external data so cannot be included from external file.
myGlobals.filters = [
'Filter-Women',
'Filter-Men',
'Filter-Girls',
'Filter-Boys',
];
myGlobals.filtered = '';
</script>
and in a separate js file:
function filter(f) {
for (var i = 0;i < myGlobals.filters.length;i++){
if ( 'Filter-'+f == myGlobals.filters[i] ) {
filterIn(document.getElementById(myGlobals.filters[i]));
} else {
filterOut(document.getElementById(myGlobals.filters[i]));
}
}
myGlobals.filtered = f;
}
function filterIn(e) {
e.classList.add('filterselected');
}
function filterOut(e) {
e.classList.remove('filterselected');
}
and in my jsp - the list is also built from the same external data as above:
<div class="filterbuttons">
<a id="Filter-Women" onclick="filter('Women')">WOMEN</a>
<a id="Filter-Men" onclick="filter('Men')">MEN</a>
<a id="Filter-Girls" onclick="filter('Girls')">GIRLS</a>
<a id="Filter-Boys" onclick="filter('Boys')">BOYS</a>
</div>
Now this all works fine in Firefox but customer also needs this to work in IE8. There, the myGlobals structure is not available, not even from the window. Any ideas?
Problem solved!
Change:
<script for="window" event="onload">
to just plain:
<script>
and everything works fine again.

Mustache.js + jQuery: what is the minimal working example ?

I would like to use mustache.js with jQuery in my HTML5 app, but I can't make all the component work together. Every file is found, there is no problem here (the template is loaded roght, I can see its value in the Firebug debugguer).
Here is my index.html :
<!DOCTYPE html>
<html lang="fr">
<head><meta charset="utf-8"></head>
<body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
<script src="../js/jquery.mustache.js"></script>
<script src="../js/app.js"></script>
<div id="content"></div>
</body>
</html>
Here is my app.js file :
$(document).ready(function() {
var template = $.get('../templates/article.mustache');
$.getJSON('../js/article.json', function(view) {
var html = Mustache.to_html(template, view);
$("#content").append(html);
});
});
The jquery.mustache.js file is the one generated from https://github.com/janl/mustache.js :
/*
Shameless port of a shameless port
#defunkt => #janl => #aq
See http://github.com/defunkt/mustache for more info.
*/
;(function($) {
// <snip> mustache.js code
$.mustache = function(template, view, partials) {
return Mustache.to_html(template, view, partials);
};
})(jQuery);
Noting is displayed. Firebug tells me
Mustache is not defined
See capture :
I know something is missing, but I can't tell what.
Thanks.
EDIT:
The correct and complete answer to a minimal example is the following :
write the template in the script, do not load it from a file
idem for the json data
read how the jQuery is generated and use $.mustache.to_html function instead of the (documented on github) Mustache.to_html (thanks to #mikez302)
refactor 'till you drop
$(document).ready(function() {
var template = " ... {{title}} ... ";
var json = {title: "titre article" }
var article = $.mustache(template, json);
$("#content").append(article);
});
But, it is easy to read the json from another file :
$(document).ready(function() {
var template = " ... {{title}} ... ";
$.getJSON('../js/article.json', function(view) {
var article = $.mustache(template, view);
$("#content").append(article);
});
});
You can finally also read the template from a file :
$(document).ready(function() {
$.getJSON('../js/article.json', function(view) {
$.get("../templates/article.mustache", function(template) {
var article = $.mustache(template, view);
$("#content").append(article);
});
});
});
Working example (without loading order problems) :
$(document).ready(function() {
$.getJSON('../js/article.json', function(model) { return onJSON(model); });
});
function onJSON(model) {
$.get("../templates/article.mustache", function(view) {
var article = $.mustache(view, model);
$("#content").append(article);
});
}
In place of Mustache.to_html, try $.mustache. It looks to me like the Mustache variable is defined within the function, so it is not directly accessible outside of it.
I know this question already ahs been answered, however I wrote a blog post on precisely this topic and thought I would share it here so anyone looking for examples of how to use Mustache with jQuery might see it.
http://blog.xoundboy.com/?p=535

How to Load Dependent Files on Demand + Check if They're Loaded or Not?

I'm trying to implement an assets/dependency loader that i've found from an old article at 24Ways.org. most of you might be familiar with it. it's from this article by Christian Heilmann:
http://24ways.org/2007/keeping-javascript-dependencies-at-bay
i've modified the script to load CSS files as well. and it's now quite close to what i want. but i still need to do some checking to see wether an asset have been completely loaded or not.
just wondering if you guys have any ideas :)
here's what my script currently looked like:
var assetLoader = {
assets: {
products: {
js: 'products.js',
css: 'products.css',
loaded: false
},
articles: {
js: 'articles.js',
css: 'articles.css',
loaded: false
},
[...]
cycle: {
js: 'jquery.cycle.min.js',
loaded: false
},
swfobject: {
js: 'jquery.swfobject.min.js',
loaded: false
}
},
add: function(asset) {
var comp = assetLoader.assets[asset];
var path = '/path/to/assets/';
if (comp && comp.loaded == false) {
if (comp.js) {
// load js
var js = document.createElement('script');
js.src = path + 'js/' + comp.js;
js.type = 'text/javascript';
js.charset = 'utf-8';
// append to document
document.getElementsByTagName('body')[0].appendChild(js);
}
if (comp.css) {
// load css
var css = document.createElement('link');
css.rel = 'stylesheet';
css.href = path + 'css/' + comp.css;
css.type = 'text/css';
css.media = 'screen, projection';
css.charset = 'utf-8';
// append to document
document.getElementsByTagName('head')[0].appendChild(css);
}
}
},
check: function(asset) {
assetLoader.assets[asset].loaded = true;
}
}
Christian explains this method in his article in great detail. I don't want to confuse you guys anymore with my bad english :P
and here's an example of how i run the script:
...
// load jquery cycle plugin
if (page=='tvc' || page=='products') {
if (!assetLoader.assets.cycle.loaded) {
assetLoader.add('cycle');
}
}
// load products page assets
if (!assetLoader.assets.products.loaded) {
assetLoader.add('products');
}
...
this kind of approach is very problematic though. coz assets loads asynchronously, which means some of the code inside products.js that depends on jquery.cycle.js might continue running before jquery.cycle.js is even loaded resulting in errors.
while i'm quite aware that scripts can be attached with an onload event, i'm just not really sure how to implement it to my script. anyone care to help me? please... :P
For js files you can use $.getScript, it provides a callback option so you can chain the loading, i.e:
$.getScript('jquery.cycle.js',function(){
$.getScript('products.js');
});
Why reinvent the wheel? Dojo has this built in with dojo.require and jQuery has the Include plugin.
As for CSS, minify and load it upfront as you normally would. This keeps things simpler and it's unlikely to be too costly load-time wise.

Categories

Resources