Hide page contents until filters are applied in WebBrowser Control - webbrowser-control

I'm modifying web contents displayed in a webbrowser control and looking for a way not to display them until all the changes are applied.
I'm currently using the DocumentComplete event and while filtering some pages, their contents are just visible. So I'd like to hide them until everything becomes okay to be shown.
simple.html
<html>
<head>
<style type="text/css">
div {
font-weight: bold;
}
</style>
</head>
<body><div>foo</div> bar</body>
</html>
demo script
new WBControl("file:///" A_ScriptDir "/simple.html")
class WBControl {
DocumentComplete(oParams*) {
doc := oParams[3].document
sleep 200 ; simulate a delay caused by a heavy task
doc.styleSheets[0].rules[0].style.fontweight := "normal"
}
__New(strURL="") {
static WB
Gui, New, Resize MaximizeBox
Gui, Add, ActiveX, vWB w780 h580, Shell.Explorer
Gui, show, w800 h600
ComObjConnect(WB, this)
WB.Navigate(strURL)
}
}
Is there a way to do it?

Try:
document.body.style.visibility := "hidden"
To restore visibility, set it to an empty string.
document.body.style.visibility := ""
You could also create a simple loading display to show instead; if you want to be fancy.

Related

View PDF preview - fit to screen (no scroll bars)

I have a PDF opening in an iFrame using Fancybox. Is it possible to width to screen so in a mobile portrait view, it shows the whole thing, albeit tiny?
I think you can be interested with this example which I Posted September 17, 2015
https://www.autoitscript.com/forum/topic/177368-how-to-get-reference-to-pdf-object-embeded-in-ie/
Firstly you should change size of iFrame Element.
In a second step you should inspect iFrame nad check how PDF object is embeded
For example this could look like this:
<script language="JavaScript">
function rsChange ()
{
var ax = document.all.TestObj;
if ( ax.readyState == 4 )
{
if ( ax.IsInitialized == false )
{
window.setTimeout( "rsChange();", 100 );
}
else
{
ax.Server = "192.168.1.3";
ax.Connect ();
}
}
}
</script>
<OBJECT language='javascript' ID='TestObj' CLASSID='CLSID:36D64AE5-6626-4DDE-A958-2FF1D46D4424' WIDTH='640px' HEIGHT='480px' onreadystatechange='rsChange();'></OBJECT>
<br><br><br>
Don't forget to do a "REGSVR32 UltraVncAx.dll", before viewing this page.<br>
The timer trick in the rsChange() function is required to get the windowful ActiveX initialized properly, before letting the ActiveX create the VNC client child window.
</body>
</html>
In such case you should change parameters in this following object:
<OBJECT language='javascript' ID='TestObj' CLASSID='CLSID:36D64AE5-6626-4DDE-A958-2FF1D46D4424' WIDTH='640px' HEIGHT='480px' onreadystatechange='rsChange();'></OBJECT>

Printing PDF documents from Windows 8 App

I'm trying to print a PDF file from my Windows 8 app to connected printer. I'm coding with WinJS, and know that I have to create a print task to initiate printing from a Windows 8 app. So, after reviewing the documentation, I have this code:
onPrintTaskRequested: function (e) {
var self = Application.navigator.pageControl,
printTask = e.request.createPrintTask("Print Test Doc", function (args) {
args.setSource(MSApp.getHtmlPrintDocumentSource(document));
// Register the handler for print task completion event
printTask.oncompleted = self.onPrintTaskCompleted;
});
}
According to the documentation, the MSApp.getHhtmlPrintDocumentSource method accepts a specific set of data types. As stated in the documentation:
This can be the root document, the document in an IFrame, a document
fragment, or a SVG document. Be aware that htmlDoc must be a document,
not an element.
Apparently I cannot simply set the argument for getHtmlPrintDocumentSource to a .PDF or .PNG binary. So, I'm curious: does the WinJS library offer a method for printing so that I can implement the printing of a PDF file to a connected printer? Can anybody offer some tips to implement?
After trial and error, I was finally able implement the printing of a Base64 stream representing a PDF binary from a Windows 8 application.
I'm coding the app in HTML / CSS / WinJS. Essentially here is a brief explanation of how it was accomplished:
Create a new <canvas> element within the default.html file. Place it right after the open tag of the element. Like this:
<body role="application" class="app">
<canvas id="pdf-render-output"></canvas>
.
.
.
</body>
Then inside the default.css file, setup a few rules as well as a print media query. Like this:
body > canvas {
display: none;
}
.
. /* all your app's default css styles */
.
#media print {
body > * {
display:none;
max-width: 100%;
}
html {
max-width: 100%;
border-top-color: none;
border-top: 0;
}
body > canvas {
display: block;
border: none;
max-width: 100%;
width: 100%;
height: 100%;
position: relative;
}
}
Of note is the order in which the rules are declared in CSS. It's important to place the print media query after declaring default CSS rules.
After this is setup, javascript handles the rest. The basic idea is to render the PDF.js output to the "hidden" canvas in the DOM. When the document object gets sent to print, the CSS print media declaration is queried so that all elements under <body> are hidden except for the canvas element. Here is the javascript to print only the first page in the PDF:
//Define a container for the Base64 data we'll use with PDF.js
var pdfPrintData = {};
//Function to render PDF to canvas and begin printing contract with Windows 8 OS
printPrescription: function () {
var self = Application.navigator.pageControl,
printManager = Windows.Graphics.Printing.PrintManager.getForCurrentView();
self.getPDF().done(function () {
var pdfStream = pdfPrintData.base64,
pdfFile = convertDataURIToBinary(pdfStream);
PDFJS.disableWorker = true;
PDFJS.getDocument(pdfFile).then(function (pdf) {
var numPages = pdf.numPages,
renderCanvas = $('#pdf-render-output')[0];
//setup canvas
renderCanvas.height = pdf.getPage(1).data.getViewport(1).height;
renderCanvas.width = pdf.getPage(1).data.getViewport(1).width;
//Setup a render context for pdf.js to out a pdf file to the canvas.
var renderContext = {
canvasContext: renderCanvas.getContext('2d'),
viewport: pdf.getPage(1).data.getViewport(1)
};
//Bring up Windows 8 OS print after PDF is rendered to render context.
pdf.getPage(1).data.render(renderContext).then(function () {
printManager.onprinttaskrequested = self.onPrintTaskRequested;
Windows.Graphics.Printing.PrintManager.showPrintUIAsync();
});
})
});
},
onPrintTaskRequested: function (e) {
var self = Application.navigator.pageControl,
printTask = e.request.createPrintTask("Print Prescription", function (args) {
args.setSource(MSApp.getHtmlPrintDocumentSource(document));
printTask.oncompleted = self.onPrintTaskCompleted;
});
},
onPrintTaskCompleted: function (e) {
if (e.completion === Windows.Graphics.Printing.PrintTaskCompletion.failed) {
console.log("[ERX] : Failed to print!");
}
}
The self.getPDF method is just a function that retrieves the Base64 data stream, and that streams gets set on the .base64 property of the global pdfPrintData object. For some reason, I was not able to render the pdf using pdf.js to a dynamically create canvas in a dynamically created document. I had to render the output of the pdf.js render method to a canvas already present in the DOM.
As far as I know, MSApp.getHtmlPrintDocumentSource(document) is meant to be used with HTML document objects, and nothing else.
If you can assume Windows 8.1, you can try to assemble a new HTML document from your PDF file by exporting each page into a raster image using PdfPage.RenderToStreamAsync. There is a sample project in MSDN for a PDF viewer that uses this new API where you can learn how to use this method.
If you cannot assume Windows 8.1 and you need to support plain Windows 8 or Windows RT (ARM), you might need to use a third party library to create the raster images or to do the printing all together.
Amyuni PDF Creator for WinRT for example can do the printing for you. Disclaimer: I currently work for the company that develops the library

Add a dynamic text to SP21010 Rich Text Editor when a particular Markup Style is applied

In Sharepoint 2010, I have built a custom page layout and have applied custom styles. Page layout consist of single rich text editor HTML field. Now I have a need to add some custom text next to the selected text when a particular markup Style is applied.
I can do that using jQuery once the page is saved but that is after the user has finished editing.
The requirement is for them to see the text while they are still in edit mode so that they get a true WYSIWYG experience . Below is the jQuery code I am using to display the text after page is saved:
<script type="text/javascript">
$(document).ready(function () {
$('.topicpagelayout2-styleElement-H3').wrap('<div class="hd leftcontent" />');
$('.topicpagelayout2-styleElement-H3').append('<span class="top">Top</span>');
$('.topicpagelayout2-styleElement-H3').addClass('header2');
var count=0;
$('.leftcontent').each(function(index) {
count++;
$(this).attr('id','div_'+count);
});
//$("span.ms-formfieldlabel").css("display", "none");
setLeftContent();
});
</script>
You can use use css content for this.
See this if it may give you some idea
http://www.quirksmode.org/css/content.html

WinJS not unloading js/css

I'm working on a Windows 8 Metro app and I've found (even on their sample applications where I haven't touched the code) that as you navigate between pages, the top level "default.html" acquires every single js and css file ever loaded during the application's run.
This is causing me a lot of headaches as my css is colliding between difference pages. Am I missing something or is this is serious bug?
Not unloading JavaScript and CSS was a deliberate choice, not an accident or oversight.
First off, understand that page controls are purely a JavaScript construction - the browser engine has absolutely no knowledge of them. The browser just sees a chunk of DOM that was dynamically generated by scripts.
The web platform doesn't let you unload script files - once they're loaded into the context, they're there forever.
With CSS, they could have tried removing tags, but it opens up a can of worms. Depending on which order pages are navigated to, you could end up with different styles applied in the same app. What if two pages refer to the same style sheet? Do you add the same link tag twice? And which one do you remove?
It's a mess. Instead, WinJS guarantees that scripts and stylesheets will be loaded once and only once, the first time they're referenced. So you can have every page in your app reference "myStyles.css" and it'll only be loaded once (and there will only be one style tag).
So what do you do to prevent the issues you're seeing? First off, remember you're building an app, not a web site that will arbitrarily grow new content. Decide on your general styles and classes. Put shared styling in your default.css and reference it from your default.html file.
For individual pages, the easiest thing to do is prefix your styles with the page name. Instead of:
<div class='intro'></div>
do
<div class='page1-intro'></div>
Then you're guaranteed to avoid collisions.
If you're referencing page elements by ID, well don't do that. Using ID's in pages causes all sorts of potential weirdness (what if you render the same page control twice at the same time? Also, the ID doesn't exist until after the page has been loaded into the DOM, which means data-win-options references by ID don't work). But if you insist, again, consider prefixing the ids with the page.
Basically, set up ad-hoc namespaces to keep you from colliding. It's a lot easier than ripping out link tags manually and will result in a lot better app experience than doing full navigations.
Its not a bug, it is part of the default app pattern used by the WinJS tempaltes. The default WinJS templates use a single-page model, meaning that all content is loaded into the default.html using a PageNavigatorControl. As a result, there is a single DOM in memory at all time. If you followed a similar pattern in a regular browser, you would see the same behavior.
You can, if you want, use more traditional navigation using multiple pages and traditional href links. That is not the recommended approach, but if you are trying to bring existing web assets built using that model, it can make things easier.
You can resolve this problem by querying the document for the link elements that import your styles and disabling the ones you don't want. You need to make sure that you don't disable the MS CSS files and the default.css file in your project, assuming you use it to define the common styles for your app.
Here is a sample that shows you how to do it. This is a file called page2.html which, when loaded by the WinJS.Pages.UI.render method will locate and disable the link elements it doesn't want. It makes sure that the page2.css file is enabled and keeps a list of the files it simply ignores.
(I put this in the ready handler function, but I tend to use this technique in the handler for the WinJS.Navigation events and rely on consistent file naming to get the result I want).
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>UnloadCSS</title>
<!-- WinJS references -->
<link href="//Microsoft.WinJS.1.0/css/ui-dark.css" rel="stylesheet" />
<script src="//Microsoft.WinJS.1.0/js/base.js"></script>
<script src="//Microsoft.WinJS.1.0/js/ui.js"></script>
<!-- UnloadCSS references -->
<link href="/css/page2.css" rel="stylesheet" />
<script>
WinJS.UI.Pages.define("/page2.html", {
ready: function () {
var ignoreList = ["/css/ui-dark.css", "/css/ui-light.css", "/css/default.css"];
var myCSS = "/css/page2.css";
WinJS.Utilities.query("link").forEach(function (linkElem) {
if (linkElem.href.indexOf(myCSS) > -1) {
linkElem.disabled = false;
} else {
var ignore = false;
ignoreList.forEach(function (ignoreItem) {
if (linkElem.href.indexOf(ignoreItem) > -1) {
ignore = true;
}
});
if (!ignore) {
linkElem.disabled = true;
}
}
});
}
});
</script>
</head>
<body>
<button>Change </button>
</body>
</html>
this could be a good solution with a convention names aproach :
var currentPage = Application.navigator.pageControl.uri.replace("ms-appx://" + Windows.ApplicationModel.Package.current.id.name.toLowerCase(), "");
var currentCss = currentPage.replace(".html", ".css");
var ignoreList = ["/css/ui-dark.css", "/css/ui-light.css", "/css/default.css"];
WinJS.Utilities.query("link").forEach(function (linkElem) {
if (linkElem.href.toLowerCase().indexOf(currentCss) > -1) {
linkElem.disabled = false;
} else {
var ignore = false;
ignoreList.forEach(function (ignoreItem) {
if (linkElem.href.toLowerCase().indexOf(ignoreItem.toLowerCase()) > -1) {
ignore = true;
}});
if (!ignore) {
linkElem.disabled = true;
}
}
});

removing the scroll bars and borders from the web browser object

I have a powerpoint that is using a web browser object. The trouble is that the scrollbars on the web browser object are always there, regardless of whether or not they are needed. Is there some way to remove the scroll bars?
I have tried adding:
WebBrowser.Document.body.Scroll = "no"
but that makes the object stop working all together.
Also, the object has a thin light colored (i think it is white but it is hard to tell) border around it. Since most of my presentation is black this does not blend well though i have set the background color of the html displayed to be black. Is there a way to get rid of the border as well?
if they cannot be done with vba can they be done at all?
My understanding is no, this is not possible. I dislike the scroll bar, but it's a part of IE and I don't see any way to remove it without completely disabling functionality as you have already seen.
JimmyPena,
I did it. After some tests I discovered that if I set the image to webbrowser and try to set other Document.Body properties in the same "f5" execution it didn't work.
If you try to use "f8", it works, ironically.
I think it is because that webbrowser component cannot set some properties after loading an object.
Sooooo, i tried to make an HTML file in which my object (in my case, an gif image) was set and all properties was set as well, including scroll removal, margin removal and border removal.
You can see my codes below.
HTML (test.html):
<html>
<head>
</head>
<body style="overflow: hidden; margin: 0; border: 0;">
<img src="Assets/loading-small.gif" />
</body>
</html>
VBA:
Sub abaSV_showLoadingIcon()
AbaSV.WebBrowser1.Visible = True
AbaSV.WebBrowser1.Navigate ThisWorkbook.path & "\test.html"
End Sub
I think that should help you, JimmyPena and uncertaintea.
SeeYa!
Your idea works just fine, except for the VBA part.
So what I did is to creat a html file as you did, assigning the properties and calling the gif image.
Then in VBA i used the following code (in the sheet where the webborser can be found):
Private Sub worksheet_activate()
WebBrowser1.Navigate "insert html file path.html"
End Sub
I solved this by applying in the html file this code under the <head> tag:
<style type="text/css">
html {
overflow:hidden;
}
</style>
Use Document.Body.Scroll = "No" to disable scroll bar in Webbrowser
Option Explicit
Private Sub
UserForm_Activate()
WebBrowser1.Navigate "C:-Download-P.gif"
End Sub
Private Sub
WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
With WebBrowser1
. Width = 80
. Height = 80
. Document.Body.Scroll = "No"
End With
End Sub