Javascript `this` not working as I thought? - javascript

I'm adapting a pretty basic js function into a class. Anyway, basically it just creates a floating container
above the main page. I'm aware it's incomplete, but I'm in the middle of typing it up, and keep getting caught out when attempting to call the close() function. Firefox returns a this.sdiv is undefined. I'm confused as to how this can be the case when close() is Pop's method and sdiv is defined in the first line of the Pop class?
function Pop( wpx,hpx ){
Pop.prototype.sdiv;
Pop.prototype.shadow;
Pop.prototype.pdiv;
// start with the invisible screen, which
// covers the main page
this.sdiv = document.createElement("DIV")
this.sdiv.className = "popScreen";
this.sdiv.id = "popScreen";
// this screen covers the full document, so
// base dimensions on the document size
this.sdiv.style.width = document.body.clientWidth + "px";
this.sdiv.style.height = document.body.clientHeight + "px";
document.body.appendChild( this.sdiv );
// attach drop shadow
this.shadow = document.createElement("DIV");
this.shadow.className = "popShadow";
this.shadow.style.width = wpx + "px";
this.shadow.style.height = hpx + "px";
this.shadow.style.left = ( ( window.innerWidth / 2 ) - ( wpx / 2 ) ) + "px";
this.shadow.style.top = ( ( window.innerHeight / 2 ) - ( hpx / 2 ) ) + "px";
document.body.appendChild( this.shadow );
this.pdiv = document.createElement("DIV");
this.pdiv.className = "pop";
this.pdiv.id = "pop";
this.pdiv.style.position = "absolute";
this.pdiv.style.width = wpx + "px";
this.pdiv.style.height = hpx + "px";
this.shadow.appendChild( this.pdiv );
// bind an event to the screen div so that when it is clicked
// the Pop dialogue is closed and the user is return to the main page
$("div#popScreen").click( function( ){
Pop.prototype.close( );
} );
Pop.prototype.go = function( url, method, data ){
if( method == null )
$("div#pop").load( url );
}
Pop.prototype.close = function( ){
this.sdiv.parentNode.removeChild( this.sdiv );
this.shadow.parentNode.removeChild( this.shadow );
this.pdiv.parentNode.removeChild( this.pdiv );
}
}
Thanks in advance for any help

You can't use Pop.prototype.close() to close all Pop instances. Instead, for each instance of Pop that you have created with the new operator, you need to call popInstance.close().

this in javascript works very differently to this in oo languages.
The error you have is here:
Pop.prototype.close = function( ){
this.sdiv.parentNode.removeChild( this.sdiv );
this.shadow.parentNode.removeChild( this.shadow );
this.pdiv.parentNode.removeChild( this.pdiv );
}
In that function this is probably referring to the window (set a breakpoint and have a look in firebug)
Perhaps something along these lines will work.
var parent = this;
Pop.prototype.close = function(){
parent.sdiv.parentNode.removeChild( this.sdiv );
parent.shadow.parentNode.removeChild( this.shadow );
parent.pdiv.parentNode.removeChild( this.pdiv );
}

Related

Photoshop JS specify font

I'm trying to modify a script to work for what I need it to do and keep getting the "TypeError: undefined is not an object ... I can't figure out why though. I've copy and pasted pretty much everything. The problem line as setting the font to Adobe Garamond.
Script listener has these lines that I think are related but, I don't know JS enough to get it.
var idfontPostScriptName = stringIDToTypeID( "fontPostScriptName" );
desc22.putString( idfontPostScriptName, """AGaramondPro-Regular""" );
var idFntN = charIDToTypeID( "FntN" );
desc22.putString( idFntN, """Adobe Garamond Pro""" );
var idFntS = charIDToTypeID( "FntS" );
desc22.putString( idFntS, """Regular""" );
My script looks like
// this script is a variation of the script addTimeStamp.js that is installed with PH7
//OPENED document has size
if ( documents.length > 0 )
{
var originalDialogMode = app.displayDialogs;
app.displayDialogs = DialogModes.ERROR;
var originalRulerUnits = preferences.rulerUnits;
preferences.rulerUnits = Units.PIXELS;
try
{
var docRef = activeDocument;
// Now create a text layer at the front
var myLayerRef = docRef.artLayers.add();
myLayerRef.kind = LayerKind.TEXT;
myLayerRef.name = "Filename";
var myTextRef = myLayerRef.textItem;
// strip the extension off
var fileNameNoExtension = docRef.name;
fileNameNoExtension = fileNameNoExtension.split( "." );
if ( fileNameNoExtension.length > 1 ) {
fileNameNoExtension.length--;
}
fileNameNoExtension = fileNameNoExtension.join(".");
myTextRef.contents = fileNameNoExtension;
// off set the text to be in the middle
myTextRef.position = new Array( docRef.width / 2, docRef.height / 2 );
myTextRef.size = 135;
myTextRef.textItem.font = 'AGaramondPro-Regular';
}
catch( e )
{
// An error occurred. Restore ruler units, then propagate the error back
// to the user
preferences.rulerUnits = originalRulerUnits;
app.displayDialogs = originalDialogMode;
throw e;
}
// Everything went Ok. Restore ruler units
preferences.rulerUnits = originalRulerUnits;
app.displayDialogs = originalDialogMode;
}
else
{
alert( "You must have a document open to add the filename!" );
}
Oh my hell. Just answered my own question again. Sorry guys.
myTextRef.font = 'AGaramondPro-Regular';

Canvas Greek google fonts not rendering correctly

I assume that this is a bug but if any of you know any work around please let me know.
First of all, the fonts are loaded 101%.
I load Google fonts synchronously
I check with interval to make sure that the font is loaded.
I convert a string into an image (with the below function) by using canvas with success (when
I use English characters)
After rendering a couple English characters I try to render a Greek
word but canvas fall backs to browsers default font.
Firefox doesn't have any issue at all, it works great. The issue is
with Chrome.
Bellow is the function that creates a ribbon-label background image on the top left corner from a given string (PS: this function return imageData that are being merged with other imageData later on):
ImageProcessor.prototype.createLabelImageData = function ( str, size, font, color, backgroundColor, shadowColor, shadowOffsetX, shadowOffsetY, shadowBlur, width, height ) {
this.canvas.width = width || this.settings.width;
this.canvas.height = height || this.settings.height;
this.ctx.clearRect( 0, 0, this.canvas.width, this.canvas.height );
this.ctx.font = "Bold " + ( size || 64 ) + "px " + ( font || "Arial" );
this.ctx.textAlign = "center";
this.ctx.textBaseline = "middle";
var labelHeight = ( size || 64 ) + ( ( size || 64 ) / 4 );
var labelTop = this.canvas.height / 2 - labelHeight / 2;
var labelWidth = this.canvas.width;
var strLen = this.ctx.measureText( str + " " ).width;
var side = Math.sqrt( ( strLen * strLen ) / 2 );
var distance = Math.sqrt( ( side * side ) - ( ( strLen / 2 ) * ( strLen / 2 ) ) );
this.ctx.save();
this.ctx.rotate( -Math.PI / 4 );
this.ctx.translate( -this.canvas.width / 2, -this.canvas.height / 2 + distance );
this.ctx.fillStyle = ( backgroundColor || '#f00' );
this.ctx.beginPath();
this.ctx.moveTo( 0, labelTop );
this.ctx.lineTo( labelWidth, labelTop );
this.ctx.lineTo( labelWidth, labelTop + labelHeight );
this.ctx.lineTo( 0, labelTop + labelHeight );
this.ctx.closePath();
this.ctx.fill();
if ( shadowColor ) {
this.ctx.shadowColor = shadowColor;
this.ctx.shadowOffsetX = ( shadowOffsetX || 0 );
this.ctx.shadowOffsetY = ( shadowOffsetY || 0 );
this.ctx.shadowBlur = ( shadowBlur || size || 64 );
}
this.ctx.fillStyle = ( color || "#fff" );
this.ctx.fillText( str, this.canvas.width / 2, this.canvas.height / 2 );
this.ctx.restore();
var imageData = this.ctx.getImageData( 0, 0, this.canvas.width, this.canvas.height );
this.canvas.width = this.settings.width;
this.canvas.height = this.settings.height;
return imageData;
};
Well after some testing, trial and error and many many hours of reading...
I found out that it doesn't matter if the font has been downloaded when you want to use it in canvas. What worked for me before anything else and any check was to create n*2 div elements (n the number of fonts loaded) and position them outside of the view-port. n*2 because in some I added font-weight:bold.
Bottom line is that the exact font you wish to use in canvas must be:
Preloaded
Create a dummy dom element with innerHTML text of all language
variations (latin & greek in my case).
Keep in mid that you have to create extra elements for the bold variation of the font.
Here is the code that I'm currently using to preload fonts and make sure they are available in canvas.
Vise.prototype.initializeFonts = function ( settings, globalCallback ) {
var that = this; // reference to parent class
/********************************************
********************************************
**
**
** Default settings
**
**
********************************************
********************************************/
var defaults = {
interval: 100,
timeout: 10000,
families: [
'Open+Sans+Condensed:300,300italic,700:latin,greek',
'Open+Sans:300italic,400italic,600italic,700italic,800italic,400,300,600,700,800:latin,greek',
'Roboto+Condensed:300italic,400italic,700italic,400,700,300:latin,greek',
'Roboto:400,100,100italic,300,300italic,400italic,500,500italic,700,700italic,900,900italic:latin,greek'
]
};
// initialization
this.fonts = new Fonts( $.extend( true, defaults, settings ) );
this.fonts.onload = globalCallback;
this.fonts.load();
};
/********************************************
********************************************
**
**
** Fonts class
**
**
********************************************
********************************************/
function Fonts( settings ) {
this.settings = settings;
this.success = [];
this.fail = [];
this.interval = null;
this.elapsedTime = this.settings.interval;
this.fontDetective = new Detector();
}
Fonts.prototype.load = function () {
WebFont.load( {
google: {
families: this.settings.families
}
} );
for ( var i in this.settings.families ) {
var el, elBold;
var familyStr = this.settings.families[ i ];
var family = familyStr.split( ':' )[ 0 ].replace( /[+]/gi, ' ' );
el = document.createElement( "div" );
el.innerHTML = "Font loader Φόρτωμα γραμματοσειράς";
el.style.fontFamily = family;
el.style.color = "#f00";
el.style.position = "fixed";
el.style.zIndex = 9999;
el.style.left = "9999px";
document.body.appendChild( el );
elBold = document.createElement( "div" );
elBold.innerHTML = "Font loader Φόρτωμα γραμματοσειράς";
elBold.style.fontFamily = family;
elBold.style.fontWeight = "bold";
elBold.style.color = "#f00";
elBold.style.position = "fixed";
elBold.style.zIndex = 9999;
elBold.style.left = "9999px";
document.body.appendChild( elBold );
}
this.interval = setInterval( this.areLoaded.bind( this ), this.settings.interval );
};
Fonts.prototype.areLoaded = function () {
for ( var i in this.settings.families ) {
var familyStr = this.settings.families[ i ];
var family = familyStr.split( ':' )[ 0 ].replace( /[+]/gi, ' ' );
var successIdx, failIdx;
if ( this.fontDetective.detect( family ) ) {
successIdx = this.success.indexOf( family );
failIdx = this.fail.indexOf( family );
if ( successIdx === -1 ) {
this.success.push( family );
console.log( "[" + family + "] was successfully loaded." );
}
if ( failIdx > -1 ) {
this.fail.splice( failIdx, 1 );
}
} else {
successIdx = this.success.indexOf( family );
failIdx = this.fail.indexOf( family );
if ( successIdx > -1 ) {
this.success.splice( successIdx, 1 );
}
if ( failIdx === -1 ) {
this.fail.push( family );
}
}
}
if ( this.elapsedTime >= this.settings.timeout ) {
clearInterval( this.interval );
var err = new Error( "Unable to load fonts: " + this.fail.toString() );
this.onload( err, null );
return;
}
if ( this.success.length === this.settings.families.length ) {
clearInterval( this.interval );
this.onload( null, null );
return;
}
this.elapsedTime += this.settings.interval;
};
This is what worked for me in case someone else has the same issue on chrome.
PS: Take a look at fontdetect.js which I use in my code.

Why can't I draw elements to the stage?

Fiddle - http://liveweave.com/JS9EBN
This is a starter template for web design applications. (well almost except for the drawing problem)
Elements are drawn to the stage like so.
// Handles Drawable Elements
$("#canvas").on('mousedown touchstart', function(e) {
if(drawable) {
drawing = true;
mS.x = e.pageX;
mS.y = e.pageY;
dBox = $("<" + $('.draw-elements input[type=radio]:checked').val() + " class='box' />")
.html("Certains textes");
$(this).append(dBox);
// Do not select text when drawing
return false;
}
});
$(document).on('mousemove touchmove', function(e) {
if(drawing && drawable){
var mPos = {x:e.pageX, y:e.pageY};
var css = {};
css.position = 'absolute';
css.left = (mPos.x > mS.x) ? mS.x : mPos.x;
css.top = (mPos.y > mS.y) ? mS.y : mPos.y;
css.width = Math.abs(mPos.x - mS.x);
css.height = Math.abs(mPos.y - mS.y);
css.border = '1px dotted rgb(0, 34, 102)';
dBox.css(css);
// Do not select text when drawing
return false;
}
}).on('mouseup touchend', function(e) {
drawing = false;
});
As long as my select tool is not called I can draw elements without a problem, but when it is called and I come back to draw a div I can no longer draw elements to my stage.
After some tinkering I noticed the problem resides with my drag function for each element that's selected.
var HandleSelectedElement = function() {
if ($(".select-tool.activetool").is(":visible")) {
if(elmstyle) {
$('#canvas').children().drag("start",function( ev, dd ){
dd.attrc = $( ev.target ).prop("className");
dd.attrd = $( ev.target ).prop("id");
dd.width = $( this ).width();
dd.height = $( this ).height();
})
.drag(function( ev, dd ){
var props = {};
if ( dd.attrc.indexOf("E") > -1 ){
props.width = Math.max( 32, dd.width + dd.deltaX );
}
if ( dd.attrc.indexOf("S") > -1 ){
props.height = Math.max( 32, dd.height + dd.deltaY );
}
if ( dd.attrc.indexOf("W") > -1 ){
props.width = Math.max( 32, dd.width - dd.deltaX );
props.left = dd.originalX + dd.width - props.width;
}
if ( dd.attrc.indexOf("N") > -1 ){
props.height = Math.max( 32, dd.height - dd.deltaY );
props.top = dd.originalY + dd.height - props.height;
}
if ( dd.attrd.indexOf("stylethis") > -1 ){
props.top = dd.offsetY;
props.left = dd.offsetX;
}
$('#stylethis').css( props );
}, {relative:true});
}
};
I don't understand what's wrong.
I couldn't find out how to solve the initial problem. So I decided to do a work around.
Here's the fiddle: http://liveweave.com/g2aKlD
I decided to refresh the canvas each time a tool is clicked. I take the canvas's html and set that as a textarea's value. I then set the textarea's value as the canvas's html.
$("#code").val($("#canvas").html());
$("#canvas").html($("#code").val());
This way whatever called the initial bug is removed completely. However last time I did this all spaces where turned into a otherwise known as a non-breakable space (I've also seen this also add unnecessary line breaks and paragraphs when not needed)
I still don't understand why my draw function did not work when drag was turned off.
I really hate having to do this (being refreshing the canvas) because the more elements that are in there and the more refreshing is done, the more ram it uses which makes the browser work the cpu that much harder.
I hope someone can come across a better solution.

Display full sized image on <img> hover?

I have an <img> in an MVC 4 Razor Display Template, and I'd like to display a tooltip containing the full sized image when the user hovers over the image.
HTML:
<img height="50" width="50" src="#Model.ImageString" />
#Model.ImageString contains an image data string, which looks like this:
"data:image/*;base64," + Convert.ToBase64String(file.Data)
If you couldn't guess, file.Data is a byte[].
How can I display a full-sized tooltip upon hovering the <img>?
Here is a very quick example: http://jsfiddle.net/bGn96/
This is along the lines of what Shan Robertson is suggesting.
var $tooltip = $('#fullsize');
$('img').on('mouseenter', function() {
var img = this,
$img = $(img),
offset = $img.offset();
$tooltip
.css({
'top': offset.top,
'left': offset.left
})
.append($img.clone())
.removeClass('hidden');
});
$tooltip.on('mouseleave', function() {
$tooltip.empty().addClass('hidden');
});
A library that provides the desired functionality can be found here: http://cssglobe.com/lab/tooltip/02/
var Controls = {
init: function () {
var imgLink = document.getElementById('thumb');
imgLink.addEventListener('mouseover', Controls.mouseOverListener, false );
imgLink.addEventListener('mouseout', Controls.mouseOutListener, false );
},
mouseOverListener: function ( event ) {
Controls.displayTooltip ( this );
},
mouseOutListener: function ( event ) {
Controls.hideTooltip ( this );
},
displayTooltip: function ( imgLink ) {
var tooltip = document.createElement ( "div" );
var fullImg = document.createElement ( "img" );
fullImg.src = imgLink.src;
tooltip.appendChild ( fullImg );
tooltip.className = "imgTooltip";
tooltip.style.top = "60px";
imgLink._tooltip = tooltip;
Controls._tooltip = tooltip;
imgLink.parentNode.appendChild ( tooltip );
imgLink.addEventListener ( "mousemove", Controls.followMouse, false);
},
hideTooltip : function ( imgLink ) {
imgLink.parentNode.removeChild ( imgLink._tooltip );
imgLink._tooltip = null;
Controls._tooltip = null;
},
mouseX: function ( event ) {
if ( !event ) event = window.event;
if ( event.pageX ) return event.pageX;
else if ( event.clientX )
return event.clientX + (document.documentElement.scrollLeft ?
document.documentElement.scrollLeft :
document.body.scrollLeft);
else return 0;
},
mouseY: function ( event ) {
if (!event) event = window.event;
if (event.pageY) return event.pageY;
else if (event.clientY)
return event.clientY + (document.documentElement.scrollTop ?
document.documentElement.scrollTop :
document.body.scrollTop);
else return 0;
},
followMouse: function ( event ) {
var tooltip = Controls._tooltip.style;
var offX = 15, offY = 15;
tooltip.left = (parseInt(Controls.mouseX(event))+offX) + 'px';
tooltip.top = (parseInt(Controls.mouseY(event))+offY) + 'px';
}
};
Controls.init();
EDIT:
Fiddle: http://jsfiddle.net/enzoferber/SyJsF/2/
Now the tooltip will follow the mouse.
mouseX() and mouseY() will return the current [x,y] mouse coords. And the follow listener is made with the 'mousemove' event that is attached after the tooltip is created.
Oh, and yeah, I changed the image. Now everyone can be happy....
Assuming you are using Javascript to do this:
Have a tooltip container ready in the dom
on hover, grab the file href and make a new image tag inside of the tooltip container.
Just make sure to not specify the image dimensions in the tag, or if you do, display the fullsize dimensions not 50x50.

Image upload popup in ckeditor is not woking in Google chrome

When I click browse server in ckeditor the image browser popup doesnt appear.I am facing problem only in Google Chrome.I am using 18.0.1025.152 m verion of Google Chrome
I have made changes in ckeditor/plugins/popup/plugin.js
try
{
// Chrome 18 is problematic, but it's not really needed here (#8855).
var ua = navigator.userAgent.toLowerCase();
if ( ua.indexOf('chrome/18' ) == -1 )
{
popupWindow.moveTo( left, top );
popupWindow.resizeTo( width, height );
}
popupWindow.focus();
popupWindow.location.href = url;
}
catch ( e )
{
popupWindow = window.open( url, null, options, true );
}
I followed this link enter link description here
But I am unable to resolve the issue.Can anyone help
If you edit the source files you have to repackage them again. It's much simpler to update to CKEditor 3.6.3 and get all the other bug fixes.
I am using opencart 1.5.1.3 ckeditor. I edit the /admin/view/javascript/ckeditor/ckeditor.js and re-align the javascript code with http://jsbeautifier.org/
I have tried with the patch from ckeditor community and little modifications. It works!
http://dev.ckeditor.com/ticket/8855
So if anyone has face the similar issue like me in opencart you can try with below changes.
+++ b/v1.5.1.3/admin/view/javascript/ckeditor/ckeditor.js
## -9190,8 +9190,21 ## For licensing, see LICENSE.html or http://ckeditor.com/license
var s = window.open('', null, p, true);
if (!s) return false;
try {
- s.moveTo(r, q);
- s.resizeTo(n, o);
+ // s.moveTo(r, q);
+ // s.resizeTo(n, o);
+ // Chrome 18 is problematic, but it's not really needed here (#8855).
+ var ua = navigator.userAgent.toLowerCase();
+ var useResize = true;
+ if (ua.indexOf('chrome') > -1) {
+ var chromeVersion = ua.replace(/^.*chrome\/([\d]+).*$/i, '$1')
+ if(chromeVersion >= 18) {
+ useResize = false;
+ }
+ }
+ if (useResize) {
+ s.moveTo( r, q );
+ s.resizeTo( n, o );
+ }
s.focus();
s.location.href = m;
} catch (t) {
I'm using the CKEditor 3.6.2 that comes bundled with primefaces-extensions, so upgrading is not that easy. But executing the following fix against the page also worked. I pasted it in the config file, to be sure that it is fired after the CKEDITOR variable is initialized.
CKEDITOR.editor.prototype['popup'] = function( url, width, height, options ) {
width = width || '80%';
height = height || '70%';
if ( typeof width == 'string' && width.length > 1 && width.substr( width.length - 1, 1 ) == '%' )
width = parseInt( window.screen.width * parseInt( width, 10 ) / 100, 10 );
if ( typeof height == 'string' && height.length > 1 && height.substr( height.length - 1, 1 ) == '%' )
height = parseInt( window.screen.height * parseInt( height, 10 ) / 100, 10 );
if ( width < 640 )
width = 640;
if ( height < 420 )
height = 420;
var top = parseInt( ( window.screen.height - height ) / 2, 10 ),
left = parseInt( ( window.screen.width - width ) / 2, 10 );
options = ( options || 'location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable=yes,scrollbars=yes' ) +
',width=' + width +
',height=' + height +
',top=' + top +
',left=' + left;
var popupWindow = window.open( '', null, options, true );
// Blocked by a popup blocker.
if ( !popupWindow )
return false;
try
{
// Chrome 18 is problematic, but it's not really needed here (#8855).
var ua = navigator.userAgent.toLowerCase();
if ( ua.indexOf( ' chrome/18' ) == -1 )
{
popupWindow.moveTo( left, top );
popupWindow.resizeTo( width, height );
}
popupWindow.focus();
popupWindow.location.href = url;
}
catch ( e )
{
popupWindow = window.open( url, null, options, true );
}
return true;
}
$(document).ready(
function() {
setContentHeight();
makeInstructionsTogglable();
window.onbeforeunload = function() {
if (editor.isDirty()) {
return "Are you sure you want to navigate away? You have unsaved changes."
}
};
}
);
$(window).resize(function() {
setContentHeight();
});

Categories

Resources