3324 </xsl:text> |
3330 </xsl:text> |
3325 <xsl:text> make_clickable(span, func) { |
3331 <xsl:text> make_clickable(span, func) { |
3326 </xsl:text> |
3332 </xsl:text> |
3327 <xsl:text> let txt = this.text_elt; |
3333 <xsl:text> let txt = this.text_elt; |
3328 </xsl:text> |
3334 </xsl:text> |
|
3335 <xsl:text> let original_text_y = this.text_bbox.y; |
|
3336 </xsl:text> |
|
3337 <xsl:text> let highlight = this.highlight_elt; |
|
3338 </xsl:text> |
|
3339 <xsl:text> let original_h_y = this.highlight_bbox.y; |
|
3340 </xsl:text> |
|
3341 <xsl:text> let clickable = highlight.cloneNode(); |
|
3342 </xsl:text> |
|
3343 <xsl:text> let yoffset = span.getBBox().y - original_text_y; |
|
3344 </xsl:text> |
|
3345 <xsl:text> clickable.y.baseVal.value = original_h_y + yoffset; |
|
3346 </xsl:text> |
|
3347 <xsl:text> clickable.style.pointerEvents = "bounding-box"; |
|
3348 </xsl:text> |
|
3349 <xsl:text> //clickable.style.visibility = "hidden"; |
|
3350 </xsl:text> |
|
3351 <xsl:text> //clickable.onclick = () => alert("love JS"); |
|
3352 </xsl:text> |
|
3353 <xsl:text> clickable.onclick = func; |
|
3354 </xsl:text> |
|
3355 <xsl:text> this.element.appendChild(clickable); |
|
3356 </xsl:text> |
|
3357 <xsl:text> this.clickables.push(clickable) |
|
3358 </xsl:text> |
|
3359 <xsl:text> } |
|
3360 </xsl:text> |
|
3361 <xsl:text> reset_clickables() { |
|
3362 </xsl:text> |
|
3363 <xsl:text> while(this.clickables.length){ |
|
3364 </xsl:text> |
|
3365 <xsl:text> this.element.removeChild(this.clickables.pop()); |
|
3366 </xsl:text> |
|
3367 <xsl:text> } |
|
3368 </xsl:text> |
|
3369 <xsl:text> } |
|
3370 </xsl:text> |
|
3371 <xsl:text> // Set text content when content is smaller than menu (no scrolling) |
|
3372 </xsl:text> |
|
3373 <xsl:text> set_complete_text(){ |
|
3374 </xsl:text> |
|
3375 <xsl:text> let spans = this.text_elt.children; |
|
3376 </xsl:text> |
|
3377 <xsl:text> let c = 0; |
|
3378 </xsl:text> |
|
3379 <xsl:text> for(let item of this.content){ |
|
3380 </xsl:text> |
|
3381 <xsl:text> let span=spans[c]; |
|
3382 </xsl:text> |
|
3383 <xsl:text> span.textContent = item; |
|
3384 </xsl:text> |
|
3385 <xsl:text> let sel = c; |
|
3386 </xsl:text> |
|
3387 <xsl:text> this.make_clickable(span, (evt) => this.bound_on_selection_click(sel)); |
|
3388 </xsl:text> |
|
3389 <xsl:text> c++; |
|
3390 </xsl:text> |
|
3391 <xsl:text> } |
|
3392 </xsl:text> |
|
3393 <xsl:text> } |
|
3394 </xsl:text> |
|
3395 <xsl:text> // Move partial view : |
|
3396 </xsl:text> |
|
3397 <xsl:text> // false : upward, lower value |
|
3398 </xsl:text> |
|
3399 <xsl:text> // true : downward, higher value |
|
3400 </xsl:text> |
|
3401 <xsl:text> scroll(forward){ |
|
3402 </xsl:text> |
|
3403 <xsl:text> let contentlength = this.content.length; |
|
3404 </xsl:text> |
|
3405 <xsl:text> let spans = this.text_elt.children; |
|
3406 </xsl:text> |
|
3407 <xsl:text> let spanslength = spans.length; |
|
3408 </xsl:text> |
|
3409 <xsl:text> // reduce accounted menu size according to prsence of scroll buttons |
|
3410 </xsl:text> |
|
3411 <xsl:text> // since we scroll there is necessarly one button |
|
3412 </xsl:text> |
|
3413 <xsl:text> spanslength--; |
|
3414 </xsl:text> |
|
3415 <xsl:text> if(forward){ |
|
3416 </xsl:text> |
|
3417 <xsl:text> // reduce accounted menu size because of back button |
|
3418 </xsl:text> |
|
3419 <xsl:text> if(this.menu_offset != 0) spanslength--; |
|
3420 </xsl:text> |
|
3421 <xsl:text> this.menu_offset = Math.min( |
|
3422 </xsl:text> |
|
3423 <xsl:text> contentlength - spans.length + 1, |
|
3424 </xsl:text> |
|
3425 <xsl:text> this.menu_offset + spanslength); |
|
3426 </xsl:text> |
|
3427 <xsl:text> }else{ |
|
3428 </xsl:text> |
|
3429 <xsl:text> if(this.menu_offset - spanslength > 0) spanslength--; |
|
3430 </xsl:text> |
|
3431 <xsl:text> this.menu_offset = Math.max( |
|
3432 </xsl:text> |
|
3433 <xsl:text> 0, |
|
3434 </xsl:text> |
|
3435 <xsl:text> this.menu_offset - spanslength); |
|
3436 </xsl:text> |
|
3437 <xsl:text> } |
|
3438 </xsl:text> |
|
3439 <xsl:text> if(this.menu_offset == 1) |
|
3440 </xsl:text> |
|
3441 <xsl:text> this.menu_offset = 0; |
|
3442 </xsl:text> |
|
3443 <xsl:text> |
|
3444 </xsl:text> |
|
3445 <xsl:text> this.reset_highlight(); |
|
3446 </xsl:text> |
|
3447 <xsl:text> |
|
3448 </xsl:text> |
|
3449 <xsl:text> this.reset_clickables(); |
|
3450 </xsl:text> |
|
3451 <xsl:text> this.set_partial_text(); |
|
3452 </xsl:text> |
|
3453 <xsl:text> |
|
3454 </xsl:text> |
|
3455 <xsl:text> this.highlight_selection(); |
|
3456 </xsl:text> |
|
3457 <xsl:text> } |
|
3458 </xsl:text> |
|
3459 <xsl:text> // Setup partial view text content |
|
3460 </xsl:text> |
|
3461 <xsl:text> // with jumps at first and last entry when appropriate |
|
3462 </xsl:text> |
|
3463 <xsl:text> set_partial_text(){ |
|
3464 </xsl:text> |
|
3465 <xsl:text> let spans = this.text_elt.children; |
|
3466 </xsl:text> |
|
3467 <xsl:text> let contentlength = this.content.length; |
|
3468 </xsl:text> |
|
3469 <xsl:text> let spanslength = spans.length; |
|
3470 </xsl:text> |
|
3471 <xsl:text> let i = this.menu_offset, c = 0; |
|
3472 </xsl:text> |
|
3473 <xsl:text> let m = this.box_bbox; |
|
3474 </xsl:text> |
|
3475 <xsl:text> while(c < spanslength){ |
|
3476 </xsl:text> |
|
3477 <xsl:text> let span=spans[c]; |
|
3478 </xsl:text> |
|
3479 <xsl:text> let onclickfunc; |
|
3480 </xsl:text> |
|
3481 <xsl:text> // backward jump only present if not exactly at start |
|
3482 </xsl:text> |
|
3483 <xsl:text> if(c == 0 && i != 0){ |
|
3484 </xsl:text> |
|
3485 <xsl:text> span.textContent = "▲"; |
|
3486 </xsl:text> |
|
3487 <xsl:text> onclickfunc = this.bound_on_backward_click; |
|
3488 </xsl:text> |
|
3489 <xsl:text> let o = span.getBBox(); |
|
3490 </xsl:text> |
|
3491 <xsl:text> span.setAttribute("dx", (m.width - o.width)/2); |
|
3492 </xsl:text> |
|
3493 <xsl:text> // presence of forward jump when not right at the end |
|
3494 </xsl:text> |
|
3495 <xsl:text> }else if(c == spanslength-1 && i < contentlength - 1){ |
|
3496 </xsl:text> |
|
3497 <xsl:text> span.textContent = "▼"; |
|
3498 </xsl:text> |
|
3499 <xsl:text> onclickfunc = this.bound_on_forward_click; |
|
3500 </xsl:text> |
|
3501 <xsl:text> let o = span.getBBox(); |
|
3502 </xsl:text> |
|
3503 <xsl:text> span.setAttribute("dx", (m.width - o.width)/2); |
|
3504 </xsl:text> |
|
3505 <xsl:text> // otherwise normal content |
|
3506 </xsl:text> |
|
3507 <xsl:text> }else{ |
|
3508 </xsl:text> |
|
3509 <xsl:text> span.textContent = this.content[i]; |
|
3510 </xsl:text> |
|
3511 <xsl:text> let sel = i; |
|
3512 </xsl:text> |
|
3513 <xsl:text> onclickfunc = (evt) => this.bound_on_selection_click(sel); |
|
3514 </xsl:text> |
|
3515 <xsl:text> span.removeAttribute("dx"); |
|
3516 </xsl:text> |
|
3517 <xsl:text> i++; |
|
3518 </xsl:text> |
|
3519 <xsl:text> } |
|
3520 </xsl:text> |
|
3521 <xsl:text> this.make_clickable(span, onclickfunc); |
|
3522 </xsl:text> |
|
3523 <xsl:text> c++; |
|
3524 </xsl:text> |
|
3525 <xsl:text> } |
|
3526 </xsl:text> |
|
3527 <xsl:text> } |
|
3528 </xsl:text> |
|
3529 <xsl:text> open(){ |
|
3530 </xsl:text> |
|
3531 <xsl:text> let length = this.content.length; |
|
3532 </xsl:text> |
|
3533 <xsl:text> // systematically reset text, to strip eventual whitespace spans |
|
3534 </xsl:text> |
|
3535 <xsl:text> this.reset_text(); |
|
3536 </xsl:text> |
|
3537 <xsl:text> // grow as much as needed or possible |
|
3538 </xsl:text> |
|
3539 <xsl:text> let slots = this.grow_text(length); |
|
3540 </xsl:text> |
|
3541 <xsl:text> // Depending on final size |
|
3542 </xsl:text> |
|
3543 <xsl:text> if(slots == length) { |
|
3544 </xsl:text> |
|
3545 <xsl:text> // show all at once |
|
3546 </xsl:text> |
|
3547 <xsl:text> this.set_complete_text(); |
|
3548 </xsl:text> |
|
3549 <xsl:text> } else { |
|
3550 </xsl:text> |
|
3551 <xsl:text> // eventualy align menu to current selection, compensating for lift |
|
3552 </xsl:text> |
|
3553 <xsl:text> let offset = this.last_selection - this.lift; |
|
3554 </xsl:text> |
|
3555 <xsl:text> if(offset > 0) |
|
3556 </xsl:text> |
|
3557 <xsl:text> this.menu_offset = Math.min(offset + 1, length - slots + 1); |
|
3558 </xsl:text> |
|
3559 <xsl:text> else |
|
3560 </xsl:text> |
|
3561 <xsl:text> this.menu_offset = 0; |
|
3562 </xsl:text> |
|
3563 <xsl:text> // show surrounding values |
|
3564 </xsl:text> |
|
3565 <xsl:text> this.set_partial_text(); |
|
3566 </xsl:text> |
|
3567 <xsl:text> } |
|
3568 </xsl:text> |
|
3569 <xsl:text> // Now that text size is known, we can set the box around it |
|
3570 </xsl:text> |
|
3571 <xsl:text> this.adjust_box_to_text(); |
|
3572 </xsl:text> |
|
3573 <xsl:text> // Take button out until menu closed |
|
3574 </xsl:text> |
|
3575 <xsl:text> this.element.removeChild(this.button_elt); |
|
3576 </xsl:text> |
|
3577 <xsl:text> // Rise widget to top by moving it to last position among siblings |
|
3578 </xsl:text> |
|
3579 <xsl:text> this.element.parentNode.appendChild(this.element.parentNode.removeChild(this.element)); |
|
3580 </xsl:text> |
|
3581 <xsl:text> // disable interaction with background |
|
3582 </xsl:text> |
|
3583 <xsl:text> svg_root.addEventListener("pointerdown", numb_event, true); |
|
3584 </xsl:text> |
|
3585 <xsl:text> svg_root.addEventListener("pointerup", numb_event, true); |
|
3586 </xsl:text> |
|
3587 <xsl:text> svg_root.addEventListener("click", this.bound_close_on_click_elsewhere, true); |
|
3588 </xsl:text> |
|
3589 <xsl:text> this.highlight_selection(); |
|
3590 </xsl:text> |
|
3591 <xsl:text> |
|
3592 </xsl:text> |
|
3593 <xsl:text> // mark as open |
|
3594 </xsl:text> |
|
3595 <xsl:text> this.opened = true; |
|
3596 </xsl:text> |
|
3597 <xsl:text> } |
|
3598 </xsl:text> |
|
3599 <xsl:text> // Put text element in normalized state |
|
3600 </xsl:text> |
|
3601 <xsl:text> reset_text(){ |
|
3602 </xsl:text> |
|
3603 <xsl:text> let txt = this.text_elt; |
|
3604 </xsl:text> |
3329 <xsl:text> let first = txt.firstElementChild; |
3605 <xsl:text> let first = txt.firstElementChild; |
3330 </xsl:text> |
3606 </xsl:text> |
|
3607 <xsl:text> // remove attribute eventually added to first text line while opening |
|
3608 </xsl:text> |
|
3609 <xsl:text> first.onclick = null; |
|
3610 </xsl:text> |
|
3611 <xsl:text> first.removeAttribute("dy"); |
|
3612 </xsl:text> |
|
3613 <xsl:text> first.removeAttribute("dx"); |
|
3614 </xsl:text> |
|
3615 <xsl:text> // keep only the first line of text |
|
3616 </xsl:text> |
|
3617 <xsl:text> for(let span of Array.from(txt.children).slice(1)){ |
|
3618 </xsl:text> |
|
3619 <xsl:text> txt.removeChild(span) |
|
3620 </xsl:text> |
|
3621 <xsl:text> } |
|
3622 </xsl:text> |
|
3623 <xsl:text> } |
|
3624 </xsl:text> |
|
3625 <xsl:text> // Put rectangle element in saved original state |
|
3626 </xsl:text> |
|
3627 <xsl:text> reset_box(){ |
|
3628 </xsl:text> |
|
3629 <xsl:text> let m = this.box_bbox; |
|
3630 </xsl:text> |
|
3631 <xsl:text> let b = this.box_elt; |
|
3632 </xsl:text> |
|
3633 <xsl:text> b.x.baseVal.value = m.x; |
|
3634 </xsl:text> |
|
3635 <xsl:text> b.y.baseVal.value = m.y; |
|
3636 </xsl:text> |
|
3637 <xsl:text> b.width.baseVal.value = m.width; |
|
3638 </xsl:text> |
|
3639 <xsl:text> b.height.baseVal.value = m.height; |
|
3640 </xsl:text> |
|
3641 <xsl:text> } |
|
3642 </xsl:text> |
|
3643 <xsl:text> highlight_selection(){ |
|
3644 </xsl:text> |
|
3645 <xsl:text> let highlighted_row = this.last_selection - this.menu_offset; |
|
3646 </xsl:text> |
|
3647 <xsl:text> if(highlighted_row < 0) return; |
|
3648 </xsl:text> |
|
3649 <xsl:text> let spans = this.text_elt.children; |
|
3650 </xsl:text> |
|
3651 <xsl:text> let spanslength = spans.length; |
|
3652 </xsl:text> |
|
3653 <xsl:text> let contentlength = this.content.length; |
|
3654 </xsl:text> |
|
3655 <xsl:text> if(this.menu_offset != 0) { |
|
3656 </xsl:text> |
|
3657 <xsl:text> spanslength--; |
|
3658 </xsl:text> |
|
3659 <xsl:text> highlighted_row++; |
|
3660 </xsl:text> |
|
3661 <xsl:text> } |
|
3662 </xsl:text> |
|
3663 <xsl:text> if(this.menu_offset + spanslength < contentlength - 1) spanslength--; |
|
3664 </xsl:text> |
|
3665 <xsl:text> if(highlighted_row > spanslength) return; |
|
3666 </xsl:text> |
3331 <xsl:text> let original_text_y = this.text_bbox.y; |
3667 <xsl:text> let original_text_y = this.text_bbox.y; |
3332 </xsl:text> |
3668 </xsl:text> |
3333 <xsl:text> let highlight = this.highlight_elt; |
3669 <xsl:text> let highlight = this.highlight_elt; |
3334 </xsl:text> |
3670 </xsl:text> |
3335 <xsl:text> let original_h_y = highlight.getBBox().y; |
3671 <xsl:text> let span = spans[highlighted_row]; |
3336 </xsl:text> |
|
3337 <xsl:text> let clickable = highlight.cloneNode(); |
|
3338 </xsl:text> |
3672 </xsl:text> |
3339 <xsl:text> let yoffset = span.getBBox().y - original_text_y; |
3673 <xsl:text> let yoffset = span.getBBox().y - original_text_y; |
3340 </xsl:text> |
3674 </xsl:text> |
3341 <xsl:text> clickable.setAttribute("y", original_h_y + yoffset); |
3675 <xsl:text> highlight.y.baseVal.value = this.highlight_bbox.y + yoffset; |
3342 </xsl:text> |
3676 </xsl:text> |
3343 <xsl:text> clickable.style.pointerEvents = "bounding-box"; |
3677 <xsl:text> highlight.style.visibility = "visible"; |
3344 </xsl:text> |
3678 </xsl:text> |
3345 <xsl:text> clickable.style.visibility = "hidden"; |
3679 <xsl:text> } |
3346 </xsl:text> |
3680 </xsl:text> |
3347 <xsl:text> //clickable.onclick = () => alert("love JS"); |
3681 <xsl:text> reset_highlight(){ |
3348 </xsl:text> |
3682 </xsl:text> |
3349 <xsl:text> clickable.onclick = func; |
3683 <xsl:text> let highlight = this.highlight_elt; |
3350 </xsl:text> |
3684 </xsl:text> |
3351 <xsl:text> this.element.appendChild(clickable); |
3685 <xsl:text> highlight.y.baseVal.value = this.highlight_bbox.y; |
3352 </xsl:text> |
3686 </xsl:text> |
3353 <xsl:text> this.clickables.push(clickable) |
3687 <xsl:text> highlight.style.visibility = "hidden"; |
3354 </xsl:text> |
|
3355 <xsl:text> } |
|
3356 </xsl:text> |
|
3357 <xsl:text> reset_clickables() { |
|
3358 </xsl:text> |
|
3359 <xsl:text> while(this.clickables.length){ |
|
3360 </xsl:text> |
|
3361 <xsl:text> this.element.removeChild(this.clickables.pop()); |
|
3362 </xsl:text> |
|
3363 <xsl:text> } |
|
3364 </xsl:text> |
|
3365 <xsl:text> } |
|
3366 </xsl:text> |
|
3367 <xsl:text> // Set text content when content is smaller than menu (no scrolling) |
|
3368 </xsl:text> |
|
3369 <xsl:text> set_complete_text(){ |
|
3370 </xsl:text> |
|
3371 <xsl:text> let spans = this.text_elt.children; |
|
3372 </xsl:text> |
|
3373 <xsl:text> let c = 0; |
|
3374 </xsl:text> |
|
3375 <xsl:text> for(let item of this.content){ |
|
3376 </xsl:text> |
|
3377 <xsl:text> let span=spans[c]; |
|
3378 </xsl:text> |
|
3379 <xsl:text> span.textContent = item; |
|
3380 </xsl:text> |
|
3381 <xsl:text> let sel = c; |
|
3382 </xsl:text> |
|
3383 <xsl:text> this.make_clickable(span, (evt) => this.bound_on_selection_click(sel)); |
|
3384 </xsl:text> |
|
3385 <xsl:text> c++; |
|
3386 </xsl:text> |
|
3387 <xsl:text> } |
|
3388 </xsl:text> |
|
3389 <xsl:text> } |
|
3390 </xsl:text> |
|
3391 <xsl:text> // Move partial view : |
|
3392 </xsl:text> |
|
3393 <xsl:text> // false : upward, lower value |
|
3394 </xsl:text> |
|
3395 <xsl:text> // true : downward, higher value |
|
3396 </xsl:text> |
|
3397 <xsl:text> scroll(forward){ |
|
3398 </xsl:text> |
|
3399 <xsl:text> let contentlength = this.content.length; |
|
3400 </xsl:text> |
|
3401 <xsl:text> let spans = this.text_elt.children; |
|
3402 </xsl:text> |
|
3403 <xsl:text> let spanslength = spans.length; |
|
3404 </xsl:text> |
|
3405 <xsl:text> // reduce accounted menu size according to jumps |
|
3406 </xsl:text> |
|
3407 <xsl:text> if(this.menu_offset != 0) spanslength--; |
|
3408 </xsl:text> |
|
3409 <xsl:text> if(this.menu_offset < contentlength - 1) spanslength--; |
|
3410 </xsl:text> |
|
3411 <xsl:text> if(forward){ |
|
3412 </xsl:text> |
|
3413 <xsl:text> this.menu_offset = Math.min( |
|
3414 </xsl:text> |
|
3415 <xsl:text> contentlength - spans.length + 1, |
|
3416 </xsl:text> |
|
3417 <xsl:text> this.menu_offset + spanslength); |
|
3418 </xsl:text> |
|
3419 <xsl:text> }else{ |
|
3420 </xsl:text> |
|
3421 <xsl:text> this.menu_offset = Math.max( |
|
3422 </xsl:text> |
|
3423 <xsl:text> 0, |
|
3424 </xsl:text> |
|
3425 <xsl:text> this.menu_offset - spanslength); |
|
3426 </xsl:text> |
|
3427 <xsl:text> } |
|
3428 </xsl:text> |
|
3429 <xsl:text> this.reset_clickables(); |
|
3430 </xsl:text> |
|
3431 <xsl:text> this.set_partial_text(); |
|
3432 </xsl:text> |
|
3433 <xsl:text> } |
|
3434 </xsl:text> |
|
3435 <xsl:text> // Setup partial view text content |
|
3436 </xsl:text> |
|
3437 <xsl:text> // with jumps at first and last entry when appropriate |
|
3438 </xsl:text> |
|
3439 <xsl:text> set_partial_text(){ |
|
3440 </xsl:text> |
|
3441 <xsl:text> let spans = this.text_elt.children; |
|
3442 </xsl:text> |
|
3443 <xsl:text> let contentlength = this.content.length; |
|
3444 </xsl:text> |
|
3445 <xsl:text> let spanslength = spans.length; |
|
3446 </xsl:text> |
|
3447 <xsl:text> let i = this.menu_offset, c = 0; |
|
3448 </xsl:text> |
|
3449 <xsl:text> let m = this.box_bbox; |
|
3450 </xsl:text> |
|
3451 <xsl:text> while(c < spanslength){ |
|
3452 </xsl:text> |
|
3453 <xsl:text> let span=spans[c]; |
|
3454 </xsl:text> |
|
3455 <xsl:text> let onclickfunc; |
|
3456 </xsl:text> |
|
3457 <xsl:text> // backward jump only present if not exactly at start |
|
3458 </xsl:text> |
|
3459 <xsl:text> if(c == 0 && i != 0){ |
|
3460 </xsl:text> |
|
3461 <xsl:text> span.textContent = "▲"; |
|
3462 </xsl:text> |
|
3463 <xsl:text> onclickfunc = this.bound_on_backward_click; |
|
3464 </xsl:text> |
|
3465 <xsl:text> let o = span.getBBox(); |
|
3466 </xsl:text> |
|
3467 <xsl:text> span.setAttribute("dx", (m.width - o.width)/2); |
|
3468 </xsl:text> |
|
3469 <xsl:text> // presence of forward jump when not right at the end |
|
3470 </xsl:text> |
|
3471 <xsl:text> }else if(c == spanslength-1 && i < contentlength - 1){ |
|
3472 </xsl:text> |
|
3473 <xsl:text> span.textContent = "▼"; |
|
3474 </xsl:text> |
|
3475 <xsl:text> onclickfunc = this.bound_on_forward_click; |
|
3476 </xsl:text> |
|
3477 <xsl:text> let o = span.getBBox(); |
|
3478 </xsl:text> |
|
3479 <xsl:text> span.setAttribute("dx", (m.width - o.width)/2); |
|
3480 </xsl:text> |
|
3481 <xsl:text> // otherwise normal content |
|
3482 </xsl:text> |
|
3483 <xsl:text> }else{ |
|
3484 </xsl:text> |
|
3485 <xsl:text> span.textContent = this.content[i]; |
|
3486 </xsl:text> |
|
3487 <xsl:text> let sel = i; |
|
3488 </xsl:text> |
|
3489 <xsl:text> onclickfunc = (evt) => this.bound_on_selection_click(sel); |
|
3490 </xsl:text> |
|
3491 <xsl:text> span.removeAttribute("dx"); |
|
3492 </xsl:text> |
|
3493 <xsl:text> i++; |
|
3494 </xsl:text> |
|
3495 <xsl:text> } |
|
3496 </xsl:text> |
|
3497 <xsl:text> this.make_clickable(span, onclickfunc); |
|
3498 </xsl:text> |
|
3499 <xsl:text> c++; |
|
3500 </xsl:text> |
|
3501 <xsl:text> } |
|
3502 </xsl:text> |
|
3503 <xsl:text> } |
|
3504 </xsl:text> |
|
3505 <xsl:text> open(){ |
|
3506 </xsl:text> |
|
3507 <xsl:text> let length = this.content.length; |
|
3508 </xsl:text> |
|
3509 <xsl:text> // systematically reset text, to strip eventual whitespace spans |
|
3510 </xsl:text> |
|
3511 <xsl:text> this.reset_text(); |
|
3512 </xsl:text> |
|
3513 <xsl:text> // grow as much as needed or possible |
|
3514 </xsl:text> |
|
3515 <xsl:text> let slots = this.grow_text(length); |
|
3516 </xsl:text> |
|
3517 <xsl:text> // Depending on final size |
|
3518 </xsl:text> |
|
3519 <xsl:text> if(slots == length) { |
|
3520 </xsl:text> |
|
3521 <xsl:text> // show all at once |
|
3522 </xsl:text> |
|
3523 <xsl:text> this.set_complete_text(); |
|
3524 </xsl:text> |
|
3525 <xsl:text> } else { |
|
3526 </xsl:text> |
|
3527 <xsl:text> // eventualy align menu to current selection, compensating for lift |
|
3528 </xsl:text> |
|
3529 <xsl:text> let offset = this.last_selection - this.lift; |
|
3530 </xsl:text> |
|
3531 <xsl:text> if(offset > 0) |
|
3532 </xsl:text> |
|
3533 <xsl:text> this.menu_offset = Math.min(offset + 1, length - slots + 1); |
|
3534 </xsl:text> |
|
3535 <xsl:text> else |
|
3536 </xsl:text> |
|
3537 <xsl:text> this.menu_offset = 0; |
|
3538 </xsl:text> |
|
3539 <xsl:text> // show surrounding values |
|
3540 </xsl:text> |
|
3541 <xsl:text> this.set_partial_text(); |
|
3542 </xsl:text> |
|
3543 <xsl:text> } |
|
3544 </xsl:text> |
|
3545 <xsl:text> // Now that text size is known, we can set the box around it |
|
3546 </xsl:text> |
|
3547 <xsl:text> this.adjust_box_to_text(); |
|
3548 </xsl:text> |
|
3549 <xsl:text> // Take button out until menu closed |
|
3550 </xsl:text> |
|
3551 <xsl:text> this.element.removeChild(this.button_elt); |
|
3552 </xsl:text> |
|
3553 <xsl:text> // Rise widget to top by moving it to last position among siblings |
|
3554 </xsl:text> |
|
3555 <xsl:text> this.element.parentNode.appendChild(this.element.parentNode.removeChild(this.element)); |
|
3556 </xsl:text> |
|
3557 <xsl:text> // disable interaction with background |
|
3558 </xsl:text> |
|
3559 <xsl:text> svg_root.addEventListener("pointerdown", numb_event, true); |
|
3560 </xsl:text> |
|
3561 <xsl:text> svg_root.addEventListener("pointerup", numb_event, true); |
|
3562 </xsl:text> |
|
3563 <xsl:text> svg_root.addEventListener("click", this.bound_close_on_click_elsewhere, true); |
|
3564 </xsl:text> |
|
3565 <xsl:text> // mark as open |
|
3566 </xsl:text> |
|
3567 <xsl:text> this.opened = true; |
|
3568 </xsl:text> |
|
3569 <xsl:text> } |
|
3570 </xsl:text> |
|
3571 <xsl:text> // Put text element in normalized state |
|
3572 </xsl:text> |
|
3573 <xsl:text> reset_text(){ |
|
3574 </xsl:text> |
|
3575 <xsl:text> let txt = this.text_elt; |
|
3576 </xsl:text> |
|
3577 <xsl:text> let first = txt.firstElementChild; |
|
3578 </xsl:text> |
|
3579 <xsl:text> // remove attribute eventually added to first text line while opening |
|
3580 </xsl:text> |
|
3581 <xsl:text> first.onclick = null; |
|
3582 </xsl:text> |
|
3583 <xsl:text> first.removeAttribute("dy"); |
|
3584 </xsl:text> |
|
3585 <xsl:text> first.removeAttribute("dx"); |
|
3586 </xsl:text> |
|
3587 <xsl:text> // keep only the first line of text |
|
3588 </xsl:text> |
|
3589 <xsl:text> for(let span of Array.from(txt.children).slice(1)){ |
|
3590 </xsl:text> |
|
3591 <xsl:text> txt.removeChild(span) |
|
3592 </xsl:text> |
|
3593 <xsl:text> } |
|
3594 </xsl:text> |
|
3595 <xsl:text> } |
|
3596 </xsl:text> |
|
3597 <xsl:text> // Put rectangle element in saved original state |
|
3598 </xsl:text> |
|
3599 <xsl:text> reset_box(){ |
|
3600 </xsl:text> |
|
3601 <xsl:text> let m = this.box_bbox; |
|
3602 </xsl:text> |
|
3603 <xsl:text> let b = this.box_elt; |
|
3604 </xsl:text> |
|
3605 <xsl:text> b.x.baseVal.value = m.x; |
|
3606 </xsl:text> |
|
3607 <xsl:text> b.y.baseVal.value = m.y; |
|
3608 </xsl:text> |
|
3609 <xsl:text> b.width.baseVal.value = m.width; |
|
3610 </xsl:text> |
|
3611 <xsl:text> b.height.baseVal.value = m.height; |
|
3612 </xsl:text> |
3688 </xsl:text> |
3613 <xsl:text> } |
3689 <xsl:text> } |
3614 </xsl:text> |
3690 </xsl:text> |
3615 <xsl:text> // Use margin and text size to compute box size |
3691 <xsl:text> // Use margin and text size to compute box size |
3616 </xsl:text> |
3692 </xsl:text> |