How to change in text before saving webpage as a picture - puppeteer-sharp

Is it possible with Puppeteersharp to render text, and highlight words that match specific criteria, before saving the webpage as a picture?
In order to save the webpage as html and then do the work, adds others problems (links to picture etc..)

You can use page.evaluate like so:
await page.evaluate(() => {
const pTags = document.getElementsByTagName("p")
for (let i=0;i<pTags.length-1;i++){
pTags[i].style.background="red"
}
})

Related

Get the current selection on PowerPoint Add-In

I'm developing a Add-in for PowerPoint that inserts images in the document.
I'm currently able to insert the image, but what I'm not able to do is to replace a current selected image.
So, for example, imagine that:
The user added an image available on the Add-in, inside an empty slide
He then selected this image and wants to replace it with another one also available on the Add-in.
He clicks/selects the slide image, and then clicks on the image inside the Add-in that he wants to replace.
The thing is that I'm not able to get his selection with the Office API.
Can someone help me?
My current code looks like this:
const insertFile = (binaryStr: string) => {
Office.context.document.setSelectedDataAsync(
binaryStr,
{
coercionType: Office.CoercionType.Image,
},
(result) => {
if (result.status === Office.AsyncResultStatus.Failed) {
console.error(result.error.message);
}
}
);
};
Try to use the getSelectedDataAsync method which reads the data contained in the current selection in the document.

Let user select a photo from a gallery

After going over ANY option possible, I can't find a solution to a simple problem :
Letting a user select a photo from a large gallery and save it to collection.
Like an image picker, you pick an image from a gallery and the window is closed.
No photo selection option on "user input" menu.
No way to connect any gallery including Wix Gallery to a data set as INPUT.
3rd apps let you do that but it's being saved in their own servers, and its limited to just a few photos, not to a large set
We basically have more than 100 photos in an album that a user should be able to somehow pick.
Another option is to open some kind of window with Pinterest stream and collect the URL of a selection, which also seems impossible.
There is no built-in image picker, but you can roll your own with a bit of code.
Here's a bit of code that should get you started in the right direction:
import wixData from 'wix-data';
import wixUsers from 'wix-users';
$w.onReady(function () {
$w('#gallery').clickAction = "none";
$w("#gallery").onItemClicked( (event) => {
let imageSrc = event.item.src;
let toInsert = {
"user": wixUsers.currentUser.id,
"image": imageSrc
}
wixData.insert("SelectedImages", toInsert)
.then( () => {
$w('#gallery').hide("fold");
} );
} );
} );
This code assumes you have a collection where you want to store "selected" images. That collection has at least two fields that have the following keys: user and image.
When an image in the gallery is clicked an event handler gets the src of the image and inserts it into the collection along with the current user's ID. Then the gallery is hidden.
All of the above can be customized to fit your specific situation, but this should give you an idea of what can be done.

CKEditor: Modifying view without changing data

I have content that references Images by ID within a placeholder (e.g. "$m(12345)" ). I have a REST call that will return an img-tag for the placeholder.
I would like CKEditor to display the image when the content is opened in editor, or a placeholder is inserted. But I want the placeholder to remain in the content (including when switching to the Source view)
I've tried to do this by adding a rule to the dataFilter:
CKEDITOR.on('instanceLoaded', function(ckeditor){
var mediaPlaceholderRegex = /\$m\(.*\)/;
ckeditor.editor.dataProcessor.dataFilter.addRules({
text: function( text, node ) {
return text.replace( mediaPlaceholderRegex, function( match ) {
var params = "placeholder="+match;
var xhttp = new XMLHttpRequest();
xhttp.open("POST", url, false);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send(params);
return xhttp.responseText;
} );
}
});
});
It does the job of replacing the placeholder with the image tag, but the img-tag is also there when switching to the source view.
Is there an easy way to only apply a filter to the wysiwyg view.
The only way I see is to add a htmlFilter that would revert the img-tag back to a placeholder.
Is there an easy way to only apply a filter to the wysiwyg view. The only way I see is to add a htmlFilter that would revert the img-tag back to a placeholder.
Good thinking. Either that of if you don't want your images to be removed/fetched from the server on every mode change, you can for example put your placeholder into the data- attribute for the image tag. It all depends on your use case but the bottom line is that dataFilter is used when you load data into the editor and htmlFilter when you get data from the editor (same methods are used when getting data and switching to source mode so htmlFilter applies here).

Scraping with casperjs -- Not sure how to handle empty div

I'm using casperjs to scrape a site. I setup a function which stores a string into a variable named images (shown below) and it works great.
images = casper.getElementsAttribute('.search-product-image','src');
I then call that variable in fs so I can export it to a CSV, which also works fine.
casper.then(function() {
var f = fs.open('e36v10.csv', 'w');
f.write(imagessplit + String.fromCharCode(13));
f.close();
});
The issue I just noticed is that not all products have images, so when the scraper hits a product without an image it passes by it obviously. I need it to at least alert me somehow (something as simple as filler text thats says, "no image here") when it passes by a product without an image because what I do is I copy that string (along with may other strings) and organize them into columns within the CSV and it messes up the order of everything without having some sort of filler text ("no image here"). Thanks
Edit
Below is the exact source from the website I am trying to pull from.
A product I can get the image from and my code works fine:
<div class="search-v4-product-image">
<img alt="238692" class="search-product-image" src="http://d5otzd52uv6zz.cloudfront.net/group.jpg">
<p class="image-overlay">Generic</p>
</div>
A product with no image and my scraper passes right by it without alerting me.
<div class="search-v4-product-image"> </div>
First I would do images = casper.getElementsInfo('.search-product-image') which will give you an array of elements matching .search-product-image. Then you can iterate over this array and extract the src attribute from each element with: var src = image.attributes.src
Now that you have the src attribute you can simply check wether it has a value or not. If it does not, then you could assign it to placeholder text.
You can write this functionality for the page context this way:
casper.then(function(){
var imgList = this.evaluate(function(){
var productImages = document.querySelectorAll("div.search-v4-product-image"),
imageList = [];
Array.prototype.forEach.call(productImages, function(div){
if (div.children.length == 0) {
imageList.push({empty: true});
} else {
var img = div.children[0]; // assumes that the image is the first child
imageList.push({empty: false, src: img.src});
}
});
return imageList;
});
var csv = "";
imgList.forEach(function(img){
if (img.empty) {
csv += ";empty";
} else {
csv += img.src+";";
}
});
fs.write('e36v10.csv', csv, 'w');
});
This iterates over all divs and pushes the src to an array. You can check the empty property for every element.
I suspect that the output would be more meaningful if you iterate over all product divs and check it this way. Because then you can also write the product name to the csv.
You could use CSS selectors but then you would need make the :nth-child selection much higher in the hierarchy (product div list). This is because :nth-child only works based on its parent and not over the whole tree.

Creating image with hyperlink using google-apps-script

I have been trying to put an image with a hyperlink on it into a google apps script ui. I first thought of using createAnchor(), but that only allows text. Then I thought of using a button, but as far as I know you cannot open a new tab/window and redirect in a callback function.
I also tried createHTML(), but the element is not handled by it as yet.
I have seen people overlay transparent buttons over images, but still have same issue in callback.
My research has not found an answer to this. Does anyone have any solutions/examples?
Thanks
This worked for me on Chrome20 and IE9
// Container for box and results
var imageContainer = app.createFlexTable();
// Setup the button
var button = app.createButton("ImageButton");
button.setStyleAttribute("background", "url(dontshowimagehere.JPG) no-repeat");
button.setStyleAttribute("position", "absolute");
button.setStyleAttribute("color", "transparent");
button.setStyleAttribute('zIndex','1');
button.setStyleAttribute("border", "0px solid black");
imageContainer.setWidget(0, 0, button);
// image to click
var image = app.createImage("image.jpg").setId(imageId);
imageContainer.setWidget(1,0, image);
The image has a slight (3px) offset. If important, this looks to fix it http://www.w3schools.com/css/css_positioning.asp (use relative for the flex table and top etc for the image and button)
Did you try a transparent Anchor overlaying the image?
function doGet() {
var app = UiApp.createApplication().setTitle("Image Anchor");
var panel = app.createAbsolutePanel().setWidth('50%').setHeight('50%');
var image = app.createImage().setUrl("https://lh6.googleusercontent.com/-v0Q3gPQz03Q/T_y5gcVw7LI/AAAAAAAAAF8/ol9uup7Xm2g/s512/GooglePlus-512-Red.png").setStyleAttribute("width", "28px").setStyleAttribute("height", "28px");
var anchor = app.createAnchor("?", "https://plus.google.com/u/1/116085534841818923812/posts").setHeight("28px").setWidth("28px").setStyleAttribute("opacity", "0.1").setTarget("blank");
panel.add(image,100,50);
panel.add(anchor,100,50);
app.add(panel);
return app.close();
}
app.createAbsolutePanel()
.add(app.createImage('https://www.google.com/images/logos/google_logo_41.png'))
.add(app.createAnchor('','https://www.google.co.uk/intl/en/about/')
.setStyleAttributes({position:'absolute',top:'0px',left:'0px',width:'201px',height:'47px',opacity:'0'}))
This is a tested one. It works fine.
It doesn't work with positioning the image (as 'absolute').
It doesn't work with .setHorizontalAlignment(UiApp.HorizontalAlignment.CENTER)
I don't believe this is possible with the widgets available. I would suggest altering your UI's design to utilize an Anchor widget instead.
Use HTML Box if you are coding directly on your page. Click "Edit" to edit your page and go to "Insert>HTML Box" in your menu. It will accept javascript too! There are a few caveats - when using javascript, HTML Box will not accept links...too bad, but too many exploits there.
If you are coding in apps script, you could try to place the image on a panel and use absolute panel and position your link over your image. Another method could be to use the .setStyleAttribute for CSS styling and utilize the zIndex parameter to place a panel over top of your image....like so:
var panel = app.createSimplePanel();
// add your image to the simple panel or whatever panel you wish to choose in your GUI
var popPanel = app.createSimplePanel()
.setStyleAttribute('top','Y')
.setStyleAttribute('left','X')
.setStyleAttribute('zIndex','1')
.setStyleAttribute('position','fixed');
// add your anchor to the popPanel
app.add(panel).add(popPanel);
Not 100% sure if you can make this panel transparent, but you could try something like:
.setStyleAttribute('background',transparent')
or change the opacity via:
.setStyleAttribute('opacity','.5')
Hopes this gives you a few ideas!
I managed to do it with a single Anchor object and using CSS3.
It works on Chrome, I did not test it in other Browsers.
gui.createAnchor("", false, "$DESTINATION_URL$")
.setStyleAttributes({ "display":"block",
"width":"$IMAGE_WIDTH_IN_PIXEL$",
"height":"$IMAGE_HEIGHT_IN_PIXEL$",
"background":"url($URL_OF_THE_IMAGE$)",
"background-size":"100% 100%",
"background-repeat":"no-repeat" })
Of course you have to replace the $......$ with your data.
Thierry
If you first create all your HTML in a string, you can then replace the content of a page with the HTML you want like this:
var myString = 'the html you want to add, for example you image link and button';
var page = SitesApp.getSite('example.com', 'mysite').getChildByName('targetpage');
var upage = page.setHtmlContent('<div>' + myString + '</div>');

Resources