how to export the freetext annotations with contents-richtext - javascript

I've updated the WebViewer from a very old version to the latest version (v5.0).
And I found that there is no "contents-richtext" data in the exported XMLdata,
I've tried to set exportContentsRichText = true
but It's not effective. Does anyone know how to export the annotations with contents-richetext content

For the last few versions WebViewer no longer exports contents-richtext elements for newly created annotations. If an annotation has an associated contents-richtext element then WebViewer should preserve it when exporting though.
By default WebViewer doesn't take advantage of separate styles in the contents so there shouldn't be any difference with just using the contents element.
Regardless, it is still possible to export contents-richtext by extending the serialize function on annotations as shown here https://groups.google.com/d/msg/pdfnet-webviewer/lptUPUcV80c/1NUgYZ_8AwAJ. Instead of adding an attribute you would create a subelement and append it as a child of the element used in the serialize function.

Related

Setting global properties by calling imported javascript functions in QML

I use the Universal style for my QtQuick app and I want to provide a ColorDialog for adjusting the accent color.
I have something like this:
ColorDialog {
id: accChooser
title: "Please choose a color"
onAccepted: {
setGlobalAccentColor(accChooser.color)
}
}
*Note that I cannot simply write Universal.accent=... inside a child item because it has no effect on the parent.See this.
and this function:
function setGlobalAccentColor(accentColor){
Universal.accent = accentColor
}
It works when the function setGlobalAccentColor is defined within the same QML file as accChooser,but if I define that function inside an external JS file (say helpers.js) and import it via:
import "helpers.js" as JSHelpers
and use it this way:
ColorDialog{
...
JSHelpers.setGlobalAccentColor(colorDialog.color)
...
}
it doesn't work.There's no specific error or warning message in the output of the app.
Thanks.
May be it is required to import the universal style in the javascript file.
The documentation universal style says below (look in dependency section)
The Universal style must be separately imported to gain access to the
attributes that are specific to the Universal style
You can try importing as said below into your javascript (helpers.js) file.
.import QtQuick.Controls.Universal 2.12 as JsUniversal
And then try accessing (like example: JsUniversal.accent..).
Note that I cannot simply write Universal.accent=... inside a child item because it has no effect on the parent.See this.
While setting it to the child won't affect your whole application, you can set it directly to the whole window.
Window.window.Universal.accent = accentColor;
Universal is an attached object, you can attach it to an abitrary object, not just the current one, by doing <object>.<AttachingType>.
We attach it to the parent window by accessing the window via another attached property: Window.window.

How can I access native HTML attributes in stenciljs? And how to make it appear in the documentation?

The web components made with stenciljs don't extend HTMLElement. How can I access the native attributes and use them in my component, say the title attribute? When I add #Prop() title and use it in my template an error is shown.
Adding #Prop() also makes the attributes visible in the generated documentation. How can I add the used or required native attributes to the generated documentation?
Compiler error I'm getting:
The #Prop() name "title" is a reserved public name. Please rename the "title" prop so it does not conflict
with an existing standardized prototype member. Reusing prop names that are already defined on the element's
prototype may cause unexpected runtime errors or user-interface issues on various browsers, so it's best to
avoid them entirely.
Yes, you are not allowed to do so but you can pass HTML attributes directly to the element without declaring them with the #Prop decorator. In your case, just pass title to your component.
<your-component title="test title"></your-component>
Then, if you would like to read the value of your title attribute, you have to get the reference to the host element first.
#Element() host: HTMLElement;
Then, you can read it with your host element's getAttribute method, for instance:
componentDidLoad() {
const title = this.host.getAttribute('title');
console.log(title); // or do something with it
}
#Prop() is like reading from tag to component
#Prop({"reflectToAttr": true}) will keep a two way binding and updates both - tag to component & component to tag
It's important to know that you are not allowed to update your #Prop variables inside the component until you specifically allow it with the mutable property. #Prop({"mutable": true})
If you want both just use comma seperated syntax like:
#Prop({"mutable": true, "reflectToAttr": true})
For details please go here:
https://stenciljs.com/docs/properties
I faced sometimes some issues using the native attributes like "title", "focus" and so on. The correct way would be using "data" before the attribute like "data-title", "data-focus" and in the component #Prop() dataTitle, #Prop() dataFocus.
But to be honest i don't like that the developer using the web-components have to learn a web-component specific syntax so i use the native attributes anyway. Which results sometimes in some errors that you can fix easily. But this would be a topic for another question.
#Update
I just realized that in newer StencilJS versions is just #Prop({"reflect": true}) but the idea is still the same

not able to call child class method twice in parent js file

I have a category dropdown(in parent js) whose subcategory fills on parent page load as well on dropdown change . subcategory will fill from child js method .I have to create child js instance twice . on page load and on dropdown down change.
I dont want to create object in document.ready or as global variable
where should i create child class object exactly so that it can be used all over ?
problem is that jquery not letting me call
$.getScript('../Reports/assets/js/BookingReports.js'
twice as it send error that child class name(BookingReports) identifier as already created .
class ReportsInterface extends ReportBase {
constructor() {
super();
this.fillSubCategory;
}
init() {
this.Categories();
}
Categories() {
//fill category
this.FillSubCategory();
}
FillSubCategory() {
if(!this.fillSubCategory) {
$.getScript(
'../Reports/assets/js/BookingReports.js',
function() {
this.fillSubCategory=new FillSubCategory("1");
obj.GetSubCategory();
}
)
}
}
}
$(document).ready(function() {
$("#ddlcategory").on('change', function() {
(new ReportsInterface()).showReportBooking();
})
})
i also tried to save object in parent class property but .cannot use it as object later on. how can I call child class method twice without creating any global variable ?
If you are using ES6, I would recommend not using JQuery to import separate files but rather using the ES6 import/export syntax.
I imagine the issue is that since $.getScript makes an http request to redownload the script file, it is actually running the script file twice (one for each download); in the second download, it will run into the naming conflict. ES6 import/exports would solve this issue for you, preventing BookingReport from being redefined.
You should be aware of a couple of things however:
(1) Using your JQuery setup, you get the benefit of lazy loading. To get the same in ES6, you'd have to use the slightly more complicated dynamic imports (see that same link above) -- for this app, however, it doesn't really look like you'd need that.
(2) You might want to familiarize yourself with a bundler like Webpack as this will do ahead-of-time importing and leave you with a single file to download rather than having to ping-pong back and forth from the server as you try to download all of the modularized files.

Add HTML object to an event javascript/meteor

How can I add HTML objects to an event?I would like to do something like this:
Template.Schedule.events({
'dblclick .mycol' (event){
event.target.childNodes.append("<strong>Test</strong>");
}
});
I know I could style it and change the innerHTML and so on for the given example, but I actually want to add other HTML objects, like a select-tag, how can I do that?
The vanilla JS way
You could use innerHTML here to change the html content of the clicked element:
'dblclick .mycol' (event){
const target = event.currentTarget
target.innerHTML = target.innerHTML + "<strong>Test</strong>"
}
If you want to manipulate the parent in the event you can use outerHTML
The jQuery way
Your approach of using append is requiring jQuery:
'dblclick .mycol' (event){
$(event.currentTarget).append($("<strong>Test</strong>"))
}
Bonus: Optimization for using jQuery
In a meteor blaze template-events each event has a reference to the template instance. This template instance keeps a reference to a jQuery object and it's part of the DOM that it manipulates.
template.$ returns a jQuery object of those same elements. jQuery
objects are similar to arrays, with additional methods defined by the
jQuery library.
The template instance serves as the document root for the selector.
Only elements inside the template and its sub-templates can match
parts of the selector.
You can access it via templateInstance.$ if your seconds event parameter is namend templateInstance. With
'dblclick .mycol' (event, templateInstance){
templateInstance.$(event.currentTarget).append($("<strong>Test</strong>"))
}
This saves jQuery the need to traverse the whole DOM, makes it more efficient on large documents.
The Meteor Blaze way
Now these are neat little tricks when there is need for manipulation on a small scale. However, you may want your app to be scalable and profit all the time from the Blaze rendering engine.
In such cases you may rather want to generate a way of dynamically inserting templates.
Consider the following template, that is nowhere imported yet:
rowcontent.html
<template name="rowcontent">
<strong>Test</strong>
<p>someData{{someData}}</p>
</template>
rowcontent.js
import './rowcontent.html' // currently just the import
You can dynamically add it at runtime to an element using Blaze.renderWithData so:
'dblclick .mycol' (event, templateInstance) {
import './rowcontent.js' // use the right path here
Blaze.renderWithData(Template.rowcontent, {someData: 'toBePassedToRowContent'}, event.currentTarget)
}
which will result in:
This is my col Test
someDatatoBePassedToRowContent
The advantage of this approach is that you can pass the data to the template and have all the reactive benefits remaining, thus handle the newly added template like any other template in Meteor.
Alternatives
Declarative dynamic templates using Template.dynamic

True custom attributes (e.g. Microdata) in React

The site I am developing makes use of Microdata (using schema.org). As we are shifting development over to use React to render our views I have hit a blocker where React will only render attributes in the HTML spec however Microdata specifies custom attributes such as itemscope.
As I'm relatively new to React and haven't had chance to fully understand the core just yet, my question is what would be the best way to extend the functionality of react.js to allow for defined custom attributes, e.g., Microdata?
Is there a way of extending the attributes/props parser or is it a job for a mixin which checks all passed props and modifies the DOM element directly?
(Hopefully we'll be able to put together a drop in extension for everyone to provide support for this when a solution is clear.)
You can also use "is" attribute. It will disable the attribute white-list of React and allow every attribute. But you have to write class instead of className and for instead of htmlFor if you use is.
<div is my-custom-attribute="here" class="instead-of-className"></div>
Update React 16 custom attributes are now possible
In react 16 custom attributes are now possible
React 16 custom attributes
It looks like these non-standard properties have been added to React
itemProp: MUST_USE_ATTRIBUTE, // Microdata: http://schema.org/docs/gs.html
itemScope: MUST_USE_ATTRIBUTE | HAS_BOOLEAN_VALUE, // Microdata: http://schema.org/docs/gs.html
itemType: MUST_USE_ATTRIBUTE, // Microdata: http://schema.org/docs/gs.html
Note that properties have capital letter in the middle:
<div itemProp="whatever..." itemScope itemType="http://schema.org/Offer">
will generate proper lowercase attributes as result.
You should be able to do it with componentDidMount:
...
componentDidMount: function() {
if (this.props.itemtype) {
this.getDOMNode().setAttribute('itemscope', true)
this.getDOMNode().setAttribute('itemtype', this.props.itemtype)
}
if (this.props.itemprop) {
this.getDOMNode().setAttribute('itemprop', this.props.itemprop)
}
}
...
The whole check for Microdata attributes can be wrapped into a mixin for convenient. The problem with this approach is that it won't work for built-in React component (components created by React.DOM). Update: Looking closer at React.DOM, I come up with this http://plnkr.co/edit/UjXSveVHdj8T3xnyhmKb?p=preview. Basically we wrap the built-in components in a custom component with our mixin. Since your components are built upon React 's built-in DOM components, this would work without you having to include the mixin in the components.
The real solution would be injecting a custom config instead of React's DefaultDOMPropertyConfig, however I can't find a way to do so in a drop-in manner (DOMProperty is hidden by the module system).
For those who's still looking for answers:
https://facebook.github.io/react/docs/tags-and-attributes.html
Example:
<div itemScope itemType="http://schema.org/Article"></div>
So far, the best method I've found is based off of some Amp interop code linked from a comment on react's bug tracker thread on the subject. I modified it slightly to work with a newer version of React (15.5.4) and TypeScript.
For regular ES6, you can just remove the type annotation for attributeName. Using require was needed in TS since DOMProperty isn't exposed in react's index.d.ts, but again import could be used in regular ES6.
// tslint:disable-next-line:no-var-requires
const DOMProperty = require("react-dom/lib/DOMProperty");
if (typeof DOMProperty.properties.zz === "undefined") {
DOMProperty.injection.injectDOMPropertyConfig({
Properties: { zz: DOMProperty.MUST_USE_ATTRIBUTE },
isCustomAttribute: (attributeName: string) => attributeName.startsWith("zz-")
});
}
Now you can use any attribute starting with zz-
<div zz-context="foo" />
Normally it'd be a bad idea to use internal parts of react like this, but I think it is better than any of the other methods. It works the same way as existing open-ended attributes like data- and the JSX is even type safe in TS. I believe the next major version of react is going to do away with the whitelist anyway, so hopefully changes won't be needed before we can remove this shim entirely.

Categories