Active Reports 6 PdfExport.Export() method throws ArgumentOutOfRangeException after Windows 10 Creators Update - windows-10

Problem
I have some code that uses Active Reports 6's PdfExport class to generate a PDF report. I'm running this code on a Windows 10 machine. After the Creators update, the code started throwing an ArgumentOutOfRangeException.
The code worked fine when it was run on Windows Server, just not on my Windows 10 machine.
Also, I tried switching to the XlsExport class, and the report worked fine.
Code
public static void ExportPDF(ActiveReport report, Stream stream)
{
try
{
report.Run();
using (PdfExport pdf = new PdfExport())
{
// exception occurs here
pdf.Export(report.Document, stream);
}
}
catch (Exception)
{
throw;
}
}
Error details
ArgumentOutOfRangeException
Message
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
Stacktrace
at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
at System.Collections.Generic.List`1.get_Item(Int32 index)
at #mqc.#Vqc.#RZc(Int32 fontIndex, String fontName, FontStyle fontStyle, Single sizeInPoints, Boolean vertical)
at DataDynamics.ActiveReports.Export.Pdf.PdfExport.#7pk(Document document, Stream stream, String pageRange)
at DataDynamics.ActiveReports.Export.Pdf.PdfExport.Export(Document document, Stream stream, String pageRange)
at DataDynamics.ActiveReports.Export.Pdf.PdfExport.Export(Document document, Stream stream)
...

After reading this post on the Active Reports support forum, and some some trial and error, I discovered a fix.
Solution
Open up the report designer file code behind. In my case, it was in the file SomeReport.rpx.vb.
Locate the designer generated code region:
#Region "ActiveReports Designer generated code"
Public WithEvents Detail1 As DataDynamics.ActiveReports.Detail
Friend WithEvents ReportHeader1 As DataDynamics.ActiveReports.ReportHeader
Friend WithEvents ReportFooter1 As DataDynamics.ActiveReports.ReportFooter
....
1. Style declarations require font-family
Inside that region of code, look for instances of Style properties:
Me.Label2.Style = "font-family: Arial; color: Black; font-size: 10pt; font-weight: bold; text-align: right; ddo-char-set: 1"
You need to make sure every Style property includes a font-family. Go through your code and fix any that are missing.
2. StyleSheet declarations also require font-family
Also look for instances of code like this, and make sure they also have a font-family defined.
Me.StyleSheet.Add(New DDCssLib.StyleSheetRule("font-family: Times New Roman; font-style: inherit; font-variant: inherit; font-weight: bold; font-size: 16pt; font-size-adjust: inherit; font-stretch: inherit", "Heading1"))
3. Look out for font-family: inherit
You need to explicitly define the font-family, if you see font-family: inherit anywhere in the designed code, replace it with a font name.
Conclusion
Once you've added all the missing font-family , your report should work.

Related

Chrome Extension causing misbehavior with divs on active websites [duplicate]

I wrote a Google Chrome extension, which popups a dialog with an autocomplete field and it's own style, but there are some sites where my CSS gets totally broken, which doesn't look very nice.
I know about isolating styles with iFrames, but in Google Chrome extension there is no way to isolate my HTML and CSS in this way. Another method is to wrap all my stuff into a separated div with it's own id and relative styles for that id, and I do so, but it seems that it doesn't work on some sites with "hard" tags style overloading or "!important" directives in the CSS code.
So, I want to know is there any way to really isolate my styles in z convenient way or it's my bad carma to overload every little CSS property to fix one or another style issue for each site?
By the way: I set up my manifest to load all the things at the "document_end", but I see it's not being applied to the stylesheets which is every time loaded whenever the DOM is ready.
At the time of asking the question, your only option was to either use iframes, or stylesheets with a very high specificity and explicitly set all properties that might affect styles. The last method is very cumbersome, because there will always be some property that is overlooked by you. Consequently, the only usable method for isolating stylesheets was to use iframes.
The solution to this problem -isolation of styles without iframes- is Shadow DOM (since Chrome 25). You can find a tutorial at HTML5 Rocks. For a real-world Chrome extension that uses Shadow DOM to isolate styles, see Display #Anchors (source code here).
As I've recently gone through the gauntlet of this issue, I want to share some information I think is valuable.
First, Rob W's answer is correct. Shadow DOM is the correct solution to this problem. However, in my case not only did I need CSS isolation, I also needed JavaScript events. For example, what happens if the user clicks a button that lives within the isolated HTML? This gets really ugly with just Shadow DOM, but we have another Web Components technology, Custom Elements, to the rescue. Except that as of this writing there is a bug in chrome that prevents custom element in chrome extensions. See my questions here and here and the bug here.
So where does that leave us? I believe the best solution today is IFrames, which is what I went with. The article shahalpk linked is great but it only describes part of the process. Here's how I did it:
First, create an html file and js file for your isolated widget. Everything inside these files will run in an isolated environment in an iframe. Be sure to source your js file from the html file.
//iframe.js
var button = document.querySelector('.my-button');
button.addEventListener('click', function() {
// do useful things
});
//iframe.html
<style>
/* css */
</style>
<button class='my-button'>Hi there</button>
<script src='iframe.js'></script>
Next, inside your content script create an iframe element in javascript. You need to do it in javascript because you have to use chrome.extension.getURL in order to grab your iframe html file:
var iframe = document.createElement('iframe');
iframe.src = chrome.extension.getURL("iframe.html");
document.body.appendChild(iframe);
And that's it.
One thing to keep in mind: If you need to communicated between the iframe and the rest of the content script, you need to chrome.runtime.sendMessage() to the background page, and then chrome.tabs.sendMessage from the background page back to the tab. They can't communicate directly.
EDIT: I wrote a blog post detailing everything I learned through my process, including a complete example chrome extension and lots of links to different information:
https://apitman.com/3/#chrome-extension-content-script-stylesheet-isolation
In case my blog goes down, here's the sources to the original post:
Blog post
Example source
Either use all
.some-selector {
all: initial;
}
.some-selector * {
all: unset;
}
or use Shadow DOM
Library
function Widget(nodeName, appendTo){
this.outer = document.createElement(nodeName || 'DIV');
this.outer.className = 'extension-widget-' + chrome.runtime.id;
this.inner = this.outer.createShadowRoot();
(appendTo || document.body).appendChild(this.outer);
}
Widget.prototype.show = function(){
this.outer.style.display = 'block';
return this;
};
Widget.prototype.hide = function(){
this.outer.style.display = 'none';
return this;
};
Usage
var myWidget = new Widget();
myWidget.inner.innerHTML = '<h1>myWidget</h1>';
You can access the widget contents via myWidget.inner and the outer via myWidget.outer.
Styles
/*
* Reset Widget Wrapper Element
*/
.extension-widget-__MSG_##extension_id__ {
background: none;
border: none;
bottom: auto;
box-shadow: none;
color: black;
cursor: auto;
display: inline;
float: none;
font-family : "Helvetica Neue", "Helvetica", "Arial", sans-serif;
font-size: inherit;
font-style: normal;
font-variant: normal;
font-weight: normal;
height: auto;
left: auto;
letter-spacing: 0;
line-height: 100%;
margin: 0;
max-height: none;
max-width: none;
min-height: 0;
min-width: 0;
opacity: 1;
padding: 0;
position: static;
right: auto;
text-align: left;
text-decoration: none;
text-indent: 0;
text-shadow: none;
text-transform: none;
top: auto;
vertical-align: baseline;
white-space: normal;
width: auto;
z-index: 2147483648;
}
/*
* Add your own styles here
* but always prefix them with:
*
* .extension-widget-__MSG_##extension_id__
*
*/
.extension-widget-__MSG_##extension_id__{
position: fixed;
top: 100px;
margin: 0 auto;
left: 0;
right: 0;
width: 500px;
}
.extension-widget-__MSG_##extension_id__::shadow h1 {
display: block;
margin: 0 auto;
padding: 20px;
background-color: yellow;
border: 10px solid green;
font-size: 20px;
text-align: center;
}
I recently created Boundary, a CSS+JS library to solve problems just like this. Boundary creates elements that are completely separate from the existing webpage's CSS.
Take creating a dialog for example. After installing Boundary, you can do this in your content script
var dialog = Boundary.createBox("yourDialogID", "yourDialogClassName");
Boundary.loadBoxCSS("#yourDialogID", "style-for-elems-in-dialog.css");
Boundary.appendToBox(
"#yourDialogID",
"<button id='submit_button'>submit</button>"
);
Boundary.find("#submit_button").click(function() {
// some js after button is clicked.
});
Elements within #yourDialogID will not be affected by the existing webpage. And find() function returns a regular jQuery DOM element so you can do whatever you want with it.
Hope this helps. Please let me know if you have any question.
https://github.com/liviavinci/Boundary
Use iframes. It's a workaround, but works fine.
Maxime has written an article on it.

"Unknown props" warning on console when attaching additional props

I'm using Styled Components v2.1.1.
The documentation says that to avoid unnecessary wrappers we can use the .attrs constructor. See: https://www.styled-components.com/docs/basics#attaching-additional-props
I've tried to use it but I always receive the following warning in the console:
Warning: Unknown props `margin`, `padding` on <input> tag. Remove these props from the element. For details, see (removed )
in input (created by styled.input)
in styled.input (created by InputContainer)
in div (created by InputContainer)
in InputContainer
I've created a Webpack Bin to show the error: https://www.webpackbin.com/bins/-KpKbVG-Ed0jysHeFVVY
Am I using it in the wrong way or is there an issue?
As it seems, the example provided on the styled components website is not an actual usable example.
Since the attrs function creates attributes for the properties you set, the error is correct in saying that the html <input> tag does not support the attributes margin and padding: MDN - HTML input attributes
The error you're seeing was marked as an issue on the styled-components GitHub.
The actual solution is not to literally use the example given in the styled-components documentation. For the full explanation, please refer to the issue report.
The code example given by one of the contributers on Github is to modify the example as follows:
const getSize = p => p.size || '1em'
const Input = styled.input.attrs({
// we can define static props
type: 'password'
})`
color: palevioletred;
font-size: 1em;
border: 2px solid palevioletred;
border-radius: 3px;
/* here we use the dynamically computed props */
margin: ${getSize};
padding: ${getSize};
`;

loading otf font fails due to 'invalid version tag'

I have an element which requires a custom font (this one, specifically) and a Polymer code base. I import it in a separate style block as follows:
<style>
#font-face {
font-family: "Hattori";
src: url("../fonts/Hattori-Hanzo.otf");
font-weight: normal;
font-style: normal;
}
</style>
Then in Polymer's dom-module block I apply this font to a d3 item as follows:
var legend = main.append("g")
.attr("font-family", "Hattori")
However, in Chrome devtools I get:
Failed to decode downloaded font: http://localhost:8080/src/fonts/Hattori-Hanzo.otf
OTS parsing error: invalid version tag
I checked, and the right font file is in the exact location specified by that url. I have another font in that exact folder being imported just fine by another component, in the same method, so I'm not sure what's going wrong here.

Node.JS Vash TypeError: while rendering template object is not a function

There is another thread that covers this, but I am not allowed to post to it. Also, the only answer does not seem to solve my problem.
I am getting the Object not a function error when using the #html.extend() method. I have read all of the very limited threads on this topic. They all say the same thing. That I need to ensure the path is correct to the layout.vash file I am extending. My declaration looks like this in the file that I want to want to extend with my layout.vash file.
#html.extend('layout', function (model) {
.... do stuff ...
})
What is odd, is that some pages work fine others don't. The path is correct. I am sure of this because of the fact the files in the same director exhibit different behavior.
Does anyone know what other mistake I could be making to cause this error?
In my case, vash was unable to parse the content within ...
I pulled it out from the layout page and created a separate .css file, and the annoying "object is not a function" error disappeared.
I speculate that vash collides with some css syntax.
For you info, my style statements that caused the trouble were these.
<style type="text/css">
*{padding:0;margin:0;}
html{border-top:10px #1abf89 solid;}
body{width:800px;margin:0 auto;padding:5% 20px 20px;font-family:Palatino, Optima, Georgia, serif;}
#media all and (max-width:1024px){ body, pre a{width:60%;} }
small{color:#999;}
#toolbar{margin-bottom:1em;position:fixed;left:20px;margin-top:5px;}
#toolbar [class^="icon-"]:before, #toolbar [class*=" icon-"]:before{font-family:'pen'}
#mode{color:#1abf89;;cursor:pointer;}
#mode.disabled{color:#666;}
#mode:before{content: '\e813';}
#hinted{color:#1abf89;cursor:pointer;}
#hinted.disabled{color:#666;}
#hinted:before{content: '\e816';}
#fork{position:fixed;right:0;top:0;}
/*
When the webpage is printed
this media query hides extra elements,
and makes the text content fit the page.
*/
#media print {
#fork, #toolbar {
display: none;
}
body {
width: 94%;
padding-top: 1em;
font-size: 12px;
}
html {
border-top: 0;
}
}
</style>

Calculate text width in pixels server-side

I'm trying to use the following code on my server to estimate the length of some text fields and potentially trim them before sending them by email...
String.prototype.visualLength = function()
{
var element = document.createElement("span");
element.css({
"visibility": "hidden",
"white-space": "nowrap",
"font-weight": "normal",
"font-size": "18px",
"line-height": "40px",
"font-family": "Helvetica, Arial, sans-serif",
"text-decoration": "none"
});
document.body.appendChild(element);
element.innerHTML = this;
return element.offsetWidth;
};
String.prototype.trimToPx = function(length)
{
var tmp = this;
var trimmed = this;
if (tmp.visualLength() > length)
{
trimmed += "...";
while (trimmed.visualLength() > length)
{
tmp = tmp.substring(0, tmp.length-1);
trimmed = tmp + "...";
}
};
return trimmed;
};
Obviously I'm getting an error because "document" is not defined server-side. I added the Meteor packages htmljs and domutils hoping they might solve this, but in vain. And I can't add the Node.js package jsdom because apparently it won't work in deployed Meteor apps.
Any idea how to achieve what I'm trying to do?
You cannot truly rely what will happen on client-side. Even Ubuntu and Windows shows the fonts different because of different hinting, antialiasing and they may have an effect on the displayed sizes.
If you modify your span's css as following, when it has a text larger than the desired space, no matter what, the remaining will be displayed as ...
max-width: 10%;
border: 1px #000 solid; // JUST TO SEE the effect clearly
width: 10%;
overflow: hidden;
height: 20px;
text-overflow: ellipsis;
display: block;
white-space: nowrap;
** Please note that you need a proper height value, other wise the text will go to bottom and what you want will not be achieved.
Try on http://jsfiddle.net/sG6H2/
I don't think this is possible. Server-side code running in node.js does not run in the context of a web browser's rendering environment and so can't access the browser's DOM and available fonts and display configuration. Even if you were to successfully run your code and compute a number, that computation has no relationship to my device when I receive your email. The fonts, the display size and resolution (could be a desktop, could be a mobile device), my own configuration (for example I set a minimum font size in Firefox on my desktop), etc. Instead try defining your size in em units instead of pixels.

Resources