Upgrading tabulator from 4.2 to 5.2 - Table not initialized - tabulator

I am upgrading from Tabulator 4.2.7 to 5.2 and am getting table not initialized. I have simply replaced the CDN reference with the new one . Is there something else I should be doing?
<link href="https://unpkg.com/tabulator-tables#4.2.7/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables#4.2.7/dist/js/tabulator.min.js"></script>
<!--
<link href="https://unpkg.com/tabulator-tables#5.2.3/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables#5.2.3/dist/js/tabulator.min.js"></script>
-->

This is the correct behaviour from 5.0 and is why you see the message in the console.
Using the data property on the table constructor is the correct way to initialize the table data.
This happens because Tabulator now initializes asynchronously, this happens for two reasons, the first is to allow consistent initialization between async and synchronous data sources, the second is to allow binding of events to the table before initialization is completed, to catch things like the tableBuilt event.
If you want to continue to use the setData to initialize the data in your table (which is unnecessary if you correctly initialize the data in the table using the data setup option) then you need to call it in the tableBuilt event which is fired after the table has been fully initialized
table.on("tableBuilt", function(){
table.setData(data);
});
https://github.com/olifolkerd/tabulator/issues/3407

Related

What's the best practice to fix history.pushState which is deleted by office.js?

Our team wants to build a documentation website that can be opened in browsers and Excel add-ins.
We chose Docusaurus V2 as the main framework to build the documentation website, and embedded office.js in it.
Office.js deletes history.pushState and history.replaceState APIs after being loaded,
so I added some JS code to polyfill it, as follows:
<html>
<head>
... ...
<script type="text/javascript">
if (history) {
var pushStateRef = history.pushState;
var replaceStateRef = history.replaceState;
}
function patch() {
if (history && !history.pushState) {
history.pushState = pushStateRef;
history.replaceState = replaceStateRef;
}
}
function onOfficejsLoad() {
Office.onReady(function() {
console.log('office.js is ready.');
patch();
});
}
</script>
<script
type="text/javascript"
src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"
onload="onOfficejsLoad();"
></script>
</head>
</html>
The above code made the website to work well within our add-in in Excel Online in Chrome, Safari, as well as IE 11. However, it did not work well in Excel for Windows: when we clicked to tigger a router event, e.g. clicking on docusaurus' sidebar, there was a error, the router had no effect, and the sidebar did not work well (see Screenshot).
I managed to fix this error by adding the loading of history.js:
<html>
<head>
... ...
<script
type="text/javascript"
src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js"
onload="onOfficejsLoad();"
></script>
<script
nomodule
type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/html5-history-api/4.2.10/history.js"
></script>
</head>
</html>
I still post the question, because I don't understand why the previous version did work our in add-in in Excel Online IE 11, but not in Excel for Windows, shouldn't their behaviors the same? Most importantly, when developing Excel add-ins, is there any best practice to follow to manage the conflit of history.pushState and office.js?
I added some JS code to polyfill it
I think what you have done is what I would have done too. I don't think Office.js is right to delete/override the history methods, but perhaps they had good reasons to do so (e.g. only allowing full page refreshes).
However, it did not work well in Excel for Windows
Do you know what browser is being used in Excel for Windows? It could be an entirely different browser that doesn't conform to the standards/runs in a different environment (e.g. not all the HTML5 APIs are provided on the window object). That could be why there's the weird behavior.
Sorry I don't have a Windows machine to debug this issue.

Migrate custom admin pages with dialogs from 4.5.12 to 5.3.4

We have code to open dialogs for links on admin pages by calling the javascript function mgnlOpenDialog(), like this,
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
[#assign cms=JspTaglibs["cms-taglib"]]
<html>
<head>
<title>UCP Books</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link href="${this.request.contextPath}/.resources/admin-css/admin-all.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="${this.request.contextPath}/.magnolia/pages/javascript.js"><!-- --></script>
<script type="text/javascript">
function displayDialog()
{
if ( ! window.focus ) return true;
var path = "${this.path}";
var nodeCollection = null;
var node = "${this.nodeName}";
var paragraph = null;
var repository = "${this.repository}";
var dialogPage = ".magnolia/dialogs/author.html";
mgnlOpenDialog( path, nodeCollection, node, paragraph, repository, dialogPage );
return false;
}
</script>
</head>
<body id="mgnl" class="mgnlBgLight mgnlImportExport">
<h2>
${this.messages.get("module.books.pages.AuthorDetailPage.header")}
<span class="mgnlControlButton" onclick="displayDialog();">
${this.messages.get("module.books.pages.edit")}
</span>
</h2>
<div class="pageFrame">${this.content}</div>
</body>
</html>
Now we are migrating our site from 4.5.12 to 5.3.4, and I noticed that the dialog definitions got updated. Now when I click on the link, there is still the dialog popup, but the popup is blank with the old style "Save" and "Cancel" buttons displaying at the bottom. It seems we need to convert our admin pages to content apps. But to do it that way will require a lot of changes in our code. So I'd like to know if there is an alternative way to replace mgnlOpenDialog() function to invoke the dialogs when I click on the links on the admin pages.
Thanks very much!
Aiping
Yeah this doesn't work any longer. Assuming you needed to open the dialogs explicitly because you had content you were editing in other workspaces then website. Correct?
When migrating custom data to M5, if you had that content in data workspace, you can use migration task to move it from the shared workspace into separate workspace and to also migrate your dialog. Not sure at the moment if it generates also app for you, but if not you can use this script to create one.
Once you have dialog migrated (or created from scratch) and your app created (either via script above or manually) you can just simply open any content in that app for editing and copy url from there. That would be the url you need to call to open dialog for editing from anywhere. It will be something like http://<your host>:<your port>/<contextPath>/.magnolia/admincentral#app:<yourAppName>:detail;/path/to/edited/content:edit
of course, assuming your subapp is called "detail" and your edit action "edit" as suggested in the tutorial or generated by the script.
Good luck,
Jan
Thanks Jan!
This seems a right direction to go by calling the url,
http://<your host>:<your port>/<contextPath>/.magnolia/admincentral#app:<yourAppName>:detail;/path/to/edited/content:edit.
I've configured the detail subapp and added this line to my code,
title
and it works. I'll post more in details later.
Thanks,
Aiping
Jan, I tried your solution as I commented here and it works well, except for one issue. Here I'm pointing to several screenshots to better explain it.
https://plus.google.com/u/0/photos/103180294078685589341/albums/6081701864232931905
On the app_faqSearch_1.png, there is a search form only.
The app_faqSearch_2.png is the page with the search results.
When I click on the "faq0004" link on app_faqSearch_2.png, the app_faqSearch_3.png appears. The code behind the scenes is,
faq0004
The problem is when I close the dialog tab "/FAQ/TOPICS/COMMAS/...", on the app_faqSearch_4.png, the search results are not there anymore since the view got reloaded.
Is there a way to configure to prevent the view from being reloaded if it's already opened, like for this URL in my case, /magnoliaAuthor/.magnolia/admincentral#app:faqSearch:main;
Or is there a way to explicitly open a dialog, instead of an editor, by passing the node path and workspace when click on the link like "faq0004"? Similar way to open the "editMessage" dialog in "contacts" app.
Thanks very much,
Aiping

Remove main.js from Liferay Theme

I currently fight to reduce the amount of requests on page load. The main.js is not used in our custom theme, but still gets loaded.
So how can I remove the theme's main.js, so that the browser won't attempt to load it?
Overwriting it with an empty file in our theme is not an solution (wont reduce request count).
I can find the main.js instances in the following places:
In html/common/themes/bottom.jsp, (with a hook you can modify this)
<script src="<%= HtmlUtil.escape(PortalUtil.getStaticResourceURL(request, themeDisplay.getPathThemeJavaScript() + "/main.js")) %>" type="text/javascript"></script>
And in /themes/_unstyled/templates/init.vm (in your custom theme's init_custom.vm you can change this variable)
#set ($js_main_file = $htmlUtil.escape($portalUtil.getStaticResourceURL($request, "$javascript_folder/main.js")))
and finally in portal-impl/src/VM_liferay.vm (this is in the jar file so you might want to go the ext way but i think you may not need to do anything with this file since this is just a macro which is defined, the thing you may want to change is how this macro (sort of function in velocity) is accessed and from where it is accessed)
#macro (js $file_name)
#if ($file_name == $js_main_file)
<script id="mainLiferayThemeJavaScript" src="$file_name" type="text/javascript"></script>
#else
<script src="$file_name" type="text/javascript"></script>
#end
#end
I am not sure if modifying these files would give the behaviour you desire but you may try and find out. I have not tried yet.

WebSeal JSF Context path stripping Junction Name

We are using WAS & IHS as servers and WebSEAL as reverse proxy.
Application is developed using JSF 2.0 and using .xhtml pages for view.
Issue: Using ${facesContext.externalContext.requestContextPath} to generate the context for JavaScript and CSS files.
When the application is accessed through WebSEAL, getting correct context for JavaScript file, but the CSS context is missing the webSEAL junction name.
In Source Code:
JS is included as:
<script src="${facesContext.externalContext.requestContextPath}/js/jquery/jquery-1.6.1.min.js" type="text/javascript"></script>
CSS is included as:
var cssElement = document.createElement("link");
cssElement.setAttribute("rel", "stylesheet");
cssElement.setAttribute("type", "text/css");
cssElement.setAttribute("href", "${facesContext.externalContext.requestContextPath}/css/stylecontent.css");
Links Rendered on Browser:
For JavaScript(it has context name):
<script src="/junction/appcontext/js/jquery/jquery-1.6.1.min.js" type="text/javascript"></script>
For CSS:
<link href="/appcontext/css/stylecontent.css" rel="stylesheet" type="text/css"/>
Hence,
CSS files are not loading on the page.
Anyone has any hints?
Just incase some one is stuck with the same problem:
It got resolved by making some configuration at the WebSEAL junction level.
by default, WebSEAL looks for static resources on the the server itself, hence it strips the junction off.
Settings need to be applied to "look for resources under the junction"

How to call functions in the original page(tab) in Chrome Extensions

I'm now making a Chrome Extension. I want to call JS functions that are defined in the original page (tab), from Chrome Extension. It doesn't matter whether background.html or Content_Script calls them.
For example:
Original page (tab)
<html>
<head>
<title>Original Page</title>
<script>
function greeting(){
alert("Ohayou!");
// some other codes here
}
</script>
</head>
<body></body>
</html>
Then I want to call the function "greeting" in the original page, from Google Extensions.
How can I do the above?
Edit: This solution is obsolete since Manifest V3 (i.e. January 2022 in Chromium-based browsers) which prevents executing arbitrary (e.g. insecure) JavaScript in a page.
You can also simply write in your content script:
location.href="javascript:greeting(); void 0";
For the first part you can use this nice answer: Insert code into the page context using a content script.
To call a function back in your content script is easy. You can create your own event which you can then listen on in your content script.
This would work like this:
injected code:
var evt = document.createEvent('Event');
evt.initEvent('myCustomEvent', true, false);
// fire the event
document.dispatchEvent(evt);
contentscript:
document.addEventListener('myCustomEvent', function() {
// do whatever is necessary
});

Resources