Best JavaScript code snippet using puppeteer
rainyday.js
Source:rainyday.js
1/**2 * Defines a new instance of the rainyday.js.3 * @param canvasid DOM id of the canvas used for rendering4 * @param sourceid DOM id of the image element used as background image5 * @param width width of the rendering6 * @param height height of the rendering7 * @param opacity opacity attribute value of the glass canvas (default: 1)8 * @param blur blur radius (default: 20)9 */10function RainyDay(canvasid, sourceid, width, height, opacity, blur) {11 this.canvasid = canvasid;12 this.canvas = document.getElementById(canvasid);13 this.sourceid = sourceid;14 this.img = document.getElementById(sourceid);15 this.opacity = opacity ? opacity : 1;16 this.blurRadius = blur ? blur : 20;17 // draw and blur the background image18 this.prepareBackground(width, height);19 this.w = this.canvas.width;20 this.h = this.canvas.height;21 // create the glass canvas22 this.prepareGlass();23 this.drops = [];24 this.animateDrops();25 // assume default reflection mechanism26 this.reflection = this.REFLECTION_MINIATURE;27 // assume default trail mechanism28 this.trail = this.TRAIL_DROPS;29 // assume default gravity30 this.gravity = this.GRAVITY_NON_LINEAR;31 // drop size threshold for the gravity algorhitm32 this.VARIABLE_GRAVITY_THRESHOLD = 3;33 // gravity angle34 this.VARIABLE_GRAVITY_ANGLE = Math.PI / 2;35 // angle variance36 this.VARIABLE_GRAVITY_ANGLE_VARIANCE = 0;37 // frames per second animation speed38 this.VARIABLE_FPS = 15;39 // context fill style when no REFLECTION_NONE is used40 this.VARIABLE_FILL_STYLE = '#8ED6FF';41 // collisions enabled by default42 this.VARIABLE_COLLISIONS = true;43 this.REFLECTION_SCALEDOWN_FACTOR = 5;44 this.REFLECTION_DROP_MAPPING_WIDTH = 200;45 this.REFLECTION_DROP_MAPPING_HEIGHT = 200;46 // assume default collision algorhitm47 this.collision = this.COLLISION_SIMPLE;48}49RainyDay.prototype.animateDrops = function() {50 var raf = window.requestAnimationFrame ||51 window.webkitRequestAnimationFrame ||52 window.mozRequestAnimationFrame ||53 function(callback) {54 window.setTimeout(callback, 1000 / this.rainyday.VARIABLE_FPS);55 };56 if (this.addDropCallback)57 this.addDropCallback();58 // |this.drops| array may be changed as we iterate over drops59 var dropsClone = this.drops.slice();60 var newDrops = [];61 for (var i = 0; i < dropsClone.length; ++i) {62 if (dropsClone[i].animate())63 newDrops.push(dropsClone[i]);64 }65 this.drops = newDrops;66 raf(this.animateDrops.bind(this));67}68/**69 * Create the helper canvas for rendering raindrop reflections.70 */71RainyDay.prototype.prepareReflections = function() {72 // new canvas73 this.reflected = document.createElement('canvas');74 this.reflected.width = this.canvas.width / this.REFLECTION_SCALEDOWN_FACTOR;75 this.reflected.height = this.canvas.height / this.REFLECTION_SCALEDOWN_FACTOR;76 var ctx = this.reflected.getContext('2d');77 ctx.drawImage(this.img, 0, 0, this.reflected.width, this.reflected.height);78};79/**80 * Create the glass canvas and position it directly over the main one.81 */82RainyDay.prototype.prepareGlass = function() {83 this.glass = document.createElement('canvas');84 this.glass.width = this.canvas.width;85 this.glass.height = this.canvas.height;86 this.context = this.glass.getContext('2d');87};88/**89 * Creates a new preset object with given attributes.90 * @param min minimum size of a drop91 * @param base base value for randomizing drop size92 * @param quan probability of selecting this preset (must be between 0 and 1)93 * @returns present object with given attributes94 */95RainyDay.prototype.preset = function(min, base, quan) {96 return {97 "min": min,98 "base": base,99 "quan": quan100 }101};102/**103 * Main function for starting rain rendering.104 * @param presets list of presets to be applied105 * @param speed speed of the animation (if not provided or 0 static image will be generated)106 */107RainyDay.prototype.rain = function(presets, speed) {108 // prepare canvas for drop reflections109 if (this.reflection != this.REFLECTION_NONE) {110 this.prepareReflections();111 }112 if (speed > 0) {113 // animation114 this.presets = presets;115 this.PRIVATE_GRAVITY_FORCE_FACTOR_Y = (this.VARIABLE_FPS * 0.005) / 25;116 this.PRIVATE_GRAVITY_FORCE_FACTOR_X = ((Math.PI / 2) - this.VARIABLE_GRAVITY_ANGLE) * (this.VARIABLE_FPS * 0.005) / 50;117 // prepare gravity matrix118 if (this.VARIABLE_COLLISIONS) {119 // calculate max radius of a drop to establish gravity matrix resolution120 var maxDropRadius = 0;121 for (var i = 0; i < presets.length; i++) {122 if (presets[i].base + presets[i].min > maxDropRadius) {123 maxDropRadius = Math.floor(presets[i].base + presets[i].min);124 }125 }126 if (maxDropRadius > 0) {127 // initialize the gravity matrix128 var mwi = Math.ceil(this.w / maxDropRadius);129 var mhi = Math.ceil(this.h / maxDropRadius);130 this.matrix = new CollisionMatrix(mwi, mhi, maxDropRadius);131 } else {132 this.VARIABLE_COLLISIONS = false;133 }134 }135 var lastExecutionTime = 0;136 this.addDropCallback = function() {137 var timestamp = new Date().getTime();138 if (timestamp - lastExecutionTime < speed)139 return;140 lastExecutionTime = timestamp;141 var context = this.canvas.getContext("2d");142 context.clearRect(0,0,this.canvas.width,this.canvas.height);143 context.drawImage(this.background, 0, 0, this.canvas.width, this.canvas.height);144 var random = Math.random();145 // select matching preset146 var preset;147 for (var i = 0; i < presets.length; i++) {148 if (random < presets[i].quan) {149 preset = presets[i];150 break;151 }152 }153 if (preset) {154 this.putDrop(new Drop(this, Math.random() * this.w, Math.random() * this.h, preset.min, preset.base));155 }156 context.save();157 context.globalAlpha = this.opacity;158 context.drawImage(this.glass, 0, 0, this.canvas.width, this.canvas.height);159 context.restore();160 }.bind(this);161 } else {162 // static picture163 for (var i = 0; i < presets.length; i++) {164 var preset = presets[i];165 for (var c = 0; c < preset.quan; ++c) {166 this.putDrop(new Drop(this, Math.random() * this.w, Math.random() * this.h, preset.min, preset.base));167 }168 }169 }170};171/**172 * Adds a new raindrop to the animation.173 * @param drop drop object to be added to the animation174 */175RainyDay.prototype.putDrop = function(drop) {176 drop.draw();177 if (this.gravity && drop.r1 > this.VARIABLE_GRAVITY_THRESHOLD) {178 if (this.VARIABLE_COLLISIONS) {179 // put on the gravity matrix180 this.matrix.update(drop);181 }182 this.drops.push(drop);183 }184};185RainyDay.prototype.clearDrop = function(drop, force) {186 var result = drop.clear(force);187 if (result) {188 var index = this.drops.indexOf(drop);189 if (index >= 0)190 this.drops.splice(index, 1);191 }192 return result;193}194/**195 * Imperfectly approximates shape of a circle.196 * @param iterations number of iterations applied to the size approximation algorithm197 * @returns list of points approximating a circle shape198 */199RainyDay.prototype.getLinepoints = function(iterations) {200 var pointList = {};201 pointList.first = {202 x: 0,203 y: 1204 };205 var lastPoint = {206 x: 1,207 y: 1208 }209 var minY = 1;210 var maxY = 1;211 var point;212 var nextPoint;213 var dx, newX, newY;214 pointList.first.next = lastPoint;215 for (var i = 0; i < iterations; i++) {216 point = pointList.first;217 while (point.next != null) {218 nextPoint = point.next;219 dx = nextPoint.x - point.x;220 newX = 0.5 * (point.x + nextPoint.x);221 newY = 0.5 * (point.y + nextPoint.y);222 newY += dx * (Math.random() * 2 - 1);223 var newPoint = {224 x: newX,225 y: newY226 };227 //min, max228 if (newY < minY) {229 minY = newY;230 } else if (newY > maxY) {231 maxY = newY;232 }233 //put between points234 newPoint.next = nextPoint;235 point.next = newPoint;236 point = nextPoint;237 }238 }239 //normalize to values between 0 and 1240 if (maxY != minY) {241 var normalizeRate = 1 / (maxY - minY);242 point = pointList.first;243 while (point != null) {244 point.y = normalizeRate * (point.y - minY);245 point = point.next;246 }247 } else {248 point = pointList.first;249 while (point != null) {250 point.y = 1;251 point = point.next;252 }253 }254 return pointList;255};256/**257 * Defines a new raindrop object.258 * @param rainyday reference to the parent object259 * @param centerX x position of the center of this drop260 * @param centerY y position of the center of this drop261 * @param min minimum size of a drop262 * @param base base value for randomizing drop size263 */264function Drop(rainyday, centerX, centerY, min, base) {265 this.x = Math.floor(centerX);266 this.y = Math.floor(centerY);267 this.r1 = (Math.random() * base) + min;268 this.rainyday = rainyday;269 var iterations = 4;270 this.r2 = 0.8 * this.r1;271 this.linepoints = rainyday.getLinepoints(iterations);272 this.context = rainyday.context;273 this.reflection = rainyday.reflected;274}275/**276 * Draws a raindrop on canvas at the current position.277 */278Drop.prototype.draw = function() {279 var phase = 0;280 var point;281 var rad, theta;282 var x0, y0;283 this.context.save();284 this.context.beginPath();285 point = this.linepoints.first;286 theta = phase;287 rad = this.r2 + 0.5 * Math.random() * (this.r2 - this.r1);288 x0 = this.x + rad * Math.cos(theta);289 y0 = this.y + rad * Math.sin(theta);290 this.context.lineTo(x0, y0);291 while (point.next != null) {292 point = point.next;293 theta = (Math.PI * 2 * point.x) + phase;294 rad = this.r2 + 0.5 * Math.random() * (this.r2 - this.r1);295 x0 = this.x + rad * Math.cos(theta);296 y0 = this.y + rad * Math.sin(theta);297 this.context.lineTo(x0, y0);298 }299 this.context.clip();300 if (this.rainyday.reflection) {301 this.rainyday.reflection(this);302 }303 this.context.restore();304};305/**306 * Clears the raindrop region.307 * @param force force stop308 * @returns true if the animation is stopped309 */310Drop.prototype.clear = function(force) {311 this.context.clearRect(this.x - this.r1 - 1, this.y - this.r1 - 1, 2 * this.r1 + 2, 2 * this.r1 + 2);312 if (force) {313 // forced314 this.terminate = true;315 return true;316 }317 if (this.y - this.r1 > this.rainyday.h) {318 // over the bottom edge, stop the thread319 return true;320 }321 if ((this.x - this.r1 > this.rainyday.w) || (this.x + this.r1 < 0)) {322 // over the right or left edge, stop the thread323 return true;324 }325 return false;326};327/**328 * Moves the raindrop to a new position according to the gravity.329 */330Drop.prototype.animate = function() {331 if (this.terminate) {332 return false;333 }334 var stopped = this.rainyday.gravity(this);335 if (!stopped && this.rainyday.trail) {336 this.rainyday.trail(this);337 }338 if (this.rainyday.VARIABLE_COLLISIONS) {339 var collisions = this.rainyday.matrix.update(this, stopped);340 if (collisions) {341 this.rainyday.collision(this, collisions);342 }343 }344 return !stopped || this.terminate345};346/**347 * Merge linepoints with another drop348 * @param drop the other drop349 */350Drop.prototype.merge = function(drop) {351};352/**353 * TRAIL function: no trail at all354 * @param drop raindrop object355 */356RainyDay.prototype.TRAIL_NONE = function(drop) {357 // nothing going on here358};359/**360 * TRAIL function: trail of small drops (default)361 * @param drop raindrop object362 */363RainyDay.prototype.TRAIL_DROPS = function(drop) {364 if (!drop.trail_y || drop.y - drop.trail_y >= Math.random() * 10 * drop.r1) {365 drop.trail_y = drop.y;366 this.putDrop(new Drop(this, drop.x, drop.y - drop.r1 - 5, 0, Math.ceil(drop.r1 / 5)));367 }368};369/**370 * TRAIL function: trail of unblurred image371 * @param drop raindrop object372 */373RainyDay.prototype.TRAIL_SMUDGE = function(drop) {374 var context = this.canvas.getContext('2d');375 var y = drop.y - drop.r1 - 2;376 var x = drop.x - drop.r2 + (Math.random() * 2);377 if (y < 0 || x < 0) {378 return;379 }380 var w = drop.r2;381 this.context.drawImage(this.img,382 // coordinates of source image383 (x * this.img.width) / this.w, (y * this.img.height) / this.h, w, 2,384 // destination385 x, y, w, 2);386};387/**388 * GRAVITY function: no gravity at all389 * @param drop raindrop object390 * @returns true if the animation is stopped391 */392RainyDay.prototype.GRAVITY_NONE = function(drop) {393 return true;394};395/**396 * GRAVITY function: linear gravity397 * @param drop raindrop object398 * @returns true if the animation is stopped399 */400RainyDay.prototype.GRAVITY_LINEAR = function(drop) {401 if (this.clearDrop(drop)) {402 return true;403 }404 if (drop.yspeed) {405 drop.yspeed += this.PRIVATE_GRAVITY_FORCE_FACTOR_Y * Math.floor(drop.r1);406 drop.xspeed += this.PRIVATE_GRAVITY_FORCE_FACTOR_X * Math.floor(drop.r1);407 } else {408 drop.yspeed = this.PRIVATE_GRAVITY_FORCE_FACTOR_Y;409 drop.xspeed = this.PRIVATE_GRAVITY_FORCE_FACTOR_X;410 }411 drop.y += drop.yspeed;412 drop.draw();413 return false;414};415/**416 * GRAVITY function: non-linear gravity (default)417 * @param drop raindrop object418 * @returns true if the animation is stopped419 */420RainyDay.prototype.GRAVITY_NON_LINEAR = function(drop) {421 if (this.clearDrop(drop)) {422 return true;423 }424 if (drop.collided) {425 drop.collided = false;426 drop.seed = Math.floor(drop.r1 * Math.random() * this.VARIABLE_FPS);427 drop.skipping = false;428 drop.slowing = false;429 } else if (!drop.seed || drop.seed < 0) {430 drop.seed = Math.floor(drop.r1 * Math.random() * this.VARIABLE_FPS);431 drop.skipping = drop.skipping == false ? true : false;432 drop.slowing = true;433 }434 drop.seed--;435 if (drop.yspeed) {436 if (drop.slowing) {437 drop.yspeed /= 1.1;438 drop.xspeed /= 1.1;439 if (drop.yspeed < this.PRIVATE_GRAVITY_FORCE_FACTOR_Y) {440 drop.slowing = false;441 }442 } else if (drop.skipping) {443 drop.yspeed = this.PRIVATE_GRAVITY_FORCE_FACTOR_Y;444 drop.xspeed = this.PRIVATE_GRAVITY_FORCE_FACTOR_X;445 } else {446 drop.yspeed += 1 * this.PRIVATE_GRAVITY_FORCE_FACTOR_Y * Math.floor(drop.r1);447 drop.xspeed += 1 * this.PRIVATE_GRAVITY_FORCE_FACTOR_X * Math.floor(drop.r1);448 }449 } else {450 drop.yspeed = this.PRIVATE_GRAVITY_FORCE_FACTOR_Y;451 drop.xspeed = this.PRIVATE_GRAVITY_FORCE_FACTOR_X;452 }453 if (this.VARIABLE_GRAVITY_ANGLE_VARIANCE != 0) {454 drop.xspeed += ((Math.random() * 2 - 1) * this.VARIABLE_GRAVITY_ANGLE_VARIANCE);455 }456 drop.y += drop.yspeed;457 drop.x += drop.xspeed;458 drop.draw();459 return false;460};461/**462 * REFLECTION function: no reflection at all463 * @param drop raindrop object464 */465RainyDay.prototype.REFLECTION_NONE = function(drop) {466 this.context.fillStyle = this.VARIABLE_FILL_STYLE;467 this.context.fill();468};469/**470 * REFLECTION function: miniature reflection (default)471 * @param drop raindrop object472 */473RainyDay.prototype.REFLECTION_MINIATURE = function(drop) {474 // this maps the area of size (REFLECTION_DROP_MAPPING_WIDTH * 2, REFLECTION_DROP_MAPPING_HEIGHT * 2)475 // around point (drop.x, drop.y) into the drop area476 var sx = Math.max((drop.x - this.REFLECTION_DROP_MAPPING_WIDTH) / this.REFLECTION_SCALEDOWN_FACTOR, 0);477 var sy = Math.max((drop.y - this.REFLECTION_DROP_MAPPING_HEIGHT) / this.REFLECTION_SCALEDOWN_FACTOR, 0);478 var sw = Math.min(this.REFLECTION_DROP_MAPPING_WIDTH * 2 / this.REFLECTION_SCALEDOWN_FACTOR, this.reflected.width - sx);479 var sh = Math.min(this.REFLECTION_DROP_MAPPING_HEIGHT * 2 / this.REFLECTION_SCALEDOWN_FACTOR, this.reflected.height - sy);480 this.context.drawImage(this.reflected,481 // coordinates of source image482 sx, sy, sw, sh,483 // destination484 drop.x - drop.r1,485 drop.y - drop.r1,486 drop.r1 * 2,487 drop.r1 * 2);488};489/**490 * COLLISION function: default collision implementation491 * @param drop one of the drops colliding492 * @param colllisions list of potential collisions493 */494RainyDay.prototype.COLLISION_SIMPLE = function(drop, collisions) {495 var item = collisions;496 var drop2;497 while (item != null) {498 var p = item.drop;499 if (Math.sqrt(Math.pow(drop.x - p.x, 2) + Math.pow(drop.y - p.y, 2)) < (drop.r1 + p.r1)) {500 drop2 = p;501 break;502 }503 item = item.next;504 }505 if (!drop2) {506 return;507 }508 // rename so that we're dealing with low/high drops509 var higher, lower;510 if (drop.y > drop2.y) {511 higher = drop;512 lower = drop2;513 } else {514 higher = drop2;515 lower = drop;516 }517 this.clearDrop(lower);518 // force stopping the second drop519 this.clearDrop(higher, true);520 lower.draw();521 // combine linepoints522 higher.merge(lower);523 lower.r1 = 0.8 * Math.sqrt((lower.r1 * lower.r1) + (higher.r2 * higher.r2));524 lower.r2 = 0.8 * lower.r1;525 lower.collided = true;526};527var mul_table = [528 512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512,529 454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512,530 482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456,531 437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512,532 497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328,533 320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456,534 446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335,535 329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512,536 505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405,537 399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328,538 324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271,539 268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456,540 451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388,541 385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335,542 332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292,543 289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259544];545var shg_table = [546 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17,547 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19,548 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20,549 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,550 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,551 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22,552 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,553 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23,554 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,555 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,556 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,557 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,558 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,559 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,560 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,561 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24562];563/**564 * Resizes canvas, draws original image and applies bluring algorithm.565 * @param width width of the canvas566 * @param height height of the canvas567 */568RainyDay.prototype.prepareBackground = function(width, height) {569 if (width && height) {570 this.canvas.style.width = width + "px";571 this.canvas.style.height = height + "px";572 this.canvas.width = width;573 this.canvas.height = height;574 } else {575 width = this.canvas.width;576 height = this.canvas.height;577 }578 this.background = document.createElement('canvas');579 this.background.width = this.canvas.width;580 this.background.height = this.canvas.height;581 var context = this.background.getContext("2d");582 context.clearRect(0, 0, width, height);583 context.drawImage(this.img, 0, 0, width, height);584 if (isNaN(this.blurRadius) || this.blurRadius < 1) return;585 this.stackBlurCanvasRGB(0, 0, width, height, this.blurRadius);586};587/**588 * Implements the Stack Blur Algorithm (@see http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html).589 * @param top_x x of top-left corner of the blurred rectangle590 * @param top_y y of top-left corner of the blurred rectangle591 * @param width width of the canvas592 * @param height height of the canvas593 * @param radius blur radius594 */595RainyDay.prototype.stackBlurCanvasRGB = function(top_x, top_y, width, height, radius) {596 radius |= 0;597 var context = this.background.getContext("2d");598 var imageData = context.getImageData(top_x, top_y, width, height);599 var pixels = imageData.data;600 var x, y, i, p, yp, yi, yw, r_sum, g_sum, b_sum,601 r_out_sum, g_out_sum, b_out_sum,602 r_in_sum, g_in_sum, b_in_sum,603 pr, pg, pb, rbs;604 var div = radius + radius + 1;605 var w4 = width << 2;606 var widthMinus1 = width - 1;607 var heightMinus1 = height - 1;608 var radiusPlus1 = radius + 1;609 var sumFactor = radiusPlus1 * (radiusPlus1 + 1) / 2;610 var stackStart = new BlurStack();611 var stack = stackStart;612 for (i = 1; i < div; i++) {613 stack = stack.next = new BlurStack();614 if (i == radiusPlus1) var stackEnd = stack;615 }616 stack.next = stackStart;617 var stackIn = null;618 var stackOut = null;619 yw = yi = 0;620 var mul_sum = mul_table[radius];621 var shg_sum = shg_table[radius];622 for (y = 0; y < height; y++) {623 r_in_sum = g_in_sum = b_in_sum = r_sum = g_sum = b_sum = 0;624 r_out_sum = radiusPlus1 * (pr = pixels[yi]);625 g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]);626 b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]);627 r_sum += sumFactor * pr;628 g_sum += sumFactor * pg;629 b_sum += sumFactor * pb;630 stack = stackStart;631 for (i = 0; i < radiusPlus1; i++) {632 stack.r = pr;633 stack.g = pg;634 stack.b = pb;635 stack = stack.next;636 }637 for (i = 1; i < radiusPlus1; i++) {638 p = yi + ((widthMinus1 < i ? widthMinus1 : i) << 2);639 r_sum += (stack.r = (pr = pixels[p])) * (rbs = radiusPlus1 - i);640 g_sum += (stack.g = (pg = pixels[p + 1])) * rbs;641 b_sum += (stack.b = (pb = pixels[p + 2])) * rbs;642 r_in_sum += pr;643 g_in_sum += pg;644 b_in_sum += pb;645 stack = stack.next;646 }647 stackIn = stackStart;648 stackOut = stackEnd;649 for (x = 0; x < width; x++) {650 pixels[yi] = (r_sum * mul_sum) >> shg_sum;651 pixels[yi + 1] = (g_sum * mul_sum) >> shg_sum;652 pixels[yi + 2] = (b_sum * mul_sum) >> shg_sum;653 r_sum -= r_out_sum;654 g_sum -= g_out_sum;655 b_sum -= b_out_sum;656 r_out_sum -= stackIn.r;657 g_out_sum -= stackIn.g;658 b_out_sum -= stackIn.b;659 p = (yw + ((p = x + radius + 1) < widthMinus1 ? p : widthMinus1)) << 2;660 r_in_sum += (stackIn.r = pixels[p]);661 g_in_sum += (stackIn.g = pixels[p + 1]);662 b_in_sum += (stackIn.b = pixels[p + 2]);663 r_sum += r_in_sum;664 g_sum += g_in_sum;665 b_sum += b_in_sum;666 stackIn = stackIn.next;667 r_out_sum += (pr = stackOut.r);668 g_out_sum += (pg = stackOut.g);669 b_out_sum += (pb = stackOut.b);670 r_in_sum -= pr;671 g_in_sum -= pg;672 b_in_sum -= pb;673 stackOut = stackOut.next;674 yi += 4;675 }676 yw += width;677 }678 for (x = 0; x < width; x++) {679 g_in_sum = b_in_sum = r_in_sum = g_sum = b_sum = r_sum = 0;680 yi = x << 2;681 r_out_sum = radiusPlus1 * (pr = pixels[yi]);682 g_out_sum = radiusPlus1 * (pg = pixels[yi + 1]);683 b_out_sum = radiusPlus1 * (pb = pixels[yi + 2]);684 r_sum += sumFactor * pr;685 g_sum += sumFactor * pg;686 b_sum += sumFactor * pb;687 stack = stackStart;688 for (i = 0; i < radiusPlus1; i++) {689 stack.r = pr;690 stack.g = pg;691 stack.b = pb;692 stack = stack.next;693 }694 yp = width;695 for (i = 1; i <= radius; i++) {696 yi = (yp + x) << 2;697 r_sum += (stack.r = (pr = pixels[yi])) * (rbs = radiusPlus1 - i);698 g_sum += (stack.g = (pg = pixels[yi + 1])) * rbs;699 b_sum += (stack.b = (pb = pixels[yi + 2])) * rbs;700 r_in_sum += pr;701 g_in_sum += pg;702 b_in_sum += pb;703 stack = stack.next;704 if (i < heightMinus1) {705 yp += width;706 }707 }708 yi = x;709 stackIn = stackStart;710 stackOut = stackEnd;711 for (y = 0; y < height; y++) {712 p = yi << 2;713 pixels[p] = (r_sum * mul_sum) >> shg_sum;714 pixels[p + 1] = (g_sum * mul_sum) >> shg_sum;715 pixels[p + 2] = (b_sum * mul_sum) >> shg_sum;716 r_sum -= r_out_sum;717 g_sum -= g_out_sum;718 b_sum -= b_out_sum;719 r_out_sum -= stackIn.r;720 g_out_sum -= stackIn.g;721 b_out_sum -= stackIn.b;722 p = (x + (((p = y + radiusPlus1) < heightMinus1 ? p : heightMinus1) * width)) << 2;723 r_sum += (r_in_sum += (stackIn.r = pixels[p]));724 g_sum += (g_in_sum += (stackIn.g = pixels[p + 1]));725 b_sum += (b_in_sum += (stackIn.b = pixels[p + 2]));726 stackIn = stackIn.next;727 r_out_sum += (pr = stackOut.r);728 g_out_sum += (pg = stackOut.g);729 b_out_sum += (pb = stackOut.b);730 r_in_sum -= pr;731 g_in_sum -= pg;732 b_in_sum -= pb;733 stackOut = stackOut.next;734 yi += width;735 }736 }737 context.putImageData(imageData, top_x, top_y);738};739/**740 * Defines a new helper object for Stack Blur Algorithm.741 */742function BlurStack() {743 this.r = 0;744 this.g = 0;745 this.b = 0;746 this.a = 0;747 this.next = null;748}749/**750 * Defines a gravity matrix object which handles collision detection.751 * @param x number of columns in the matrix752 * @param y number of rows in the matrix753 * @param r grid size754 */755function CollisionMatrix(x, y, r) {756 this.resolution = r;757 this.xc = x;758 this.yc = y;759 this.matrix = new Array(x);760 for (var i = 0; i <= (x + 5); i++) {761 this.matrix[i] = Array(y);762 for (var j = 0; j <= (y + 5); ++j) {763 this.matrix[i][j] = new DropItem(null);764 }765 }766}767/**768 * Updates position of the given drop on the collision matrix.769 * @param drop raindrop to be positioned/repositioned770 * @forceDelete if true the raindrop will be removed from the matrix771 * @returns collisions if any772 */773CollisionMatrix.prototype.update = function(drop, forceDelete) {774 if (drop.gid) {775 this.matrix[drop.gmx][drop.gmy].remove(drop);776 if (forceDelete) {777 return null;778 }779 drop.gmx = Math.floor(drop.x / this.resolution);780 drop.gmy = Math.floor(drop.y / this.resolution);781 this.matrix[drop.gmx][drop.gmy].add(drop);782 var collisions = this.collisions(drop);783 if (collisions && collisions.next != null) {784 return collisions.next;785 }786 } else {787 drop.gid = Math.random().toString(36).substr(2, 9);788 drop.gmx = Math.floor(drop.x / this.resolution);789 drop.gmy = Math.floor(drop.y / this.resolution);790 this.matrix[drop.gmx][drop.gmy].add(drop);791 }792 return null;793};794/**795 * Looks for collisions with the given raindrop.796 * @param drop raindrop to be checked797 * @returns list of drops that collide with it798 */799CollisionMatrix.prototype.collisions = function(drop) {800 var item = new DropItem(null);801 var first = item;802 item = this.addAll(item, drop.gmx - 1, drop.gmy + 1);803 item = this.addAll(item, drop.gmx, drop.gmy + 1);804 item = this.addAll(item, drop.gmx + 1, drop.gmy + 1);805 return first;806};807/**808 * Appends all found drop at a given location to the given item.809 * @param to item to which the results will be appended to810 * @param x x position in the matrix811 * @param y y position in the matrix812 * @returns last discovered item on the list813 */814CollisionMatrix.prototype.addAll = function(to, x, y) {815 if (x > 0 && y > 0 && x < this.xc && y < this.yc) {816 var items = this.matrix[x][y];817 while (items.next != null) {818 items = items.next;819 to.next = new DropItem(items.drop);820 to = to.next;821 }822 }823 return to;824};825/**826 * Defines a linked list item.827 */828function DropItem(drop) {829 this.drop = drop;830 this.next = null;831}832/**833 * Adds the raindrop to the end of the list.834 * @param drop raindrop to be added835 */836DropItem.prototype.add = function(drop) {837 var item = this;838 while (item.next != null) {839 item = item.next;840 }841 item.next = new DropItem(drop);842};843/**844 * Removes the raindrop from the list.845 * @param drop raindrop to be removed846 */847DropItem.prototype.remove = function(drop) {848 var item = this;849 var prevItem = null;850 while (item.next != null) {851 prevItem = item;852 item = item.next;853 if (item.drop.gid == drop.gid) {854 prevItem.next = item.next;855 }856 }...
DragAndDrop.js
Source:DragAndDrop.js
1/*!2 * ${copyright}3 */4sap.ui.define([5 "sap/ui/Device",6 "../UIArea",7 "sap/ui/thirdparty/jquery",8 // jQuery Plugin "control"9 "sap/ui/dom/jquery/control"10],11function(Device, UIArea, jQuery) {12 "use strict";13 var DnD = {},14 oDragControl = null, // the control being dragged15 oDropControl = null, // the current drop target control16 oValidDropControl = null, // the control which the dragged control can be dropped on based on the valid drop info17 aValidDragInfos = [], // valid DragInfos configured for the currently dragged source18 aValidDropInfos = [], // valid DropInfos configured for the current drop target19 oDragSession = null, // stores active drag session throughout a drag activity20 $DropIndicator, // drop position indicator21 $GhostContainer, // container to place custom ghosts22 sCalculatedDropPosition, // calculated position of the drop action relative to the valid dropped control.23 iTargetEnteringTime; // timestamp of drag enter24 function addStyleClass(oElement, sStyleClass) {25 if (!oElement) {26 return;27 }28 if (oElement.addStyleClass) {29 oElement.addStyleClass(sStyleClass);30 } else {31 oElement.$().addClass(sStyleClass);32 }33 }34 function removeStyleClass(oElement, sStyleClass) {35 if (!oElement) {36 return;37 }38 if (oElement.removeStyleClass) {39 oElement.removeStyleClass(sStyleClass);40 } else {41 oElement.$().removeClass(sStyleClass);42 }43 }44 function dispatchEvent(oEvent, sEventName) {45 var oControl = jQuery(oEvent.target).control(0, true);46 if (!oControl) {47 return;48 }49 var oNewEvent = jQuery.Event(null, oEvent);50 oNewEvent.type = sEventName;51 oControl.getUIArea()._handleEvent(oNewEvent);52 }53 function setDragGhost(oDragControl, oEvent) {54 if (Device.browser.msie || !oDragControl || !oDragControl.getDragGhost) {55 return;56 }57 var oDragGhost = oDragControl.getDragGhost();58 if (!oDragGhost) {59 return;60 }61 if (!$GhostContainer) {62 $GhostContainer = jQuery('<div class="sapUiDnDGhostContainer"></div>');63 jQuery(document.body).append($GhostContainer);64 }65 $GhostContainer.append(oDragGhost);66 window.setTimeout(function() { $GhostContainer.empty(); }, 0);67 var oOriginalEvent = oEvent.originalEvent;68 oOriginalEvent.dataTransfer.setDragImage(oDragGhost, oOriginalEvent.offsetX, oOriginalEvent.offsetY);69 }70 function createDragSession(oEvent) {71 var mData = {},72 mIndicatorConfig,73 oDataTransfer = oEvent.originalEvent.dataTransfer,74 setTransferData = function(sType, sData) {75 // set to original dataTransfer object if type is supported by the current browser (non-text causes error in IE+Edge)76 if (oDataTransfer && sType == "text" || (Device.browser != "msie" && Device.browser != "edge")) {77 oDataTransfer.setData(sType, sData);78 }79 };80 /**81 * When a user requests to drag some controls that can be dragged, a drag session is started.82 * The drag session can be used to transfer data between applications or between dragged and dropped controls.83 * Please see provided APIs for more details.84 *85 * <b>Note:</b> This object only exists during a drag-and-drop operation.86 *87 * @namespace88 * @name sap.ui.core.dnd.DragSession89 * @static90 * @abstract91 * @public92 */93 return /** @lends sap.ui.core.dnd.DragSession */ {94 /**95 * Sets string data with any MIME type.96 * <b>Note:</b> This works in all browsers, apart from Internet Explorer and Microsoft Edge. It also works if you navigate between97 * different windows.98 *99 * @param {string} sKey The key of the data100 * @param {string} sData Data101 * @public102 */103 setData: function(sKey, sData) {104 sData = "" + sData;105 mData[sKey] = sData;106 setTransferData(sKey, sData);107 },108 /**109 * Returns the data that has been set via <code>setData</code> method.110 *111 * @param {string} sKey The key of the data112 * @returns {string} Data113 * @public114 */115 getData: function(sKey) {116 return mData[sKey];117 },118 /**119 * Sets string data with plain text MIME type.120 * <b>Note:</b> This works in all browsers, including Internet Explorer and Microsoft Edge. It also works if you navigate between121 * different windows.122 *123 * @param {string} sData Data124 * @public125 */126 setTextData: function(sData) {127 sData = "" + sData;128 mData["text/plain"] = sData;129 mData["text"] = sData;130 setTransferData("text/plain", sData);131 setTransferData("text", sData);132 },133 /**134 * Returns the data that has been set via <code>setTextData</code> method.135 *136 * @returns {string} Data137 * @public138 */139 getTextData: function() {140 return mData["text/plain"];141 },142 /**143 * Sets any type of data (even functions, pointers, anything non-serializable) with any MIME type.144 * This works in all browsers, including Internet Explorer and Microsoft Edge, but only within a UI5 application within the same145 * window/frame.146 *147 * @param {string} sKey The key of the data148 * @param {any} vData Data149 */150 setComplexData: function(sKey, vData) {151 mData[sKey] = vData;152 },153 /**154 * Returns the data that has been set via <code>setComplexData</code> method.155 *156 * @param {string} sKey The key of the data157 * @returns {any} The previously set data or undefined158 * @public159 */160 getComplexData: function(sKey) {161 return mData[sKey];162 },163 /**164 * Returns the drop indicator.165 *166 * @returns {HTMLElement|null} Drop indicator's DOM reference167 * @protected168 */169 getIndicator: function() {170 return $DropIndicator && $DropIndicator[0];171 },172 /**173 * Defines the visual configuration of the drop indicator for the current <code>DropInfo</code>.174 *175 * @param {object} mConfig Custom styles of the drop indicator.176 * @protected177 */178 setIndicatorConfig: function(mConfig) {179 mIndicatorConfig = mConfig;180 },181 /**182 * Returns the visual configuration of the drop indicator.183 *184 * @returns {object} Drop indicator configuration185 * @protected186 */187 getIndicatorConfig: function(mConfig) {188 return mIndicatorConfig;189 },190 /**191 * Returns the dragged control, if available within the same UI5 application frame.192 *193 * @returns {sap.ui.core.Element|null}194 * @protected195 */196 getDragControl: function() {197 return oDragControl;198 },199 /**200 * The valid drop target underneath the dragged control.201 *202 * @returns {sap.ui.core.Element|null}203 * @protected204 */205 getDropControl: function() {206 return oValidDropControl;207 },208 /**209 * Set the valid drop control.210 *211 * @protected212 */213 setDropControl: function(oControl) {214 oValidDropControl = oControl;215 },216 /**217 * Returns the drop configuration corresponding to the drop control.218 *219 * @returns {sap.ui.core.dnd.DropInfo|null}220 * @protected221 */222 getDropInfo: function() {223 return aValidDropInfos[0] || null;224 },225 /**226 * Returns the calculated position of the drop action relative to the valid dropped control.227 *228 * @returns {String}229 * @protected230 */231 getDropPosition: function() {232 return sCalculatedDropPosition;233 }234 };235 }236 function closeDragSession(oEvent) {237 hideDropIndicator();238 removeStyleClass(oDragControl, "sapUiDnDDragging");239 oDragControl = oDropControl = oValidDropControl = oDragSession = null;240 sCalculatedDropPosition = "";241 aValidDragInfos = [];242 aValidDropInfos = [];243 }244 function getDropIndicator() {245 if ($DropIndicator) {246 return $DropIndicator;247 }248 $DropIndicator = jQuery("<div class='sapUiDnDIndicator'></div>");249 jQuery(sap.ui.getCore().getStaticAreaRef()).append($DropIndicator);250 return $DropIndicator;251 }252 function hideDropIndicator() {253 if ($DropIndicator) {254 $DropIndicator.removeAttr("style").hide();255 }256 }257 function showDropIndicator(oEvent, oDropTarget, sDropPosition, sDropLayout) {258 if (!oDropTarget) {259 return;260 }261 var mIndicatorConfig = oEvent.dragSession && oEvent.dragSession.getIndicatorConfig(),262 mClientRect = oDropTarget.getBoundingClientRect(),263 iPageYOffset = window.pageYOffset,264 iPageXOffset = window.pageXOffset,265 $Indicator = getDropIndicator(),266 sRelativePosition,267 mStyle = {},268 mDropRect = {269 top: mClientRect.top + iPageYOffset,270 bottom: mClientRect.bottom + iPageYOffset,271 left: mClientRect.left + iPageXOffset,272 right: mClientRect.right + iPageXOffset,273 width: mClientRect.width,274 height: mClientRect.height275 };276 if (!sDropPosition || sDropPosition == "On") {277 sRelativePosition = "On";278 sDropLayout = "";279 } else if (sDropLayout == "Horizontal") {280 var iCursorX = oEvent.pageX - mDropRect.left;281 mStyle.height = mDropRect.height;282 mStyle.top = mDropRect.top;283 if (sDropPosition == "Between") {284 mStyle.width = "";285 if (iCursorX < mDropRect.width * 0.5) {286 sRelativePosition = "Before";287 mStyle.left = mDropRect.left;288 } else {289 sRelativePosition = "After";290 mStyle.left = mDropRect.right;291 }292 } else if (sDropPosition == "OnOrBetween") {293 if (iCursorX < mDropRect.width * 0.25) {294 sRelativePosition = "Before";295 mStyle.left = mDropRect.left;296 mStyle.width = "";297 } else if (iCursorX > mDropRect.width * 0.75) {298 sRelativePosition = "After";299 mStyle.left = mDropRect.right;300 mStyle.width = "";301 } else {302 sRelativePosition = "On";303 }304 }305 } else {306 var iCursorY = oEvent.pageY - mDropRect.top;307 mStyle.width = mDropRect.width;308 mStyle.left = mDropRect.left;309 if (sDropPosition == "Between") {310 mStyle.height = "";311 if (iCursorY < mDropRect.height * 0.5) {312 sRelativePosition = "Before";313 mStyle.top = mDropRect.top;314 } else {315 sRelativePosition = "After";316 mStyle.top = mDropRect.bottom;317 }318 } else if (sDropPosition == "OnOrBetween") {319 if (iCursorY < mDropRect.height * 0.25) {320 sRelativePosition = "Before";321 mStyle.top = mDropRect.top;322 mStyle.height = "";323 } else if (iCursorY > mDropRect.height * 0.75) {324 sRelativePosition = "After";325 mStyle.top = mDropRect.bottom;326 mStyle.height = "";327 } else {328 sRelativePosition = "On";329 }330 }331 }332 if (mIndicatorConfig && mIndicatorConfig.display == "none") {333 return sRelativePosition;334 }335 if (sRelativePosition == "On") {336 mStyle.top = mDropRect.top;337 mStyle.left = mDropRect.left;338 mStyle.width = mDropRect.width;339 mStyle.height = mDropRect.height;340 sDropPosition = sRelativePosition;341 } else {342 sDropPosition = "Between";343 }344 $Indicator.attr("data-drop-layout", sDropLayout);345 $Indicator.attr("data-drop-position", sDropPosition);346 $Indicator.css(jQuery.extend(mStyle, mIndicatorConfig)).show();347 return sRelativePosition;348 }349 function getDragDropConfigs(oControl) {350 var oParent = oControl.getParent(),351 aSelfConfigs = (oControl.getDragDropConfig) ? oControl.getDragDropConfig() : [],352 aParentConfigs = (oParent && oParent.getDragDropConfig) ? oParent.getDragDropConfig() : [];353 return aSelfConfigs.concat(aParentConfigs);354 }355 function getValidDragInfos(oDragControl) {356 var aDragDropConfigs = getDragDropConfigs(oDragControl);357 return aDragDropConfigs.filter(function(oDragOrDropInfo) {358 return oDragOrDropInfo.isDraggable(oDragControl);359 });360 }361 function getValidDropInfos(oDropControl, aDragInfos, oEvent) {362 var aDragDropConfigs = getDragDropConfigs(oDropControl);363 aDragInfos = aDragInfos || [];364 return aDragDropConfigs.filter(function(oDragOrDropInfo) {365 // DragDropInfo defined at the drop target is irrelevant we only need DropInfos366 return !oDragOrDropInfo.isA("sap.ui.core.dnd.IDragInfo");367 }).concat(aDragInfos).filter(function(oDropInfo) {368 if (!oDropInfo.isDroppable(oDropControl, oEvent)) {369 return false;370 }371 // master group matches always372 var sDropGroupName = oDropInfo.getGroupName();373 if (!sDropGroupName) {374 return true;375 }376 // group name matching377 return aDragInfos.some(function(oDragInfo) {378 return oDragInfo.getGroupName() == sDropGroupName;379 });380 });381 }382 function setDropEffect(oEvent, oDropInfo) {383 // allow dropping384 oEvent.preventDefault();385 // set visual drop indicator from drop info386 var sDropEffect = oDropInfo.getDropEffect().toLowerCase();387 oEvent.originalEvent.dataTransfer.dropEffect = sDropEffect;388 }389 function showDropPosition(oEvent, oDropInfo, oValidDropControl) {390 // no target aggregation so entire control is the target391 var sTargetAggregation = oDropInfo.getTargetAggregation();392 if (!sTargetAggregation) {393 return showDropIndicator(oEvent, oValidDropControl.getDomRef());394 }395 // whether the current DOM element corresponds to the configured aggregation396 var oTargetDomRef;397 if (oEvent.getMark("DragWithin") == sTargetAggregation) {398 oTargetDomRef = oValidDropControl.getDomRefForSetting(sTargetAggregation);399 }400 // not dragging over an aggregated child of the element401 oTargetDomRef = oTargetDomRef || oValidDropControl.getDomRef();402 // let the user know the drop position403 return showDropIndicator(oEvent, oTargetDomRef, oDropInfo.getDropPosition(true), oDropInfo.getDropLayout(true));404 }405 // before controls handle UIArea events406 DnD.preprocessEvent = function(oEvent) {407 if (oDragSession && oEvent.type.indexOf("dr") == 0) {408 // attach dragSession to all drag events409 oEvent.dragSession = oDragSession;410 }411 var sEventHandler = "onbefore" + oEvent.type;412 if (DnD[sEventHandler]) {413 DnD[sEventHandler](oEvent);414 }415 };416 // after controls handle UIArea events417 DnD.postprocessEvent = function(oEvent) {418 var sEventHandler = "onafter" + oEvent.type;419 if (DnD[sEventHandler]) {420 DnD[sEventHandler](oEvent);421 }422 };423 DnD.onbeforedragstart = function(oEvent) {424 // draggable implicitly425 if (!oEvent.target.draggable) {426 return;427 }428 // the text inside input fields should still be selectable429 if (/^(input|textarea)$/i.test(document.activeElement.tagName)) {430 return;431 }432 // identify the control being dragged433 oDragControl = jQuery(oEvent.target).control(0, true);434 if (!oDragControl) {435 return;436 }437 // identify and remember the applicable DragInfos438 aValidDragInfos = getValidDragInfos(oDragControl);439 if (!aValidDragInfos.length) {440 return;441 }442 // firefox needs data set to allow dragging443 if (Device.browser.firefox && oEvent.originalEvent.dataTransfer.types.length === 0) {444 oEvent.originalEvent.dataTransfer.setData("ui5/dummyDataForFirefox", "data");445 }446 // create the drag session object and attach to the event447 oEvent.dragSession = oDragSession = createDragSession(oEvent);448 };449 DnD.onafterdragstart = function(oEvent) {450 // drag is not possible if preventDefault is called for dragstart event451 if (!aValidDragInfos.length || oEvent.isDefaultPrevented()) {452 closeDragSession();453 return;454 }455 // fire dragstart event of valid DragInfos and filter if preventDefault is called456 aValidDragInfos = oEvent.isMarked("NonDraggable") ? [] : aValidDragInfos.filter(function(oDragInfo) {457 return oDragInfo.fireDragStart(oEvent);458 });459 // check whether drag is possible460 if (!aValidDragInfos.length) {461 oEvent.preventDefault();462 closeDragSession();463 return;464 }465 // set custom drag ghost466 setDragGhost(oDragControl, oEvent);467 // set dragging class of the drag source468 addStyleClass(oDragControl, "sapUiDnDDragging");469 };470 DnD.onbeforedragenter = function(oEvent) {471 // check whether we remain within the same control472 var oControl = jQuery(oEvent.target).control(0, true);473 if (oControl && oDropControl === oControl) {474 oEvent.setMark("DragWithin", "SameControl");475 } else {476 iTargetEnteringTime = Date.now();477 oDropControl = oControl;478 }479 var aDropInfos = [];480 oValidDropControl = oControl;481 // find the first valid drop control and corresponding valid DropInfos at the control hierarchy482 for (var i = 0; i < 20 && oValidDropControl; i++, oValidDropControl = oValidDropControl.getParent()) {483 aDropInfos = getValidDropInfos(oValidDropControl, aValidDragInfos, oEvent);484 if (aDropInfos.length) {485 break;486 }487 }488 // if we are not dragging within the same control we can update valid drop infos489 if (oEvent.getMark("DragWithin") != "SameControl") {490 aValidDropInfos = aDropInfos;491 if (oDragSession) {492 oDragSession.setIndicatorConfig(null);493 }494 }495 // no valid drop info found496 if (!aValidDropInfos.length) {497 oValidDropControl = null;498 } else if (!oDragSession) {499 // something is dragged from outside the browser500 oEvent.dragSession = oDragSession = createDragSession(oEvent);501 }502 };503 DnD.onafterdragenter = function(oEvent) {504 // drop is not possible if there is no valid drop control or dragenter event is marked as NonDroppable505 if (!oValidDropControl || oEvent.isMarked("NonDroppable")) {506 aValidDropInfos = [];507 } else if (oEvent.getMark("DragWithin") != "SameControl") {508 // fire dragenter event of valid DropInfos and filter if preventDefault is called509 aValidDropInfos = aValidDropInfos.filter(function(oDropInfo) {510 return oDropInfo.fireDragEnter(oEvent);511 });512 }513 // set drop effect and drop position514 var oValidDropInfo = aValidDropInfos[0];515 if (!oValidDropInfo || oValidDropInfo.getDropEffect() == "None") {516 hideDropIndicator();517 sCalculatedDropPosition = "";518 } else {519 setDropEffect(oEvent, oValidDropInfo);520 sCalculatedDropPosition = showDropPosition(oEvent, oValidDropInfo, oValidDropControl);521 }522 };523 DnD.onbeforedragover = function(oEvent) {524 // handle longdragover event525 var iCurrentTime = Date.now();526 if (iCurrentTime - iTargetEnteringTime >= 1000) {527 dispatchEvent(oEvent, "longdragover");528 iTargetEnteringTime = iCurrentTime;529 }530 };531 DnD.onafterdragover = function(oEvent) {532 var oValidDropInfo = aValidDropInfos[0];533 // let the browser do the default if there is no valid drop info534 if (!oValidDropInfo || oValidDropInfo.getDropEffect() == "None") {535 return;536 }537 // fire dragover events of valid DropInfos538 aValidDropInfos.forEach(function(oDropInfo) {539 oDropInfo.fireDragOver(oEvent);540 });541 // browsers drop effect must be set on dragover always542 setDropEffect(oEvent, oValidDropInfo);543 // drop position is set already at dragenter it should not be changed for DropPosition=On544 if (oValidDropInfo && oValidDropInfo.getDropPosition(true) == "On") {545 return;546 }547 // drop indicator position may change depending on the mouse pointer location548 sCalculatedDropPosition = showDropPosition(oEvent, oValidDropInfo, oValidDropControl);549 };550 DnD.onbeforedrop = function(oEvent) {551 // prevent default action552 if (aValidDropInfos.length) {553 oEvent.preventDefault();554 }555 };556 DnD.onafterdrop = function(oEvent) {557 // fire drop events of valid DropInfos558 aValidDropInfos.forEach(function(oDropInfo) {559 oDropInfo.fireDrop(oEvent);560 });561 // dragend event is not dispatched if the dragged element is removed562 this.iDragEndTimer = window.requestAnimationFrame(this.onafterdragend.bind(this, oEvent));563 };564 DnD.onafterdragend = function(oEvent) {565 // cleanup the timer if there is a waiting job on the queue566 this.iDragEndTimer = window.cancelAnimationFrame(this.iDragEndTimer);567 // fire dragend event of valid DragInfos568 aValidDragInfos.forEach(function(oDragInfo) {569 oDragInfo.fireDragEnd(oEvent);570 });571 // finalize drag session572 closeDragSession();573 };574 // process the events of the UIArea575 UIArea.addEventPreprocessor(DnD.preprocessEvent);576 UIArea.addEventPostprocessor(DnD.postprocessEvent);577 return DnD;...
viewerDragDropMixinSpec.js
Source:viewerDragDropMixinSpec.js
1defineSuite([2 'Widgets/Viewer/viewerDragDropMixin',3 'Core/defined',4 'Core/TimeInterval',5 'Specs/createViewer',6 'Specs/DomEventSimulator',7 'Specs/pollToPromise'8 ], function(9 viewerDragDropMixin,10 defined,11 TimeInterval,12 createViewer,13 DomEventSimulator,14 pollToPromise) {15 'use strict';1617 var container;18 var viewer;19 beforeEach(function() {20 container = document.createElement('div');21 container.id = 'container';22 container.style.display = 'none';23 document.body.appendChild(container);2425 //Impersonate FileReader for drag and drop tests26 var fakeFileReader = jasmine.createSpyObj('FileReader', ['readAsText']);27 fakeFileReader.readAsText = function(file) {28 if (defined(file.czmlString)) {29 this.onload({30 target : {31 result : file.czmlString32 }33 });34 } else {35 this.onerror({36 target : {37 error : file.errorMessage38 }39 });40 }41 };42 spyOn(window, 'FileReader').and.returnValue(fakeFileReader);43 });4445 afterEach(function() {46 if (viewer && !viewer.isDestroyed()) {47 viewer = viewer.destroy();48 }4950 document.body.removeChild(container);51 });5253 it('mixin sets default values', function() {54 viewer = createViewer(container);55 viewer.extend(viewerDragDropMixin);56 expect(viewer.dropTarget).toBe(viewer.container);57 expect(viewer.dropEnabled).toEqual(true);58 expect(viewer.clearOnDrop).toEqual(true);59 expect(viewer.clampToGround).toEqual(true);60 expect(viewer.flyToOnDrop).toEqual(true);61 });6263 it('clearOnDrop defaults to true when dataSourceBrowser is not used', function() {64 viewer = createViewer(container, {65 dataSourceBrowser : false66 });67 viewer.extend(viewerDragDropMixin);68 expect(viewer.clearOnDrop).toEqual(true);69 });7071 it('mixin sets option values', function() {72 viewer = createViewer(container);73 viewer.extend(viewerDragDropMixin, {74 dropTarget : document.body,75 clearOnDrop : false,76 clampToGround : false,77 flyToOnDrop: false78 });79 expect(viewer.dropTarget).toBe(document.body);80 expect(viewer.dropEnabled).toEqual(true);81 expect(viewer.clearOnDrop).toEqual(false);82 expect(viewer.clampToGround).toEqual(false);83 expect(viewer.flyToOnDrop).toEqual(false);84 });8586 it('mixin works with dropTarget id string', function() {87 viewer = createViewer(container);88 viewer.extend(viewerDragDropMixin, {89 dropTarget : 'container'90 });91 expect(viewer.dropTarget).toBe(container);92 });9394 var czml1 = [{95 id : 'document',96 version : '1.0',97 clock : {98 interval : '2000-01-01/2001-01-01'99 }100 }, {101 id : 'test'102 }];103104 var czml2 = [{105 id : 'document',106 version : '1.0',107 clock : {108 interval : '2000-01-02/2001-01-02'109 }110 }, {111 id : 'test2'112 }];113114 it('handleDrop processes drop event', function() {115 var mockEvent = {116 dataTransfer : {117 files : [{118 name : 'czml1.czml',119 czmlString : JSON.stringify(czml1)120 }]121 },122 stopPropagation : function() {123 },124 preventDefault : function() {125 }126 };127128 viewer = createViewer(container);129 viewer.extend(viewerDragDropMixin);130131 DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent);132133 return pollToPromise(function() {134 return viewer.dataSources.length === 1;135 }).then(function() {136 var dataSource = viewer.dataSources.get(0);137 var interval = TimeInterval.fromIso8601({138 iso8601 : czml1[0].clock.interval139 });140 expect(dataSource.entities.getById('test')).toBeDefined();141 expect(dataSource.clock.startTime).toEqual(interval.start);142 expect(dataSource.clock.stopTime).toEqual(interval.stop);143 });144 });145146 it('handleDrop processes drop event with multiple files', function() {147 var mockEvent = {148 dataTransfer : {149 files : [{150 name : 'czml1.czml',151 czmlString : JSON.stringify(czml1)152 }, {153 name : 'czml2.czml',154 czmlString : JSON.stringify(czml2)155 }]156 },157 stopPropagation : function() {158 },159 preventDefault : function() {160 }161 };162163 viewer = createViewer(container);164 viewer.extend(viewerDragDropMixin);165166 DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent);167168 return pollToPromise(function() {169 return viewer.dataSources.length === 2;170 }).then(function() {171 var source1 = viewer.dataSources.get(0);172 var source2 = viewer.dataSources.get(1);173 expect(source1.entities.getById('test')).toBeDefined();174 expect(source2.entities.getById('test2')).toBeDefined();175 //Interval of first file should be used.176 var interval = TimeInterval.fromIso8601({177 iso8601 : czml1[0].clock.interval178 });179 expect(source1.clock.startTime).toEqual(interval.start);180 expect(source1.clock.stopTime).toEqual(interval.stop);181 });182 });183184 it('handleDrop obeys clearOnDrop', function() {185 var mockEvent = {186 dataTransfer : {187 files : [{188 name : 'czml1.czml',189 czmlString : JSON.stringify(czml1)190 }, {191 name : 'czml2.czml',192 czmlString : JSON.stringify(czml2)193 }]194 },195 stopPropagation : function() {196 },197 preventDefault : function() {198 }199 };200201 viewer = createViewer(container);202 viewer.extend(viewerDragDropMixin);203204 DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent);205206 return pollToPromise(function() {207 return viewer.dataSources.length === 2;208 }).then(function() {209 var source1 = viewer.dataSources.get(0);210 var source2 = viewer.dataSources.get(1);211 expect(source1.entities.getById('test')).toBeDefined();212 expect(source2.entities.getById('test2')).toBeDefined();213 //Interval of first file should be used.214 var interval = TimeInterval.fromIso8601({215 iso8601 : czml1[0].clock.interval216 });217 expect(source1.clock.startTime).toEqual(interval.start);218 expect(source1.clock.stopTime).toEqual(interval.stop);219220 viewer.clearOnDrop = false;221 DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent);222223 return pollToPromise(function() {224 return viewer.dataSources.length === 4;225 }).then(function() {226 var source1 = viewer.dataSources.get(0);227 var source2 = viewer.dataSources.get(1);228 var source3 = viewer.dataSources.get(2);229 var source4 = viewer.dataSources.get(3);230231 expect(source1.entities.getById('test')).toBeDefined();232 expect(source2.entities.getById('test2')).toBeDefined();233 expect(source3.entities.getById('test')).toBeDefined();234 expect(source4.entities.getById('test2')).toBeDefined();235236 viewer.clearOnDrop = true;237 DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent);238239 return pollToPromise(function() {240 return viewer.dataSources.length === 2;241 }).then(function() {242 var source1 = viewer.dataSources.get(0);243 var source2 = viewer.dataSources.get(1);244 expect(source1.entities.getById('test')).toBeDefined();245 expect(source2.entities.getById('test2')).toBeDefined();246 //Interval of first file should be used.247 var interval = TimeInterval.fromIso8601({248 iso8601 : czml1[0].clock.interval249 });250 expect(source1.clock.startTime).toEqual(interval.start);251 expect(source1.clock.stopTime).toEqual(interval.stop);252 });253 });254 });255 });256257 it('dropError is raised on exception', function() {258 var mockEvent = {259 dataTransfer : {260 files : [{261 name : 'czml1.czml',262 czmlString : 'bad JSON'263 }]264 },265 stopPropagation : function() {266 },267 preventDefault : function() {268 }269 };270271 viewer = createViewer(container);272 viewer.extend(viewerDragDropMixin);273274 var spyListener = jasmine.createSpy('listener');275276 viewer.dropError.addEventListener(spyListener);277 DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent);278279 return pollToPromise(function() {280 return spyListener.calls.any();281 }).then(function() {282 expect(spyListener).toHaveBeenCalledWith(viewer, 'czml1.czml', jasmine.any(SyntaxError));283284 viewer.dropError.removeEventListener(spyListener);285 });286 });287288 it('dropError is raised FileReader error', function() {289 var mockEvent = {290 dataTransfer : {291 files : [{292 name : 'czml1.czml',293 errorMessage : 'bad JSON'294 }]295 },296 stopPropagation : function() {297 },298 preventDefault : function() {299 }300 };301302 viewer = createViewer(container);303 viewer.extend(viewerDragDropMixin);304305 var spyListener = jasmine.createSpy('listener');306307 viewer.dropError.addEventListener(spyListener);308 DomEventSimulator.fireMockEvent(viewer._handleDrop, mockEvent);309310 return pollToPromise(function() {311 return spyListener.calls.any();312 }).then(function() {313 expect(spyListener).toHaveBeenCalledWith(viewer, mockEvent.dataTransfer.files[0].name, mockEvent.dataTransfer.files[0].errorMessage);314315 viewer.dropError.removeEventListener(spyListener);316 });317 });318319 function MockContainer() {320 var events = {};321 this.events = events;322323 this.addEventListener = function(name, func, bubble) {324 events[name] = {325 func : func,326 bubble : bubble327 };328 };329330 this.removeEventListener = function(name, func, bubble) {331 var subscribed = events[name];332 expect(subscribed.func).toBe(func);333 expect(subscribed.bubble).toEqual(bubble);334 delete events[name];335 };336 }337338 it('enable/disable subscribes to provided dropTarget.', function() {339 var dropTarget = new MockContainer();340341 viewer = createViewer(container);342 viewer.extend(viewerDragDropMixin, {343 dropTarget : dropTarget344 });345346 expect(dropTarget.events.drop).toBeDefined();347 expect(dropTarget.events.dragenter).toBeDefined();348 expect(dropTarget.events.dragover).toBeDefined();349 expect(dropTarget.events.dragexit).toBeDefined();350351 viewer.dropEnabled = false;352 expect(dropTarget.events.drop).toBeUndefined();353 expect(dropTarget.events.dragenter).toBeUndefined();354 expect(dropTarget.events.dragover).toBeUndefined();355 expect(dropTarget.events.dragexit).toBeUndefined();356357 viewer.dropEnabled = true;358 expect(dropTarget.events.drop).toBeDefined();359 expect(dropTarget.events.dragenter).toBeDefined();360 expect(dropTarget.events.dragover).toBeDefined();361 expect(dropTarget.events.dragexit).toBeDefined();362 });363364 it('can set new dropTarget.', function() {365 var dropTarget1 = new MockContainer();366 var dropTarget2 = new MockContainer();367368 viewer = createViewer(container);369 viewer.extend(viewerDragDropMixin, {370 dropTarget : dropTarget1371 });372373 expect(dropTarget1.events.drop).toBeDefined();374 expect(dropTarget1.events.dragenter).toBeDefined();375 expect(dropTarget1.events.dragover).toBeDefined();376 expect(dropTarget1.events.dragexit).toBeDefined();377378 viewer.dropTarget = dropTarget2;379 expect(dropTarget1.events.drop).toBeUndefined();380 expect(dropTarget1.events.dragenter).toBeUndefined();381 expect(dropTarget1.events.dragover).toBeUndefined();382 expect(dropTarget1.events.dragexit).toBeUndefined();383384 expect(dropTarget2.events.drop).toBeDefined();385 expect(dropTarget2.events.dragenter).toBeDefined();386 expect(dropTarget2.events.dragover).toBeDefined();387 expect(dropTarget2.events.dragexit).toBeDefined();388 });389390 it('can set proxy.', function() {391 var proxy = {};392393 viewer = createViewer(container);394 viewer.extend(viewerDragDropMixin, {395 proxy : proxy396 });397 expect(viewer.proxy).toBe(proxy);398 });399400 it('throws with undefined viewer', function() {401 expect(function() {402 viewerDragDropMixin(undefined);403 }).toThrowDeveloperError();404 });405406 it('throws with non-existant string container', function() {407 viewer = createViewer(container);408 expect(function() {409 viewer.extend(viewerDragDropMixin, {410 dropTarget : 'doesNotExist'411 });412 }).toThrowDeveloperError();413 });414415 it('throws if dropTarget property already added by another mixin.', function() {416 viewer = createViewer(container);417 viewer.dropTarget = true;418 expect(function() {419 viewer.extend(viewerDragDropMixin);420 }).toThrowDeveloperError();421 });422423 it('throws if dropEnabled property already added by another mixin.', function() {424 viewer = createViewer(container);425 viewer.dropEnabled = true;426 expect(function() {427 viewer.extend(viewerDragDropMixin);428 }).toThrowDeveloperError();429 });430431 it('throws if dropError property already added by another mixin.', function() {432 viewer = createViewer(container);433 viewer.dropError = true;434 expect(function() {435 viewer.extend(viewerDragDropMixin);436 }).toThrowDeveloperError();437 });438439 it('throws if clearOnDrop property already added by another mixin.', function() {440 viewer = createViewer(container);441 viewer.clearOnDrop = true;442 expect(function() {443 viewer.extend(viewerDragDropMixin);444 }).toThrowDeveloperError();445 });446447 it('throws if flyToOnDrop property already added by another mixin.', function() {448 viewer = createViewer(container);449 viewer.flyToOnDrop = true;450 expect(function() {451 viewer.extend(viewerDragDropMixin);452 }).toThrowDeveloperError();453 });454455 it('setting dropTarget to undefined throws exception', function() {456 viewer = createViewer(container);457 viewer.extend(viewerDragDropMixin);458 expect(function() {459 viewer.dropTarget = undefined;460 }).toThrowDeveloperError();461 });
...
DropInfo.qunit.js
Source:DropInfo.qunit.js
1/*global QUnit,sinon*/2sap.ui.define([3 "jquery.sap.global",4 "./TestControl",5 "sap/ui/core/dnd/DropInfo",6 "sap/ui/base/ManagedObject",7 "sap/ui/core/ElementMetadata",8 "sap/base/Log"9], function(jQuery, TestControl, DropInfo, ManagedObject, ElementMetadata, Log) {10 "use strict";11 QUnit.test("Default values", function(assert) {12 var oDropInfo = new DropInfo();13 assert.strictEqual(oDropInfo.getTargetAggregation(), "", "Default value of targetAggregation is correct");14 assert.strictEqual(oDropInfo.getGroupName(), "", "Default value of targetAggregation is correct");15 assert.strictEqual(oDropInfo.getDropEffect(), "Move", "Default value of dropEffect is correct");16 assert.strictEqual(oDropInfo.getDropPosition(), "On", "Default value of dropPosition is correct");17 assert.strictEqual(oDropInfo.getDropLayout(), "Default", "Default value of dropLayout is correct");18 assert.strictEqual(oDropInfo.getEnabled(), true, "Default value of enabled is correct");19 assert.strictEqual(oDropInfo.isDraggable(), false, "DropInfo is not draggable.");20 oDropInfo.destroy();21 });22 QUnit.test("invalidation", function(assert) {23 var oDropInfo = new DropInfo();24 var fnInvalidateSpy = sinon.spy(oDropInfo, "invalidate");25 oDropInfo.setEnabled(false);26 assert.strictEqual(fnInvalidateSpy.callCount, 0, "Invalidation has not happened for enabled property");27 oDropInfo.setGroupName("abc");28 assert.strictEqual(fnInvalidateSpy.callCount, 0, "Invalidation has not happened for groupName property");29 oDropInfo.setTargetAggregation("items");30 assert.strictEqual(fnInvalidateSpy.callCount, 0, "Invalidation has not happened for targetAggregation property");31 oDropInfo.setDropEffect("Copy");32 assert.strictEqual(fnInvalidateSpy.callCount, 0, "Invalidation has not happened for dropEffect property");33 oDropInfo.setDropPosition("Between");34 assert.strictEqual(fnInvalidateSpy.callCount, 0, "Invalidation has not happened for dropPosition property");35 oDropInfo.setDropLayout("Horizontal");36 assert.strictEqual(fnInvalidateSpy.callCount, 0, "Invalidation has not happened for dropLayout property");37 oDropInfo.destroy();38 });39 QUnit.test("TemporaryDropPosition", function(assert) {40 var oDropInfo = new DropInfo();41 oDropInfo.sTemporaryDropPosition = "Between";42 assert.strictEqual(oDropInfo.getDropPosition(), "On", "Public API returns the correct DropPosition value");43 assert.strictEqual(oDropInfo.getDropPosition(true), "Between", "Temporary DropPosition is returned when 1st param is true");44 oDropInfo.destroy();45 });46 QUnit.test("getDropLayout", function(assert) {47 var oDropInfo = new DropInfo({48 targetAggregation: "test"49 });50 var oControl = new TestControl({51 dragDropConfig: oDropInfo52 });53 assert.strictEqual(oDropInfo.getDropLayout(true), "Horizontal", "Default value is taken from metadata.dnd.layout");54 oDropInfo.setDropLayout("Vertical");55 assert.strictEqual(oDropInfo.getDropLayout(), "Vertical", "Public API returned the control value");56 assert.strictEqual(oDropInfo.getDropLayout(true), "Vertical", "Nothing to detect property value is returned");57 oControl.destroy();58 });59 QUnit.test("isDroppable - An unrelated element", function(assert) {60 var oDropInfo = new DropInfo();61 var oManagedObject = new ManagedObject();62 assert.notOk(oDropInfo.isDroppable(undefined), "Not droppable: Drag target is not specified");63 assert.notOk(oDropInfo.isDroppable(oManagedObject), "Not droppable: Drag target is not an instanceof Element");64 oManagedObject.destroy();65 oDropInfo.destroy();66 });67 QUnit.test("isDroppable - Test control not known to the DropInfo", function(assert) {68 var oDropInfo = new DropInfo();69 var oControl = new TestControl();70 assert.notOk(oDropInfo.isDroppable(oControl), "Not droppable: The drop target is not known");71 oDropInfo.destroy();72 oControl.destroy();73 });74 QUnit.test("isDroppable - The control itself", function(assert) {75 var oDropInfo = new DropInfo();76 var oControl = new TestControl({77 dragDropConfig: oDropInfo78 });79 assert.ok(oDropInfo.isDroppable(oControl), "Droppable: The drop target is the control itself");80 oDropInfo.setTargetAggregation("children");81 assert.notOk(oDropInfo.isDroppable(oControl), "Not Droppable: targetAggregation is defined");82 oControl.destroy();83 });84 QUnit.test("isDroppable - Aggregated child element", function(assert) {85 var oDropInfo = new DropInfo({86 targetAggregation: "children"87 });88 var oControl = new TestControl();89 var oParent = new TestControl({90 dragDropConfig: oDropInfo,91 children: oControl92 });93 assert.ok(oDropInfo.isDroppable(oControl), "Droppable: Child control is in the defined targetAggregation");94 oDropInfo.setTargetAggregation("thereIsNoSuchAnAggregationName");95 assert.notOk(oDropInfo.isDroppable(oControl), "Not Droppable: Child control is not in the defined targetAggregation");96 oParent.destroy();97 });98 QUnit.test("isDroppable - Empty Aggregation", function(assert) {99 var oDropInfo = new DropInfo({100 targetAggregation: "children"101 });102 var oControl = new TestControl({103 dragDropConfig: oDropInfo104 });105 var oEvent = new jQuery.Event("dragenter");106 oControl.placeAt("qunit-fixture");107 sap.ui.getCore().applyChanges();108 oEvent.target = oControl.getDomRef("children");109 assert.notOk(oDropInfo.isDroppable(oControl, oEvent), "Not Droppable: event target is the defined targetAggregation DOM");110 assert.strictEqual(oEvent.getMark("DragWithin"), undefined, "Event is not marked as found aggregation name");111 oEvent.target = oControl.getDomRef("children").firstChild;112 assert.ok(oDropInfo.isDroppable(oControl, oEvent), "Droppable: event target is in the defined targetAggregation DOM");113 assert.strictEqual(oEvent.getMark("DragWithin"), "children", "Event is not marked for the found aggregation name");114 oEvent.target = oControl.getDomRef("title");115 assert.notOk(oDropInfo.isDroppable(oControl, oEvent), "Not Droppable: event target is in the valid targetAggregation DOM");116 oEvent.target = oControl.getDomRef();117 assert.notOk(oDropInfo.isDroppable(oControl, oEvent), "Not Droppable: targetAggregation is defined control self is not the drop target.");118 oControl.destroy();119 });120 QUnit.test("isDroppable - Enabled", function(assert) {121 var oDropInfo = new DropInfo({122 enabled: false123 });124 var oControl = new TestControl({125 dragDropConfig: oDropInfo126 });127 assert.notOk(oDropInfo.isDroppable(oControl), "Not droppable: DropInfo is not enabled");128 oDropInfo.setEnabled(true);129 assert.ok(oDropInfo.isDroppable(oControl), "Droppable: DropInfo is enabled and drop target is the control itself");130 oControl.destroy();131 });132 QUnit.test("isDroppable - metadata disallows", function(assert) {133 var oDropInfo = new DropInfo();134 var oChild = new TestControl();135 var oParent = new TestControl({136 dragDropConfig: oDropInfo,137 children: oChild138 });139 var fnLogSpy = this.spy(Log, "warning");140 this.stub(ElementMetadata.prototype, "getDragDropInfo").returns({droppable: false});141 assert.notOk(oDropInfo.isDroppable(oParent), "Not droppable: Element metadata does not allow droppping");142 assert.strictEqual(fnLogSpy.callCount, 1, "Not droppable is logged");143 oDropInfo.setTargetAggregation("children");144 assert.notOk(oDropInfo.isDroppable(oChild), "Not droppable: Aggregation metadata does not allow dropping");145 assert.strictEqual(fnLogSpy.callCount, 2, "Not droppable is logged again");146 oParent.destroy();147 });148 QUnit.test("fireDragEnter - invalid parameters", function(assert) {149 var oDragEnterEvent = new jQuery.Event("dragenter");150 var fnDragEnterSpy = sinon.spy();151 var oDropInfo = new DropInfo({152 dragEnter: fnDragEnterSpy153 });154 oDropInfo.fireDragEnter();155 assert.ok(fnDragEnterSpy.notCalled, "dragEnter event is not fired, there is no parameter");156 oDropInfo.fireDragEnter(oDragEnterEvent);157 assert.ok(fnDragEnterSpy.notCalled, "dragEnter event is not fired, dragSession does not exist");158 oDropInfo.destroy();159 });160 QUnit.test("fireDragEnter - event parameters", function(assert) {161 var fnDragEnterSpy = sinon.spy(function(oEvent) {162 var mParameters = oEvent.getParameters();163 assert.ok(mParameters.dragSession, "dragSession exists");164 assert.strictEqual(mParameters.target, oControl, "target is valid");165 assert.strictEqual(mParameters.browserEvent, oDragEnterEvent.originalEvent, "browserEvent is valid");166 });167 var oDropInfo = new DropInfo({168 dragEnter: fnDragEnterSpy169 });170 var oControl = new TestControl({171 title: "Control",172 dragDropConfig: oDropInfo173 });174 var oDragEnterEvent = new jQuery.Event("dragstart");175 oDragEnterEvent.dragSession = {176 getDropControl: function() {177 return oControl;178 }179 };180 var bEventValue = oDropInfo.fireDragEnter(oDragEnterEvent);181 assert.ok(fnDragEnterSpy.calledOnce, "dragEnter event is fired once");182 assert.ok(bEventValue, "dragEnter event is returned true");183 oDropInfo.detachDragEnter(fnDragEnterSpy);184 oDropInfo.attachDragEnter(function(oEvent) {185 oEvent.preventDefault();186 });187 bEventValue = oDropInfo.fireDragEnter(oDragEnterEvent);188 assert.notOk(bEventValue, "default is prevented for dragEnter event");189 oControl.destroy();190 });191 QUnit.test("fireDragOver - invalid parameters", function(assert) {192 var oDragOverEvent = new jQuery.Event("dragover");193 var fnDragOverSpy = sinon.spy();194 var oDropInfo = new DropInfo({195 dragOver: fnDragOverSpy196 });197 oDropInfo.fireDragOver();198 assert.ok(fnDragOverSpy.notCalled, "dragOver event is not fired, there is no parameter");199 oDropInfo.fireDragOver(oDragOverEvent);200 assert.ok(fnDragOverSpy.notCalled, "dragOver event is not fired, dragSession does not exist");201 oDropInfo.destroy();202 });203 QUnit.test("fireDragOver - event parameters", function(assert) {204 var fnDragOverSpy = sinon.spy(function(oEvent) {205 var mParameters = oEvent.getParameters();206 assert.ok(mParameters.dragSession, "dragSession exists");207 assert.strictEqual(mParameters.target, oControl, "target is valid");208 assert.strictEqual(mParameters.dropPosition, "On", "dropPosition is valid");209 assert.strictEqual(mParameters.browserEvent, oDragOverEvent.originalEvent, "browserEvent is valid");210 });211 var oDropInfo = new DropInfo({212 dragOver: fnDragOverSpy213 });214 var oControl = new TestControl({215 title: "Control",216 dragDropConfig: oDropInfo217 });218 var oDragOverEvent = new jQuery.Event("dragstart");219 oDragOverEvent.dragSession = {220 getDropControl: function() {221 return oControl;222 },223 getDropPosition: function() {224 return "On";225 }226 };227 var bEventValue = oDropInfo.fireDragOver(oDragOverEvent);228 assert.ok(fnDragOverSpy.calledOnce, "dragOver event is fired once");229 assert.ok(bEventValue, "dragOver event is returned true");230 oControl.destroy();231 });232 QUnit.test("fireDrop - invalid parameters", function(assert) {233 var oDropEvent = new jQuery.Event("drop");234 var fnDropSpy = sinon.spy();235 var oDropInfo = new DropInfo({236 drop: fnDropSpy237 });238 oDropInfo.fireDrop();239 assert.ok(fnDropSpy.notCalled, "drop event is not fired, there is no parameter");240 oDropInfo.fireDrop(oDropEvent);241 assert.ok(fnDropSpy.notCalled, "drop event is not fired, dragSession does not exist");242 oDropInfo.destroy();243 });244 QUnit.test("fireDrop - event parameters", function(assert) {245 var fnDropSpy = sinon.spy(function(oEvent) {246 var mParameters = oEvent.getParameters();247 assert.ok(mParameters.dragSession, "dragSession exists");248 assert.strictEqual(mParameters.browserEvent, oDropEvent.originalEvent, "browserEvent is valid");249 assert.strictEqual(mParameters.draggedControl, oControl, "draggedControl is valid");250 assert.strictEqual(mParameters.draggedControl, oControl, "droppedControl is valid");251 assert.strictEqual(mParameters.dropPosition, "On", "dropPosition is valid");252 });253 var oDropInfo = new DropInfo({254 drop: fnDropSpy255 });256 var oControl = new TestControl({257 title: "Control",258 dragDropConfig: oDropInfo259 });260 var oDropEvent = new jQuery.Event("dragstart");261 oDropEvent.dragSession = {262 getDropControl: function() {263 return oControl;264 },265 getDragControl: function() {266 return oControl;267 },268 getDropPosition: function() {269 return oDropInfo.getDropPosition();270 }271 };272 oDropInfo.fireDrop(oDropEvent);273 assert.ok(fnDropSpy.calledOnce, "drop event is fired once");274 oControl.destroy();275 });...
viewerDragDropMixin.js
Source:viewerDragDropMixin.js
1define([2 '../../Core/defaultValue',3 '../../Core/defined',4 '../../Core/defineProperties',5 '../../Core/DeveloperError',6 '../../Core/Event',7 '../../Core/wrapFunction',8 '../../DataSources/CzmlDataSource',9 '../../DataSources/GeoJsonDataSource',10 '../../DataSources/KmlDataSource',11 '../getElement'12 ], function(13 defaultValue,14 defined,15 defineProperties,16 DeveloperError,17 Event,18 wrapFunction,19 CzmlDataSource,20 GeoJsonDataSource,21 KmlDataSource,22 getElement) {23 'use strict';2425 /**26 * A mixin which adds default drag and drop support for CZML files to the Viewer widget.27 * Rather than being called directly, this function is normally passed as28 * a parameter to {@link Viewer#extend}, as shown in the example below.29 * @exports viewerDragDropMixin30 *31 * @param {Viewer} viewer The viewer instance.32 * @param {Object} [options] Object with the following properties:33 * @param {Element|String} [options.dropTarget=viewer.container] The DOM element which will serve as the drop target.34 * @param {Boolean} [options.clearOnDrop=true] When true, dropping files will clear all existing data sources first, when false, new data sources will be loaded after the existing ones.35 * @param {Boolean} [options.flyToOnDrop=true] When true, dropping files will fly to the data source once it is loaded.36 * @param {Boolean} [options.clampToGround=true] When true, datasources are clamped to the ground.37 * @param {DefaultProxy} [options.proxy] The proxy to be used for KML network links.38 *39 * @exception {DeveloperError} Element with id <options.dropTarget> does not exist in the document.40 * @exception {DeveloperError} dropTarget is already defined by another mixin.41 * @exception {DeveloperError} dropEnabled is already defined by another mixin.42 * @exception {DeveloperError} dropError is already defined by another mixin.43 * @exception {DeveloperError} clearOnDrop is already defined by another mixin.44 *45 * @example46 * // Add basic drag and drop support and pop up an alert window on error.47 * var viewer = new Cesium.Viewer('cesiumContainer');48 * viewer.extend(Cesium.viewerDragDropMixin);49 * viewer.dropError.addEventListener(function(viewerArg, source, error) {50 * window.alert('Error processing ' + source + ':' + error);51 * });52 */53 function viewerDragDropMixin(viewer, options) {54 //>>includeStart('debug', pragmas.debug);55 if (!defined(viewer)) {56 throw new DeveloperError('viewer is required.');57 }58 if (viewer.hasOwnProperty('dropTarget')) {59 throw new DeveloperError('dropTarget is already defined by another mixin.');60 }61 if (viewer.hasOwnProperty('dropEnabled')) {62 throw new DeveloperError('dropEnabled is already defined by another mixin.');63 }64 if (viewer.hasOwnProperty('dropError')) {65 throw new DeveloperError('dropError is already defined by another mixin.');66 }67 if (viewer.hasOwnProperty('clearOnDrop')) {68 throw new DeveloperError('clearOnDrop is already defined by another mixin.');69 }70 if (viewer.hasOwnProperty('flyToOnDrop')) {71 throw new DeveloperError('flyToOnDrop is already defined by another mixin.');72 }73 //>>includeEnd('debug');7475 options = defaultValue(options, defaultValue.EMPTY_OBJECT);7677 //Local variables to be closed over by defineProperties.78 var dropEnabled = true;79 var flyToOnDrop = defaultValue(options.flyToOnDrop, true);80 var dropError = new Event();81 var clearOnDrop = defaultValue(options.clearOnDrop, true);82 var dropTarget = defaultValue(options.dropTarget, viewer.container);83 var clampToGround = defaultValue(options.clampToGround, true);84 var proxy = options.proxy;8586 dropTarget = getElement(dropTarget);8788 defineProperties(viewer, {89 /**90 * Gets or sets the element to serve as the drop target.91 * @memberof viewerDragDropMixin.prototype92 * @type {Element}93 */94 dropTarget : {95 //TODO See https://github.com/AnalyticalGraphicsInc/cesium/issues/83296 get : function() {97 return dropTarget;98 },99 set : function(value) {100 //>>includeStart('debug', pragmas.debug);101 if (!defined(value)) {102 throw new DeveloperError('value is required.');103 }104 //>>includeEnd('debug');105106 unsubscribe(dropTarget, handleDrop);107 dropTarget = value;108 subscribe(dropTarget, handleDrop);109 }110 },111112 /**113 * Gets or sets a value indicating if drag and drop support is enabled.114 * @memberof viewerDragDropMixin.prototype115 * @type {Element}116 */117 dropEnabled : {118 get : function() {119 return dropEnabled;120 },121 set : function(value) {122 if (value !== dropEnabled) {123 if (value) {124 subscribe(dropTarget, handleDrop);125 } else {126 unsubscribe(dropTarget, handleDrop);127 }128 dropEnabled = value;129 }130 }131 },132133 /**134 * Gets the event that will be raised when an error is encountered during drop processing.135 * @memberof viewerDragDropMixin.prototype136 * @type {Event}137 */138 dropError : {139 get : function() {140 return dropError;141 }142 },143144 /**145 * Gets or sets a value indicating if existing data sources should be cleared before adding the newly dropped sources.146 * @memberof viewerDragDropMixin.prototype147 * @type {Boolean}148 */149 clearOnDrop : {150 get : function() {151 return clearOnDrop;152 },153 set : function(value) {154 clearOnDrop = value;155 }156 },157158 /**159 * Gets or sets a value indicating if the camera should fly to the data source after it is loaded.160 * @memberof viewerDragDropMixin.prototype161 * @type {Boolean}162 */163 flyToOnDrop : {164 get : function() {165 return flyToOnDrop;166 },167 set : function(value) {168 flyToOnDrop = value;169 }170 },171172 /**173 * Gets or sets the proxy to be used for KML.174 * @memberof viewerDragDropMixin.prototype175 * @type {DefaultProxy}176 */177 proxy : {178 get : function() {179 return proxy;180 },181 set : function(value) {182 proxy = value;183 }184 },185186 /**187 * Gets or sets a value indicating if the datasources should be clamped to the ground188 * @memberof viewerDragDropMixin.prototype189 * @type {Boolean}190 */191 clampToGround : {192 get : function() {193 return clampToGround;194 },195 set : function(value) {196 clampToGround = value;197 }198 }199 });200201 function handleDrop(event) {202 stop(event);203204 if (clearOnDrop) {205 viewer.entities.removeAll();206 viewer.dataSources.removeAll();207 }208209 var files = event.dataTransfer.files;210 var length = files.length;211 for (var i = 0; i < length; i++) {212 var file = files[i];213 var reader = new FileReader();214 reader.onload = createOnLoadCallback(viewer, file, proxy, clampToGround);215 reader.onerror = createDropErrorCallback(viewer, file);216 reader.readAsText(file);217 }218 }219220 //Enable drop by default;221 subscribe(dropTarget, handleDrop);222223 //Wrap the destroy function to make sure all events are unsubscribed from224 viewer.destroy = wrapFunction(viewer, viewer.destroy, function() {225 viewer.dropEnabled = false;226 });227228 //Specs need access to handleDrop229 viewer._handleDrop = handleDrop;230 }231232 function stop(event) {233 event.stopPropagation();234 event.preventDefault();235 }236237 function unsubscribe(dropTarget, handleDrop) {238 var currentTarget = dropTarget;239 if (defined(currentTarget)) {240 currentTarget.removeEventListener('drop', handleDrop, false);241 currentTarget.removeEventListener('dragenter', stop, false);242 currentTarget.removeEventListener('dragover', stop, false);243 currentTarget.removeEventListener('dragexit', stop, false);244 }245 }246247 function subscribe(dropTarget, handleDrop) {248 dropTarget.addEventListener('drop', handleDrop, false);249 dropTarget.addEventListener('dragenter', stop, false);250 dropTarget.addEventListener('dragover', stop, false);251 dropTarget.addEventListener('dragexit', stop, false);252 }253254 function createOnLoadCallback(viewer, file, proxy, clampToGround) {255 var scene = viewer.scene;256 return function(evt) {257 var fileName = file.name;258 try {259 var loadPromise;260261 if (/\.czml$/i.test(fileName)) {262 loadPromise = CzmlDataSource.load(JSON.parse(evt.target.result), {263 sourceUri : fileName264 });265 } else if (/\.geojson$/i.test(fileName) || /\.json$/i.test(fileName) || /\.topojson$/i.test(fileName)) {266 loadPromise = GeoJsonDataSource.load(JSON.parse(evt.target.result), {267 sourceUri : fileName,268 clampToGround : clampToGround269 });270 } else if (/\.(kml|kmz)$/i.test(fileName)) {271 loadPromise = KmlDataSource.load(file, {272 sourceUri : fileName,273 proxy : proxy,274 camera : scene.camera,275 canvas : scene.canvas276 });277 } else {278 viewer.dropError.raiseEvent(viewer, fileName, 'Unrecognized file: ' + fileName);279 return;280 }281282 if (defined(loadPromise)) {283 viewer.dataSources.add(loadPromise).then(function(dataSource) {284 if (viewer.flyToOnDrop) {285 viewer.flyTo(dataSource);286 }287 }).otherwise(function(error) {288 viewer.dropError.raiseEvent(viewer, fileName, error);289 });290 }291 } catch (error) {292 viewer.dropError.raiseEvent(viewer, fileName, error);293 }294 };295 }296297 function createDropErrorCallback(viewer, file) {298 return function(evt) {299 viewer.dropError.raiseEvent(viewer, file.name, evt.target.error);300 };301 }302303 return viewerDragDropMixin;
...
dd.js
Source:dd.js
1/**2 * Drag and Drop handler3 *4 * @namespace M.course.management5 * @class DragDrop6 * @constructor7 * @extends Base8 */9function DragDrop(config) {10 Console.superclass.constructor.apply(this, [config]);11}12DragDrop.NAME = 'moodle-course-management-dd';13DragDrop.CSS_PREFIX = 'management-dd';14DragDrop.ATTRS = {15 /**16 * The management console this drag and drop has been set up for.17 * @attribute console18 * @type Console19 * @writeOnce20 */21 console : {22 writeOnce : 'initOnly'23 }24};25DragDrop.prototype = {26 /**27 * True if the user is dragging a course upwards.28 * @property goingup29 * @protected30 * @default false31 */32 goingup : false,33 /**34 * The last Y position of the course being dragged35 * @property lasty36 * @protected37 * @default null38 */39 lasty : null,40 /**41 * The sibling above the course being dragged currently (tracking its original position).42 *43 * @property previoussibling44 * @protected45 * @default false46 */47 previoussibling : null,48 /**49 * Initialises the DragDrop instance.50 * @method initializer51 */52 initializer : function() {53 var managementconsole = this.get('console'),54 container = managementconsole.get('element'),55 categorylisting = container.one('#category-listing'),56 courselisting = container.one('#course-listing > .course-listing'),57 categoryul = (categorylisting) ? categorylisting.one('ul.ml') : null,58 courseul = (courselisting) ? courselisting.one('ul.ml') : null,59 canmoveoutof = (courselisting) ? courselisting.getData('canmoveoutof') : false,60 contstraint = (canmoveoutof) ? container : courseul;61 if (!courseul) {62 // No course listings found.63 return false;64 }65 courseul.all('> li').each(function(li){66 this.initCourseListing(li, contstraint);67 }, this);68 courseul.setData('dd', new Y.DD.Drop({69 node: courseul70 }));71 if (canmoveoutof && categoryul) {72 // Category UL may not be there if viewmode is just courses.73 categoryul.all('li > div').each(function(div){74 this.initCategoryListitem(div);75 }, this);76 }77 Y.DD.DDM.on('drag:start', this.dragStart, this);78 Y.DD.DDM.on('drag:end', this.dragEnd, this);79 Y.DD.DDM.on('drag:drag', this.dragDrag, this);80 Y.DD.DDM.on('drop:over', this.dropOver, this);81 Y.DD.DDM.on('drop:enter', this.dropEnter, this);82 Y.DD.DDM.on('drop:exit', this.dropExit, this);83 Y.DD.DDM.on('drop:hit', this.dropHit, this);84 },85 /**86 * Initialises a course listing.87 * @method initCourseListing88 * @param Node89 */90 initCourseListing : function(node, contstraint) {91 node.setData('dd', new Y.DD.Drag({92 node : node,93 target : {94 padding: '0 0 0 20'95 }96 }).addHandle(97 '.drag-handle'98 ).plug(Y.Plugin.DDProxy, {99 moveOnEnd: false,100 borderStyle: false101 }).plug(Y.Plugin.DDConstrained, {102 constrain2node: contstraint103 }));104 },105 /**106 * Initialises a category listing.107 * @method initCategoryListitem108 * @param Node109 */110 initCategoryListitem : function(node) {111 node.setData('dd', new Y.DD.Drop({112 node: node113 }));114 },115 /**116 * Dragging has started.117 * @method dragStart118 * @private119 * @param {EventFacade} e120 */121 dragStart : function(e) {122 var drag = e.target,123 node = drag.get('node'),124 dragnode = drag.get('dragNode');125 node.addClass('course-being-dragged');126 dragnode.addClass('course-being-dragged-proxy').set('innerHTML', node.one('a.coursename').get('innerHTML'));127 this.previoussibling = node.get('previousSibling');128 },129 /**130 * Dragging has ended.131 * @method dragEnd132 * @private133 * @param {EventFacade} e134 */135 dragEnd : function(e) {136 var drag = e.target,137 node = drag.get('node');138 node.removeClass('course-being-dragged');139 this.get('console').get('element').all('#category-listing li.highlight').removeClass('highlight');140 },141 /**142 * Dragging in progress.143 * @method dragDrag144 * @private145 * @param {EventFacade} e146 */147 dragDrag : function(e) {148 var y = e.target.lastXY[1];149 if (y < this.lasty) {150 this.goingup = true;151 } else {152 this.goingup = false;153 }154 this.lasty = y;155 },156 /**157 * The course has been dragged over a drop target.158 * @method dropOver159 * @private160 * @param {EventFacade} e161 */162 dropOver : function(e) {163 //Get a reference to our drag and drop nodes164 var drag = e.drag.get('node'),165 drop = e.drop.get('node'),166 tag = drop.get('tagName').toLowerCase();167 if (tag === 'li' && drop.hasClass('listitem-course')) {168 if (!this.goingup) {169 drop = drop.get('nextSibling');170 if (!drop) {171 drop = e.drop.get('node');172 drop.get('parentNode').append(drag);173 return false;174 }175 }176 drop.get('parentNode').insertBefore(drag, drop);177 e.drop.sizeShim();178 }179 },180 /**181 * The course has been dragged over a drop target.182 * @method dropEnter183 * @private184 * @param {EventFacade} e185 */186 dropEnter : function(e) {187 var drop = e.drop.get('node'),188 tag = drop.get('tagName').toLowerCase();189 if (tag === 'div') {190 drop.ancestor('li.listitem-category').addClass('highlight');191 }192 },193 /**194 * The course has been dragged off a drop target.195 * @method dropExit196 * @private197 * @param {EventFacade} e198 */199 dropExit : function(e) {200 var drop = e.drop.get('node'),201 tag = drop.get('tagName').toLowerCase();202 if (tag === 'div') {203 drop.ancestor('li.listitem-category').removeClass('highlight');204 }205 },206 /**207 * The course has been dropped on a target.208 * @method dropHit209 * @private210 * @param {EventFacade} e211 */212 dropHit : function(e) {213 var drag = e.drag.get('node'),214 drop = e.drop.get('node'),215 iscategory = (drop.ancestor('.listitem-category') !== null),216 iscourse = !iscategory && (drop.test('.listitem-course')),217 managementconsole = this.get('console'),218 categoryid,219 category,220 courseid,221 course,222 aftercourseid,223 previoussibling,224 previousid;225 if (!drag.test('.listitem-course')) {226 Y.log('It was not a course being dragged.', 'warn', 'moodle-course-management');227 return false;228 }229 courseid = drag.getData('id');230 if (iscategory) {231 categoryid = drop.ancestor('.listitem-category').getData('id');232 Y.log('Course ' + courseid + ' dragged into category ' + categoryid);233 category = managementconsole.getCategoryById(categoryid);234 if (category) {235 course = managementconsole.getCourseById(courseid);236 if (course) {237 category.moveCourseTo(course);238 }239 }240 } else if (iscourse || drop.ancestor('#course-listing')) {241 course = managementconsole.getCourseById(courseid);242 previoussibling = drag.get('previousSibling');243 aftercourseid = (previoussibling) ? previoussibling.getData('id') || 0 : 0;244 previousid = (this.previoussibling) ? this.previoussibling.getData('id') : 0;245 if (aftercourseid !== previousid) {246 course.moveAfter(aftercourseid, previousid);247 }248 } else {249 Y.log('Course dropped over unhandled target.', 'info', 'moodle-course-management');250 }251 }252};...
form-picker.js
Source:form-picker.js
1(function($) {2 'use strict';3 $(document).ready(function() {4 /*5 $("#dropper-default").dateDropper({6 dropWidth: 200,7 dropPrimaryColor: "#1abc9c",8 dropBorder: "1px solid #1abc9c"9 }),10 $("#dropper-animation").dateDropper({11 dropWidth: 200,12 init_animation: "bounce",13 dropPrimaryColor: "#1abc9c",14 dropBorder: "1px solid #1abc9c"15 }),16 $("#dropper-format").dateDropper({17 dropWidth: 200,18 format: "F S, Y",19 dropPrimaryColor: "#1abc9c",20 dropBorder: "1px solid #1abc9c"21 }),22 $("#dropper-lang").dateDropper({23 dropWidth: 200,24 format: "F S, Y",25 dropPrimaryColor: "#1abc9c",26 dropBorder: "1px solid #1abc9c",27 lang: "ar"28 }),29 $("#dropper-lock").dateDropper({30 dropWidth: 200,31 format: "F S, Y",32 dropPrimaryColor: "#1abc9c",33 dropBorder: "1px solid #1abc9c",34 lock: "from"35 }),36 $("#dropper-max-year").dateDropper({37 dropWidth: 200,38 dropPrimaryColor: "#1abc9c",39 dropBorder: "1px solid #1abc9c",40 maxYear: "2020"41 }),42 $("#dropper-min-year").dateDropper({43 dropWidth: 200,44 dropPrimaryColor: "#1abc9c",45 dropBorder: "1px solid #1abc9c",46 minYear: "1990"47 }),48 $("#year-range").dateDropper({49 dropWidth: 200,50 dropPrimaryColor: "#1abc9c",51 dropBorder: "1px solid #1abc9c",52 yearsRange: "5"53 }),54 $("#dropper-width").dateDropper({55 dropPrimaryColor: "#1abc9c",56 dropBorder: "1px solid #1abc9c",57 dropWidth: 50058 }),59 $("#dropper-dangercolor").dateDropper({60 dropWidth: 200,61 dropPrimaryColor: "#e74c3c",62 dropBorder: "1px solid #e74c3c",63 }),64 $("#dropper-backcolor").dateDropper({65 dropWidth: 200,66 dropPrimaryColor: "#1abc9c",67 dropBorder: "1px solid #1abc9c",68 dropBackgroundColor: "#bdc3c7"69 }),70 $("#dropper-txtcolor").dateDropper({71 dropWidth: 200,72 dropPrimaryColor: "#46627f",73 dropBorder: "1px solid #46627f",74 dropTextColor: "#FFF",75 dropBackgroundColor: "#e74c3c"76 }),77 $("#dropper-radius").dateDropper({78 dropWidth: 200,79 dropPrimaryColor: "#1abc9c",80 dropBorder: "1px solid #1abc9c",81 dropBorderRadius: "0"82 }),83 $("#dropper-border").dateDropper({84 dropWidth: 200,85 dropPrimaryColor: "#1abc9c",86 dropBorder: "2px solid #1abc9c"87 }),88 $("#dropper-shadow").dateDropper({89 dropWidth: 200,90 dropPrimaryColor: "#1abc9c",91 dropBorder: "1px solid #1abc9c",92 dropBorderRadius: "20px",93 dropShadow: "0 0 20px 0 rgba(26, 188, 156, 0.6)"94 }),95 */96 $('#inlinedatetimepicker').datetimepicker({97 inline: true,98 sideBySide: true99 });100 $('#datepicker').datetimepicker({101 format: 'L'102 });103 $('#timepicker').datetimepicker({104 format: 'LT'105 });106 107 $('.demo').each( function() {108 //109 // Dear reader, it's actually very easy to initialize MiniColors. For example:110 //111 // $(selector).minicolors();112 //113 // The way I've done it below is just for the demo, so don't get confused114 // by it. Also, data- attributes aren't supported at this time...they're115 // only used for this demo.116 //117 $(this).minicolors({118 control: $(this).attr('data-control') || 'hue',119 defaultValue: $(this).attr('data-defaultValue') || '',120 format: $(this).attr('data-format') || 'hex',121 keywords: $(this).attr('data-keywords') || '',122 inline: $(this).attr('data-inline') === 'true',123 letterCase: $(this).attr('data-letterCase') || 'lowercase',124 opacity: $(this).attr('data-opacity'),125 position: $(this).attr('data-position') || 'bottom left',126 swatches: $(this).attr('data-swatches') ? $(this).attr('data-swatches').split('|') : [],127 change: function(value, opacity) {128 if( !value ) return;129 if( opacity ) value += ', ' + opacity;130 if( typeof console === 'object' ) {131 console.log(value);132 }133 },134 theme: 'bootstrap'135 });136 });137 })...
date-time-dropper.js
Source:date-time-dropper.js
1/*=========================================================================================2 File Name: date-time-dropper.js3 Description: Datepicker and Timepicker plugins based on jQuery4 ----------------------------------------------------------------------------------------5 Item Name: Modern Admin - Clean Bootstrap 4 Dashboard HTML Template6 Version: 3.07 Author: GeeksLabs8 Author URL: http://www.themeforest.net/user/geekslabs9==========================================================================================*/10$(document).ready(function(){11 /********************************************12 * Date Dropper *13 ********************************************/14 // Options15 // Animate16 $('#animate').dateDropper({17 dropWidth: 20018 });19 // Init Animation20 $('#init_animation').dateDropper({21 dropWidth: 200,22 init_animation: 'bounce'23 });24 // Format25 $('#format').dateDropper({26 dropWidth: 200,27 format: 'j l, F, Y'28 });29 // Lang30 $('#lang').dateDropper({31 dropWidth: 200,32 lang: 'ar' // Arabic33 });34 // Lock35 $('#lock').dateDropper({36 dropWidth: 200,37 lock: 'from' // To select date after today, 'to' to select date before today38 });39 // Max Year40 $('#maxYear').dateDropper({41 dropWidth: 200,42 maxYear: '2020'43 });44 // Min Year45 $('#minYear').dateDropper({46 dropWidth: 200,47 minYear: '2001'48 });49 // Years Range50 $('#yearsRange').dateDropper({51 dropWidth: 200,52 yearsRange: '5'53 });54 // Styles55 // Drop Primary Color56 $('#dropPrimaryColor').dateDropper({57 dropWidth: 200,58 dropPrimaryColor: '#F6BB42',59 dropBorder: '1px solid #F6BB42'60 });61 // Drop Text Color62 $('#dropTextColor').dateDropper({63 dropWidth: 200,64 dropPrimaryColor: '#10617E',65 dropBorder: '1px solid #10617E',66 dropBackgroundColor: '#23b1e3',67 dropTextColor: '#FFF'68 });69 // Drop Background Color70 $('#dropBackgroundColor').dateDropper({71 dropWidth: 200,72 dropBackgroundColor: '#ACDAEC',73 });74 // Drop Border75 $('#dropBorder').dateDropper({76 dropWidth: 200,77 dropPrimaryColor: '#2fb594',78 dropBorder: '1px solid #2dad8d',79 });80 // Drop Border Radius81 $('#dropBorderRadius').dateDropper({82 dropWidth: 200,83 dropPrimaryColor: '#e8273a',84 dropBorder: '1px solid #e71e32',85 dropBorderRadius: '0'86 });87 // Drop Shadow88 $('#dropShadow').dateDropper({89 dropWidth: 200,90 dropPrimaryColor: '#fa4420',91 dropBorder: '1px solid #fa4420',92 dropBorderRadius: '20',93 dropShadow: '0 0 10px 0 rgba(250, 68, 32, 0.6)'94 });95 // Drop Width96 $('#dropWidth').dateDropper({97 dropWidth: 25098 });99 // Drop Text Weight100 $('#dropTextWeight').dateDropper({101 dropWidth: 200,102 dropTextWeight: 'normal'103 });104 /********************************************105 * Time Dropper *106 ********************************************/107 // Options108 // Auto Switch109 $('#autoswitch').timeDropper();110 // Meridians111 $('#meridians').timeDropper({112 meridians: true113 });114 // Format115 $('#timeformat').timeDropper({116 format: 'HH:mm A'117 });118 // Mousewheel119 $('#mousewheel').timeDropper({120 mousewheel: true121 });122 // Init Animation123 $('#time_init_animation').timeDropper({124 init_animation: 'dropDown',125 meridians: true126 });127 // Set Current Time128 $('#setCurrentTime').timeDropper();129 // Styles130 // Primary Color131 $('#primaryColor').timeDropper({132 primaryColor: '#2fb594',133 borderColor: '#2fb594'134 });135 // Text Color136 $('#textColor').timeDropper({137 primaryColor: '#2fb594',138 textColor: '#e8273a'139 });140 // Background Color141 $('#backgroundColor').timeDropper({142 primaryColor: '#FFF',143 backgroundColor: '#fa4420',144 borderColor: '#781602',145 textColor: '#781602'146 });147 // Border Color148 $('#borderColor').timeDropper({149 primaryColor: '#FFF',150 backgroundColor: '#23b1e3',151 borderColor: '#FFF',152 textColor: '#FFF'153 });...
Using AI Code Generation
1const puppeteer = require('puppeteer');2(async () => {3 const browser = await puppeteer.launch();4 const page = await browser.newPage();5 await page.screenshot({path: 'google.png'});6 await browser.close();7})();8{9 "scripts": {10 },11 "dependencies": {12 }13}
Using AI Code Generation
1const puppeteer = require('puppeteer');2(async () => {3 const browser = await puppeteer.launch({headless: false});4 const page = await browser.newPage();5 await page.screenshot({path: 'example.png'});6 await browser.close();7})();8const puppeteer = require('puppeteer');9(async () => {10 const browser = await puppeteer.launch({headless: false});11 const page = await browser.newPage();12 await page.screenshot({path: 'example.png'});13 await browser.close();14})();15const puppeteer = require('puppeteer');16(async () => {17 const browser = await puppeteer.launch({headless: false});18 const page = await browser.newPage();19 await page.screenshot({path: 'example.png'});20 await browser.close();21})();22const puppeteer = require('puppeteer');23(async () => {24 const browser = await puppeteer.launch({headless: false});25 const page = await browser.newPage();26 await page.screenshot({path: 'example.png'});27 await browser.close();28})();29const puppeteer = require('puppeteer');30(async () => {31 const browser = await puppeteer.launch({headless: false});32 const page = await browser.newPage();33 await page.screenshot({path: 'example.png'});34 await browser.close();35})();36const puppeteer = require('puppeteer');37(async () => {38 const browser = await puppeteer.launch({headless: false});39 const page = await browser.newPage();40 await page.screenshot({path: 'example.png'});41 await browser.close();42})();43const puppeteer = require('p
Using AI Code Generation
1const puppeteer = require('puppeteer');2const fs = require('fs');3const path = require('path');4(async () => {5 const browser = await puppeteer.launch({headless: false});6 const page = await browser.newPage();7 await page.screenshot({path: 'example.png'});8 await browser.close();9})();
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!