Debian package: Use sed inline edits in combination with dh_install
[conkeror.git] / modules / new-tabs.js
blobc780c7619bd7fdbdabbd85e5c405491eff880ce7
1 /**
2  * (C) Copyright 2008 Jeremy Maitin-Shepard
3  * (C) Copyright 2008 Nicholas A. Zigarovich
4  * (C) Copyright 2008 John J. Foerch
5  * (C) Copyright 2011 Peter Lunicks
6  *
7  * Use, modification, and distribution are subject to the terms specified in the
8  * COPYING file.
9  **/
11 require("mode.js");
13 define_variable("tab_bar_button_select", 0,
14                 "The mouse button that selects tabs." +
15                 "0 = left, 1 = middle, 2 = right, null = disabled.");
17 define_variable("tab_bar_button_close", 2,
18                 "The mouse button that closes tabs." +
19                 "0 = left, 1 = middle, 2 = right, null = disabled.");
21 define_variable("tab_bar_show_icon", false,
22                 "Whether or not to show buffer icons in tabs.");
24 define_variable("tab_bar_show_index", true,
25                 "Whether or not to show the tab index in each tab.");
27 /**
28  * Constructs a tab bar for the given window.
29  */
30 function tab_bar (window) {
31     window.tab_bar = this;
32     var scrollbox = create_XUL(window, "arrowscrollbox");
33     scrollbox.setAttribute("id", "tab2-bar");
34     scrollbox.setAttribute("orient", "horizontal");
35     var after = window.buffers.container;
36     this.window = window;
37     this.element = scrollbox;
38     after.parentNode.insertBefore(scrollbox, after);
40     add_hook.call(window, "select_buffer_hook", tab_bar_select_buffer);
41     add_hook.call(window, "create_buffer_early_hook", tab_bar_add_buffer);
42     add_hook.call(window, "kill_buffer_hook", tab_bar_kill_buffer);
43     add_hook.call(window, "move_buffer_hook", tab_bar_move_buffer);
44     add_hook.call(window, "create_buffer_hook", tab_bar_update_buffer_title);
45     add_hook.call(window, "buffer_title_change_hook", tab_bar_update_buffer_title);
46     add_hook.call(window, "buffer_description_change_hook", tab_bar_update_buffer_title);
47     add_hook.call(window, "buffer_icon_change_hook", tab_bar_update_buffer_icon);
49     window.buffers.for_each(function (b) tab_bar_add_buffer(b, true));
50     this.update_multiple_attribute();
51     if (window.buffers.current != null)
52         tab_bar_select_buffer(window.buffers.current);
56 /**
57  * Destroys the tab bar.
58  */
59 tab_bar.prototype.destroy = function () {
60     remove_hook.call(this.window, "select_buffer_hook", tab_bar_select_buffer);
61     remove_hook.call(this.window, "create_buffer_early_hook", tab_bar_add_buffer);
62     remove_hook.call(this.window, "kill_buffer_hook", tab_bar_kill_buffer);
63     remove_hook.call(this.window, "move_buffer_hook", tab_bar_move_buffer);
64     remove_hook.call(this.window, "create_buffer_hook", tab_bar_update_buffer_title);
65     remove_hook.call(this.window, "buffer_title_change_hook", tab_bar_update_buffer_title);
66     remove_hook.call(this.window, "buffer_description_change_hook", tab_bar_update_buffer_title);
67     remove_hook.call(this.window, "buffer_icon_change_hook", tab_bar_update_buffer_icon);
68     this.window.buffers.for_each(function (b) { delete b.tab; });
69     this.selected_buffer = null;
70     this.element.parentNode.removeChild(this.element);
71     delete this.window.tab_bar;
75 /**
76  * Updates the "index" node and "ordinal" attribute of all tabs.
77  */
78 tab_bar.prototype.update_ordinals = function () {
79     var buffers = this.window.buffers;
80     for (var i = 0, n = this.element.childNodes.length; i < n; i++) {
81         var ordinal = buffers.index_of(this.element.childNodes[i].buffer) + 1;
82         this.element.childNodes[i].setAttribute("ordinal", ordinal);
83         this.element.childNodes[i].index.setAttribute("value", ordinal);
84     }
88 /**
89  * Updates the "multiple" attribute of the tab bar.
90  */
91 tab_bar.prototype.update_multiple_attribute = function () {
92     if (this.window.buffers.count > 1)
93         this.element.setAttribute("multiple", "true");
94     else
95         this.element.setAttribute("multiple", "false");
99 /**
100  * Adds a tab for the given buffer.  When second argument 'noupdate' is
101  * true, a new tab in the middle of the buffer list will not cause the
102  * ordinals of other tabs to be updated.  This is used during
103  * initialization of the tab bar.
104  */
105 function tab_bar_add_buffer (buffer, noupdate) {
107     // Get the tab bar
108     var tabbar = buffer.window.tab_bar;
109     tabbar.update_multiple_attribute();
111     var ordinal = buffer.window.buffers.index_of(buffer) + 1;
112     if (ordinal < buffer.window.buffers.buffer_list.length && ! noupdate)
113         tabbar.update_ordinals();
115     // Create a tab and add it to the tab bar
116     var tab = create_XUL(buffer.window, "hbox");
117     tab.buffer = buffer;
118     tab.setAttribute("class", "tab2");
119     tab.addEventListener("click", function (event) {
120             if (event.button == tab_bar_button_select) {
121                 if (!tab.buffer.dead)
122                     tab.buffer.window.buffers.current = tab.buffer;
123             }
124         }, false /* not capturing */);
125     tab.setAttribute("selected", "false");
127     // Create the label to hold the buffer icon
128     var image = create_XUL(buffer.window, "image");
129     image.setAttribute("class", "tab2-icon");
130     if (buffer.icon != null)
131         image.setAttribute("src", buffer.icon);
133     // Create the label to hold the tab number
134     var index = create_XUL(buffer.window, "label");
135     index.setAttribute("class", "tab2-index");
136     index.setAttribute("value", ordinal);
138     // Create the label to hold the tab title
139     var label = create_XUL(buffer.window, "label");
140     label.setAttribute("class", "tab2-label");
141     label.setAttribute("crop", "end");
143     // No close button, just use the designated mouse button.
144     tab.addEventListener("click", function (event) {
145             if (event.button == tab_bar_button_close) {
146                 kill_buffer(tab.buffer);
147                 event.stopPropagation();
148             }
149         }, false /* not capturing */);
151     // Add all the stuff to the new tab
152     tab.image = image;
153     tab.label = label;
154     tab.index = index;
155     if (tab_bar_show_index)
156         tab.appendChild(index);
157     if (tab_bar_show_icon)
158         tab.appendChild(image);
159     tab.appendChild(label);
160     tabbar.element.appendChild(tab);
161     buffer.tab = tab;
162     tab_bar_update_buffer_title(buffer);
164     // Note, XULRunner 1.9.x puts the tab in the wrong location if we set
165     // the ordinal before adding the tab to the tab-bar.
166     tab.setAttribute("ordinal", ordinal);
171  * Removes the tab for the given buffer.
172  */
173 function tab_bar_kill_buffer (b) {
174     var t = b.window.tab_bar;
175     t.update_multiple_attribute();
176     if (t.selected_buffer == b)
177         t.selected_buffer = null;
178     b.tab.parentNode.removeChild(b.tab);
179     t = b.window.tab_bar;
180     delete b.tab;
182     // Renumber the tabs.
183     t.update_ordinals();
188  * Updates all tab indices and ensure that the current tab is still visible.
189  */
190 function tab_bar_move_buffer (b) {
191     var t = b.window.tab_bar;
192     t.update_ordinals();
193     t.element.ensureElementIsVisible(b.window.buffers.current.tab);
198  * Updates the tab of the given buffer to indicate it is the currently open one.
199  */
200 function tab_bar_select_buffer (b) {
201     var t = b.window.tab_bar;
202     if (t.selected_buffer != null)
203         t.selected_buffer.tab.setAttribute("selected", "false");
204     t.selected_buffer = b;
205     b.tab.setAttribute("selected", "true");
206     t.element.ensureElementIsVisible(b.tab);
211  * Updates the tab title for the given buffer.
212  */
213 function tab_bar_update_buffer_title (b) {
214     var title = b.title;
215     if (title == null || title.length == 0)
216         title = b.description;
217     b.tab.label.setAttribute("value", title);
222  * Updates the tab icon for the given buffer.
223  */
224 function tab_bar_update_buffer_icon (b) {
225     if (b.icon != null)
226         b.tab.image.setAttribute("src", b.icon);
227     else
228         b.tab.image.removeAttribute("src");
233  * Inserts the tab bar in the given window.
234  */
235 function tab_bar_install (window) {
236     if (window.tab_bar)
237         throw new Error("tab bar already initialized for window");
238     new tab_bar(window);
243  * Removes the tab bar from the given window.
244  * If the tab bar is not installed, throws an error.
245  */
246 function tab_bar_uninstall (window) {
247     if (!window.tab_bar)
248         throw new Error("tab bar not initialized for window");
249     window.tab_bar.destroy();
253 define_global_mode("tab_bar_mode",
254                    function () { // enable
255                        add_hook("window_initialize_hook", tab_bar_install);
256                        for_each_window(tab_bar_install);
257                    },
258                    function () { // disable
259                        remove_hook("window_initialize_hook", tab_bar_install);
260                        for_each_window(tab_bar_uninstall);
261                    });
263 tab_bar_mode(true);
265 provide("tab-bar");
266 provide("new-tabs");