// ========================================================================== // Project: SproutCore - JavaScript Application Framework // Copyright: ©2006-2011 Strobe Inc. and contributors. // portions copyright @2011 Apple Inc. // License: Licensed under MIT license (see license.js) // ========================================================================== /*global module test htmlbody ok equals same */ (function() { var logoURL = sc_static('images/sproutcore.png'); var sampleURLs = [ "http://www.public-domain-image.com/cache/nature-landscapes-public-domain-images-pictures/canyon-public-domain-images-pictures/zion-hiker-the-sweetie-hiking-in-zion-narrows_w725_h544.jpg", "http://www.public-domain-image.com/cache/people-public-domain-images-pictures/children-kids-public-domain-images-pictures/children-playing_w562_h725.jpg", "http://www.public-domain-image.com/cache/architecture-public-domain-images-pictures/fountain-public-domain-images-pictures/water-fountain-in-park_w725_h544.jpg", "http://www.public-domain-image.com/cache/nature-landscapes-public-domain-images-pictures/canyon-public-domain-images-pictures/winter-at-bryce-canyon_w725_h544.jpg", "http://www.public-domain-image.com/cache/fauna-animals-public-domain-images-pictures/prairie-dog-public-domain-images-pictures/prairie-dog-pups_w725_h483.jpg", "http://www.public-domain-image.com/cache/fauna-animals-public-domain-images-pictures/prairie-dog-public-domain-images-pictures/prairie-rattlesnake-crotalus-viridis_w725_h484.jpg", "http://www.public-domain-image.com/cache/fauna-animals-public-domain-images-pictures/tigers-public-domain-images-pictures/bengal-tiger_w725_h486.jpg", "http://www.public-domain-image.com/cache/nature-landscapes-public-domain-images-pictures/field-public-domain-images-pictures/wooden-logs-in-field_w725_h483.jpg", "http://www.public-domain-image.com/cache/nature-landscapes-public-domain-images-pictures/field-public-domain-images-pictures/wheat-yellow-in-field_w725_h544.jpg", "http://www.public-domain-image.com/cache/nature-landscapes-public-domain-images-pictures/field-public-domain-images-pictures/vineyards_w725_h544.jpg", "http://www.public-domain-image.com/cache/nature-landscapes-public-domain-images-pictures/autumn-public-domain-images-pictures/old-trees-with-leaves-on-ground-in-autumn_w725_h484.jpg", "http://www.public-domain-image.com/cache/nature-landscapes-public-domain-images-pictures/canyon-public-domain-images-pictures/yaki-point-at-the-grand-canyon_w725_h547.jpg", "http://www.public-domain-image.com/cache/nature-landscapes-public-domain-images-pictures/canyon-public-domain-images-pictures/grand-canyons-overlook-railings-pointing_w725_h544.jpg", "http://www.public-domain-image.com/cache/nature-landscapes-public-domain-images-pictures/coast-public-domain-images-pictures/sand-ocean-tidepools-sea-swimming-swimmers-waves_w725_h544.jpg", "http://www.public-domain-image.com/cache/nature-landscapes-public-domain-images-pictures/coast-public-domain-images-pictures/waves-breaking-rocks_w725_h544.jpg", "http://www.public-domain-image.com/cache/nature-landscapes-public-domain-images-pictures/sand-public-domain-images-pictures/sand-footstep_w725_h482.jpg"]; var pane = SC.ControlTestPane.design() .add("image_not_loaded", SC.ImageView, { value: null, layout : { width: 200, height: 300 }, useCanvas: NO }) .add("image_loaded", SC.ImageView, { value: logoURL, layout : { width: 200, height: 300 }, useImageQueue: NO, useCanvas: NO }) .add('sprite_image', SC.ImageView, { layout: { width: 200, height: 300 }, value: 'sprite-class', useCanvas: NO }) .add('image_canvas', SC.ImageView, { layout: { width: 200, height: 300 }, useCanvas: YES, value: logoURL }) .add('image_holder', SC.View, { layout: { width: 200, height: 200 } }); pane.show(); module('SC.ImageView ui', pane.standardSetup()); test("Verify that all the rendering properties of an image that is being loaded are correct", function() { var imageView = pane.view('image_not_loaded'), url; ok(imageView.get('isVisibleInWindow'), 'image_not_loaded is visible in window'); imageView.set('value', logoURL); ok(imageView.get('status') !== SC.IMAGE_STATE_LOADED, 'PRECOND - status should not be loaded (status=%@)'.fmt(imageView.get('status'))); ok(imageView.get('status') === SC.IMAGE_STATE_LOADING, 'PRECOND - status should be loading (status=%@)'.fmt(imageView.get('status'))); url = imageView.$('img').attr('src'); ok((url.indexOf('base64')!=-1) || (url.indexOf('blank.gif')!=-1), "The src should be blank URL. url = %@".fmt(url)); }); test("Verify that all the rendering properties of an image that is loaded are correct", function() { var imageView = pane.view('image_loaded'), imgEl; ok(imageView.get('isVisibleInWindow'), 'image_loaded is visible in window'); imageView.addObserver('status', this, function() { equals(SC.IMAGE_STATE_LOADED, imageView.get('status'), 'status should be loaded'); // Status has changed, but the observer fires immediately, so pause in order to have the DOM updated setTimeout(function() { imgEl = imageView.$('img'); ok(imgEl.attr('src').indexOf(logoURL) !== 0, "img src should be set to logoURL"); window.start(); // continue the tests }, 100); }); stop(); }); test("Verify that the tooltip is correctly being set as both the title and attribute (disabling localization for this test)", function() { var imageView = pane.view('image_loaded'), testToolTip = 'This is a test tooltip', imgEl; imageView.set('localization', NO); imageView.set('toolTip', testToolTip); imageView.addObserver('status', this, function() { setTimeout(function() { imgEl = imageView.$('img'); equals(imgEl.attr('title'), testToolTip, "title attribute"); equals(imgEl.attr('alt'), testToolTip, "alt attribute"); window.start(); // continue the tests }, 100); }); stop(); }); test("Verify canvas rendering and properties", function() { var view = pane.view('image_canvas'), canvasEl = view.$(); equals(canvasEl.attr('width'), 200, "The width of the canvas element should be set"); equals(canvasEl.attr('height'), 300, "The height of the canvas element should be set"); }); test("Using imageQueue", function() { var imageHolder = pane.view('image_holder'), imageView1, imageView2, lastMod1, lastMod2; stop(); // Only allow 1 image at a time SC.imageQueue.loadLimit = 1; // Add a random value so that the images appear as unique lastMod1 = Math.round(Math.random() * 100000); lastMod2 = Math.round(Math.random() * 100000); // Set the first view to load in the background (ie. it should load last although it was created first) imageView1 = SC.ImageView.create({ value: logoURL + "?lastmod=" + lastMod1, canLoadInBackground: YES }); imageView2 = SC.ImageView.create({ value: logoURL + "?lastmod=" + lastMod2, canLoadInBackground: NO }); // The second image should load first and the first not be loaded yet imageView2.addObserver('status', this, function() { equals(imageView2.get('status'), SC.IMAGE_STATE_LOADED, 'imageView2 status on imageView2 status change'); equals(imageView1.get('status'), SC.IMAGE_STATE_LOADING, 'imageView1 status on imageView2 status change'); }); imageView1.addObserver('status', this, function() { equals(imageView2.get('status'), SC.IMAGE_STATE_LOADED, 'imageView2 status on imageView1 status change'); equals(imageView1.get('status'), SC.IMAGE_STATE_LOADED, 'imageView1 status on imageView1 status change'); window.start(); // starts the test runner }); imageHolder.appendChild(imageView1); imageHolder.appendChild(imageView2); }); function testScale(imageView, isImg) { stop(); // Default is SC.FILL imageView.addObserver('status', this, function() { // Status has changed, but the observer fires immediately, so pause in order to have the DOM updated setTimeout(function() { var imgEl, innerFrame, testImg = !imageView.get('useCanvas'); // Default is SC.FILL innerFrame = imageView.get('innerFrame'); equals(innerFrame.width, 588, "SC.FILL width"); equals(innerFrame.height, 90, "SC.FILL height"); if (testImg) { imgEl = imageView.$('img'); equals(imgEl.css('width'), "588px", "SC.FILL width"); equals(imgEl.css('height'), "90px", "SC.FILL height"); } SC.RunLoop.begin(); imageView.set('scale', SC.SCALE_NONE); SC.RunLoop.end(); innerFrame = imageView.get('innerFrame'); equals(innerFrame.width, 271, "SC.SCALE_NONE width"); equals(innerFrame.height, 60, "SC.SCALE_NONE height"); if (testImg) { equals(imgEl.css('width'), "271px", "SC.SCALE_NONE width"); equals(imgEl.css('height'), "60px", "SC.SCALE_NONE height"); } SC.RunLoop.begin(); imageView.set('scale', SC.FILL_PROPORTIONALLY); SC.RunLoop.end(); innerFrame = imageView.get('innerFrame'); equals(innerFrame.width, 588, "SC.FILL_PROPORTIONALLY width"); equals(innerFrame.height, 130, "SC.FILL_PROPORTIONALLY height"); if (testImg) { equals(imgEl.css('width'), "588px", "SC.FILL_PROPORTIONALLY width"); equals(imgEl.css('height'), "130px", "SC.FILL_PROPORTIONALLY height"); } SC.RunLoop.begin(); imageView.set('scale', SC.BEST_FIT); SC.RunLoop.end(); innerFrame = imageView.get('innerFrame'); equals(innerFrame.width, 407, "SC.BEST_FIT width"); equals(innerFrame.height, 90, "SC.BEST_FIT height"); if (testImg) { equals(imgEl.css('width'), "407px", "SC.BEST_FIT width"); equals(imgEl.css('height'), "90px", "SC.BEST_FIT height"); } SC.RunLoop.begin(); imageView.set('scale', SC.BEST_FIT_DOWN_ONLY); SC.RunLoop.end(); innerFrame = imageView.get('innerFrame'); equals(innerFrame.width, 271, "SC.BEST_FIT_DOWN_ONLY width (larger frame)"); equals(innerFrame.height, 60, "SC.BEST_FIT_DOWN_ONLY height (larger frame)"); if (testImg) { equals(imgEl.css('width'), "271px", "SC.BEST_FIT_DOWN_ONLY width (larger frame)"); equals(imgEl.css('height'), "60px", "SC.BEST_FIT_DOWN_ONLY height (larger frame)"); } SC.RunLoop.begin(); imageView.set('layout', { top: 0, left: 0, width: 147, height: 90 }); SC.RunLoop.end(); innerFrame = imageView.get('innerFrame'); equals(innerFrame.width, 147, "SC.BEST_FIT_DOWN_ONLY width (smaller size frame)"); equals(innerFrame.height, 33, "SC.BEST_FIT_DOWN_ONLY height (smaller size frame)"); if (testImg) { equals(imgEl.css('width'), "147px", "SC.BEST_FIT_DOWN_ONLY width (smaller size frame)"); equals(imgEl.css('height'), "33px", "SC.BEST_FIT_DOWN_ONLY height (smaller size frame)"); } window.start(); // starts the test runner }, 100); }); } test("Scaling images (img)", function() { var imageHolder = pane.view('image_holder'), imageView; // The logo is 271x60 imageView = SC.ImageView.create({ value: logoURL + "?lastmod=" + Math.round(Math.random() * 100000), layout: { top: 0, left: 0, width: 588, height: 90 }, useCanvas: NO }); testScale(imageView); imageHolder.appendChild(imageView); }); test("Scaling images (img) with static layout", function() { var imageHolder = pane.view('image_holder'), imageView; // The logo is 294x60 imageView = SC.ImageView.create({ value: logoURL + "?lastmod=" + Math.round(Math.random() * 100000), layout: { top: 0, left: 0, width: 588, height: 90 }, useCanvas: NO, useStaticLayout: YES }); testScale(imageView); imageHolder.appendChild(imageView); }); test("Scaling images (canvas)", function() { var imageHolder = pane.view('image_holder'), imageView; // The logo is 294x60 imageView = SC.ImageView.create({ value: logoURL + "?lastmod=" + Math.round(Math.random() * 100000), layout: { top: 0, left: 0, width: 588, height: 90 } }); testScale(imageView); imageHolder.appendChild(imageView); }); test("Scaling images (canvas) with static layout", function() { var imageHolder = pane.view('image_holder'), imageView; // The logo is 294x60 imageView = SC.ImageView.create({ value: logoURL + "?lastmod=" + Math.round(Math.random() * 100000), layout: { top: 0, left: 0, width: 588, height: 90 }, useStaticLayout: YES }); testScale(imageView); imageHolder.appendChild(imageView); }); function testAlign(imageView) { stop(); // Default is SC.FILL imageView.addObserver('status', this, function() { // Status has changed, but the observer fires immediately, so pause in order to have the DOM updated setTimeout(function() { var imgEl, innerFrame, testImg = !imageView.get('useCanvas'); // Default is SC.ALIGN_CENTER innerFrame = imageView.get('innerFrame'); equals(innerFrame.y, 30, "SC.ALIGN_CENTER top"); equals(innerFrame.x, 158.5, "SC.ALIGN_CENTER left"); if (testImg) { imgEl = imageView.$('img'); equals(imgEl.css('top'), "30px", "SC.ALIGN_CENTER top"); equals(imgEl.css('left'), "159px", "SC.ALIGN_CENTER left"); } SC.RunLoop.begin(); imageView.set('align', SC.ALIGN_TOP_LEFT); SC.RunLoop.end(); innerFrame = imageView.get('innerFrame'); equals(innerFrame.y, 0, "SC.ALIGN_TOP_LEFT top"); equals(innerFrame.x, 0, "SC.ALIGN_TOP_LEFT left"); if (testImg) { equals(imgEl.css('top'), "0px", "SC.ALIGN_TOP_LEFT top"); equals(imgEl.css('left'), "0px", "SC.ALIGN_TOP_LEFT left"); } SC.RunLoop.begin(); imageView.set('align', SC.ALIGN_TOP); SC.RunLoop.end(); innerFrame = imageView.get('innerFrame'); equals(innerFrame.y, 0, "SC.ALIGN_TOP top"); equals(innerFrame.x, 158.5, "SC.ALIGN_TOP left"); if (testImg) { equals(imgEl.css('top'), "0px", "SC.ALIGN_TOP top"); equals(imgEl.css('left'), "159px", "SC.ALIGN_TOP left"); } SC.RunLoop.begin(); imageView.set('align', SC.ALIGN_TOP_RIGHT); SC.RunLoop.end(); innerFrame = imageView.get('innerFrame'); equals(innerFrame.y, 0, "SC.ALIGN_TOP_RIGHT top"); equals(innerFrame.x, 317, "SC.ALIGN_TOP_RIGHT left"); if (testImg) { equals(imgEl.css('top'), "0px", "SC.ALIGN_TOP_RIGHT top"); equals(imgEl.css('left'), "317px", "SC.ALIGN_TOP_RIGHT left"); } SC.RunLoop.begin(); imageView.set('align', SC.ALIGN_RIGHT); SC.RunLoop.end(); innerFrame = imageView.get('innerFrame'); equals(innerFrame.y, 30, "SC.ALIGN_RIGHT top"); equals(innerFrame.x, 317, "SC.ALIGN_RIGHT left"); if (testImg) { equals(imgEl.css('top'), "30px", "SC.ALIGN_RIGHT top"); equals(imgEl.css('left'), "317px", "SC.ALIGN_RIGHT left"); } SC.RunLoop.begin(); imageView.set('align', SC.ALIGN_BOTTOM_RIGHT); SC.RunLoop.end(); innerFrame = imageView.get('innerFrame'); equals(innerFrame.y, 60, "SC.ALIGN_BOTTOM_RIGHT top"); equals(innerFrame.x, 317, "SC.ALIGN_BOTTOM_RIGHT left"); if (testImg) { equals(imgEl.css('top'), "60px", "SC.ALIGN_BOTTOM_RIGHT top"); equals(imgEl.css('left'), "317px", "SC.ALIGN_BOTTOM_RIGHT left"); } SC.RunLoop.begin(); imageView.set('align', SC.ALIGN_BOTTOM); SC.RunLoop.end(); innerFrame = imageView.get('innerFrame'); equals(innerFrame.y, 60, "SC.ALIGN_BOTTOM top"); equals(innerFrame.x, 158.5, "SC.ALIGN_BOTTOM left"); if (testImg) { equals(imgEl.css('top'), "60px", "SC.ALIGN_BOTTOM top"); equals(imgEl.css('left'), "159px", "SC.ALIGN_BOTTOM left"); } SC.RunLoop.begin(); imageView.set('align', SC.ALIGN_BOTTOM_LEFT); SC.RunLoop.end(); innerFrame = imageView.get('innerFrame'); equals(innerFrame.y, 60, "SC.ALIGN_BOTTOM_LEFT top"); equals(innerFrame.x, 0, "SC.ALIGN_BOTTOM_LEFT left"); if (testImg) { equals(imgEl.css('top'), "60px", "SC.ALIGN_BOTTOM_LEFT top"); equals(imgEl.css('left'), "0px", "SC.ALIGN_BOTTOM_LEFT left"); } SC.RunLoop.begin(); imageView.set('align', SC.ALIGN_LEFT); SC.RunLoop.end(); innerFrame = imageView.get('innerFrame'); equals(innerFrame.y, 30, "SC.ALIGN_LEFT top"); equals(innerFrame.x, 0, "SC.ALIGN_LEFT left"); if (testImg) { equals(imgEl.css('top'), "30px", "SC.ALIGN_LEFT top"); equals(imgEl.css('left'), "0px", "SC.ALIGN_LEFT left"); } window.start(); // starts the test runner }, 100); }); } test("Aligning images (img)", function() { var imageHolder = pane.view('image_holder'), imageView; // The logo is 294x60 imageView = SC.ImageView.create({ value: logoURL + "?lastmod=" + Math.round(Math.random() * 100000), layout: { top: 0, left: 0, width: 588, height: 120 }, useCanvas: NO, scale: SC.SCALE_NONE }); testAlign(imageView); imageHolder.appendChild(imageView); }); test("Aligning images (img) with static layout", function() { var imageHolder = pane.view('image_holder'), imageView; // The logo is 294x60 imageView = SC.ImageView.create({ value: logoURL + "?lastmod=" + Math.round(Math.random() * 100000), layout: { top: 0, left: 0, width: 588, height: 120 }, useCanvas: NO, useStaticLayout: YES, scale: SC.SCALE_NONE }); testAlign(imageView); imageHolder.appendChild(imageView); }); test("Aligning images (canvas)", function() { var imageHolder = pane.view('image_holder'), imageView; // The logo is 294x60 imageView = SC.ImageView.create({ value: logoURL + "?lastmod=" + Math.round(Math.random() * 100000), layout: { top: 0, left: 0, width: 588, height: 120 }, scale: SC.SCALE_NONE }); testAlign(imageView); imageHolder.appendChild(imageView); }); test("Aligning images (canvas) with static layout", function() { var imageHolder = pane.view('image_holder'), imageView; // The logo is 294x60 imageView = SC.ImageView.create({ value: logoURL + "?lastmod=" + Math.round(Math.random() * 100000), layout: { top: 0, left: 0, width: 588, height: 120 }, useStaticLayout: YES, scale: SC.SCALE_NONE }); testAlign(imageView); imageHolder.appendChild(imageView); }); test("CSS class is applied for ImageView using a sprite for value", function() { var view = pane.view('sprite_image'), viewElem = view.$('img'); ok(viewElem.hasClass('sprite-class'), "element given correct class"); SC.run(function() { view.set('value', 'another-sprite'); }); ok(!viewElem.hasClass('sprite-class'), "When value changed, element has old class removed"); ok(viewElem.hasClass('another-sprite'), "When value changed, element has new class added"); SC.run(function() { view.set('value', null); }); ok(!viewElem.hasClass('another-sprite'), "When value removed, element has old class removed"); }); })();