3
<!-- ***** BEGIN LICENSE BLOCK *****
4
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
6
- The contents of this file are subject to the Mozilla Public License Version
7
- 1.1 (the "License"); you may not use this file except in compliance with
8
- the License. You may obtain a copy of the License at
9
- http://www.mozilla.org/MPL/
11
- Software distributed under the License is distributed on an "AS IS" basis,
12
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
- for the specific language governing rights and limitations under the
16
- The Original Code is Nvu.
18
- The Initial Developer of the Original Code is
20
- Portions created by the Initial Developer are Copyright (C) 2003
21
- the Initial Developer. All Rights Reserved.
24
- Daniel Glazman <glazman@disruptive-innovations.com>, on behalf of Linspire Inc.
25
- Fabien Cazenave (Kaze) http://fabiwan.kenobi.free.fr/
27
- Alternatively, the contents of this file may be used under the terms of
28
- either the GNU General Public License Version 2 or later (the "GPL"), or
29
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30
- in which case the provisions of the GPL or the LGPL are applicable instead
31
- of those above. If you wish to allow use of your version of this file only
32
- under the terms of either the GPL or the LGPL, and not to allow others to
33
- use your version of this file under the terms of the MPL, indicate your
34
- decision by deleting the provisions above and replace them with the notice
35
- and other provisions required by the LGPL or the GPL. If you do not delete
36
- the provisions above, a recipient may use your version of this file under
37
- the terms of any one of the MPL, the GPL or the LGPL.
39
- ***** END LICENSE BLOCK ***** -->
42
<!ENTITY % tabEditorDTD SYSTEM "chrome://editor/locale/tabeditor.dtd" >
46
<bindings id="tabEditorBindings"
47
xmlns="http://www.mozilla.org/xbl"
48
xmlns:html="http://www.w3.org/1999/xhtml"
49
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
50
xmlns:xbl="http://www.mozilla.org/xbl">
52
<binding id="tabeditor">
54
<stylesheet src="chrome://editor/skin/editor.css"/>
58
<xul:stringbundle src="chrome://editor/locale/tabeditor.properties"/>
59
<xul:tabbox anonid="EditorTabbox" flex="1" onselect="this.parentNode.setFocus();">
60
<xul:hbox class="tabbrowser-strip chromeclass-toolbar" context="_child">
63
<xul:menuitem label="&newTab.label;" accesskey="&newTab.accesskey;" command="cmd_newEditorTab"/>
65
<!-- Kaze: these two items refer to the active tab, not to the pointed tab. Danger!
66
<xul:menuitem label="&revert.label;" accesskey="&revert.accesskey;" command="cmd_revert"/>
67
<xul:menuitem label="&refreshImages.label;" acceskey="&refreshImages.accesskey;" command="cmd_refreshImages"/>
69
<xul:menuitem label="&revert.label;" accesskey="&revert.accesskey;"
70
oncommand="var tabeditor = this.parentNode.parentNode.parentNode.parentNode;
71
RevertTab(tabeditor.mContextTab);"/>
72
<xul:menuitem label="&refreshImages.label;" acceskey="&refreshImages.accesskey;"
73
oncommand="var tabeditor = this.parentNode.parentNode.parentNode.parentNode;
74
RefreshTab(tabeditor.mContextTab);"/>
76
<xul:menuitem label="&closeTab.label;" accesskey="&closeTab.accesskey;"
77
oncommand="var tabeditor = this.parentNode.parentNode.parentNode.parentNode;
78
CloseTab(tabeditor.mContextTab); SelectTabEditor();"/><!-- Kaze: added 'SelectTabEditor' -->
80
<xul:menuitem label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
81
oncommand="var tabeditor = this.parentNode.parentNode.parentNode.parentNode;
82
RemoveAllTabsBut(tabeditor.mContextTab);"/>
85
<xul:tabs flex="1" class="tabbrowser-tabs" anonid="EditorTabs" closebutton="true"
87
onclick="this.parentNode.parentNode.parentNode.onTabClick(event)"
88
onclosetab="CloseCurrentTab(true); SelectTabEditor()"
89
onmousedown="this.parentNode.parentNode.parentNode.updateContextTab(event);"
90
oncommand="SelectTabEditor()">
91
<xul:tab label="&untitledDocument.label;"
92
maxwidth="200" width="0" minwidth="30" flex="100"
97
<xul:columns><xul:column anonid="vRulerColumn"/><xul:column flex="1"/></xul:columns>
99
<xul:row anonid="hRulerRow" style="border-top: outset 1px;">
101
<xul:stack id="hRuler" style="min-height: 22px; overflow: hidden"
102
onmousedown="window.InitiateMoveObjectInRuler(event)"/>
105
<xul:stack id="vRuler" onmousedown="window.InitiateMoveObjectInRuler(event)"
106
style="border-right: outset 1px; width: auto; min-width: 1em; overflow: hidden"/>
107
<xul:tabpanels anonid="EditorTabpanels" selectedIndex="0">
108
<xul:editor editortype="html" type="content-primary" id="content-frame"
109
context="editorContentContext"
110
flex="1" tooltip="aHTMLTooltip"/>
121
ShowRulers(!(this.getAttribute("collapserulers") == "true"));
122
document.addEventListener("keypress", this._keyEventHandler, false);
128
const editors = this.mTabPanels.childNodes;
129
for (var i = 0; i < editors.length; i++)
131
editors[i].removeEventListener("DOMTitleChanged", this.changeTabTitle, false);
133
document.removeEventListener("keypress", this._keyEventHandler, false);
137
<field name="endNavigationCallback">null</field>
138
<field name="mCurrentLoadedTab">null</field>
139
<field name="mContextTab">null</field>
141
<field name="_keyEventHandler" readonly="true">
144
handleEvent: function handleEvent(aEvent) {
145
if (!aEvent.isTrusted) {
146
// Don't let untrusted events mess with tabs.
150
if (aEvent.ctrlKey && aEvent.keyCode == KeyEvent.DOM_VK_F4)
152
CloseCurrentTab(true);
159
<property name="mTabbox">
162
return document.getAnonymousElementByAttribute(this, "anonid", "EditorTabbox");
167
<property name="mTabs">
170
return document.getAnonymousElementByAttribute(this, "anonid", "EditorTabs");
175
<property name="mTabpanels">
178
return document.getAnonymousElementByAttribute(this, "anonid", "EditorTabpanels");
183
<property name="mHRulerRow">
186
return document.getAnonymousElementByAttribute(this, "anonid", "hRulerRow");
191
<property name="mVRulerColumn">
194
return document.getAnonymousElementByAttribute(this, "anonid", "vRulerColumn");
199
<property name="selectedPanel">
202
return this.mTabbox.selectedPanel;
207
this.mTabbox.selectedPanel = val;
212
<property name="selectedTab">
215
return this.mTabbox.selectedTab;
220
this.mTabbox.selectedTab = val;
225
<property name="selectedIndex">
228
return this.mTabbox.selectedIndex;
233
this.mTabbox.selectedIndex = val;
238
<method name="onTabClick">
239
<parameter name="event"/>
242
if (event.button != 1 || event.target.localName != 'tab')
245
CloseTab(event.target);
246
this.SelectTabEditor(); // Kaze
247
event.stopPropagation();
252
<method name="setFocus">
257
this.selectedPanel.contentWindow.focus();
264
<method name="updateContextTab">
265
<parameter name="aEvent"/>
268
if (aEvent.originalTarget.localName == "tab")
269
this.mContextTab = aEvent.originalTarget;
271
this.mContextTab = this.selectedTab; // Kaze
272
//~ this.mContextTab = document.popupNode;
277
<method name="ShowRulers">
278
<parameter name="show" />
283
this.mHRulerRow.setAttribute("collapsed", false);
284
this.mVRulerColumn.setAttribute("collapsed", false);
288
this.mHRulerRow.setAttribute("collapsed", true);
289
this.mVRulerColumn.setAttribute("collapsed", true);
295
<method name="showCurrentTabAsModified">
296
<parameter name="val" />
300
this.selectedTab.setAttribute("modified", "true");
302
this.selectedTab.removeAttribute("modified");
307
<method name="_prepareForNewEditor">
310
var selectedEditor = this.selectedPanel;
311
selectedEditor.removeAttribute("id");
316
<method name="SelectTabEditor">
319
//~ GetCurrentEditingSession().setEditorOnControllers(window.content, GetCurrentEditor());
320
// <Kaze> this line above creates a bug when the last tab is closed
322
GetCurrentEditingSession().setEditorOnControllers(window.content, GetCurrentEditor());
325
var current = this.selectedPanel;
326
this.setContentFrameId(current);
328
window.UpdateWindowTitle();
330
window.updateCommands("save");
331
window.updateCommands("undo");
332
window.updateCommands("select");
333
window.updateCommands("style");
334
window.goUpdateCommand("cmd_dtdStrictness");
335
window.goUpdateCommand("cmd_dtdStrictness2");
337
if (current.hasAttribute("displaymode"))
338
window.SetEditMode(current.getAttribute("displaymode"));
340
window.SetEditMode(0);
341
if (current.getAttribute("blockoutlines"))
342
window.document.getElementById("blockOutlines").setAttribute("checked", true);
344
window.document.getElementById("blockOutlines").removeAttribute("checked");
349
<method name="_newEditor">
352
var newe = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "editor");
353
newe.setAttribute("type", "content-primary");
354
newe.setAttribute("id", "content-frame");
355
newe.setAttribute("flex", "1");
356
newe.setAttribute("tooltip", "aHTMLTooltip");
357
newe.setAttribute("context", "editorContentContext");
364
<method name="_stopThrobber">
365
<parameter name="aTab" />
368
aTab.removeAttribute("busy");
373
<method name="setContentFrameId">
374
<parameter name="editorElement" />
377
var elt = this.mTabpanels.firstChild;
380
if (elt != editorElement)
382
elt.removeAttribute("id");
385
elt = elt.nextSibling;
387
editorElement.setAttribute("id", "content-frame");
392
<method name="stopWebNavigation">
393
<parameter name="notifyOnly" />
397
GetCurrentEditorElement().webNavigation.stop(
398
Components.interfaces.nsIWebNavigation.STOP_ALL);
400
if (this.endNavigationCallback)
402
this.endNavigationCallback();
403
if (this.mCurrentLoadedTab)
405
this._stopThrobber(this.mCurrentLoadedTab);
406
this.mCurrentLoadedTab = null;
408
this.endNavigationCallback = null;
414
<method name="_editURL">
415
<parameter name="editorElement" />
416
<parameter name="url" />
417
<parameter name="newEditor" />
418
<parameter name="tabIndex" />
419
<parameter name="template" />
420
<parameter name="fromTemplate" />
423
function nsLDBBrowserContentListener(boundElt, aStopCallback, aTab, aIsTemplate, aIsFromTemplate)
425
this.init(boundElt, aStopCallback, aTab, aIsTemplate, aIsFromTemplate);
428
nsLDBBrowserContentListener.prototype = {
430
init : function(aBoundElt, aStopCallback, aTab, aIsTemplate, aIsFromTemplate)
432
this.mBoundElt = aBoundElt;
433
this.mStopCallback = aStopCallback;
435
this.mIsTemplate = aIsTemplate;
436
this.mIsFromTemplate = aIsFromTemplate;
439
QueryInterface : function(aIID)
441
if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
442
aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
443
aIID.equals(Components.interfaces.nsISupports))
445
throw Components.results.NS_NOINTERFACE;
448
// nsIWebProgressListener implementation
449
onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
451
if (aStateFlags == 0xc0010 && !aStatus)
453
this.mStopCallback(this.mTab);
455
this.mBoundElt.stopWebNavigation(true);
457
var e = GetCurrentEditor();
458
var d = e.document.documentElement;
461
var b = e.document.getElementsByTagName("body").item(0);
462
b._editor = GetCurrentEditorElement();
465
// Are we trying to import a template from DW ?
468
var URL = Components.classes["@mozilla.org/network/standard-url;1"].createInstance(Components.interfaces.nsIURL);
473
// is the new document a template ?
477
d.setAttribute("template", "true");
480
else if (fromTemplate)
482
e instanceof Components.interfaces.nsIHTMLTemplateEditor;
483
e.isDocumentBasedOnTemplate = true;
485
d.removeAttribute("template");
486
d.setAttribute("templateref", url);
488
SetDocumentURI(GetIOService().newURI("about:blank", e.documentCharacterSet, null));
490
e.resetModificationCount();
494
WarnIfDocumentIsTemplate();
498
onProgressChange : function(aWebProgress, aRequest,
499
aCurSelfProgress, aMaxSelfProgress,
500
aCurTotalProgress, aMaxTotalProgress)
504
onLocationChange : function(aWebProgress, aRequest, aLocation)
508
onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
512
onSecurityChange : function(aWebProgress, aRequest, aState)
516
mStopCallback : null,
520
mIsFromTemplate : false
523
// first, add the editor to the panels' list
524
var tabAlreadyDisplayed = true;
526
//this.setContentFrameId(editorElement);
530
this.mTabpanels.appendChild(editorElement);
532
// then create a new tab
533
var newTab = this.mTabs.appendItem("(" + window.GetString("untitled") + ")", url);
534
newTab.setAttribute("busy", "true");
535
newTab.setAttribute("maxwidth", "200");
536
newTab.setAttribute("width", "0");
537
newTab.setAttribute("minwidth", "30");
538
newTab.setAttribute("flex", "100");
539
newTab.setAttribute("crop", "end");
541
// select that new tab
542
this.selectedTab = newTab;
544
// and finish the whole thing making the editor editable
545
editorElement.makeEditable("html", true);
546
window.document.getElementById("blockOutlines").removeAttribute("checked");
550
if (this.selectedIndex != tabIndex)
552
this.selectedIndex = tabIndex;
553
tabAlreadyDisplayed = false;
555
newTab = this.selectedTab;
556
newTab.setAttribute("busy", "true");
559
editorElement.addEventListener("DOMTitleChanged", this.changeTabTitle, false);
561
var docShell = editorElement.boxObject.QueryInterface(Components.interfaces.nsIEditorBoxObject).docShell;
562
var progress = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);
563
gProgressListener = new nsLDBBrowserContentListener(this, this._stopThrobber, newTab, template, fromTemplate);
564
this.mCurrentLoadedTab = newTab;
566
progress.addProgressListener(gProgressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
569
EditorSharedStartup();
570
SetupComposerWindowCommands();
572
// making the editor load the document now
573
window.EditorLoadUrl(url);
575
window.SetSaveAndPublishUI(url);
576
if (!tabAlreadyDisplayed)
582
<method name="changeTabTitle">
583
<parameter name="evt" />
586
var e = evt.currentTarget;
587
var title = evt.target.title;
589
if (!e.getEditor(e.contentWindow) && !title)
592
var tabbox = this.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
593
var editors = this.parentNode.childNodes;
594
var i, l = editors.length;
597
if (editors.item(i) == e)
599
var tab = tabbox.mTabs.childNodes.item(i);
609
<method name="_checkIfUrlIsAlreadyEdited">
610
<parameter name="url" />
613
// always accept a new blank document
614
if (IsUrlAboutBlank(url))
617
// TBD : check all editor windows
618
var editors = this.mTabpanels.childNodes;
619
var i, l = editors.length;
623
var elt = e.getEditor(e.contentWindow);
624
if (elt && elt.document.URL == url)
632
<!-- Kaze: I've changed this method and made it public, to call it from editPage() -->
633
<method name="checkIfUrlIsAlreadyEdited">
634
<parameter name="url" />
637
// always accept a new blank document
638
if (IsUrlAboutBlank(url))
641
// TBD : check all editor windows
642
var editors = this.mTabpanels.childNodes;
643
var i, l = editors.length;
647
var elt = e.getEditor(e.contentWindow);
648
//~ if (elt && elt.document.URL == url) { // Kaze: bugfix
649
if (elt && unescape(elt.document.URL) == unescape(url)) {
650
this.selectedIndex = i; // Kaze: bugfix
651
this.stopWebNavigation(); // Kaze: bugfix
652
window.UpdateWindowTitle();
661
<method name="editURL">
662
<parameter name="url" />
663
<parameter name="newTab" />
664
<parameter name="template" />
665
<parameter name="fromTemplate" />
668
//~ var edited = this._checkIfUrlIsAlreadyEdited(url);
669
var edited = this.checkIfUrlIsAlreadyEdited(url);
670
SetEditMode(kDisplayModeNormal); // Kaze: bugfix
675
// let's see if we can reuse an empty tab
676
var reusableEditor = null;
677
var reusableEditorIndex = -1;
678
var editors = this.mTabpanels.childNodes;
679
var i, l = editors.length;
683
var elt = e.getEditor(e.contentWindow);
684
if (elt && elt.documentIsEmpty && !elt.documentModified && !window.IsHTMLSourceChanged())
687
reusableEditorIndex = i;
692
if (newTab || !reusableEditor)
694
this._prepareForNewEditor();
695
var newEditor = this._newEditor();
696
this._editURL(newEditor, url, true, 0, template, fromTemplate);
697
window.content.focus();
700
this._editURL(reusableEditor, url, false, reusableEditorIndex, template, fromTemplate);
701
window.content.focus();
702
return reusableEditor;
705
// give focus to that editor
706
this.selectedPanel = edited;
711
<method name="newBlankTab">
712
<parameter name="type" />
713
<parameter name="strictness" />
717
return this.editURL(strictness ? "about:xstrictblank" : "about:xblank",
720
return this.editURL(strictness ? "about:strictblank" : "about:blank",
725
<method name="newTemplateTab">
728
return this.editURL("about:blank", true, true, false);
732
<method name="getCurrentEditorElement">
735
return this.selectedPanel;
743
<handler event="DOMAttrModified" phase="target">
745
var attrName = event.attrName.toLowerCase();
746
var oldValue = event.prevValue.toLowerCase();
747
var newValue = event.newValue.toLowerCase();
749
// only if a new value is specified
750
if (oldValue != newValue && newValue) {
751
if (attrName == "collapserulers") {
752
ShowRulers(!(newValue == "true"));