aboutsummaryrefslogtreecommitdiff
path: root/public/assets/javascripts/ckeditor/plugins/studip-floatbar/plugin.js
blob: b1d53422700d6237f1c2e6e8988d4cd4c8e413ee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/**
 * plugin.js - Make CKEditor's toolbar stick to the top of the
 * browser window, so it doesn't scroll out.
 *
 * Developer documentation can be found at
 * http://docs.studip.de/develop/Entwickler/Wysiwyg.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * @author      Robert Costa <zabbarob@gmail.com>
 * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
 * @category    Stud.IP
 */
(function (CKEDITOR, $) {

    CKEDITOR.plugins.add('studip-floatbar', {
        // TODO remove dependance on sharedspace
        requires: 'sharedspace',
        init: init
    });

    function init(editor) {
        // create the div for our toolbar
        var toolbar = $('<div>')
        .attr('id', createNewId('cktoolbar'))
        .addClass('cktoolbar')
        .css('max-width', editor.config.width)
        .insertBefore(editor.element.$);

        // insert toolbar placeholder
        // - needed to compute correct toolbar position when floating
        $('<div>')
        .attr('id', toolbar.attr('id') + '-placeholder')
        .addClass('ckplaceholder')
        .insertBefore(toolbar);

        // configure shared spaces plug to use our toolbar
        editor.config.sharedSpaces = { top: toolbar.attr('id') };

        // add listener for later intialization tasks (don't activate inside a dialog)
        if (!$(editor.element.$).closest('.ui-dialog').length) {
            CKEDITOR.on('instanceReady', onInstanceReady);
        }
    }

    function onInstanceReady(event) {
        // do not scroll toolbar out of viewport
        function stickyTools() {
            updateStickyTools(event.editor);
        };
        $(window).scroll(stickyTools);
        $(window).resize(stickyTools);
        event.editor.on('focus', stickyTools); // hidden toolbar might scroll off screen
    }

    function updateStickyTools(editor) {
        var MARGIN = $('#barBottomContainer').length ?
                $('#barBottomContainer').height() : 25;

        var toolbarId = editor.config.sharedSpaces.top;

        var $toolbar = $('#' + toolbarId);

        var placeholder = $('#' + toolbarId + '-placeholder');

        if ($toolbar.length === 0 || placeholder.length === 0) {
            // toolbar/editor removed by some JS code (e.g. when sending messages)
            // TODO remove listeners!!
            return;
        }

        var outOfView = $(window).scrollTop() + MARGIN
                > placeholder.offset().top;

        var $container = $(editor.container.$);
        var width = $container.outerWidth(true);

        // is(':visible'): offset() is wrong for hidden elements
        if ($toolbar.is(':visible') && outOfView) {

            // compute toolbar position
            // make sure it doesn't scroll below editor area
            var editorBottom = $container.position().top +
                               $container.outerHeight(true);

            var bottomMargin = 50;

            var maxToolbarTop = editorBottom
                - bottomMargin
                - $toolbar.outerHeight(true)
                - $(window).scrollTop();

            // reposition floating toolbar
            placeholder.css('height', $toolbar.height());

            $toolbar.css({
                position: 'fixed',
                top: Math.min(MARGIN, maxToolbarTop),
                width: width
            });

        } else {

            // reset toolbar to inline-mode
            $toolbar.css({
                position: 'relative',
                top: '',
                width: width
            });

            placeholder.css('height', 0);
        }
    }

    // create an unused id
    function createNewId(prefix) {
        var i = 0;
        while ($('#' + prefix + i).length > 0) {
            i++;
        }
        return prefix + i;
    }

})(CKEDITOR, jQuery);