CKEditor: Custom HTML when inserting image - html

I'm using CKEditor as a rich text editor for my website. On that site I also have a custom image manager that I use in CKEditor using the "filebrowserImageBrowseUrl" config parameter.
This puts a "Browse Server" button in the image properties that lets me select a file from my image manager. This works just fine.
However, when I insert an image from my image manager and resize it in CKEditor this only adds a style attribute to the img tags. When people browse me website they will see the image as the size I want, but they also have to download a large amount of data, even if the image size is only a thumbnail.
My image manager has automatic resizing when you put a width and height as a query string to the image url.
How can I override the img tag CKEditor creates so that the selected width and height is put as query variables into the src attribute in the img tag in addition to the style attribute (so that CKEditor still knows which size the image has)?
I did find another question posted here: CKEditor: Customized HTML on inserting an image
But the answers for that question doesn't seem to work since the width and height from that example contains the image's original size instead of the custom size. I've also debugged the various variables from those methods without finding the custom size.
So the question remains: How can I override CKEditor's output HTML to put an image's size as query variables as well as in the style attributes where CKEditor puts it by default?
UPDATE
To make all the comments below a bit more comprehensive, here's a condensed version:
CKEDITOR.on('instanceReady', function (ev) {
var editor = ev.editor,
dataProcessor = editor.dataProcessor,
htmlFilter = dataProcessor && dataProcessor.htmlFilter;
htmlFilter.addRules( {
elements : {
$ : function( element ) {
// Output dimensions of images as width and height attributes on src
if ( element.name == 'img' ) {
var style = element.attributes.style;
if (style) {
// Get the width from the style.
var match = /(?:^|\s)width\s*:\s*(\d+)px/i.exec( style ),
width = match && match[1];
// Get the height from the style.
match = /(?:^|\s)height\s*:\s*(\d+)px/i.exec( style );
var height = match && match[1];
var imgsrc = element.attributes.src + "?width=" + width + "&height=" + height;
element.attributes.src = imgsrc;
element.attributes['data-cke-saved-src'] = imgsrc;
}
}
}
}
});
});
This code is run whenever the CKEditor generates the actual HTML, which happens when you either view the source by clicking the "Source" button, or by performing an HTTP POST of that page.
A small warning, though. The code above will keep appending the width and height query strings for each click on the "Source" button, or for each postback, so you might want to add some extra logic to filter out the width and height query strings before appending them to the src attribute.

If you look at the Output HTML sample in your copy of CKEditor you can see how it uses the htmlFilter to change the images to put the dimensions in attributes. Based on that code you can write your own code so that it changes the url of the image.
And be careful: URLs are protected to avoid problems with the browsers, so modifying the "src" attribute might not be enough. Look at the properties of the object that you are modifying.

Related

Re-size image in html tag for copyright purposes

Is it possible to resize a image to a lower resolution when it's being used from a url in a a <img> tag?
for example <img src="http://someplace.com/img" width="100" height="100">
I want to use a personalized image that's created with a Shopify app and is referenced in a line_item property, and use it in a confirmation email but I don't want the customer to be able to right click and save it.
is it possible to lower the resolution of the image?
CSS Only changes the image size visually. it means the file size is still like the original file and if the viewer download/save the image, it is getting it in its original size.
so just for visual purposes you can use something like this:
img.resize {
width:100px;
height: auto;
}
But if you want to hide the original file size you need to resize it with image editing software and upload the smaller one in the new URL and use it.
You can use an image manipulation library to resize and/or blur the images or change their resolution. You can manipulate a single image or multiple images in a folder and store the manipulated images in a new folder.
You can then add these new modified images to your page.
One such library is gulp-gm
gulp.src('test.png')
.pipe(gm(function (gmfile) {
return gmfile.blur(10);
}))
for resolution change
var gulp = require('gulp');
var gm = require('gulp-gm');
gulp.task('default', function () {
gulp.src('test.png')
.pipe(gm(function (gmfile) {
return gmfile.resize(100, 100);
}))
.pipe(gulp.dest('dist'));
});

Is it possible for a chrome extention popup to be part of the page?

I'm building a chrome extension but when I use the "default_popup" I can see that it only allows a max height and width, and it is appearing inline over the content of the website. Is it possible to reduce the main browser page to 80% and have 20% of the visible screen for the extension?
Is there another term I can use instead of "default_popup" in "browser_action" to achieve this?
I ran into this issue with an extension recently. I wanted content to be inserted at the top of the browser window and I wanted that content to extend to 100% of the width content window. Since a popup is limited in both width and height, I went with the approach of creating the element to be inserted (for me that was a wrapper div with some content and some buttons) and then appending each of these elements to the body of the page. For example:
let body = document.body;
let wrapper = document.createElement('div')
wrapper.setAttribute('id', 'kty208wrapper')
let header = document.createElement('h1')
header.setAttribute('id', 'kty208header')
// create buttons for increasing/decreasing font size
let btnBigger = document.createElement('button')
btnBigger.innerHTML = "+"
let btnSmaller = document.createElement('button')
btnSmaller.innerHTML = "–"
// add wrapper, header, and bigger/smaller buttons to page
body.insertBefore(wrapper, body.firstChild);
wrapper.appendChild(header)
wrapper.appendChild(btnBigger)
wrapper.appendChild(btnSmaller)
With the wrapper div I used body.insertBefore to insert the content before the start of the body content (so that my wrapper div would show at the very top of the page).
Then I appended the header and buttons to the wrapper div.
Then I was able to write my functions to reference the inserted html elements like so:
let currentSize = 60;
btnBigger.onclick = function() {
currentSize = parseFloat(currentSize) + 5 + 'px';
bigURL.style.fontSize = currentSize
bigURL.style.lineHeight = currentSize
}
Since I wanted this code to be run when a user clicked the extension icon (and not on page load) I created a background script called background.js and listened for the onClicked event. One a user clicked the icon I executed the code above, which was stored in a separate file called content.js. I had to have separate scripts because background scripts don't have access to modify the dom.
chrome.browserAction.onClicked.addListener(function(tab) {
// when a user clicks the extension icon, execute content.js
// content.js has access to the current tab's DOM while
// background.js doesn't.
chrome.tabs.executeScript(null, {file: "content.js"});
});
I hope this helps!

How to keep fluid grid of image thumbnails from shifting during load?

I'm using a bootstrap 3 fluid grid to display thumbnails, and I love how the images scale in size as the browser is resized. The downside however, is a "big bang" effect when each page is loaded. That is, the grid begins collapsed then grows as images are added. I imagine a simple fix is to hardcode image sizes, but this would lose the scaling benefit I believe.
One attempt to fix this was to load a transparent placeholder image right before each thumbnail, which would of course be cashed on the first page of results and thus expand the grid faster. On callback for thumbnail loaded event, I remove the placeholder. This seems to help, but other times I still see the shifting as badly as before. In addition, with a slow connection you can actually for a moment see the real thumb below the placeholder.
<script type="text/javascript">
$(function(){
// For each thumbnail, insert a placeholder image.
// Once the thumb is loaded, remove the placeholder.
$("[id^=thumb-]").each(function(i, thumb) {
var $thumb = $(thumb)
var imgTag = "<img id='ph-" + (i + 1) +
"' class='placeholder' src='{% static "img/placeholder.png" %}'/>";
$thumb.parent().prepend(imgTag);
var $holder = $thumb.prev();
function loaded() {
$holder.remove();
}
if (thumb.complete) {
loaded();
} else {
$thumb.on('load', loaded);
$thumb.on('error', function() {
console.log('Error with thumbnail placeholders.');
});
}
});
});
</script>
Regarding compatibility, I'd like to at least have a usable site with older browsers, but it doesn't have to be perfect.
I'm not as interested in fixing my Javascript solution above as I am the best solution overall.
Please look at the live beta site here to help diagnose. I attempted a jsfiddle, but couldn't quite reproduce it. I will paste more context into the question once we understand what was wrong.
In this case, I would recommend adding the <img> tag to the plain HTML. Then set the src in your javascript function.
You'll also need to set height and width attributes on the <img> tags so their space is preserved, to prevent redrawing the page after the images are loaded. You could do this with a simple javascript function that determines the window.width and then sets the height and width attributes.
Something like this.

SP2010 - change width of list column, or set a max-width with CSS

Some of the list columns I render have the option for the user to enter a mass of data. If they do it can cause the view of the screen to be skewed as there is too much content in one column and the rest of the columns aren't visible on the screen without scrolling.
I am seeking to change the width of list columns, similar to the solution that is described here: http://aanuwizard.com/2010/08/01/sharepoint-2010-how-to-change-width-of-list-column/ but I didn't want to use sharepoint designer. Ideally I could just set a max width for everything, so it wouldn't ruin the views if a lot of content was input.
I was hoping to do it with CSS, as I can inject css into my SP pages. Is it possible? how could I do it?
This is not a very nice solution, but if you don't want to use SharePoint Designer it might be what you need:
One thing you could do if you don't want to use the SharePoint Designer is to add a Content Editor WebPart containing a javascript that applies the CSS for you.
You would either add a stylesheet in your content editor webpart and apply your stilesheet to the desired element, or you can also try to change the .style property of your element directly. As seen here:
function changeElement(id) {
var el = document.getElementById(id);
el.style.color = "red";
el.style.fontSize = "15px";
el.style.backgroundColor = "#FFFFFF";
}
Some more information on how to do this can be found here:
http://www.w3.org/wiki/Dynamic_style_-_manipulating_CSS_with_JavaScript

Getting Image height before the image loads in HTML

I have a table that is dynamically created using DIVs. Each row of the table has two images. I want to set the height for the div (that represents a particular row) to the height of image that is greater of the two images being displayed in that particular row. The images to displayed will always change, and they are from an external server.
How do I set the height for my div so that I can fit images?
If you are trying to dynamically resize a couple of divs in a row within a table, you maybe better off using a html table instead and having each image within a td tag. This will make tr tag resize accordingly for the image in each cell.
this.img = new Image();
this.img.src = url;
alert(this.img.width);
gives the width while
var img = new Image();
img.src = url;
alert(img.width);
doesnt..
dunno why.
You can:
Not specify the height of the div, and let it expand automatically
Once the image is loaded do:
document.getElementById("myDiv").height = document.getElementById("myImage").height
We'll need a little more info to be very useful. You can get the height & width of an image after the page loads via Javascript (info), then you could resize the height of the div after loading. Otherwise, you're really out of luck since HTML itself doesn't have anything.
If you're using PHP, there's getimagesize(), which you can use if you're building the site dynamically with PHP. There are similar functions for other languages, but we'd need a little more info.
If you want the browser to do layout based on the height of an image, before it fetches the image, you need to send that height to the browser somewhere. This will require something server-side. The fastest thing would be to insert in into the html directly. Slower but more elegant would be to fetch it image by image with <script src=> statements that get instructions from a special bit of javascript-generating cgi. (The speed difference comes from network round trips.)
If you're willing to resize after the data arrives, it's much simpler. Either slap an onload handler on the images or stick them in normal dom (e.g. an actual table, though you can do it with divs and css) and let the layout engine do the work.
This question has been answered in multiple ways, and you asked the additional question "Won't this make the UI look bad?"
The answer to that question is Yes. The best thing for you to do in most cases will be to set the height of your div to something that looks good, then scale the images down to fit. This will make the rendering faster, and the final product will look better and more professional.
But that's just my own opinion, though. I have no empirical data to back that up.
Pre-load them into javascript image objects then just reference the height and width.
Might take some clever devilry to work in all browsers...
function getSize(imgSrc){
var aImg = new Image();
aImg.src = imgSrc;
aHeight = newImg.height;
aWidth = newImg.width;
}