ballonizer 0.2.4 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/examples/ballonizer_app/config.ru +4 -2
- data/examples/ballonizer_app/index.html +105 -157
- data/examples/ballonizer_app/test.db +0 -0
- data/examples/ballonizer_js_module/index.html +4 -4
- data/lib/assets/javascripts/ballonizer.js +119 -17
- data/lib/assets/stylesheets/ballonizer.css +17 -12
- data/lib/ballonizer.rb +81 -25
- data/spec/ballonizer_spec.rb +108 -45
- data/spec/javascripts/ballonizer_spec.js +186 -129
- data/spec/javascripts/fixtures/ballonized-xkcd-with-anchor-in-image.html +2 -2
- data/spec/javascripts/fixtures/ballonized-xkcd-with-ballons.html +2 -2
- data/spec/javascripts/fixtures/ballonized-xkcd-without-ballons.html +2 -2
- metadata +3 -2
@@ -54,6 +54,7 @@ describe("Ballonizer", function () {
|
|
54
54
|
afterEach(function () {
|
55
55
|
// Remove left-overs created out of the #jasmine-fixtures container
|
56
56
|
$(".ballonizer_page_form").remove();
|
57
|
+
$(".ballonizer_image_form").remove();
|
57
58
|
});
|
58
59
|
|
59
60
|
it("it's defined", function () {
|
@@ -126,13 +127,13 @@ describe("Ballonizer", function () {
|
|
126
127
|
});
|
127
128
|
});
|
128
129
|
describe("BallonizedImageContainer", function () {
|
129
|
-
it("adds a hidden form for the ballon edition in the
|
130
|
+
it("adds a hidden form for the ballon edition in the body", function () {
|
130
131
|
loadFixtures("ballonized-xkcd-without-ballons.html");
|
131
132
|
instance = Ballonizer(actionFormURL, imageToBallonizeCSSSelector, $("#jasmine-fixtures"));
|
132
|
-
expect($("
|
133
|
-
// What the value of
|
133
|
+
expect($("body")).toContain("form.ballonizer_image_form");
|
134
|
+
// What the value of action is not important, but the action attribute
|
134
135
|
// is required (http://www.w3.org/TR/html401/interact/forms.html#h-17.3)
|
135
|
-
expect($("form.ballonizer_image_form")).toHaveAttr("
|
136
|
+
expect($("form.ballonizer_image_form")).toHaveAttr("action");
|
136
137
|
expect($("form.ballonizer_image_form")).toBeHidden();
|
137
138
|
});
|
138
139
|
describe("when there's a image with ballons", function () {
|
@@ -155,6 +156,15 @@ describe("Ballonizer", function () {
|
|
155
156
|
});
|
156
157
|
});
|
157
158
|
describe("InterfaceBallon", function () {
|
159
|
+
var htmlUnescape = function (value) {
|
160
|
+
return (value)
|
161
|
+
.replace(/"/g, '"')
|
162
|
+
.replace(/'/g, "'")
|
163
|
+
.replace(/</g, '<')
|
164
|
+
.replace(/>/g, '>')
|
165
|
+
.replace(/&/g, '&');
|
166
|
+
};
|
167
|
+
|
158
168
|
var containerWidth, containerHeight;
|
159
169
|
var getBallons = function () {
|
160
170
|
loadFixtures("ballonized-xkcd-with-ballons.html");
|
@@ -185,14 +195,17 @@ describe("Ballonizer", function () {
|
|
185
195
|
it("creates a hidden edit ballon for each ballon", function () {
|
186
196
|
ballons = getBallons();
|
187
197
|
|
188
|
-
var imgContainer = ballons[0].getBallonizedImageContainer()
|
189
|
-
var
|
198
|
+
var imgContainer = ballons[0].getBallonizedImageContainer();
|
199
|
+
var imgFormInnerContainer = imgContainer.getFormInnerContainer();
|
190
200
|
|
191
|
-
expect(
|
192
|
-
expect(
|
193
|
-
expect(
|
201
|
+
expect(imgFormInnerContainer.children().length).toEqual(2);
|
202
|
+
expect(imgFormInnerContainer.children()).toBeHidden();
|
203
|
+
expect(imgFormInnerContainer).toContain(
|
204
|
+
"textarea.ballonizer_edition_ballon"
|
205
|
+
);
|
194
206
|
|
195
|
-
var
|
207
|
+
var textfields = imgFormInnerContainer.children().toArray();
|
208
|
+
var textfieldTexts = textfields.map(function (e, ix) {
|
196
209
|
/* jshint unused: false */
|
197
210
|
return $(e).val();
|
198
211
|
}).sort();
|
@@ -251,17 +264,25 @@ describe("Ballonizer", function () {
|
|
251
264
|
});
|
252
265
|
it("hide the normal ballon and put the textarea (focused) in the place", function () {
|
253
266
|
ballons = getBallons();
|
267
|
+
var normalNode = ballons[0].getNormalNode();
|
268
|
+
var editionNode = ballons[0].getEditionNode();
|
254
269
|
|
255
|
-
|
256
|
-
|
270
|
+
var normalNodeBounds = normalNode.offset();
|
271
|
+
normalNodeBounds.width = normalNode.css('width');
|
272
|
+
normalNodeBounds.height = normalNode.css('height');
|
257
273
|
|
258
|
-
|
259
|
-
|
260
|
-
expect(ballons[0].getEditionNode()).toBeFocused();
|
274
|
+
// alternate to the edition mode
|
275
|
+
realWorldEvent("dblclick", normalNode);
|
261
276
|
|
262
|
-
expect(
|
263
|
-
|
264
|
-
);
|
277
|
+
expect(normalNode).toBeHidden();
|
278
|
+
expect(editionNode).toBeVisible();
|
279
|
+
expect(editionNode).toBeFocused();
|
280
|
+
|
281
|
+
var editionNodeBounds = editionNode.offset();
|
282
|
+
editionNodeBounds.width = editionNode.css('width');
|
283
|
+
editionNodeBounds.height = editionNode.css('height');
|
284
|
+
|
285
|
+
expect(editionNodeBounds).toEqual(normalNodeBounds);
|
265
286
|
});
|
266
287
|
describe("when the container is inside a <a/> element", function () {
|
267
288
|
it("prevent the default action of changing the page", function () {
|
@@ -269,8 +290,8 @@ describe("Ballonizer", function () {
|
|
269
290
|
loadFixtures("ballonized-xkcd-with-anchor-in-image.html");
|
270
291
|
instance = Ballonizer(actionFormURL, imageToBallonizeCSSSelector, $("#jasmine-fixtures"));
|
271
292
|
var ballonizedImg = $(".ballonizer_image_container img");
|
272
|
-
realWorldEvent("dblclick", ballonizedImg)
|
273
|
-
var ballon = $(".ballonizer_ballon")
|
293
|
+
realWorldEvent("dblclick", ballonizedImg);
|
294
|
+
var ballon = $(".ballonizer_ballon");
|
274
295
|
|
275
296
|
// and then we simulate a dblclick over the ballon
|
276
297
|
var spyAnchor = spyOnEvent("#comic a", "click");
|
@@ -306,20 +327,12 @@ describe("Ballonizer", function () {
|
|
306
327
|
|
307
328
|
expect(ballons.length).toEqual(1);
|
308
329
|
expect($(".ballonizer_ballon")).toHaveLength(1);
|
309
|
-
expect($("form.ballonizer_image_form
|
330
|
+
expect($("form.ballonizer_image_form " +
|
331
|
+
".ballonizer_edition_ballon")).toHaveLength(1);
|
310
332
|
});
|
311
333
|
});
|
312
334
|
});
|
313
335
|
describe("when the ballons change", function () {
|
314
|
-
var htmlUnescape = function (value) {
|
315
|
-
return (value)
|
316
|
-
.replace(/"/g, '"')
|
317
|
-
.replace(/'/g, "'")
|
318
|
-
.replace(/</g, '<')
|
319
|
-
.replace(/>/g, '>')
|
320
|
-
.replace(/&/g, '&');
|
321
|
-
};
|
322
|
-
|
323
336
|
describe("position", function () {
|
324
337
|
var changePosition = function (ballon, dx, dy) {
|
325
338
|
ballon.getNode().simulate("drag-n-drop", { dx: dx, dy: dy });
|
@@ -332,7 +345,7 @@ describe("Ballonizer", function () {
|
|
332
345
|
it("the button to submit change appears", function () {
|
333
346
|
ballons = getBallons();
|
334
347
|
changePosition(ballons[1], -20, -20);
|
335
|
-
expect($("form.ballonizer_page_form
|
348
|
+
expect($("form.ballonizer_page_form input[name='ballonizer_submit']")).toBeVisible();
|
336
349
|
});
|
337
350
|
it("the serialize methods shows the new values", function () {
|
338
351
|
ballons = getBallons();
|
@@ -353,8 +366,10 @@ describe("Ballonizer", function () {
|
|
353
366
|
expect(ballonizer.serialize()["http://imgs.xkcd.com/comics/cells.png"][1].top).toEqual(expectedTop);
|
354
367
|
});
|
355
368
|
it("the page form data update", function () {
|
369
|
+
/* jshint camelcase: false */
|
370
|
+
// font_size is in ruby style because is sent to the ruby
|
356
371
|
ballons = getBallons();
|
357
|
-
var formData = $("form.ballonizer_page_form
|
372
|
+
var formData = $("form.ballonizer_page_form input[name='ballonizer_data']");
|
358
373
|
expect(formData).toHaveValue("");
|
359
374
|
changePosition(ballons[1], -20, -20);
|
360
375
|
expect(jQuery.parseJSON(htmlUnescape(formData.val()))).toEqual({
|
@@ -363,12 +378,14 @@ describe("Ballonizer", function () {
|
|
363
378
|
top: 0,
|
364
379
|
width: 1,
|
365
380
|
height: 0.24188790560471976,
|
381
|
+
font_size: 15,
|
366
382
|
text: 'When you see a claim that a common drug or vitamin "kills cancer cells in a petri dish", keep in mind:'
|
367
383
|
},
|
368
384
|
{ left: 0.0045871559633027525,
|
369
385
|
top: 0.8820058997050148,
|
370
386
|
width: 0.7798165137614679,
|
371
387
|
height: 0.05604719764011799,
|
388
|
+
font_size: 14,
|
372
389
|
text: 'So does a handgun.'
|
373
390
|
}
|
374
391
|
]
|
@@ -387,29 +404,40 @@ describe("Ballonizer", function () {
|
|
387
404
|
it("the button to submit change appears", function () {
|
388
405
|
ballons = getBallons();
|
389
406
|
changeSize(ballons[0], -20, -20);
|
390
|
-
expect($("form.ballonizer_page_form
|
407
|
+
expect($("form.ballonizer_page_form input[name='ballonizer_submit']")).toBeVisible();
|
391
408
|
});
|
392
|
-
it("the serialize methods shows the new values", function () {
|
409
|
+
it("the serialize methods shows the new values (to size and font-size)", function () {
|
410
|
+
/* jshint camelcase: false */
|
411
|
+
// font_size is in ruby style because is sent to the ruby
|
393
412
|
ballons = getBallons();
|
394
413
|
var ballon = ballons[0],
|
395
414
|
image = ballon.getBallonizedImageContainer(),
|
396
415
|
ballonizer = image.getBallonizerInstance(),
|
397
416
|
bounds = ballon.getPositionAndSize(),
|
398
417
|
expectedWidth = (bounds.width - 20) / containerWidth,
|
399
|
-
expectedHeight = (bounds.height - 20) / containerHeight
|
418
|
+
expectedHeight = (bounds.height - 20) / containerHeight,
|
419
|
+
expectedFontSize = 11; // verified by observation
|
400
420
|
|
401
421
|
changeSize(ballons[0], -20, -20);
|
402
422
|
|
423
|
+
// check the serialize of the ballon
|
403
424
|
expect(ballon.serialize().width).toEqual(expectedWidth);
|
404
425
|
expect(ballon.serialize().height).toEqual(expectedHeight);
|
426
|
+
expect(ballon.serialize().font_size).toEqual(expectedFontSize);
|
427
|
+
// check the serialize of the image
|
405
428
|
expect(image.serialize()[0].width).toEqual(expectedWidth);
|
406
429
|
expect(image.serialize()[0].height).toEqual(expectedHeight);
|
430
|
+
expect(image.serialize()[0].font_size).toEqual(expectedFontSize);
|
431
|
+
// check the serialize of the ballonizer
|
407
432
|
expect(ballonizer.serialize()["http://imgs.xkcd.com/comics/cells.png"][0].width).toEqual(expectedWidth);
|
408
433
|
expect(ballonizer.serialize()["http://imgs.xkcd.com/comics/cells.png"][0].height).toEqual(expectedHeight);
|
434
|
+
expect(ballonizer.serialize()["http://imgs.xkcd.com/comics/cells.png"][0].font_size).toEqual(expectedFontSize);
|
409
435
|
});
|
410
|
-
it("the page form data update", function () {
|
436
|
+
it("the page form data update (size and font-size)", function () {
|
437
|
+
/* jshint camelcase: false */
|
438
|
+
// font_size is in ruby style because is sent to the ruby
|
411
439
|
ballons = getBallons();
|
412
|
-
var formData = $("form.ballonizer_page_form
|
440
|
+
var formData = $("form.ballonizer_page_form input[name='ballonizer_data']");
|
413
441
|
expect(formData).toHaveValue("");
|
414
442
|
changeSize(ballons[0], -20, -20);
|
415
443
|
expect(jQuery.parseJSON(htmlUnescape(formData.val()))).toEqual({
|
@@ -418,12 +446,15 @@ describe("Ballonizer", function () {
|
|
418
446
|
top: 0,
|
419
447
|
width: 0.908256880733945,
|
420
448
|
height: 0.18289085545722714,
|
449
|
+
// font-size is changed by the change of the ballon size
|
450
|
+
font_size: 11,
|
421
451
|
text: 'When you see a claim that a common drug or vitamin "kills cancer cells in a petri dish", keep in mind:'
|
422
452
|
},
|
423
453
|
{ left: 0.0963302752293578,
|
424
454
|
top: 0.9410029498525073,
|
425
455
|
width: 0.7798165137614679,
|
426
456
|
height: 0.05604719764011799,
|
457
|
+
font_size: 14,
|
427
458
|
text: 'So does a handgun.'
|
428
459
|
}
|
429
460
|
]
|
@@ -441,24 +472,35 @@ describe("Ballonizer", function () {
|
|
441
472
|
it("the button to submit change appears", function () {
|
442
473
|
ballons = getBallons();
|
443
474
|
changeText(ballons[0], "Ballon new text");
|
444
|
-
expect($("form.ballonizer_page_form
|
475
|
+
expect($("form.ballonizer_page_form input[name='ballonizer_submit']")).toBeVisible();
|
445
476
|
});
|
446
|
-
it("the serialize methods shows the new values", function () {
|
477
|
+
it("the serialize methods shows the new values (for text and font-size)", function () {
|
478
|
+
/* jshint camelcase: false */
|
479
|
+
// font_size is in ruby style because is sent to the ruby
|
447
480
|
ballons = getBallons();
|
448
481
|
var ballon = ballons[0],
|
449
482
|
text = "Ballon new text",
|
450
483
|
image = ballon.getBallonizedImageContainer(),
|
451
|
-
ballonizer = image.getBallonizerInstance()
|
484
|
+
ballonizer = image.getBallonizerInstance(),
|
485
|
+
expectedFontSize = 32; // verified by observation
|
452
486
|
|
453
487
|
changeText(ballon, text);
|
454
488
|
|
489
|
+
// ballon serialize
|
455
490
|
expect(ballon.serialize().text).toEqual(text);
|
491
|
+
expect(ballon.serialize().font_size).toEqual(expectedFontSize);
|
492
|
+
// image serialize
|
456
493
|
expect(image.serialize()[0].text).toEqual(text);
|
494
|
+
expect(image.serialize()[0].font_size).toEqual(expectedFontSize);
|
495
|
+
// ballonizer serialize
|
457
496
|
expect(ballonizer.serialize()["http://imgs.xkcd.com/comics/cells.png"][0].text).toEqual(text);
|
497
|
+
expect(ballonizer.serialize()["http://imgs.xkcd.com/comics/cells.png"][0].font_size).toEqual(expectedFontSize);
|
458
498
|
});
|
459
|
-
it("the page form data update", function () {
|
499
|
+
it("the page form data update (text and font-size)", function () {
|
500
|
+
/* jshint camelcase: false */
|
501
|
+
// font_size is in ruby style because is sent to the ruby
|
460
502
|
ballons = getBallons();
|
461
|
-
var formData = $("form.ballonizer_page_form
|
503
|
+
var formData = $("form.ballonizer_page_form input[name='ballonizer_data']");
|
462
504
|
expect(formData).toHaveValue("");
|
463
505
|
changeText(ballons[0], "Ballon new text");
|
464
506
|
expect(jQuery.parseJSON(htmlUnescape(formData.val()))).toEqual({
|
@@ -467,114 +509,129 @@ describe("Ballonizer", function () {
|
|
467
509
|
top: 0,
|
468
510
|
width: 1,
|
469
511
|
height: 0.24188790560471976,
|
512
|
+
// the font-size increment as the ballon size
|
513
|
+
// is the same but have lesser text
|
514
|
+
font_size: 32,
|
470
515
|
text: 'Ballon new text'
|
471
516
|
},
|
472
517
|
{ left: 0.0963302752293578,
|
473
518
|
top: 0.9410029498525073,
|
474
519
|
width: 0.7798165137614679,
|
475
520
|
height: 0.05604719764011799,
|
521
|
+
font_size: 14,
|
476
522
|
text: 'So does a handgun.'
|
477
523
|
}
|
478
524
|
]
|
479
525
|
});
|
480
526
|
});
|
481
527
|
});
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
});
|
494
|
-
it("the serialize methods shows the new values", function () {
|
495
|
-
ballons = getBallons();
|
496
|
-
addBallon();
|
497
|
-
var image = ballons[0].getBallonizedImageContainer(),
|
498
|
-
imageData = image.serialize(),
|
499
|
-
ballonizer = image.getBallonizerInstance(),
|
500
|
-
ballonizerData = ballonizer.serialize();
|
528
|
+
});
|
529
|
+
describe("when a ballon is added", function () {
|
530
|
+
var addBallon = function () {
|
531
|
+
var offset = $(".ballonizer_image_container").offset();
|
532
|
+
$(".ballonizer_image_container img").trigger(
|
533
|
+
jQuery.Event("dblclick", {
|
534
|
+
pageX: offset.left + 100,
|
535
|
+
pageY: offset.top + 109
|
536
|
+
})
|
537
|
+
);
|
538
|
+
};
|
501
539
|
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
540
|
+
it("the button to submit change appears", function () {
|
541
|
+
getBallons();
|
542
|
+
addBallon();
|
543
|
+
expect($("form.ballonizer_page_form input[name='ballonizer_submit']")).toBeVisible();
|
544
|
+
});
|
545
|
+
it("the serialize methods shows the new values", function () {
|
546
|
+
ballons = getBallons();
|
547
|
+
addBallon();
|
548
|
+
var image = ballons[0].getBallonizedImageContainer(),
|
549
|
+
imageData = image.serialize(),
|
550
|
+
ballonizer = image.getBallonizerInstance(),
|
551
|
+
ballonizerData = ballonizer.serialize();
|
552
|
+
|
553
|
+
expect(imageData.length).toEqual(3);
|
554
|
+
expect(ballonizerData["http://imgs.xkcd.com/comics/cells.png"].length).toEqual(3);
|
555
|
+
});
|
556
|
+
it("the page form data update", function () {
|
557
|
+
/* jshint camelcase: false */
|
558
|
+
// font_size is in ruby style because is sent to the ruby
|
559
|
+
getBallons();
|
560
|
+
var formData = $("form.ballonizer_page_form input[name='ballonizer_data']");
|
561
|
+
expect(formData).toHaveValue("");
|
562
|
+
addBallon();
|
563
|
+
expect(jQuery.parseJSON(htmlUnescape(formData.val()))).toEqual({
|
564
|
+
"http://imgs.xkcd.com/comics/cells.png": [
|
565
|
+
{ left: 0,
|
566
|
+
top: 0,
|
567
|
+
width: 1,
|
568
|
+
height: 0.24188790560471976,
|
569
|
+
font_size: 15,
|
570
|
+
text: 'When you see a claim that a common drug or vitamin "kills cancer cells in a petri dish", keep in mind:'
|
571
|
+
},
|
572
|
+
{ left: 0.0963302752293578,
|
573
|
+
top: 0.9410029498525073,
|
574
|
+
width: 0.7798165137614679,
|
575
|
+
height: 0.05604719764011799,
|
576
|
+
font_size: 14,
|
577
|
+
text: 'So does a handgun.'
|
578
|
+
},
|
579
|
+
{ left: 0.40825688073394495,
|
580
|
+
top: 0.3215339233038348,
|
581
|
+
width: 0.591743119266055,
|
582
|
+
height: 0.12094395280235988,
|
583
|
+
font_size: 15, text: 'double click to edit ballon text'
|
584
|
+
}
|
585
|
+
]
|
532
586
|
});
|
533
587
|
});
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
588
|
+
});
|
589
|
+
describe("when a ballon is removed", function () {
|
590
|
+
var removeBallon = function (ballon) {
|
591
|
+
realWorldEvent("dblclick", ballon.getNode());
|
592
|
+
ballon.getNode().val("");
|
593
|
+
ballon.getNode().blur();
|
539
594
|
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
595
|
+
return ballon;
|
596
|
+
};
|
597
|
+
it("the button to submit change appears", function () {
|
598
|
+
ballons = getBallons();
|
599
|
+
removeBallon(ballons[0]);
|
600
|
+
expect($("form.ballonizer_page_form input[name='ballonizer_submit']")).toBeVisible();
|
546
601
|
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
602
|
+
return ballons;
|
603
|
+
});
|
604
|
+
it("the serialize methods shows the new values", function () {
|
605
|
+
ballons = getBallons();
|
551
606
|
|
552
|
-
|
553
|
-
|
607
|
+
var image = ballons[0].getBallonizedImageContainer(),
|
608
|
+
ballonizer = image.getBallonizerInstance();
|
554
609
|
|
555
|
-
|
610
|
+
removeBallon(ballons[0]);
|
556
611
|
|
557
|
-
|
558
|
-
|
612
|
+
var imageData = image.serialize(),
|
613
|
+
ballonizerData = ballonizer.serialize();
|
559
614
|
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
615
|
+
expect(imageData.length).toEqual(1);
|
616
|
+
expect(ballonizerData["http://imgs.xkcd.com/comics/cells.png"].length).toEqual(1);
|
617
|
+
});
|
618
|
+
it("the page form data update", function () {
|
619
|
+
/* jshint camelcase: false */
|
620
|
+
// font_size is in ruby style because is sent to the ruby
|
621
|
+
ballons = getBallons();
|
622
|
+
var formData = $("form.ballonizer_page_form input[name='ballonizer_data']");
|
623
|
+
expect(formData).toHaveValue("");
|
624
|
+
removeBallon(ballons[0]);
|
625
|
+
expect(jQuery.parseJSON(htmlUnescape(formData.val()))).toEqual({
|
626
|
+
"http://imgs.xkcd.com/comics/cells.png": [
|
627
|
+
{ left: 0.0963302752293578,
|
628
|
+
top: 0.9410029498525073,
|
629
|
+
width: 0.7798165137614679,
|
630
|
+
height: 0.05604719764011799,
|
631
|
+
font_size: 14,
|
632
|
+
text: 'So does a handgun.'
|
633
|
+
}
|
634
|
+
]
|
578
635
|
});
|
579
636
|
});
|
580
637
|
});
|
@@ -62,11 +62,11 @@
|
|
62
62
|
the events will not trigger until the image is loaded because the divs
|
63
63
|
are defined with percentuals and will have size zero (impossible to click).
|
64
64
|
-->
|
65
|
-
<a href="http://xkcd.com/1218/" ><
|
65
|
+
<a href="http://xkcd.com/1218/" ><span class="ballonizer_image_container"><img src="http://imgs.xkcd.com/comics/cells.png"
|
66
66
|
title="Now, if it selectively kills cancer cells in a petri dish, you can be sure it's at least a great breakthrough for everyone suffering from petri dish cancer."
|
67
67
|
width="218px"
|
68
68
|
height="339px"
|
69
|
-
alt="Cells" /></
|
69
|
+
alt="Cells" /></span></a>
|
70
70
|
</div>
|
71
71
|
<ul class="comicNav">
|
72
72
|
<li>
|
@@ -62,11 +62,11 @@
|
|
62
62
|
the events will not trigger until the image is loaded because the divs
|
63
63
|
are defined with percentuals and will have size zero (impossible to click).
|
64
64
|
-->
|
65
|
-
<
|
65
|
+
<span class="ballonizer_image_container"><span style="left: 0px; top: 0px; width: 218px; height: 82px; font-size: 15px;" class="ballonizer_ballon" >When you see a claim that a common drug or vitamin "kills cancer cells in a petri dish", keep in mind:</span><span style="top: 319px; left: 21px; width: 170px; height: 19px; font-size: 14px;" class="ballonizer_ballon">So does a handgun.</span><img src="http://imgs.xkcd.com/comics/cells.png"
|
66
66
|
title="Now, if it selectively kills cancer cells in a petri dish, you can be sure it's at least a great breakthrough for everyone suffering from petri dish cancer."
|
67
67
|
width="218px"
|
68
68
|
height="339px"
|
69
|
-
alt="Cells" /></
|
69
|
+
alt="Cells" /></span>
|
70
70
|
</div>
|
71
71
|
<ul class="comicNav">
|
72
72
|
<li>
|
@@ -62,11 +62,11 @@
|
|
62
62
|
the events will not trigger until the image is loaded because the divs
|
63
63
|
are defined with percentuals and will have size zero (impossible to click).
|
64
64
|
-->
|
65
|
-
<
|
65
|
+
<span class="ballonizer_image_container"><img src="http://imgs.xkcd.com/comics/cells.png"
|
66
66
|
title="Now, if it selectively kills cancer cells in a petri dish, you can be sure it's at least a great breakthrough for everyone suffering from petri dish cancer."
|
67
67
|
width="218px"
|
68
68
|
height="339px"
|
69
|
-
alt="Cells" /></
|
69
|
+
alt="Cells" /></span>
|
70
70
|
</div>
|
71
71
|
<ul class="comicNav">
|
72
72
|
<li>
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ballonizer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henrique Becker
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-07-
|
11
|
+
date: 2013-07-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -262,6 +262,7 @@ files:
|
|
262
262
|
- vendor/assets/javascripts/jquery-ui-1.10.3.custom.min.js
|
263
263
|
- examples/ballonizer_app/index.html
|
264
264
|
- examples/ballonizer_app/config.ru
|
265
|
+
- examples/ballonizer_app/test.db
|
265
266
|
- examples/ballonizer_js_module/index.html
|
266
267
|
- Rakefile
|
267
268
|
homepage: http://rubygems.org/gems/ballonizer
|