PK q?,igcontent/necko/redirect_loop.xulUT IY<;DDUx PK 3D0?Ԅ))content/necko/contents.rdfUT !@;DDUx PK -X-0+content/communicator/xml/XMLPrettyPrint.cssUT @@DDDUx@charset "UTF-8"; /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Jonas Sicking (Original author) * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ @import url("resource://gre/res/viewsource.css"); #header { background-color: #ccc; border-bottom: 3px solid black; padding: 0.5em; margin-bottom: 1em; } table { border-spacing: 0; margin: 0; } td { padding: 0; } .indent { margin-left: 1em; } .spacer { width: 1em; } .expander { cursor: pointer; -moz-user-select: none; vertical-align: top; text-align: center; } .expander-closed > * > .expander-content { display: none; } .comment { font-family: monospace; white-space: pre; } PK -X-0rExx)content/communicator/xml/XMLMonoPrint.cssUT @@DDDUx@charset "UTF-8"; /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Heikki Toivonen (Original author) * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ @import url("chrome://communicator/content/xml/XMLPrettyPrint.css"); #top > table { font-family: monospace; white-space: pre; } PK r.H0 0 +content/communicator/xml/XMLPrettyPrint.xmlUT w>DDDUx if (aTopic == "prettyprint-dom-created") document.getAnonymousNodes(this).item(0).appendChild(aSubject); PK iy.AUU+content/communicator/xml/XMLPrettyPrint.xslUT !?DDDUx
< />
< > </ >
< >
</ >
= ""
<? ?>
<?
?>
<!-- -->
<!--
-->
-
PK U,l?b content/xbl-marquee/contents.rdfUT A=GDDUx PK x091?5555#content/xbl-marquee/xbl-marquee.xmlUT lUAGDDUx 6 if (this.hasAttribute("scrollamount")) return this.getAttribute("scrollamount"); return this.defaultScrollAmount; //default value is 6 pixels this.setAttribute("scrollamount", val); 85 this.setAttribute("scrolldelay", val); // since we changed the scrolldelay, restart the marquee this._doMove(false); "left" return this.directionField; // if val is false, don't change anything if (val) { // in case direction is swapped between horizontal/vertical, use // setAttribute to make the xbl bindings change. this.setAttribute("direction", val); // since we changed the direction, set startNewDirection to true this.startNewDirection = true; this.directionField = val.toLowerCase(); // pass in aSkipSettingNewPosition as true this._doMove(true); } "left" "scroll" return this.behaviorField; this.behaviorField = val ? val.toLowerCase() : this.defaultBehavior; "scroll" 1 0 0 0 0 0 true "0.9.7" this.stopAt) || (this.dirsign == -1 && this.newPosition < this.stopAt)) { if (this.behaviorField == "alternate") { // lets start afresh this.startNewDirection = true; // swap direction const swap = {left: "right", down: "up", up: "down", right: "left"}; this.directionField = swap[this.directionField]; } else { this.newPosition = this.startAt; } } if (!this.startNewDirection) { if ((this.directionField == "up") || (this.directionField == "down")) this.outerDiv.scrollTop = this.newPosition; else this.outerDiv.scrollLeft = this.newPosition; } var myThis = this; var lambda = function myTimeOutFunction(){myThis.start();} this.runId = window.setTimeout(lambda, this.scrollDelay); ]]> PK xv0n;l3content/communicator/profile/createProfileWizard.jsUT q_@ILDDUx/* * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998-1999 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * Ben Goodger (30/09/99) * Brant Gurganus (23/03/03) * Stefan Borggraefe (17/10/03) */ var gProfile = Components.classes["@mozilla.org/profile/manager;1"].getService(Components.interfaces.nsIProfileInternal); var gProfileManagerBundle; // The directory where the profile will be created. var gProfileRoot; // Text node to display the location and name of the profile to create. var gProfileDisplay; // Called once when the wizard is opened. function initWizard() { gProfileManagerBundle = document.getElementById("bundle_profileManager"); // Initialize the profile location display. gProfileDisplay = document.getElementById("profileDisplay").firstChild; setDisplayToDefaultFolder(); } // Called every time the second wizard page is displayed. function initSecondWizardPage() { var profileName = document.getElementById("profileName"); profileName.select(); profileName.focus(); // Initialize profile name validation. checkCurrentInput(profileName.value); } function setDisplayToDefaultFolder() { setDisplayToFolder(gProfile.defaultProfileParentDir); document.getElementById("useDefault").disabled = true; } function setDisplayToFolder(profileRoot) { var profileName = document.getElementById("profileName"); profileName.focus(); gProfileRoot = profileRoot; } function updateProfileDisplay() { var currentProfileName = document.getElementById("profileName").value; var profilePathAndName = gProfileRoot.clone(); profilePathAndName.append(currentProfileName); gProfileDisplay.data = profilePathAndName.path; } // Shows the Language/Region Selection dialog and updates the data-Attributes to // the selected values. function showLangDialog() { var languageCode = document.getElementById("profileLanguage").getAttribute("data"); var regionCode = document.getElementById("profileRegion").getAttribute("data"); window.openDialog("chrome://communicator/content/profile/selectLang.xul", "", "centerscreen,modal,titlebar", languageCode, regionCode); } // Invoke a folder selection dialog for choosing the directory of profile storage. function chooseProfileFolder() { var newProfileRoot; try { var dirChooser = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker); dirChooser.init(window, gProfileManagerBundle.getString("chooseFolder"), Components.interfaces.nsIFilePicker.modeGetFolder); dirChooser.appendFilters(Components.interfaces.nsIFilePicker.filterAll); if (dirChooser.show() == dirChooser.returnCancel) return; newProfileRoot = dirChooser.file; } catch(e) { // If something fails, change nothing. return; } // Disable the "Default Folder..." button when the default profile folder // was selected manually in the File Picker. // This is always false on Windows, until bug 221872 is fixed. document.getElementById("useDefault").disabled = (newProfileRoot.equals(gProfile.defaultProfileParentDir)); setDisplayToFolder(newProfileRoot); updateProfileDisplay(); } // Checks the current user input for validity and triggers an error message accordingly. function checkCurrentInput(currentInput) { var finishButton = document.documentElement.getButton("finish"); var finishText = document.getElementById("finishText"); var canAdvance; var errorMessage = checkProfileName(currentInput); if (!errorMessage) { finishText.className = ""; finishText.firstChild.data = gProfileManagerBundle.getString("profileFinishText"); canAdvance = true; } else { finishText.className = "error"; finishText.firstChild.data = errorMessage; canAdvance = false; } document.documentElement.canAdvance = canAdvance; finishButton.disabled = !canAdvance; updateProfileDisplay(); } // Checks whether the given string is a valid profile name. // Returns an error message describing the error in the name or "" when it's valid. function checkProfileName(profileNameToCheck) { // Check for emtpy profile name. if (!/\S/.test(profileNameToCheck)) return gProfileManagerBundle.getString("profileNameEmpty"); // Check whether all characters in the profile name are allowed. if (/([\\*:?<>|\/\"])/.test(profileNameToCheck)) return gProfileManagerBundle.getFormattedString("invalidChar", [RegExp.$1]); // Check whether a profile with the same name already exists. if (gProfile.profileExists(profileNameToCheck)) return gProfileManagerBundle.getString("profileExists"); // profileNameToCheck is valid. return ""; } // Called when the first wizard page is shown. function enableNextButton() { document.documentElement.canAdvance = true; } function onCancel() { // window.opener is false if the Create Profile Wizard was opened from the command line. if (!window.opener) return true; try { gProfile.forgetCurrentProfile(); } catch (ex) { } return true; } function onFinish() { var profileName = document.getElementById("profileName").value; var languageCode = document.getElementById("profileLanguage").getAttribute("data"); var regionCode = document.getElementById("profileRegion").getAttribute("data"); var proceed = processCreateProfileData(profileName, gProfileRoot, languageCode, regionCode); // Error on profile creation. Don't leave the wizard so the user can correct his input. if (!proceed) return false; // window.opener is false if the Create Profile Wizard was opened from the command line. if (window.opener) // Add new profile to the list in the Profile Manager. window.opener.CreateProfile(profileName, gProfileRoot); else // Use the newly created Profile. gProfile.currentProfile = profileName; // Exit the wizard. return true; } // Create profile named profileName in profileRoot. function processCreateProfileData(profileName, profileRoot, languageCode, regionCode) { try { var profileLocation = profileRoot.clone(); profileLocation.append(profileName); gProfile.createNewProfileWithLocales(profileName, profileRoot.path, languageCode, regionCode, profileLocation.exists()); return true; } catch (e) { var profileCreationFailed = gProfileManagerBundle.getString("profileCreationFailed"); var profileCreationFailedTitle = gProfileManagerBundle.getString("profileCreationFailedTitle"); var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService); promptService.alert(window, profileCreationFailedTitle, profileCreationFailed); return false; } } PK 5,f/#wh h 4content/communicator/profile/createProfileWizard.xulUT M?ILDDUx %brandDTD; %profileDTD; ]> PK vq. 4@@content/editor/pref-editing.xulUT jRv>NDDUx PK vq.ו)content/editor/editorNavigatorOverlay.xulUT hRv>NDDUx PK N.'*content/editor/editorApplicationOverlay.jsUT L>NDDUx/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Netscape Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the NPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /* Implementations of nsIControllerCommand for composer commands */ function initEditorContextMenuItems(aEvent) { var shouldShowEditPage = !gContextMenu.onImage && !gContextMenu.onLink && !gContextMenu.onTextInput && !gContextMenu.inDirList; gContextMenu.showItem( "context-editpage", shouldShowEditPage ); var shouldShowEditLink = gContextMenu.onSaveableLink; gContextMenu.showItem( "context-editlink", shouldShowEditLink ); // Hide the applications separator if there's no add-on apps present. gContextMenu.showItem("context-sep-apps", gContextMenu.shouldShowSeparator("context-sep-apps")); } function initEditorContextMenuListener(aEvent) { var popup = document.getElementById("contentAreaContextMenu"); if (popup) popup.addEventListener("popupshowing", initEditorContextMenuItems, false); } addEventListener("load", initEditorContextMenuListener, false); function editDocument(aDocument) { if (!aDocument) aDocument = window._content.document; editPage(aDocument.URL, window, false); } function editPageOrFrame() { var focusedWindow = document.commandDispatcher.focusedWindow; // if the uri is a specific frame, grab it, else use the frameset uri // and let Composer handle error if necessary var url = getContentFrameURI(focusedWindow); editPage(url, window, false) } // Any non-editor window wanting to create an editor with a URL // should use this instead of "window.openDialog..." // We must always find an existing window with requested URL // (When calling from a dialog, "launchWindow" is dialog's "opener" // and we need a delay to let dialog close) function editPage(url, launchWindow, delay) { // Always strip off "view-source:" and #anchors url = url.replace(/^view-source:/, "").replace(/#.*/, ""); // User may not have supplied a window if (!launchWindow) { if (window) { launchWindow = window; } else { dump("No window to launch an editor from!\n"); return; } } // if the current window is a browser window, then extract the current charset menu setting from the current // document and use it to initialize the new composer window... var wintype = document.firstChild.getAttribute('windowtype'); var charsetArg; if (launchWindow && (wintype == "navigator:browser") && launchWindow._content.document) charsetArg = "charset=" + launchWindow._content.document.characterSet; try { var uri = createURI(url, null, null); var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(); var windowManagerInterface = windowManager.QueryInterface( Components.interfaces.nsIWindowMediator); var enumerator = windowManagerInterface.getEnumerator( "composer:html" ); var emptyWindow; while ( enumerator.hasMoreElements() ) { var win = enumerator.getNext().QueryInterface(Components.interfaces.nsIDOMWindowInternal); if ( win && win.IsWebComposer()) { if (CheckOpenWindowForURIMatch(uri, win)) { // We found an editor with our url win.focus(); return; } else if (!emptyWindow && win.PageIsEmptyAndUntouched()) { emptyWindow = win; } } } if (emptyWindow) { // we have an empty window we can use if (emptyWindow.IsInHTMLSourceMode()) emptyWindow.SetEditMode(emptyWindow.PreviousNonSourceDisplayMode); emptyWindow.EditorLoadUrl(url); emptyWindow.focus(); emptyWindow.SetSaveAndPublishUI(url); return; } // Create new Composer window if (delay) { launchWindow.delayedOpenWindow("chrome://editor/content", "chrome,all,dialog=no", url); } else launchWindow.openDialog("chrome://editor/content", "_blank", "chrome,all,dialog=no", url, charsetArg); } catch(e) {} } function createURI(urlstring) { try { var ioserv = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); return ioserv.newURI(urlstring, null, null); } catch (e) {} return null; } function CheckOpenWindowForURIMatch(uri, win) { try { var contentWindow = win.content; // need to QI win to nsIDOMWindowInternal? var contentDoc = contentWindow.document; var htmlDoc = contentDoc.QueryInterface(Components.interfaces.nsIDOMHTMLDocument); var winuri = createURI(htmlDoc.URL); return winuri.equals(uri); } catch (e) {} return false; } function NewEditorFromTemplate() { // XXX not implemented } function NewEditorFromDraft() { // XXX not implemented } PK !)W-ltʬ&content/editor/StructBarContextMenu.jsUT ]=NDDUx/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Daniel Glazman (glazman@netscape.com), original author * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ var gContextMenuNode; var gContextMenuFiringDocumentElement; function InitStructBarContextMenu(button, docElement) { gContextMenuFiringDocumentElement = docElement; gContextMenuNode = button; var tag = docElement.nodeName.toLowerCase(); var structRemoveTag = document.getElementById("structRemoveTag"); var enableRemove; switch (tag) { case "body": case "tbody": case "thead": case "tfoot": case "col": case "colgroup": case "tr": case "th": case "td": case "caption": enableRemove = false; break; default: enableRemove = true; break; } SetElementEnabled(structRemoveTag, enableRemove); var structChangeTag = document.getElementById("structChangeTag"); SetElementEnabled(structChangeTag, (tag != "body")); } function TableCellFilter(node) { switch (node.nodeName.toLowerCase()) { case "td": case "th": case "caption": return NodeFilter.FILTER_ACCEPT; break; default: return NodeFilter.FILTER_SKIP; break; } return NodeFilter.FILTER_SKIP; } function StructRemoveTag() { var editor = GetCurrentEditor(); if (!editor) return; var element = gContextMenuFiringDocumentElement; var offset = 0; var childNodes = element.parentNode.childNodes; while (childNodes[offset] != element) { ++offset; } editor.beginTransaction(); try { var tag = element.nodeName.toLowerCase(); if (tag != "table") { MoveChildNodesAfterElement(editor, element, element, offset); } else { var nodeIterator = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT, TableCellFilter, true); var node = nodeIterator.lastChild(); while (node) { MoveChildNodesAfterElement(editor, node, element, offset); node = nodeIterator.previousSibling(); } } editor.deleteNode(element); } catch (e) {}; editor.endTransaction(); } function MoveChildNodesAfterElement(editor, element, targetElement, targetOffset) { var childNodes = element.childNodes; var childNodesLength = childNodes.length; var i; for (i = childNodesLength - 1; i >= 0; i--) { var clone = childNodes.item(i).cloneNode(true); editor.insertNode(clone, targetElement.parentNode, targetOffset + 1); } } function StructChangeTag() { var textbox = document.createElementNS(XUL_NS, "textbox"); textbox.setAttribute("value", gContextMenuNode.getAttribute("value")); textbox.setAttribute("width", gContextMenuNode.boxObject.width); textbox.className = "struct-textbox"; gContextMenuNode.parentNode.replaceChild(textbox, gContextMenuNode); textbox.addEventListener("keypress", OnKeyPress, false); textbox.addEventListener("blur", ResetStructToolbar, true); textbox.select(); } function StructSelectTag() { SelectFocusNodeAncestor(gContextMenuFiringDocumentElement); } function OpenAdvancedProperties() { doAdvancedProperties(gContextMenuFiringDocumentElement); } function OnKeyPress(event) { var editor = GetCurrentEditor(); var keyCode = event.keyCode; if (keyCode == 13) { var newTag = event.target.value; var element = gContextMenuFiringDocumentElement; var offset = 0; var childNodes = element.parentNode.childNodes; while (childNodes.item(offset) != element) { offset++; } editor.beginTransaction(); try { var newElt = editor.document.createElement(newTag); if (newElt) { childNodes = element.childNodes; var childNodesLength = childNodes.length; var i; for (i = 0; i < childNodesLength; i++) { var clone = childNodes.item(i).cloneNode(true); newElt.appendChild(clone); } editor.insertNode(newElt, element.parentNode, offset+1); editor.deleteNode(element); editor.selectElement(newElt); window.content.focus(); } } catch (e) {} editor.endTransaction(); } else if (keyCode == 27) { // if the user hits Escape, we discard the changes window.content.focus(); } } PK .[^$content/editor/images/sendtoback.gifUT Gi>NDDUxGIF89a!,APH@q(cU#9Cy-`s ś c(w42 $Ӥed;PK .W-content/editor/images/sendtoback-disabled.gifUT Gi>NDDUxGIF89a!,^@06d 8‏*^dH9ʕ5r̐ѡΕ$E 4ƞ-,eҦs;PK .&content/editor/images/bringtofront.gifUT Gi>NDDUxGIF89a!,>PH@q(UZny+@m9lnA*T\jT)i2NgpuF;PK .-ݾ}}/content/editor/images/bringtofront-disabled.gifUT Gi>NDDUxGIF89a!,Z@p6d3H1Ǐ+^ȑJHPeH)]d2“1UbXsB)Z8QБ Oxh@;PK (̽$content/editor/images/tag-anchor.gifUT i9NDDUxGIF89a````@!,DZ%I "Z6TTaኦ/WDfn*],ո Ac 9 PA@Zdz;PK (A8k!content/editor/images/tag-abr.gifUT i9NDDUxGIF89a"@````@@ !,"8`hue EU.)@`(KzEh J*!owSbji9-#5V=VUJ5=3,)(212cX"Jd W ;PK r.!~!content/editor/images/tag-acr.gifUT Lw>NDDUxGIF89a8@````@@ !,8@0s" gp^av,Aw< +dB",EZ,6 z`+7Bba51'b҂)d{0 )J~ $-cdab)~z]*L.wn<*lt3-'% *c5>1THBmmmh x9>H0E;@mڷ)?6Ş8 ;PK r.?!content/editor/images/tag-adr.gifUT Lw>NDDUxGIF89a,@````@@ !,,@wH`(B1*fa7vƒN>#T,jD> *iOliQ1EE 1 ti[z2$=Oq`Xy&HJl!D7pu(*cCXgZ"!H.nDIOslj)l.|*q6xNwPF)~%  ;PK Ár.ޟҥ!content/editor/images/tag-ara.gifUT Mw>NDDUxGIF89a&@````@@ !,&@*"cA1f]H iU5nk;Ab@)NZ&.KR J:n𸼈yW\ޓ8`@J?&Q1;U"#LN#%M(;T!gZt.5gv?J+ ;PK Ár.(PP!content/editor/images/tag-bas.gifUT Mw>NDDUxGIF89a$@````@@ !,$@wт((i}flrUNJޤg]j5Tސޯ9aHxe Q`;ǵ@fѳQCE@Imop` {OBK ;%c,R_\8aL(]`fP y~/r ;PK Ár.A!content/editor/images/tag-blq.gifUT Nw>NDDUxGIF89a,```UU*@U@@ `Gq99rr9! ,,@0IRhi%*z58oij&ӱHB! B=SǸ$i Al %&P @8ZrR2 f =-_?u14n/q,6kiu#e,  tIKu4f{~NwqRQvnM!;PK ār.U$!content/editor/images/tag-bsf.gifUT Ow>NDDUxGIF89a8@````@@ !,8@0s h\]iBrG Z(=E`+#(dvbШtJUլv<-+~N2`<^%PLp!}vM4\pr(yhBt{f]+('?l*)26-87limB/W+=?D&=n^Z3 ;PK ār.m!content/editor/images/tag-btn.gifUT Ow>NDDUxGIF89a8@````@@ !,2@0.!0vix&aapd+hQ׷6h ШtJeʪجvP˒&G KӒk,sC#z^WZ#0qx$J;?tn,pzV3b9bKe) `9l @Iaf htIM6^ddDG9AcYl} ;PK ār.œ!content/editor/images/tag-cit.gifUT Ow>NDDUxGIF89a&@````@@ !,&@j-TA Z$U gk䙖|:oHKr(!p<8@l5xL.ϻHXvǡi ILlyR/KNNDDUxGIF89a2@```@@ `!,2@0s0 l)֑&'I XvVEƞ:/:&0ŞШTʤMl;BoH-9̺1$5dA=DtJb=1W[U ;PK ār.wu!content/editor/images/tag-cod.gifUT Pw>NDDUxGIF89a&@````@@ !,&@@ jLUWU]gy@P˕*ʪl:SKרx=ORS` 5\Apy |Ng>,i~\k_< S%YFQ`XU[^v 1469;J?jDx, ;PK Łr.9!content/editor/images/tag-cpt.gifUT Qw>NDDUxGIF89a6@````@@ !,6@0s%+0YWٙa*@mW`/ NPnz[iJZXj zӭ#e4`gdgKG&!&NDDUxGIF89a,@````@@ !,,@wIe #:oB ThZXumW~zKƛHm&DfҸn -M2 Hૌтa$Yi(Cs xuy 3m`G^e NDDUxGIF89a,@````@@ !,,@wH!eh)%e[eԨq@!iҕ|cJj,SC 5Tmؙ5rYeafZhY;[flHc035Uu:BT&,NXBbrx`nh:sqMS )l4  ;PK Ɓr.|!content/editor/images/tag-fnt.gifUT Sw>NDDUxGIF89a&@````@@ !,&@P.We(Y dU@ p p7GppHXŤulz5 Ht4Wp<zn8Q5bSY9(: U&e7w7L4<-Xp(36Qar+ ;PK Ɓr.!content/editor/images/tag-for.gifUT Sw>NDDUxGIF89a$@````@@ !,$@w8g qalJzM8v4Ku:2 V-S(|˦e '(g_DL8m- @hWR N_ZŘgYU`jrM>(&^gaGvw%'Wbz>@"[?xD}W/Ryk ;PK Ɓr.A!content/editor/images/tag-frm.gifUT Sw>NDDUxGIF89a(@````@@ !,(@w$#fA$tBqevfaz`*,eQ!3VkTt+ iYgV1`֜N6UUt_ǰL;Cs x}qQTSc\WO->sqJe @M+g\^jp/V#!2iS.t ;PK Ɓr.`  !content/editor/images/tag-fst.gifUT Sw>NDDUxGIF89a,@````@@ H!,,@0I9h! C eX|B[<0ȀMs q@SB8*H]OΪ %2LШq]{-b, `|OQ),l\B?HZ@htD)lm/hKb_[pm;r?Lx;.?sa^SIXX8Wn$;PK Ɓr.!content/editor/images/tag-ifr.gifUT Tw>NDDUxGIF89a.@````@@ !,.@BT 5ec\Bq"1le&Zf%ya*YbȤpYD2P첤ut 4VڂFf)7&,~URRMgthB9d\X9fVO"C9]@FT0aX575 5`U%o]$'#PT ;PK ǁr.AF!content/editor/images/tag-inp.gifUT Uw>NDDUxGIF89a&@````@@ !,&@@@U}veHeXКYXj`@``,DKV2+$ S lB/lEznǸq8zUp#l1}W*1MOS4<&:pP8O%UTe1LcPR'pr>f ;PK ǁr.Jm!content/editor/images/tag-lbl.gifUT Uw>NDDUxGIF89a&@````@@ !,&@͛&d"a`g\ E@),MJk)e/S 7\@eov4<znpiplfc*K6\++:#V,13O3\57UI1X=1R79SdIqH)( ;PK (C!content/editor/images/tag-lgn.gifUT i9NDDUxGIF89a0@````@@ !,0@0shaWRjEPpa[`xކ[@i`rl:I6Ix`ke,/7c; RV[z`oqmz{wyl8|YS^!Z>$(eHg\%*a9$!&j?979;8BA,EBTj} ;PK ǁr.l!content/editor/images/tag-lnk.gifUT Uw>NDDUxGIF89a@````@@ !,@w"-2 M AکZEp8Mvh20s Ub*Ԙj[q5v)ZegbQ(.NYcu w|3y_Lodz: %? ;PK (^Š!content/editor/images/tag-lst.gifUT i9NDDUxGIF89a2@````@@ !,2@0s0[  `W@h ˅ӡ 6l:PflZSr R׳Kŀٯv[pHvTW{j$qoxlHmwyRJ-[0&!%b +{5`g.+.")ZEA]^BIUYS ;PK ǁr.V$!content/editor/images/tag-men.gifUT Uw>NDDUxGIF89a&@````@@ !,&@И aiՑ]V]]BGE'`Cm#3bK!4:' (,ߨL-1@h|^Dڏ9%\g~;u,d. ,_7=&+.NLd$%YJ c8S-"%w?Z) ;PK ǁr.QQ!content/editor/images/tag-nbr.gifUT Vw>NDDUxGIF87a&cccBB!Zc))B!!s11RkJJ!ss9cc1kk1B,&` di(@p,x.k WXHDB@j,̑cGk8d p0 |VHPlb%~K~Us YT,. ,P  prWu/P[q>,CWJ-{}~A-u\^`ydfv-tEDF QH-:90U((q * ;PK ǁr.x!content/editor/images/tag-nfr.gifUT Vw>NDDUxGIF89a,```UU*Uc@rr9@@ 99Gq! ,,@0IZh@H[0V("ږG#bX@\bqgsc?N4 Fez@ES pD}r}4>8s>?bZ- ~m/ w2ncf]wjjvu)~p|0@5'+8! ,ǥ7 ԡ3#;PK ǁr.!content/editor/images/tag-nsc.gifUT Vw>NDDUxGIF89a,@````@@ !,,@wH 蔁8Y'`vE ŕmj "P-O&#I3KarMe @Ft%=֯V"!NDDUxGIF89a2@````@@ !,2@0s(A[聜}I1!B+[+իi~ƓL%j:h36ZX%!; Iu&m3\^^|*;UX!1kmr=swvunj&a%caKoL:{c >fA>8]!NDDUxGIF89a.@````@@ !,.@@ X `iޕmPB AL籞@8\`rl:;ȧt<Ɗ/Iʤz]5)iݧt|dY~gTTG rn4o4ouCvQ&h?^"(*ePW$>=kba`,8FQ@;6_t?:NDDUxGIF89a*@```@@ `!,*@ZQ`yaButiyڜ-̥)dol:S\J`%]Z_alc A9Ѡ&Q;:8~OOQpigm&/!_"[` \ RY9!:SAb2-m)a++Ht0 ;PK ȁr.Nz!content/editor/images/tag-scr.gifUT Xw>NDDUxGIF89a,@```@@ `!,,@Н( PtPfCehmW`YX Ȥr (ٚ)b;U)xzn?0qZN~URN(jih3jp[oj+U )"<`'muFl^/mo^)=0rZT.42eL, ;PK ȁr.*!content/editor/images/tag-slc.gifUT Xw>NDDUxGIF89a.@````@@ !,.@0 !j޷}iB֑1TE`\Xݡ6sE[8<@*eNVG ;PK ȁr.Ջ"c!content/editor/images/tag-sml.gifUT Xw>NDDUxGIF89a(@````@@ !,(@P0 灙U@@ UiʢpوdoR )J< B w |Nwx¥Y^~^db((FW)) 0`GY)[b.3'?.0_#yEL+¼ ;PK ȁr.D!content/editor/images/tag-smp.gifUT Xw>NDDUxGIF89a&@````@@ !,&@0qRe1@Vż"^ApH,VƤBV\;LSۀD3 8S Su |Nw.D1eej]X3O2 :~7G^d[07V ;3@;[%#Cxk+l ;PK Ɂr.Px!content/editor/images/tag-spn.gifUT Yw>NDDUxGIF89a&@````@@ !,&@0!h\yE`\al_@.H,TKPmf,*tb 9ΠznpqDMz!nlXa+RW/MN^2e"%Q/%VNDDUxGIF89a,@````@@ !,,@Н0 Ae,I j\F!|oWjyZȤr ( rU'|\սia+ *6k]aURNdwvY6CZrZpuvEU8,G%+[aYc-ho=g]_ ABf1X_\ (ewSF/ ;PK Ɂr.!content/editor/images/tag-stl.gifUT Yw>NDDUxGIF89a(@````@@ !,(@wт('\I#`\)Uɕ{5ҮTҕ£XKJ0 * 2\!v5NkA]UU@dOu}0a "fGg S@KI^~+~Dd@T`[[W"[4mn ;PK Ɂr.`Q*!content/editor/images/tag-stn.gifUT Yw>NDDUxGIF89a2@````@@ !,2@0s v`dEPhe!"fںUSb"4iШtJ6C֬6%'h=93:c> z>sɟio[3O>y;~({nfXl gsLj '2#O^{Ab KHPh#k+.N7Kaf%CG.GXVn ;PK Ɂr.7!content/editor/images/tag-tbd.gifUT Zw>NDDUxGIF89a*@```@@ `!,*@w#x̛灜PAlۆRV9RW /YNd&a4j8Y9J!js\ݐW_<k vk~yRs~kCFKQihWd%Y1?VO o=3C:0aG@GI$\ ;PK Ɂr.͍C!content/editor/images/tag-tbl.gifUT Zw>NDDUxGIF89a(@````@@ !,(@w"-2e-F`HƑ2f'4m\wI<.'A`g9'k+`nm`dTJ OY9@TiO0ZA7^0cRXNjl{h KUf8(\epGqg!Ger_[CT0 ;PK Ɂr.YZ!content/editor/images/tag-tft.gifUT Zw>NDDUxGIF89a*@```@@ `!,*@w!(MQimu]At]Sd[\݊#Y<v4jN')$`h9qScgUV h&S|>vdA)LYqM8c^DOi\zS%LEY{jrEE_rV1 ;PK ʁr.7!!content/editor/images/tag-thd.gifUT [w>NDDUxGIF89a*@````@@ !,*@wт(Bi& !4Jct/'Z]X,@#ޒ-e1ʜB'-*@iG ! 姑jUSejuBNDDUxGIF89a$@````@@ !,$@waB2}ui ga(YdgM˔:.LBAUzI%~p9ixܐb`΁nݸ" %PiW^Fcv:TGq{_V}WAv? dv*-a_&^j ;PK ǁr. ɾ  !content/editor/images/tag-isx.gifUT Uw>NDDUxGIF89a(```UUU*q`rr9@99G! ,(@0I)chC4A BuZeܸ,Ү黖P(3!U&PiXѐzZėN;V!Q-xh\ek osqI z#Z 0 O Ene!gUi]RJDFx~Kog@FGK yY]  ʑe$;PK ǁr."!content/editor/images/tag-met.gifUT Uw>NDDUxGIF89a$@````@@ !,$@wHPL0b2"SuR!h!^k**yRiQ 4<Hcp:c Ђ"'6@΁nrn'3q!hwZ:SgiPd/S*dZf -r%4]U`g# ;PK ʁr.Ik!content/editor/images/tag-ttl.gifUT [w>NDDUxGIF89a(@````@@ !,(@f!f2g qPuX;vnqtP=K-,KF20悩):@(QY%6TǺ:aïQOj)RCT[>CXE_t@UY 47VuDI;[9TPb+ ;PK P~(!content/editor/images/tag-pln.gifUT D9NDDUxGIF89a#̙ffff333!,#XIK ]6)(VyJ l3 켐:phn!) >K4"x+ MʹYD w`FH@]^UoE#@g;xqhz=NDDUxGIF89a:@````@@ !,:@0pN@\1.ae @ `y1+_6@J-2 ex*ȓѮجv˽VOݰxmfO[ D򠇸ScHaymw0~?n4?H48:fdX9?jH~nQ|On`IB z5&4)meV@k oL.I7&jiBh+uCh{CyPMµa_  ;PK (V4}content/editor/images/tag-a.gifUT i9NDDUxGIF89a```@`@@ !,Oz'I "]QlXA fرTHE[0Z a ZXd#Y!c`x @zN;PK Ár.!p!content/editor/images/tag-app.gifUT Mw>NDDUxGIF89a.@````@@ !,.@"+zFrd@ ! oPݖtϙjw*H0l"U,Kn :h@Ȟ#2sju ~G*eh.mlAjeopB:h&Y!8D&)`!]nYf=K#]r(aDEP t ;PK Ár.+content/editor/images/tag-b.gifUT Mw>NDDUxGIF89a```@@@ `!,@OZ% PEy榞겦HjR8W pzMN.!xFVŽMczN;PK Ár.r!content/editor/images/tag-bdo.gifUT Mw>NDDUxGIF89a@```@@ `!,@ĤALK~1\ WP.,|_`/`BeV$Ne\bJu n88xL [$jYUlɶ4|' ]X2JuMu?v1/35h\ & ;PK Ár.AR!content/editor/images/tag-big.gifUT Mw>NDDUxGIF89a@````@@ !,@u@4K(VqĀQ Ȫ1lxPxoJj%|@^AYKկt XجvyC(*EAӮs<(9@6Gr.yws;_4 T ;PK Ár.;s"content/editor/images/tag-body.gifUT Nw>NDDUxGIF89a$@````@@ !,$@w2['`]}iWƉ``~p裭f!kQL i+r tq^']Fsp p8|,j=]HstF/96^@?kB J%2dNb_<5[QSw2h97XB:D^$VA ;PK ār.ӝ content/editor/images/tag-br.gifUT Ow>NDDUxGIF89a@````@@ !,@c}' Nc&`U!Y\ q #vҀB&z O@h:P(fE&!v(H*ɅJ!$kMzpuQc8ޱ< ;PK ār.Է!content/editor/images/tag-col.gifUT Pw>NDDUxGIF89a```@`@@ !,@|J(Lc(@@x^0efĊ$euw^W CFS 0gR,vzqr !5$i:[OGաՖq&2:}+N02!0U6'Db@= W ;PK Łr.֞ϟ content/editor/images/tag-dd.gifUT Qw>NDDUxGIF89a@```@@ `!,@d}', L0S@ \PŧU[$K8-ޔ!ߎ#( @v 8hˉ"%Ҡ fA~{YLN)ЦhcA ;PK Łr.=7!content/editor/images/tag-del.gifUT Qw>NDDUxGIF89a@````@@ !,@t@A fUG`w 09NDDUxGIF89a@````@@ !,@~@K-UT*\ ivx끽Q&˒}K&E@zx,z4k\ Xk4G{+[S3 4s}(*K4u*Pff $ ;PK (L .!content/editor/images/tag-dir.gifUT i9NDDUxGIF89a```@@@ `!,@u@i @F`T0LdPyk&Jx^zETd x0''98جv4ɍd[j"mwfYFwn|k`?5 & ;PK Łr.zJҨ!content/editor/images/tag-div.gifUT Rw>NDDUxGIF89a```@`@@ !,@mwH8 'qRAƕmc Ư|0+ P@j\7tJl䷛ 12{( ^d$N:HGj2m, P ;PK Łr."a͑ content/editor/images/tag-dl.gifUT Rw>NDDUxGIF89a```@@@ `!,@VfIe"}aaZH@}*a\)3QF1 dAX('j UaJ ʅ5fS%lc|>O;PK Łr.A content/editor/images/tag-dt.gifUT Rw>NDDUxGIF89a```@@@ `!,@^}',eUE`vp_(߮R5M*eal:F!(ݴ0Q~٨SA+~';PK Ɓr.  content/editor/images/tag-em.gifUT Sw>NDDUxGIF89a@````@@ !,@`m&ĜUd!biW^naHi{js`APX0l:mL$ґVZ A, :F2kZ[9a ;PK Ɓr.z4 content/editor/images/tag-h1.gifUT Sw>NDDUxGIF89a```@`@@ !,@NfIe"},D(M'jnlD0P7n Pc FӰR^ekJVf ؤI<Z;PK Ɓr.]j; content/editor/images/tag-h2.gifUT Sw>NDDUxGIF89a```@@@ `!,@\wIe"}4QAX6kqnY^m& tBȤR{ BT:s&({UI?DDذ),ư3|gzH7^;PK Ɓr.c~˕ content/editor/images/tag-h3.gifUT Tw>NDDUxGIF89a```@@@ `!,@ZwIe"}4KAiD3azA;QͨabrĵVn(qSa18)Q.fxx|;PK Ɓr.fhpC content/editor/images/tag-h4.gifUT Tw>NDDUxGIF89a```@`@@ !,@Vf CD%mPTVmcHdH ;]79O;PK Ɓr.bT content/editor/images/tag-h5.gifUT Tw>NDDUxGIF89a```@`@@ !,@YfIe"}$DAaaڔƵqAP`kgHdłHv1U`$p`崌r`oJfR8!;PK Ɓr.zi# content/editor/images/tag-h6.gifUT Tw>NDDUxGIF89a```@`@@ !,@ZfIe"}$A`aaڔƵHdxz1 tPp3 dbA&=ш>,vXF nnTx|;PK Ɓr. content/editor/images/tag-hr.gifUT Tw>NDDUxGIF89a@````@@ !,@]fIe #} ib@ eJ Գ3 @h:OϦr|fXR V\$8j&:8񶪩// ~O;PK Ɓr.^9q"content/editor/images/tag-html.gifUT Tw>NDDUxGIF89a&@````@@ !,&@fт8&hwz _+ ̦p|&Fc H$p1m?N.'OFЯsJFse2wjrɼZvf1N3[~5^{]T@a7igXn`mb@d0k! ;PK (L~~content/editor/images/tag-i.gifUT i9NDDUxGIF89a```@`!,@Cz'I8!1ޤqa)niulHxx8C^@_1/qX`z ;PK Ɓr.P$J!content/editor/images/tag-img.gifUT Tw>NDDUxGIF89a@````@@ !,@{@Ab*+1UVY0UWv*]cPcm@`06 -3Jvz*i>1p\(ŕT(x2*UDC5H-/H yaccC X ;PK ǁr."Z!content/editor/images/tag-ins.gifUT Uw>NDDUxGIF89a```@`@@ !,@w@i d@(TVYUWf}Wqm|{nGI|4P TX: جv񾣜$6uFRN~DF6< -wB-)|k^``H U ;PK ǁr.!content/editor/images/tag-kbd.gifUT Uw>NDDUxGIF89a@````@@ !,@@%`m1LՕ!|Rxy`` EgJ o z@zఘ(,\TĬ 3Eҝѳ_HMw%sG-,2v7fe>' [ ;PK (૶= content/editor/images/tag-li.gifUT i9NDDUxGIF89a```@`!,@T}' Ÿir(iK&RFۃ`H,1Wk8R2t^7:, XUb?x<;PK ǁr.D`!content/editor/images/tag-map.gifUT Uw>NDDUxGIF89a@````@@ !,@T j0E1Lic`T`d?)( Lf1¦\R@z ,t h 6Cy,,LqB(",3Z>f & ;PK ǁr.5X!content/editor/images/tag-obj.gifUT Vw>NDDUxGIF89a0@````@@ !,0@0s(݁'mfn@ȶg@\ 4@kl:HtJ+Vfz5QriSҿESE~hUW,lkqKDsnq*WR)(%_n'fQJ[94+>bZrA68:@[v0RT1 ;PK p(c content/editor/images/tag-ol.gifUT ,9NDDUxGIF89a$@````@@ !,$nx0I8;$X $@i0( B;Ԁ-/~Aػ p$B@2BWg<9fdyal▀7  ;PK ȁr.(content/editor/images/tag-p.gifUT Ww>NDDUxGIF89a```@@@ `!,@MUB$2 @ؑi(+NeQkp84^TM7Lbj3v+t:;PK ȁr.Q\'!content/editor/images/tag-pre.gifUT Ww>NDDUxGIF89a@````@@ !,@iwHD2"fi(m]jJaX-¶S\1#h`ztJj2*[CwUQHRncpX%KN ;PK ȁr.$|9content/editor/images/tag-q.gifUT Ww>NDDUxGIF89a```@`@@ !,@Tz' J(ĐKlm[JtLaDaa@,UL6xlǩTIs X"]r;;PK ȁr. "content/editor/images/tag-s.gifUT Xw>NDDUxGIF89a```@@@ `!,@Pz' HPֵuߦ(&*1zNs*'ǹ2X6 5D+`O[c(/zzn;PK Ɂr.!content/editor/images/tag-sub.gifUT Yw>NDDUxGIF89a@```@@ `!,@|@E 1CAa]}&f=y< *%0Zצp֎F CazoܦUL`LIUn[wBDz*1G0Nd% Y ;PK Ɂr.=T !content/editor/images/tag-sup.gifUT Zw>NDDUxGIF89a@```@@ `!,@z@E 1FPX7^yxg$&NDDUxGIF89a@````@@ !,@Yf!2gƁU[hp,#kjpEeNLv[2Q'80-"]eIY+=q1;PK Ɂr.fF content/editor/images/tag-th.gifUT Zw>NDDUxGIF89a```@`@@ !,@Wfaʕ qTeD|(C,s(7*`+A$|!*n'%8Yl95|N';PK ʁr.Bܵ| content/editor/images/tag-tr.gifUT [w>NDDUxGIF89a```@@@ `!,@\fRh%G!"8$['A!PzD;j1xsJI Cx>=k4JPKVR#e3(RüL^;PK ʁr.z[ content/editor/images/tag-tt.gifUT [w>NDDUxGIF89a```@`@@ !,@X]% qha!xr*Y-`) ȤR)Vɯ k nnL5IJsrł`N ;PK (xhcontent/editor/images/tag-u.gifUT i9NDDUxGIF89a```@`!,@Lz'9D Qhj~ڱe8nojjq"FZd,gڬ28KXܽE2(r;PK p(ޚ content/editor/images/tag-ul.gifUT ,9NDDUxGIF89a$@````@@ !,$_x0I8ͻA(hp+*@q@0+j>tp?$l99 κu݂"0Z̸0w ;PK ʁr.w!content/editor/images/tag-var.gifUT \w>NDDUxGIF89a@````@@ !,@@A T,Q1 T6zVxobY&,3,F "(D ށz0H$ԩR]X;m'<:ػ.S02Jfc$*sz|6e)6 & ;PK (YI()content/editor/images/tag-userdefined.gifUT i9NDDUxGIF89a```@`@@ !,@Jz'II8!i \ahɥ줭ha{V$BDbK̈́ !eƲՠK)erx`L. ;PK r.g]]content/editor/images/smile.gifUT Lw>NDDUxGIF89a!,.-Ǒb"ZyI <!hnV~-+s)ev|jdC;PK r.([[!content/editor/images/s_smile.gifUT Kw>NDDUxGIF89a!,,-Ǒb"ZyI <!hnV~-r%)3v^g);PK r.dw]]&content/editor/images/smile_active.gifUT Lw>NDDUxGIF87aU,6&{)AsMXktR%F`yzkolp{hLa0&;PK r.0m]](content/editor/images/smile_disabled.gifUT Lw>NDDUxGIF87aԪU,6&{)AsMXktR%F`yzkolp{hLa0&;PK r.Wb^^%content/editor/images/smile_hover.gifUT Lw>NDDUxGIF87a,7&{)AsMXkq TE)tǼ[[f~7rX*A¥Q;PK r.^^content/editor/images/frown.gifUT Kw>NDDUxGIF89a3!,/-Ǒb"ZyI <!hnV~-JF4ߡ;PK dT0ªeecontent/editor/images/wink.gifUT o6@NDDUxGIF89a!,6&{)AsMXktR% 5^f/+q'@qfEa8Lɦ;PK r.c|\\content/editor/images/sick.gifUT Lw>NDDUxGIF89a!,--Ǒb"ZyI <!hnV~-*JIfWwidd;PK r.\\\!content/editor/images/s_frown.gifUT Kw>NDDUxGIF89a!,--Ǒb"ZyI <!hnV~-JVY|j;PK dT0wjcc content/editor/images/s_wink.gifUT o6@NDDUxGIF89a!,4&{)AsMXktR% 5^f/+19cl !;PK >0J"y"y content/editor/EdDialogCommon.jsUT H:@NDDUx/* * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998-1999 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * Pete Collins * Brian King * Charles Manske (cmanske@netscape.com) * Neil Rashbrook (neil@parkwaycc.co.uk) */ // Each editor window must include this file // Object to attach commonly-used widgets (all dialogs should use this) var gDialog = {}; var gValidationError = false; // Use for 'defaultIndex' param in InitPixelOrPercentMenulist const gPixel = 0; const gPercent = 1; const gMaxPixels = 100000; // Used for image size, borders, spacing, and padding // Gecko code uses 1000 for maximum rowspan, colspan // Also, editing performance is really bad above this const gMaxRows = 1000; const gMaxColumns = 1000; const gMaxTableSize = 1000000; // Width or height of table or cells // For dialogs that expand in size. Default is smaller size see "onMoreFewer()" below var SeeMore = false; // A XUL element with id="location" for managing // dialog location relative to parent window var gLocation; // The element being edited - so AdvancedEdit can have access to it var globalElement; /* Validate contents of an input field * * inputWidget The 'textbox' XUL element for text input of the attribute's value * listWidget The 'menulist' XUL element for choosing "pixel" or "percent" * May be null when no pixel/percent is used. * minVal minimum allowed for input widget's value * maxVal maximum allowed for input widget's value * (when "listWidget" is used, maxVal is used for "pixel" maximum, * 100% is assumed if "percent" is the user's choice) * element The DOM element that we set the attribute on. May be null. * attName Name of the attribute to set. May be null or ignored if "element" is null * mustHaveValue If true, error dialog is displayed if "value" is empty string * * This calls "ValidateNumberRange()", which puts up an error dialog to inform the user. * If error, we also: * Shift focus and select contents of the inputWidget, * Switch to appropriate panel of tabbed dialog if user implements "SwitchToValidate()", * and/or will expand the dialog to full size if "More / Fewer" feature is implemented * * Returns the "value" as a string, or "" if error or input contents are empty * The global "gValidationError" variable is set true if error was found */ function ValidateNumber(inputWidget, listWidget, minVal, maxVal, element, attName, mustHaveValue, mustShowMoreSection) { if (!inputWidget) { gValidationError = true; return ""; } // Global error return value gValidationError = false; var maxLimit = maxVal; var isPercent = false; var numString = TrimString(inputWidget.value); if (numString || mustHaveValue) { if (listWidget) isPercent = (listWidget.selectedIndex == 1); if (isPercent) maxLimit = 100; // This method puts up the error message numString = ValidateNumberRange(numString, minVal, maxLimit, mustHaveValue); if(!numString) { // Switch to appropriate panel for error reporting SwitchToValidatePanel(); // or expand dialog for users of "More / Fewer" button if ("dialog" in window && dialog && "MoreSection" in gDialog && gDialog.MoreSection) { if ( !SeeMore ) onMoreFewer(); } // Error - shift to offending input widget SetTextboxFocus(inputWidget); gValidationError = true; } else { if (isPercent) numString += "%"; if (element) element.setAttribute(attName, numString); } } else if (element) { GetCurrentEditor().removeAttributeOrEquivalent(element, attName, true) } return numString; } /* Validate contents of an input field * * value number to validate * minVal minimum allowed for input widget's value * maxVal maximum allowed for input widget's value * (when "listWidget" is used, maxVal is used for "pixel" maximum, * 100% is assumed if "percent" is the user's choice) * mustHaveValue If true, error dialog is displayed if "value" is empty string * * If inputWidget's value is outside of range, or is empty when "mustHaveValue" = true, * an error dialog is popuped up to inform the user. The focus is shifted * to the inputWidget. * * Returns the "value" as a string, or "" if error or input contents are empty * The global "gValidationError" variable is set true if error was found */ function ValidateNumberRange(value, minValue, maxValue, mustHaveValue) { // Initialize global error flag gValidationError = false; value = TrimString(String(value)); // We don't show error for empty string unless caller wants to if (!value && !mustHaveValue) return ""; var numberStr = ""; if (value.length > 0) { // Extract just numeric characters var number = Number(value.replace(/\D+/g, "")); if (number >= minValue && number <= maxValue ) { // Return string version of the number return String(number); } numberStr = String(number); } var message = ""; if (numberStr.length > 0) { // We have a number from user outside of allowed range message = GetString( "ValidateRangeMsg"); message = message.replace(/%n%/, numberStr); message += "\n "; } message += GetString( "ValidateNumberMsg"); // Replace variable placeholders in message with number values message = message.replace(/%min%/, minValue).replace(/%max%/, maxValue); ShowInputErrorMessage(message); // Return an empty string to indicate error gValidationError = true; return ""; } function SetTextboxFocusById(id) { SetTextboxFocus(document.getElementById(id)); } function SetTextboxFocus(textbox) { if (textbox) { //XXX Using the setTimeout is hacky workaround for bug 103197 // Must create a new function to keep "textbox" in scope setTimeout( function(textbox) { textbox.focus(); textbox.select(); }, 0, textbox ); } } function ShowInputErrorMessage(message) { AlertWithTitle(GetString("InputError"), message); window.focus(); } // Get the text appropriate to parent container // to determine what a "%" value is referring to. // elementForAtt is element we are actually setting attributes on // (a temporary copy of element in the doc to allow canceling), // but elementInDoc is needed to find parent context in document function GetAppropriatePercentString(elementForAtt, elementInDoc) { var editor = GetCurrentEditor(); try { var name = elementForAtt.nodeName.toLowerCase(); if ( name == "td" || name == "th") return GetString("PercentOfTable"); // Check if element is within a table cell if (editor.getElementOrParentByTagName("td", elementInDoc)) return GetString("PercentOfCell"); else return GetString("PercentOfWindow"); } catch (e) { return "";} } function ClearListbox(listbox) { if (listbox) { listbox.clearSelection(); while (listbox.firstChild) listbox.removeChild(listbox.firstChild); } } function forceInteger(elementID) { var editField = document.getElementById( elementID ); if ( !editField ) return; var stringIn = editField.value; if (stringIn && stringIn.length > 0) { // Strip out all nonnumeric characters stringIn = stringIn.replace(/\D+/g,""); if (!stringIn) stringIn = ""; // Write back only if changed if (stringIn != editField.value) editField.value = stringIn; } } function LimitStringLength(elementID, length) { var editField = document.getElementById( elementID ); if ( !editField ) return; var stringIn = editField.value; if (stringIn && stringIn.length > length) editField.value = stringIn.slice(0,length); } function InitPixelOrPercentMenulist(elementForAtt, elementInDoc, attribute, menulistID, defaultIndex) { if (!defaultIndex) defaultIndex = gPixel; // var size = elementForAtt.getAttribute(attribute); var size = GetHTMLOrCSSStyleValue(elementForAtt, attribute, attribute) var menulist = document.getElementById(menulistID); var pixelItem; var percentItem; if (!menulist) { dump("NO MENULIST found for ID="+menulistID+"\n"); return size; } menulist.removeAllItems(); pixelItem = menulist.appendItem(GetString("Pixels")); if (!pixelItem) return 0; percentItem = menulist.appendItem(GetAppropriatePercentString(elementForAtt, elementInDoc)); if (size && size.length > 0) { // Search for a "%" or "px" if (/%/.test(size)) { // Strip out the % size = RegExp.leftContext; if (percentItem) menulist.selectedItem = percentItem; } else { if (/px/.test(size)) // Strip out the px size = RegExp.leftContext; menulist.selectedItem = pixelItem; } } else menulist.selectedIndex = defaultIndex; return size; } function onAdvancedEdit() { // First validate data from widgets in the "simpler" property dialog if (ValidateData()) { // Set true if OK is clicked in the Advanced Edit dialog window.AdvancedEditOK = false; // Open the AdvancedEdit dialog, passing in the element to be edited // (the copy named "globalElement") window.openDialog("chrome://editor/content/EdAdvancedEdit.xul", "_blank", "chrome,close,titlebar,modal,resizable=yes", "", globalElement); window.focus(); if (window.AdvancedEditOK) { // Copy edited attributes to the dialog widgets: InitDialog(); } } } function getColor(ColorPickerID) { var colorPicker = document.getElementById(ColorPickerID); var color; if (colorPicker) { // Extract color from colorPicker and assign to colorWell. color = colorPicker.getAttribute("color"); if (color && color == "") return null; // Clear color so next if it's called again before // color picker is actually used, we dedect the "don't set color" state colorPicker.setAttribute("color",""); } return color; } function setColorWell(ColorWellID, color) { var colorWell = document.getElementById(ColorWellID); if (colorWell) { if (!color || color == "") { // Don't set color (use default) // Trigger change to not show color swatch colorWell.setAttribute("default","true"); // Style in CSS sets "background-color", // but color won't clear unless we do this: colorWell.removeAttribute("style"); } else { colorWell.removeAttribute("default"); // Use setAttribute so colorwell can be a XUL element, such as button colorWell.setAttribute("style", "background-color:"+color); } } } function getColorAndSetColorWell(ColorPickerID, ColorWellID) { var color = getColor(ColorPickerID); setColorWell(ColorWellID, color); return color; } function InitMoreFewer() { // Set SeeMore bool to the OPPOSITE of the current state, // which is automatically saved by using the 'persist="more"' // attribute on the gDialog.MoreFewerButton button // onMoreFewer will toggle it and redraw the dialog SeeMore = (gDialog.MoreFewerButton.getAttribute("more") != "1"); onMoreFewer(); gDialog.MoreFewerButton.setAttribute("accesskey",GetString("PropertiesAccessKey")); } function onMoreFewer() { if (SeeMore) { gDialog.MoreSection.collapsed = true; gDialog.MoreFewerButton.setAttribute("more","0"); gDialog.MoreFewerButton.setAttribute("label",GetString("MoreProperties")); SeeMore = false; } else { gDialog.MoreSection.collapsed = false; gDialog.MoreFewerButton.setAttribute("more","1"); gDialog.MoreFewerButton.setAttribute("label",GetString("FewerProperties")); SeeMore = true; } window.sizeToContent(); } function SwitchToValidatePanel() { // no default implementation // Only EdTableProps.js currently implements this } const nsIFilePicker = Components.interfaces.nsIFilePicker; function GetLocalFileURL(filterType) { var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker); var fileType = "html"; if (filterType == "img") { fp.init(window, GetString("SelectImageFile"), nsIFilePicker.modeOpen); fp.appendFilters(nsIFilePicker.filterImages); fileType = "image"; } // Current usage of this is in Link dialog, // where we always want HTML first else if (filterType.indexOf("html") == 0) { fp.init(window, GetString("OpenHTMLFile"), nsIFilePicker.modeOpen); // When loading into Composer, direct user to prefer HTML files and text files, // so we call separately to control the order of the filter list fp.appendFilters(nsIFilePicker.filterHTML); fp.appendFilters(nsIFilePicker.filterText); // Link dialog also allows linking to images if (filterType.indexOf("img") > 0) fp.appendFilters(nsIFilePicker.filterImages); } // Default or last filter is "All Files" fp.appendFilters(nsIFilePicker.filterAll); // set the file picker's current directory to last-opened location saved in prefs SetFilePickerDirectory(fp, fileType); /* doesn't handle *.shtml files */ try { var ret = fp.show(); if (ret == nsIFilePicker.returnCancel) return null; } catch (ex) { dump("filePicker.chooseInputFile threw an exception\n"); return null; } SaveFilePickerDirectory(fp, fileType); var fileHandler = GetFileProtocolHandler(); return fp.file ? fileHandler.getURLSpecFromFile(fp.file) : null; } function GetMetaElement(name) { if (name) { name = name.toLowerCase(); if (name != "") { var editor = GetCurrentEditor(); try { var metaNodes = editor.document.getElementsByTagName("meta"); for (var i = 0; i < metaNodes.length; i++) { var metaNode = metaNodes.item(i); if (metaNode && metaNode.getAttribute("name") == name) return metaNode; } } catch (e) {} } } return null; } function CreateMetaElement(name) { var editor = GetCurrentEditor(); try { var metaElement = editor.createElementWithDefaults("meta"); metaElement.setAttribute("name", name); return metaElement; } catch (e) {} return null; } function GetHTTPEquivMetaElement(name) { if (name) { name = name.toLowerCase(); if (name != "") { var editor = GetCurrentEditor(); try { var metaNodes = editor.document.getElementsByTagName("meta"); for (var i = 0; i < metaNodes.length; i++) { var metaNode = metaNodes.item(i); if (metaNode) { var httpEquiv = metaNode.getAttribute("http-equiv"); if (httpEquiv && httpEquiv.toLowerCase() == name) return metaNode; } } } catch (e) {} } } return null; } function CreateHTTPEquivMetaElement(name) { var editor = GetCurrentEditor(); try { var metaElement = editor.createElementWithDefaults("meta"); metaElement.setAttribute("http-equiv", name); return metaElement; } catch (e) {} return null; } function CreateHTTPEquivElement(name) { var editor = GetCurrentEditor(); try { var metaElement = editor.createElementWithDefaults("meta"); metaElement.setAttribute("http-equiv", name); return metaElement; } catch (e) {} return null; } // Change "content" attribute on a META element, // or delete entire element it if content is empty // This uses undoable editor transactions function SetMetaElementContent(metaElement, content, insertNew, prepend) { if (metaElement) { var editor = GetCurrentEditor(); try { if(!content || content == "") { if (!insertNew) editor.deleteNode(metaElement); } else { if (insertNew) { metaElement.setAttribute("content", content); if (prepend) PrependHeadElement(metaElement); else AppendHeadElement(metaElement); } else editor.setAttribute(metaElement, "content", content); } } catch (e) {} } } function GetHeadElement() { var editor = GetCurrentEditor(); try { var headList = editor.document.getElementsByTagName("head"); return headList.item(0); } catch (e) {} return null; } function PrependHeadElement(element) { var head = GetHeadElement(); if (head) { var editor = GetCurrentEditor(); try { // Use editor's undoable transaction // Last param "true" says "don't change the selection" editor.insertNode(element, head, 0, true); } catch (e) {} } } function AppendHeadElement(element) { var head = GetHeadElement(); if (head) { var position = 0; if (head.hasChildNodes()) position = head.childNodes.length; var editor = GetCurrentEditor(); try { // Use editor's undoable transaction // Last param "true" says "don't change the selection" editor.insertNode(element, head, position, true); } catch (e) {} } } function SetWindowLocation() { gLocation = document.getElementById("location"); if (gLocation) { window.screenX = Math.max(0, Math.min(window.opener.screenX + Number(gLocation.getAttribute("offsetX")), screen.availWidth - window.outerWidth)); window.screenY = Math.max(0, Math.min(window.opener.screenY + Number(gLocation.getAttribute("offsetY")), screen.availHeight - window.outerHeight)); } } function SaveWindowLocation() { if (gLocation) { var newOffsetX = window.screenX - window.opener.screenX; var newOffsetY = window.screenY - window.opener.screenY; gLocation.setAttribute("offsetX", window.screenX - window.opener.screenX); gLocation.setAttribute("offsetY", window.screenY - window.opener.screenY); } } function onCancel() { SaveWindowLocation(); // Close dialog by returning true return true; } function SetRelativeCheckbox(checkbox) { if (!checkbox) { checkbox = document.getElementById("MakeRelativeCheckbox"); if (!checkbox) return; } var editor = GetCurrentEditor(); // Mail never allows relative URLs, so hide the checkbox if (editor && (editor.flags & Components.interfaces.nsIPlaintextEditor.eEditorMailMask)) { checkbox.collapsed = true; return; } var input = document.getElementById(checkbox.getAttribute("for")); if (!input) return; var url = TrimString(input.value); var urlScheme = GetScheme(url); // Check it if url is relative (no scheme). checkbox.checked = url.length > 0 && !urlScheme; // Now do checkbox enabling: var enable = false; var docUrl = GetDocumentBaseUrl(); var docScheme = GetScheme(docUrl); if (url && docUrl && docScheme) { if (urlScheme) { // Url is absolute // If we can make a relative URL, then enable must be true! // (this lets the smarts of MakeRelativeUrl do all the hard work) enable = (GetScheme(MakeRelativeUrl(url)).length == 0); } else { // Url is relative // Check if url is a named anchor // but document doesn't have a filename // (it's probably "index.html" or "index.htm", // but we don't want to allow a malformed URL) if (url[0] == "#") { var docFilename = GetFilename(docUrl); enable = docFilename.length > 0; } else { // Any other url is assumed // to be ok to try to make absolute enable = true; } } } SetElementEnabled(checkbox, enable); } // oncommand handler for the Relativize checkbox in EditorOverlay.xul function MakeInputValueRelativeOrAbsolute(checkbox) { var input = document.getElementById(checkbox.getAttribute("for")); if (!input) return; var docUrl = GetDocumentBaseUrl(); if (!docUrl) { // Checkbox should be disabled if not saved, // but keep this error message in case we change that AlertWithTitle("", GetString("SaveToUseRelativeUrl")); window.focus(); } else { // Note that "checked" is opposite of its last state, // which determines what we want to do here if (checkbox.checked) input.value = MakeRelativeUrl(input.value); else input.value = MakeAbsoluteUrl(input.value); // Reset checkbox to reflect url state SetRelativeCheckbox(checkbox); } } var IsBlockParent = { APPLET: true, BLOCKQUOTE: true, BODY: true, CENTER: true, DD: true, DIV: true, FORM: true, LI: true, NOSCRIPT: true, OBJECT: true, TD: true, TH: true }; var NotAnInlineParent = { COL: true, COLGROUP: true, DL: true, DIR: true, MENU: true, OL: true, TABLE: true, TBODY: true, TFOOT: true, THEAD: true, TR: true, UL: true }; function nodeIsBreak(editor, node) { return !node || node.localName == 'BR' || editor.nodeIsBlock(node); } function InsertElementAroundSelection(element) { var editor = GetCurrentEditor(); editor.beginTransaction(); try { // First get the selection as a single range var range, start, end, offset; var count = editor.selection.rangeCount; if (count == 1) range = editor.selection.getRangeAt(0).cloneRange(); else { range = editor.document.createRange(); start = editor.selection.getRangeAt(0) range.setStart(start.startContainer, start.startOffset); end = editor.selection.getRangeAt(--count); range.setEnd(end.endContainer, end.endOffset); } // Flatten the selection to child nodes of the common ancestor while (range.startContainer != range.commonAncestorContainer) range.setStartBefore(range.startContainer); while (range.endContainer != range.commonAncestorContainer) range.setEndAfter(range.endContainer); if (editor.nodeIsBlock(element)) // Block element parent must be a valid block while (!(range.commonAncestorContainer.localName in IsBlockParent)) range.selectNode(range.commonAncestorContainer); else { // Fail if we're not inserting a block (use setInlineProperty instead) if (!nodeIsBreak(editor, range.commonAncestorContainer)) return false; else if (range.commonAncestorContainer.localName in NotAnInlineParent) // Inline element parent must not be an invalid block do range.selectNode(range.commonAncestorContainer); while (range.commonAncestorContainer.localName in NotAnInlineParent); else // Further insert block check for (var i = range.startOffset; ; i++) if (i == range.endOffset) return false; else if (nodeIsBreak(editor, range.commonAncestorContainer.childNodes[i])) break; } // The range may be contained by body text, which should all be selected. offset = range.startOffset; start = range.startContainer.childNodes[offset]; if (!nodeIsBreak(editor, start)) { while (!nodeIsBreak(editor, start.previousSibling)) { start = start.previousSibling; offset--; } } end = range.endContainer.childNodes[range.endOffset]; if (end && !nodeIsBreak(editor, end.previousSibling)) { while (!nodeIsBreak(editor, end)) end = end.nextSibling; } // Now insert the node editor.insertNode(element, range.commonAncestorContainer, offset, true); offset = element.childNodes.length; if (!editor.nodeIsBlock(element)) editor.setShouldTxnSetSelection(false); // Move all the old child nodes to the element var empty = true; while (start != end) { var next = start.nextSibling; editor.deleteNode(start); editor.insertNode(start, element, element.childNodes.length); empty = false; start = next; } if (!editor.nodeIsBlock(element)) editor.setShouldTxnSetSelection(true); else { // Also move a trailing
if (start && start.localName == 'BR') { editor.deleteNode(start); editor.insertNode(start, element, element.childNodes.length); empty = false; } // Still nothing? Insert a
so the node is not empty if (empty) editor.insertNode(editor.createElementWithDefaults("br"), element, element.childNodes.length); // Hack to set the selection just inside the element editor.insertNode(editor.document.createTextNode(""), element, offset); } } finally { editor.endTransaction(); } return true; } function nodeIsBlank(node) { return node && node.NODE_TYPE == Node.TEXT_NODE && !/\S/.test(node.data); } function nodeBeginsBlock(node) { while (nodeIsBlank(node)) node = node.nextSibling; return nodeIsBlock(node); } function nodeEndsBlock(node) { while (nodeIsBlank(node)) node = node.previousSibling; return nodeIsBlock(node); } // C++ function isn't exposed to JS :-( function RemoveBlockContainer(element) { var editor = GetCurrentEditor(); editor.beginTransaction(); try { var range = editor.document.createRange(); range.selectNode(element); var offset = range.startOffset; var parent = element.parentNode; // May need to insert a break after the removed element if (!nodeBeginsBlock(editor, element.nextSibling) && !nodeEndsBlock(editor, element.lastChild)) editor.insertNode(editor.createElementWithDefaults("br"), parent, range.endOffset); // May need to insert a break before the removed element, or if it was empty if (!nodeEndsBlock(editor, element.previousSibling) && !nodeBeginsBlock(editor, element.firstChild || element.nextSibling)) editor.insertNode(editor.createElementWithDefaults("br"), parent, offset++); // Now remove the element editor.deleteNode(element); // Need to copy the contained nodes? for (var i = 0; i < element.childNodes.length; i++) editor.insertNode(element.childNodes[i].cloneNode(true), parent, offset++); } finally { editor.endTransaction(); } } // C++ function isn't exposed to JS :-( function RemoveContainer(element) { var editor = GetCurrentEditor(); editor.beginTransaction(); try { var range = editor.document.createRange(); var parent = element.parentNode; // Allow for automatic joining of text nodes // so we can't delete the container yet // so we need to copy the contained nodes for (var i = 0; i < element.childNodes.length; i++) { range.selectNode(element); editor.insertNode(element.childNodes[i].cloneNode(true), parent, range.startOffset); } // Now remove the element editor.deleteNode(element); } finally { editor.endTransaction(); } } function FillLinkMenulist(linkMenulist, headingsArray) { var menupopup = linkMenulist.firstChild; var editor = GetCurrentEditor(); try { var treeWalker = editor.document.createTreeWalker(editor.document, 1, null, true); var headingList = []; var anchorList = []; // for sorting var anchorMap = {}; // for weeding out duplicates and making heading anchors unique var anchor; var i; for (var element = treeWalker.nextNode(); element; element = treeWalker.nextNode()) { // grab headings // Skip headings that already have a named anchor as their first child // (this may miss nearby anchors, but at least we don't insert another // under the same heading) if (element instanceof HTMLHeadingElement && element.textContent && !(element.firstChild instanceof HTMLAnchorElement && element.firstChild.name)) headingList.push(element); // grab named anchors if (element instanceof HTMLAnchorElement && element.name) { anchor = '#' + element.name; if (!(anchor in anchorMap)) { anchorList.push({anchor: anchor, sortkey: anchor.toLowerCase()}); anchorMap[anchor] = true; } } // grab IDs if (element.id) { anchor = '#' + element.id; if (!(anchor in anchorMap)) { anchorList.push({anchor: anchor, sortkey: anchor.toLowerCase()}); anchorMap[anchor] = true; } } } // add anchor for headings for (i = 0; i < headingList.length; i++) { var heading = headingList[i]; // Use just first 40 characters, don't add "...", // and replace whitespace with "_" and strip non-word characters anchor = '#' + ConvertToCDATAString(TruncateStringAtWordEnd(heading.textContent, 40, false)); // Append "_" to any name already in the list while (anchor in anchorMap) anchor += "_"; anchorList.push({anchor: anchor, sortkey: anchor.toLowerCase()}); anchorMap[anchor] = true; // Save nodes in an array so we can create anchor node under it later headingsArray[anchor] = heading; } if (anchorList.length) { // case insensitive sort function compare(a, b) { if(a.sortkey < b.sortkey) return -1; if(a.sortkey > b.sortkey) return 1; return 0; } anchorList.sort(compare); for (i = 0; i < anchorList.length; i++) createMenuItem(menupopup,anchorList[i].anchor); } else { var item = createMenuItem(menupopup, GetString("NoNamedAnchorsOrHeadings")); item.setAttribute("disabled", "true"); } } catch (e) {} } function createMenuItem(aMenuPopup, aLabel) { var menuitem = document.createElement("menuitem"); menuitem.setAttribute("label", aLabel); aMenuPopup.appendChild(menuitem); return menuitem; } // Shared by Image and Link dialogs for the "Choose" button for links function chooseLinkFile() { // Get a local file, converted into URL format var fileName = GetLocalFileURL("html, img"); if (fileName) { // Always try to relativize local file URLs if (gHaveDocumentUrl) fileName = MakeRelativeUrl(fileName); gDialog.hrefInput.value = fileName; // Do stuff specific to a particular dialog // (This is defined separately in Image and Link dialogs) ChangeLinkLocation(); } // Put focus into the input field SetTextboxFocus(gDialog.hrefInput); } PK vq.Rv v content/editor/EdLinkProps.xulUT tRv>NDDUx PK l!-~R !content/navigator/turboDialog.xulUT {r=qRDDUx %turboDialogDTD; %dialogOverlayDTD; %brandDTD; ]> &exitWarningMsg.label; PK . 1V"A"Acontent/navigator/viewsource.jsUT AqRDDUx/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * Doron Rosenberg (doronr@naboonline.com) * Neil Rashbrook (neil@parkwaycc.co.uk) */ const pageLoaderIface = Components.interfaces.nsIWebPageDescriptor; const nsISelectionPrivate = Components.interfaces.nsISelectionPrivate; const nsISelectionController = Components.interfaces.nsISelectionController; var gBrowser = null; var gViewSourceBundle = null; var gPrefs = null; var gLastLineFound = ''; var gGoToLine = 0; try { var prefService = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefService); gPrefs = prefService.getBranch(null); } catch (ex) { } var gSelectionListener = { timeout: 0, notifySelectionChanged: function(doc, sel, reason) { // Coalesce notifications within 100ms intervals. if (!this.timeout) this.timeout = setTimeout(updateStatusBar, 100); } } function onLoadViewSource() { viewSource(window.arguments[0]); document.commandDispatcher.focusedWindow = content; } function getBrowser() { if (!gBrowser) gBrowser = document.getElementById("content"); return gBrowser; } function getSelectionController() { return getBrowser().docShell .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsISelectionDisplay) .QueryInterface(nsISelectionController); } function getViewSourceBundle() { if (!gViewSourceBundle) gViewSourceBundle = document.getElementById("viewSourceBundle"); return gViewSourceBundle; } function viewSource(url) { if (!url) return false; // throw Components.results.NS_ERROR_FAILURE; getBrowser().addEventListener("unload", onUnloadContent, true); getBrowser().addEventListener("load", onLoadContent, true); var loadFromURL = true; // // Parse the 'arguments' supplied with the dialog. // arg[0] - URL string. // arg[1] - Charset value in the form 'charset=xxx'. // arg[2] - Page descriptor used to load content from the cache. // arg[3] - Line number to go to. // if ("arguments" in window) { var arg; // // Set the charset of the viewsource window... // if (window.arguments.length >= 2) { arg = window.arguments[1]; try { if (typeof(arg) == "string" && arg.indexOf('charset=') != -1) { var arrayArgComponents = arg.split('='); if (arrayArgComponents) { //we should "inherit" the charset menu setting in a new window getMarkupDocumentViewer().defaultCharacterSet = arrayArgComponents[1]; } } } catch (ex) { // Ignore the failure and keep processing arguments... } } // // Get any specified line to jump to. // if (window.arguments.length >= 4) { arg = window.arguments[3]; gGoToLine = parseInt(arg); } // // Use the page descriptor to load the content from the cache (if // available). // if (window.arguments.length >= 3) { arg = window.arguments[2]; try { if (typeof(arg) == "object" && arg != null) { var PageLoader = getBrowser().webNavigation.QueryInterface(pageLoaderIface); // // Load the page using the page descriptor rather than the URL. // This allows the content to be fetched from the cache (if // possible) rather than the network... // PageLoader.LoadPage(arg, pageLoaderIface.DISPLAY_AS_SOURCE); // The content was successfully loaded from the page cookie. loadFromURL = false; } } catch(ex) { // Ignore the failure. The content will be loaded via the URL // that was supplied in arg[0]. } } } if (loadFromURL) { // // Currently, an exception is thrown if the URL load fails... // var loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_NONE; var viewSrcUrl = "view-source:" + url; getBrowser().webNavigation.loadURI(viewSrcUrl, loadFlags, null, null, null); } //check the view_source.wrap_long_lines pref and set the menuitem's checked attribute accordingly if (gPrefs) { try { var wraplonglinesPrefValue = gPrefs.getBoolPref("view_source.wrap_long_lines"); if (wraplonglinesPrefValue) document.getElementById('menu_wrapLongLines').setAttribute("checked", "true"); } catch (ex) { } try { document.getElementById("menu_highlightSyntax").setAttribute("checked", gPrefs.getBoolPref("view_source.syntax_highlight")); } catch (ex) { } } else { document.getElementById("menu_highlightSyntax").setAttribute("hidden", "true"); } window._content.focus(); return true; } function onLoadContent() { // // If the view source was opened with a "go to line" argument. // if (gGoToLine > 0) { goToLine(gGoToLine); gGoToLine = 0; } document.getElementById('cmd_goToLine').removeAttribute('disabled'); // Register a listener so that we can show the caret position on the status bar. window._content.getSelection() .QueryInterface(nsISelectionPrivate) .addSelectionListener(gSelectionListener); } function onUnloadContent() { // // Disable "go to line" while reloading due to e.g. change of charset // or toggling of syntax highlighting. // document.getElementById('cmd_goToLine').setAttribute('disabled', 'true'); } function ViewSourceClose() { window.close(); } function BrowserReload() { // Reload will always reload from cache which is probably not what's wanted BrowserReloadSkipCache(); } function BrowserReloadSkipCache() { const webNavigation = getBrowser().webNavigation; webNavigation.reload(webNavigation.LOAD_FLAGS_BYPASS_PROXY | webNavigation.LOAD_FLAGS_BYPASS_CACHE); } // Strips the |view-source:| for editPage() function ViewSourceEditPage() { editPage(window.content.location.href.substring(12), window, false); } // Strips the |view-source:| for saveURL() function ViewSourceSavePage() { saveURL(window.content.location.href.substring(12), null, "SaveLinkTitle"); } function ViewSourceGoToLine() { var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] .getService(Components.interfaces.nsIPromptService); var viewSourceBundle = getViewSourceBundle(); var input = {value:gLastLineFound}; for (;;) { var ok = promptService.prompt( window, viewSourceBundle.getString("goToLineTitle"), viewSourceBundle.getString("goToLineText"), input, null, {value:0}); if (!ok) return; var line = parseInt(input.value); if (!(line > 0)) { promptService.alert(window, viewSourceBundle.getString("invalidInputTitle"), viewSourceBundle.getString("invalidInputText")); continue; } var found = goToLine(line); if (found) { break; } promptService.alert(window, viewSourceBundle.getString("outOfRangeTitle"), viewSourceBundle.getString("outOfRangeText")); } } function goToLine(line) { var viewsource = window._content.document.body; // // The source document is made up of a number of pre elements with // id attributes in the format
, meaning that
  // the first line in the pre element is number 123.
  // Do binary search to find the pre element containing the line.
  //
  var pre;
  for (var lbound = 0, ubound = viewsource.childNodes.length; ; ) {
    var middle = (lbound + ubound) >> 1;
    pre = viewsource.childNodes[middle];

    var firstLine = parseInt(pre.id.substring(4));

    if (lbound == ubound - 1) {
      break;
    }

    if (line >= firstLine) {
      lbound = middle;
    } else {
      ubound = middle;
    }
  }

  var result = {};
  var found = findLocation(pre, line, null, -1, false, result);

  if (!found) {
    return false;
  }

  var selection = window._content.getSelection();
  selection.removeAllRanges();

  // In our case, the range's startOffset is after "\n" on the previous line.
  // Tune the selection at the beginning of the next line and do some tweaking
  // to position the focusNode and the caret at the beginning of the line.

  selection.QueryInterface(nsISelectionPrivate)
    .interlinePosition = true;	

  selection.addRange(result.range);

  if (!selection.isCollapsed) {
    selection.collapseToEnd();

    var offset = result.range.startOffset;
    var node = result.range.startContainer;
    if (offset < node.data.length) {
      // The same text node spans across the "\n", just focus where we were.
      selection.extend(node, offset);
    }
    else {
      // There is another tag just after the "\n", hook there. We need
      // to focus a safe point because there are edgy cases such as
      // ...\n... vs.
      // ...\n......
      node = node.nextSibling ? node.nextSibling : node.parentNode.nextSibling;
      selection.extend(node, 0);
    }
  }

  var selCon = getSelectionController();
  selCon.setDisplaySelection(nsISelectionController.SELECTION_ON);
  selCon.setCaretEnabled(true);
  selCon.setCaretVisibilityDuringSelection(true);

  // Scroll the beginning of the line into view.
  selCon.scrollSelectionIntoView(
    nsISelectionController.SELECTION_NORMAL,
    nsISelectionController.SELECTION_FOCUS_REGION,
    true);

  gLastLineFound = line;

  document.getElementById("statusbar-line-col").label = getViewSourceBundle()
      .getFormattedString("statusBarLineCol", [line, 1]);

  return true;
}

function updateStatusBar()
{
  // Reset the coalesce flag.
  gSelectionListener.timeout = 0;

  var statusBarField = document.getElementById("statusbar-line-col");

  var selection = window._content.getSelection();
  if (!selection.focusNode) {
    statusBarField.label = '';
    return;
  }
  if (selection.focusNode.nodeType != Node.TEXT_NODE) {
    return;
  }

  var selCon = getSelectionController();
  selCon.setDisplaySelection(nsISelectionController.SELECTION_ON);
  selCon.setCaretEnabled(true);
  selCon.setCaretVisibilityDuringSelection(true);

  var interlinePosition = selection
      .QueryInterface(nsISelectionPrivate).interlinePosition;

  var result = {};
  findLocation(null, -1, 
      selection.focusNode, selection.focusOffset, interlinePosition, result);

  statusBarField.label = getViewSourceBundle()
      .getFormattedString("statusBarLineCol", [result.line, result.col]);
}

//
// Loops through the text lines in the pre element. The arguments are either
// (pre, line) or (node, offset, interlinePosition). result is an out
// argument. If (pre, line) are specified (and node == null), result.range is
// a range spanning the specified line. If the (node, offset,
// interlinePosition) are specified, result.line and result.col are the line
// and column number of the specified offset in the specified node relative to
// the whole file.
//
function findLocation(pre, line, node, offset, interlinePosition, result)
{
  if (node && !pre) {
    //
    // Look upwards to find the current pre element.
    //
    for (pre = node;
         pre.nodeName != "PRE";
         pre = pre.parentNode);
  }

  //
  // The source document is made up of a number of pre elements with
  // id attributes in the format 
, meaning that
  // the first line in the pre element is number 123.
  //
  var curLine = parseInt(pre.id.substring(4));

  //
  // Walk through each of the text nodes and count newlines.
  //
  var treewalker = window._content.document
      .createTreeWalker(pre, NodeFilter.SHOW_TEXT, null, false);

  //
  // The column number of the first character in the current text node.
  //
  var firstCol = 1;

  var found = false;
  for (var textNode = treewalker.firstChild();
       textNode && !found;
       textNode = treewalker.nextNode()) {

    //
    // \r is not a valid character in the DOM, so we only check for \n.
    //
    var lineArray = textNode.data.split(/\n/);
    var lastLineInNode = curLine + lineArray.length - 1;

    //
    // Check if we can skip the text node without further inspection.
    //
    if (node ? (textNode != node) : (lastLineInNode < line)) {
      if (lineArray.length > 1) {
        firstCol = 1;
      }
      firstCol += lineArray[lineArray.length - 1].length;
      curLine = lastLineInNode;
      continue;
    }

    //
    // curPos is the offset within the current text node of the first
    // character in the current line.
    //
    for (var i = 0, curPos = 0;
         i < lineArray.length;
         curPos += lineArray[i++].length + 1) {

      if (i > 0) {
        curLine++;
      }

      if (node) {
        if (offset >= curPos && offset <= curPos + lineArray[i].length) {
          //
          // If we are right after the \n of a line and interlinePosition is
          // false, the caret looks as if it were at the end of the previous
          // line, so we display that line and column instead.
          //
          if (i > 0 && offset == curPos && !interlinePosition) {
            result.line = curLine - 1;
            var prevPos = curPos - lineArray[i - 1].length;
            result.col = (i == 1 ? firstCol : 1) + offset - prevPos;

          } else {
            result.line = curLine;
            result.col = (i == 0 ? firstCol : 1) + offset - curPos;
          }
          found = true;

          break;
        }

      } else {
        if (curLine == line && !("range" in result)) {
          result.range = document.createRange();
          result.range.setStart(textNode, curPos);

          //
          // This will always be overridden later, except when we look for
          // the very last line in the file (this is the only line that does
          // not end with \n).
          //
          result.range.setEndAfter(pre.lastChild);

        } else if (curLine == line + 1) {
          result.range.setEnd(textNode, curPos - 1);
          found = true;
          break;
        }
      }
    }
  }

  return found || ("range" in result);
}

//function to toggle long-line wrapping and set the view_source.wrap_long_lines 
//pref to persist the last state
function wrapLongLines()
{
  var myWrap = window._content.document.body;

  if (myWrap.className == '')
    myWrap.className = 'wrap';
  else myWrap.className = '';

  //since multiple viewsource windows are possible, another window could have 
  //affected the pref, so instead of determining the new pref value via the current
  //pref value, we use myWrap.className  
  if (gPrefs){
    try {
      if (myWrap.className == '') {
        gPrefs.setBoolPref("view_source.wrap_long_lines", false);
      }
      else {
        gPrefs.setBoolPref("view_source.wrap_long_lines", true);
      }
    } catch (ex) {
    }
  }
}

//function to toggle syntax highlighting and set the view_source.syntax_highlight
//pref to persist the last state
function highlightSyntax()
{
  var highlightSyntaxMenu = document.getElementById("menu_highlightSyntax");
  var highlightSyntax = (highlightSyntaxMenu.getAttribute("checked") == "true");
  gPrefs.setBoolPref("view_source.syntax_highlight", highlightSyntax);

  var PageLoader = getBrowser().webNavigation.QueryInterface(pageLoaderIface);
  PageLoader.LoadPage(PageLoader.currentDescriptor, pageLoaderIface.DISPLAY_NORMAL);
}

// Fix for bug 136322: this function overrides the function in
// browser.js to call PageLoader.LoadPage() instead of BrowserReloadWithFlags()
function BrowserSetForcedCharacterSet(aCharset)
{
  var docCharset = getBrowser().docShell.QueryInterface(
                            Components.interfaces.nsIDocCharset);
  docCharset.charset = aCharset;
  var PageLoader = getBrowser().webNavigation.QueryInterface(pageLoaderIface);
  PageLoader.LoadPage(PageLoader.currentDescriptor, pageLoaderIface.DISPLAY_NORMAL);
}
PK
jF%0fyn
n
 content/navigator/viewSource.xulUT	?qRDDUx  
 






%brandDTD;

%sourceDTD;

%navigatorDTD;

%contentAreaCommandsDTD;
]>



  
  
  
  
  

  

  

    

   

  
    
  

PK
+/Hd|$|$'content/navigator/viewSourceOverlay.xulUT	;`?qRDDUx  
 






%brandDTD;

%sourceDTD;

%navigatorDTD;

%contentAreaCommandsDTD;
]>


           

  
  
    
    
    
    
  
  
    
  
         
  
  
    
    
  

  
    
    
  

  
    
    
    
    
      
    
    
  
  


PK
[0`+llcontent/navigator/contents.rdfUT	/?@qRDDUx


  
  
    
  

  
  
  



PK
3D0 11%content/navigator-region/contents.rdfUT	!@qRDDUx


  
  
    
  

  
  
  


PK
Ρb+4_0content/communicator/platformBrowserBindings.xulUT	#o;uRDDUx 












    








PK
Ρb+{p%%/content/communicator/platformEditorBindings.xulUT	#o;uRDDUx 







 





















PK
#m.T<4content/communicator/platformCommunicatorOverlay.xulUT	;q>sRDDUx 



%platformCommunicationDTD;

%utilityDTD;

]>



    
    
    
    

    
    
      
      
    
    
    
  
    
    
    
    
	
	
  

  
  
  

    
PK
w\,}Ť%content/communicator/communicator.cssUT	~
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); 

/* ::::: print preview toolbar ::::: */

toolbar[printpreview="true"] {
  -moz-binding: url("chrome://communicator/content/printPreviewBindings.xml#printpreviewtoolbar");
}
PK
(2~,content/communicator/communicatorOverlay.xulUT	09uRDDUx




PK

d0Z!(!('content/communicator/utilityOverlay.xulUT	>F@uRDDUx




%brandDTD;

%globalRegionDTD;

%utilityDTD;

]>



  
  



PK 4 ^/;O ,,$content/communicator/popupManager.jsUT ڠ?uRDDUx/* ***** BEGIN LICENSE BLOCK ***** * * The Original Code is Mozilla Communicator client code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 2002 * the Initial Developer. All Rights Reserved. * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the NPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ const nsIPermissionManager = Components.interfaces.nsIPermissionManager; const popupType = "popup"; var permissionManager = null; var permissions = []; var additions = []; var removals = []; var sortColumn = "host"; var sortAscending = false; var permissionsTreeView = { rowCount: 0, setTree: function(tree) {}, getImageSrc: function(row, column) {}, getProgressMode: function(row, column) {}, getCellValue: function(row, column) {}, getCellText: function(row, column) { var rv = permissions[row].host; return rv; }, isSeparator: function(index) { return false; }, isSorted: function() { return false; }, isContainer: function(index) { return false; }, cycleHeader: function(aColId, aElt) {}, getRowProperties: function(row, column,prop) {}, getColumnProperties: function(column, columnElement, prop) {}, getCellProperties: function(row, prop) {} }; var permissionsTree; var popupStringBundle; function Startup() { permissionManager = Components.classes["@mozilla.org/permissionmanager;1"] .getService(Components.interfaces.nsIPermissionManager); permissionsTree = document.getElementById("permissionsTree"); popupStringBundle = document.getElementById("popupStringBundle"); sortAscending = (permissionsTree.getAttribute("sortAscending") == "true"); loadPermissions(permissions); loadTree(); // window.arguments[0] contains the host to prefill if (window.arguments[0] != "") { // fill textbox to unblock/add to whitelist var prefill = window.arguments[0]; if (prefill.indexOf("www.") == 0) prefill = prefill.slice(4); document.getElementById("addSiteBox").value = prefill; } document.documentElement.addEventListener("keypress", onReturnHit, true); } function getMatch(host) { // pre-pend '.' so we always match on host boundaries. Otherwise // we might think notfoo.com matches foo.com var currentLoc = '.'+host; var nextHost; var inList; var matchIndex = null; var matchLength = 0; for (var i = 0; i < permissionsTreeView.rowCount; i++) { nextHost = '.'+permissions[i].host; if (currentLoc.length < nextHost.length) continue; // can't be a match, list host is more specific // look for an early out exact match -- check length first for speed if (currentLoc.length == nextHost.length && nextHost == currentLoc) { inList = true; matchIndex = i; break; } if (nextHost == currentLoc.substr(currentLoc.length - nextHost.length)) { inList = true; if (nextHost.length > matchLength) { matchIndex = i; matchLength = nextHost.length; } } } return matchIndex; } function onAccept() { finalizeChanges(); var unblocked = additions; permissionsTree.setAttribute("sortAscending", !sortAscending); var nextLocation; var nextUnblocked; var windowMediator = Components.classes['@mozilla.org/appshell/window-mediator;1'] .getService(Components.interfaces.nsIWindowMediator); var enumerator = windowMediator.getEnumerator("navigator:browser"); //if a site that is currently open is unblocked, make icon go away while(enumerator.hasMoreElements()) { var win = enumerator.getNext(); var browsers = win.getBrowser().browsers; for (var i = 0; i < browsers.length; i++) { try { nextLocation = browsers[i].currentURI.hostPort; } catch(ex) { //blank window } if (nextLocation) { nextLocation = '.'+nextLocation; for (var j in unblocked) { nextUnblocked = '.'+unblocked[j]; if (nextUnblocked.length > nextLocation.length) continue; // can't be a match if (nextUnblocked == nextLocation.substr(nextLocation.length - nextUnblocked.length)) { browsers[i].popupDomain = null; win.document.getElementById("popupIcon").hidden = true; } } } } } return true; } function Permission(host, number) { this.host = host; this.number = number; } function loadPermissions(table) { var enumerator = permissionManager.enumerator; var count = 0; while (enumerator.hasMoreElements()) { var permission = enumerator.getNext(); if (permission) { permission = permission.QueryInterface(Components.interfaces.nsIPermission); if ((permission.type == popupType) && (permission.capability == nsIPermissionManager.ALLOW_ACTION)) { var host = permission.host; table[count] = new Permission(host,count++); } } } } function loadTree() { var rowCount = permissions.length; permissionsTreeView.rowCount = rowCount; permissionsTree.treeBoxObject.view = permissionsTreeView; permissionColumnSort(); if (permissions.length == 0) document.getElementById("removeAllPermissions").setAttribute("disabled","true"); else document.getElementById("removeAllPermissions").removeAttribute("disabled"); } function permissionColumnSort() { sortAscending = SortTree(permissionsTree, permissionsTreeView, permissions, sortColumn, sortColumn, sortAscending); } function permissionSelected() { var selections = GetTreeSelections(permissionsTree); if (selections.length) { document.getElementById("removePermission").removeAttribute("disabled"); } } function deletePermissions() { var selections = GetTreeSelections(permissionsTree); for (var s = selections.length - 1; s >= 0; s--) { var i = selections[s]; var host = permissions[i].host; updatePendingRemovals(host); permissions[i] = null; } for (var j = 0; j < permissions.length; j++) { if (permissions[j] == null) { var k = j; while ((k < permissions.length) && (permissions[k] == null)) { k++; } permissions.splice(j, k-j); permissionsTreeView.rowCount -= k - j; permissionsTree.treeBoxObject.rowCountChanged(j, j - k); } } if (permissions.length) { var nextSelection = (selections[0] < permissions.length) ? selections[0] : permissions.length - 1; permissionsTreeView.selection.select(nextSelection); permissionsTree.treeBoxObject.ensureRowIsVisible(nextSelection); } else { document.getElementById("removePermission").setAttribute("disabled", "true") document.getElementById("removeAllPermissions").setAttribute("disabled","true"); } } function deleteAllPermissions() { for (var i = 0; i < permissions.length; i++) { var host = permissions[i].host; updatePendingRemovals(host); } permissions.length = 0; clearTree(); } function updatePendingRemovals(host) { if (additions[host]) additions[host] = null; else removals[host] = host; } function clearTree() { var oldCount = permissionsTreeView.rowCount; permissionsTreeView.rowCount = 0; permissionsTree.treeBoxObject.rowCountChanged(0, -oldCount); document.getElementById("removePermission").setAttribute("disabled", "true") document.getElementById("removeAllPermissions").setAttribute("disabled","true"); } function finalizeChanges() { var ioService = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); var uri; var host; var i; //note: the scheme will be taken off later, it is being added now only to //create the uri for add/remove for (i in additions) { host = additions[i]; if (host != null) { host = "http://" + host; uri = ioService.newURI(host, null, null); permissionManager.add(uri, popupType, true); } } for (i in removals) { host = removals[i]; if (host != null) { permissionManager.remove(host, popupType); } } } function handlePermissionKeyPress(e) { if (e.keyCode == 46) { deletePermissions(); } } function addPermission() { var addSiteBox = document.getElementById("addSiteBox"); var host = addSiteBox.value; if (host != "") { host = host.replace(/^\s*([-\w]*:\/+)?/, ""); // trim any leading space and scheme var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] .getService(Components.interfaces.nsIPromptService); var ioService = Components.classes["@mozilla.org/network/io-service;1"] .getService(Components.interfaces.nsIIOService); try { var uri = ioService.newURI("http://"+host, null, null); } catch(ex) { var msgInvalid = popupStringBundle.getFormattedString("alertInvalid", [host]); if (promptService) promptService.alert(window, "", msgInvalid); addSiteBox.value = ""; return; } host = uri.hostPort; if (!host) { addSiteBox.value = ""; return; } var length = permissions.length; var isDuplicate = false; for (var i = 0; i < length; i++) { if (permissions[i].host == host) { var msgDuplicate = popupStringBundle.getFormattedString("alertDuplicate", [host]); if (promptService) promptService.alert(window, "", msgDuplicate); isDuplicate = true; break; } } if (!isDuplicate) { var newPermission = new Permission(host, length); permissions.push(newPermission); sortAscending = !sortAscending; //keep same sort direction loadTree(); if (removals[host] != null) removals[host] = null; else additions[host] = host; } addSiteBox.value = ""; } } function onReturnHit(event) { var focusedElement = document.commandDispatcher.focusedElement; var addSiteBox = document.getElementById("addSiteBox"); if (event.keyCode == 13) { if (focusedElement) { if (focusedElement.id == "permissionsTree") return; else { event.preventBubble(); if (focusedElement == addSiteBox.inputField) { var addSiteButton = document.getElementById("addSiteButton"); addSiteButton.doCommand(); } } } } } function doHelpButton() { openHelp("pop_up_blocking"); return true; } PK H/r**//%content/communicator/popupManager.xulUT ի?uRDDUx &popupDesc.label; &popupDescAlt.label; &popupNote1.label; &popupNote2.label; PK g8/4LL(content/communicator/XPCNativeWrapper.jsUT qq?uRDDUx/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is XPConnect Native Wrapper. * * The Initial Developer of the Original Code is * Christopher A. Aillon . * Portions created by the Initial Developer are Copyright (C) 2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Christopher A. Aillon * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /** * Get a wrapper to certain XPConnect wrapped native properties of an * untrusted object. * * Usage: * var wrapper = new XPCNativeWrapper(untrusted, 'title', 'getElementById()'); * var title = wrapper.title; * var elem = wrapper.getElementById('fooId'); * * @param aUntrustedObject the untrusted object we want native wrappers for * @param arg1...argN strings of the form 'property' or 'method()' which * denote the property or method names we wish to wrap * @throws NS_ERROR_XPC_BAD_CONVERT_JS if a property or method requested * does not have a native wrapper on * the untrusted object. * @see nsXPCComponents::LookupMethod() */ function XPCNativeWrapper(aUntrustedObject) { this.mUntrustedObject = aUntrustedObject; for (var i = arguments.length - 1; i > 0; --i) this.importXPCNative(arguments[i]); } XPCNativeWrapper.prototype = { importXPCNative: function(aName) { // If we are passed a string like "foo()", ary[2] will be of type string, // and contain "()". If passed "foo", then it will be of type undefined. if (aName.slice(-2) == "()") this._doImportMethod(aName.slice(0, -2)); else this._doImportProperty(aName); }, _doImportMethod: function(aMethodName) { var nativeMethod = Components.lookupMethod(this.mUntrustedObject, aMethodName); this[aMethodName] = function() { return nativeMethod.apply(this.mUntrustedObject, arguments); }; }, _doImportProperty: function(aPropName) { var nativeMethod = Components.lookupMethod(this.mUntrustedObject, aPropName); var theGetter = function() { return nativeMethod.call(this.mUntrustedObject); }; var theSetter = function(val) { return nativeMethod.call(this.mUntrustedObject, val); }; this.__defineGetter__(aPropName, theGetter); this.__defineSetter__(aPropName, theSetter); } }; PK 3D0O ~~*content/communicator-platform/contents.rdfUT !@tRDDUx PK 3D0\ ʏAA(content/communicator-region/contents.rdfUT !@uRDDUx PK [0,:!content/communicator/contents.rdfUT /?@uRDDUx PK !-I=jj1content/communicator/pref/platformPrefOverlay.xulUT r=RDDUx PK pU2E`++content/communicator/bookmarks/bookmarks.jsUT ZBSDDUx/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Netscape Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Pierre Chanial * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the NPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ var NC_NS, WEB_NS, RDF_NS, XUL_NS, NC_NS_CMD; // definition of the services frequently used for bookmarks var kRDFContractID; var kRDFSVCIID; var kRDFRSCIID; var kRDFLITIID; var RDF; var kRDFCContractID; var kRDFCIID; var RDFC; var kRDFCUContractID; var kRDFCUIID; var RDFCU; var BMDS; var kBMSVCIID; var BMSVC; var kPREFContractID; var kPREFIID; var PREF; var kSOUNDContractID; var kSOUNDIID; var SOUND; var kWINDOWContractID; var kWINDOWIID; var WINDOWSVC; var kDSContractID; var kDSIID; var DS; // should be moved in a separate file function initServices() { NC_NS = "http://home.netscape.com/NC-rdf#"; WEB_NS = "http://home.netscape.com/WEB-rdf#"; RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"; XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; NC_NS_CMD = NC_NS + "command?cmd="; kRDFContractID = "@mozilla.org/rdf/rdf-service;1"; kRDFSVCIID = Components.interfaces.nsIRDFService; kRDFRSCIID = Components.interfaces.nsIRDFResource; kRDFLITIID = Components.interfaces.nsIRDFLiteral; RDF = Components.classes[kRDFContractID].getService(kRDFSVCIID); kRDFCContractID = "@mozilla.org/rdf/container;1"; kRDFCIID = Components.interfaces.nsIRDFContainer; RDFC = Components.classes[kRDFCContractID].createInstance(kRDFCIID); kRDFCUContractID = "@mozilla.org/rdf/container-utils;1"; kRDFCUIID = Components.interfaces.nsIRDFContainerUtils; RDFCU = Components.classes[kRDFCUContractID].getService(kRDFCUIID); kPREFContractID = "@mozilla.org/preferences-service;1"; kPREFIID = Components.interfaces.nsIPrefService; try { PREF = Components.classes[kPREFContractID].getService(kPREFIID) .getBranch(null); } catch (e) {} kSOUNDContractID = "@mozilla.org/sound;1"; kSOUNDIID = Components.interfaces.nsISound; try { SOUND = Components.classes[kSOUNDContractID].createInstance(kSOUNDIID); } catch (e) {} kWINDOWContractID = "@mozilla.org/appshell/window-mediator;1"; kWINDOWIID = Components.interfaces.nsIWindowMediator; try { WINDOWSVC = Components.classes[kWINDOWContractID].getService(kWINDOWIID); } catch (e) {} kDSContractID = "@mozilla.org/widget/dragservice;1"; kDSIID = Components.interfaces.nsIDragService; try { DS = Components.classes[kDSContractID].getService(kDSIID); } catch (e) {} } function initBMService() { kBMSVCIID = Components.interfaces.nsIBookmarksService; BMDS = RDF.GetDataSource("rdf:bookmarks"); BMSVC = BMDS.QueryInterface(kBMSVCIID); BookmarkTransaction.prototype.RDFC = RDFC; BookmarkTransaction.prototype.BMDS = BMDS; } /** * XXX - 04/16/01 * ACK! massive command name collision problems are causing big issues * in getting this stuff to work in the Navigator window. For sanity's * sake, we need to rename all the commands to be of the form cmd_bm_* * otherwise there'll continue to be problems. For now, we're just * renaming those that affect the personal toolbar (edit operations, * which were clashing with the textfield controller) * * There are also several places that need to be updated if you need * to change a command name. * 1) the controller... * - in bookmarksTree.xml if the command is tree-specifc * - in bookmarksMenu.js if the command is DOM-specific * - in bookmarks.js otherwise * 2) the command nodes in the overlay or xul file * 3) the command human-readable name key in bookmarks.properties * 4) the function 'getCommands' in bookmarks.js */ var BookmarksCommand = { ///////////////////////////////////////////////////////////////////////////// // This method constructs a menuitem for a context menu for the given command. // This is implemented by the client so that it can intercept menuitem naming // as appropriate. createMenuItem: function (aDisplayName, aCommandName, aSelection) { var xulElement = document.createElementNS(XUL_NS, "menuitem"); xulElement.setAttribute("cmd", aCommandName); var cmd = "cmd_" + aCommandName.substring(NC_NS_CMD.length); xulElement.setAttribute("command", cmd); switch (aCommandName) { case NC_NS_CMD + "bm_expandfolder": var shouldCollapse = true; for (var i=0; i 0 && common[common.length-1] == aNewArray[i]) continue; if (aNewArray[i] == aOldArray[j]) common.push(aNewArray[i]); } } return common; }, flattenEnumerator: function (aEnumerator) { if ("_index" in aEnumerator) return aEnumerator._inner; var temp = []; while (aEnumerator.hasMoreElements()) temp.push(aEnumerator.getNext()); return temp; }, ///////////////////////////////////////////////////////////////////////////// // For a given URI (a unique identifier of a resource in the graph) return // an enumeration of applicable commands for that URI. getCommands: function (aNodeID) { var type = BookmarksUtils.resolveType(aNodeID); if (!type) return null; var commands = []; // menu order: // // bm_expandfolder // bm_open // bm_openinnewwindow // bm_openinnewtab // --------------------- // bm_newfolder // --------------------- // bm_cut // bm_copy // bm_paste // --------------------- // bm_delete // --------------------- // bm_properties switch (type) { case "BookmarkSeparator": commands = ["bm_newfolder", "bm_separator", "bm_cut", "bm_copy", "bm_paste", "bm_separator", "bm_delete", "bm_separator", "bm_properties"]; break; case "Bookmark": commands = ["bm_open", "bm_openinnewwindow", "bm_openinnewtab", "bm_separator", "bm_newfolder", "bm_sortfolder", "bm_sortfolderbyname", "bm_separator", "bm_cut", "bm_copy", "bm_paste", "bm_movebookmark", "bm_separator", "bm_rename", "bm_delete", "bm_separator", "bm_properties"]; break; case "Folder": commands = ["bm_expandfolder", "bm_managefolder", "bm_separator", "bm_newfolder", "bm_sortfolder", "bm_sortfolderbyname", "bm_separator", "bm_cut", "bm_copy", "bm_paste", "bm_movebookmark", "bm_separator", "bm_rename", "bm_delete", "bm_separator", "bm_properties"]; break; case "FolderGroup": commands = ["bm_open", "bm_openinnewwindow", "bm_expandfolder", "bm_separator", "bm_newfolder", "bm_sortfolder", "bm_sortfolderbyname", "bm_separator", "bm_cut", "bm_copy", "bm_paste", "bm_movebookmark", "bm_separator", "bm_rename", "bm_delete", "bm_separator", "bm_properties"]; break; case "PersonalToolbarFolder": commands = ["bm_newfolder", "bm_sortfolder", "bm_sortfolderbyname", "bm_separator", "bm_cut", "bm_copy", "bm_paste", "bm_movebookmark", "bm_separator", "bm_rename", "bm_delete", "bm_separator", "bm_properties"]; break; case "IEFavoriteFolder": commands = ["bm_expandfolder", "bm_separator", "bm_delete"]; break; case "IEFavorite": commands = ["bm_open", "bm_openinnewwindow", "bm_openinnewtab", "bm_separator", "bm_copy"]; break; case "FileSystemObject": commands = ["bm_open", "bm_openinnewwindow", "bm_openinnewtab", "bm_separator", "bm_copy"]; break; default: commands = []; } return new CommandArrayEnumerator(commands); }, ///////////////////////////////////////////////////////////////////////////// // Retrieve the human-readable name for a particular command. Used when // manufacturing a UI to invoke commands. getCommandName: function (aCommand) { var cmdName = aCommand.substring(NC_NS_CMD.length); return BookmarksUtils.getLocaleString ("cmd_" + cmdName); /* try { // Note: this will succeed only if there's a string in the bookmarks // string bundle for this command name. Otherwise, // will throw, we'll catch & stifle the error, and look up the command // name in the datasource. return BookmarksUtils.getLocaleString ("cmd_" + cmdName); } catch (e) { } // XXX - WORK TO DO HERE! (rjc will cry if we don't fix this) // need to ask the ds for the commands for this node, however we don't // have the right params. This is kind of a problem. dump("*** BAD! EVIL! WICKED! NO! ACK! ARGH! ORGH!"+aCommand+"\n"); const rName = RDF.GetResource(NC_NS + "Name"); const rSource = RDF.GetResource(aNodeID); return BMDS.GetTarget(rSource, rName, true).Value; */ }, /////////////////////////////////////////////////////////////////////////// // Execute a command with the given source and arguments doBookmarksCommand: function (aSource, aCommand, aArgumentsArray) { var rCommand = RDF.GetResource(aCommand); var kSuppArrayContractID = "@mozilla.org/supports-array;1"; var kSuppArrayIID = Components.interfaces.nsISupportsArray; var sourcesArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID); if (aSource) { sourcesArray.AppendElement(aSource); } var argsArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID); var length = aArgumentsArray?aArgumentsArray.length:0; for (var i = 0; i < length; ++i) { var rArc = RDF.GetResource(aArgumentsArray[i].property); argsArray.AppendElement(rArc); var rValue = null; if ("resource" in aArgumentsArray[i]) { rValue = RDF.GetResource(aArgumentsArray[i].resource); } else rValue = RDF.GetLiteral(aArgumentsArray[i].literal); argsArray.AppendElement(rValue); } // Exec the command in the Bookmarks datasource. BMDS.DoCommand(sourcesArray, rCommand, argsArray); }, undoBookmarkTransaction: function () { BMSVC.transactionManager.undoTransaction(); BookmarksUtils.flushDataSource(); }, redoBookmarkTransaction: function () { BMSVC.transactionManager.redoTransaction(); BookmarksUtils.flushDataSource(); }, manageFolder: function (aSelection) { openDialog("chrome://communicator/content/bookmarks/bookmarksManager.xul", "", "chrome,all,dialog=no", aSelection.item[0].Value); }, cutBookmark: function (aSelection) { this.copyBookmark(aSelection); BookmarksUtils.removeSelection("cut", aSelection); }, copyBookmark: function (aSelection) { const kSuppArrayContractID = "@mozilla.org/supports-array;1"; const kSuppArrayIID = Components.interfaces.nsISupportsArray; var itemArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID); const kSuppWStringContractID = "@mozilla.org/supports-string;1"; const kSuppWStringIID = Components.interfaces.nsISupportsString; var bmstring = Components.classes[kSuppWStringContractID].createInstance(kSuppWStringIID); var unicodestring = Components.classes[kSuppWStringContractID].createInstance(kSuppWStringIID); var htmlstring = Components.classes[kSuppWStringContractID].createInstance(kSuppWStringIID); var sBookmarkItem = ""; var sTextUnicode = ""; var sTextHTML = ""; for (var i = 0; i < aSelection.length; ++i) { var url = BookmarksUtils.getProperty(aSelection.item[i], NC_NS+"URL" ); var name = BookmarksUtils.getProperty(aSelection.item[i], NC_NS+"Name"); sBookmarkItem += aSelection.item[i].Value + "\n"; sTextUnicode += url + "\n"; sTextHTML += "" + name + ""; } const kXferableContractID = "@mozilla.org/widget/transferable;1"; const kXferableIID = Components.interfaces.nsITransferable; var xferable = Components.classes[kXferableContractID].createInstance(kXferableIID); xferable.addDataFlavor("moz/bookmarkclipboarditem"); bmstring.data = sBookmarkItem; xferable.setTransferData("moz/bookmarkclipboarditem", bmstring, sBookmarkItem.length*2); xferable.addDataFlavor("text/html"); htmlstring.data = sTextHTML; xferable.setTransferData("text/html", htmlstring, sTextHTML.length*2); xferable.addDataFlavor("text/unicode"); unicodestring.data = sTextUnicode; xferable.setTransferData("text/unicode", unicodestring, sTextUnicode.length*2); const kClipboardContractID = "@mozilla.org/widget/clipboard;1"; const kClipboardIID = Components.interfaces.nsIClipboard; var clipboard = Components.classes[kClipboardContractID].getService(kClipboardIID); clipboard.setData(xferable, null, kClipboardIID.kGlobalClipboard); }, pasteBookmark: function (aTarget) { const kXferableContractID = "@mozilla.org/widget/transferable;1"; const kXferableIID = Components.interfaces.nsITransferable; var xferable = Components.classes[kXferableContractID].createInstance(kXferableIID); xferable.addDataFlavor("moz/bookmarkclipboarditem"); xferable.addDataFlavor("text/x-moz-url"); xferable.addDataFlavor("text/unicode"); const kClipboardContractID = "@mozilla.org/widget/clipboard;1"; const kClipboardIID = Components.interfaces.nsIClipboard; var clipboard = Components.classes[kClipboardContractID].getService(kClipboardIID); clipboard.getData(xferable, kClipboardIID.kGlobalClipboard); var flavour = { }; var data = { }; var length = { }; xferable.getAnyTransferData(flavour, data, length); var items, name, url; data = data.value.QueryInterface(Components.interfaces.nsISupportsString).data; switch (flavour.value) { case "moz/bookmarkclipboarditem": items = data.split("\n"); // since data are ended by \n, remove the last empty node items.pop(); for (var i=0; i 0; case "cmd_redo": case "cmd_bm_redo": return BMSVC.transactionManager.numberOfRedoItems > 0; case "cmd_bm_paste": if (!(aTarget && BookmarksUtils.isValidTargetContainer(aTarget.parent))) return false; const kClipboardContractID = "@mozilla.org/widget/clipboard;1"; const kClipboardIID = Components.interfaces.nsIClipboard; var clipboard = Components.classes[kClipboardContractID].getService(kClipboardIID); const kSuppArrayContractID = "@mozilla.org/supports-array;1"; const kSuppArrayIID = Components.interfaces.nsISupportsArray; var flavourArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID); const kSuppStringContractID = "@mozilla.org/supports-cstring;1"; const kSuppStringIID = Components.interfaces.nsISupportsCString; var flavours = ["moz/bookmarkclipboarditem", "text/x-moz-url"]; for (i = 0; i < flavours.length; ++i) { const kSuppString = Components.classes[kSuppStringContractID].createInstance(kSuppStringIID); kSuppString.data = flavours[i]; flavourArray.AppendElement(kSuppString); } var hasFlavours = clipboard.hasDataMatchingFlavors(flavourArray, kClipboardIID.kGlobalClipboard); return hasFlavours; case "cmd_bm_copy": return length > 0; case "cmd_bm_cut": case "cmd_bm_delete": return length > 0 && aSelection.containsMutable && !aSelection.containsPTF; case "cmd_bm_selectAll": return true; case "cmd_bm_open": case "cmd_bm_expandfolder": case "cmd_bm_managefolder": return length == 1; case "cmd_bm_openinnewwindow": case "cmd_bm_openinnewtab": case "cmd_bm_find": case "cmd_bm_import": case "cmd_bm_export": return true; case "cmd_bm_newbookmark": case "cmd_bm_newfolder": case "cmd_bm_newseparator": return (aTarget && BookmarksUtils.isValidTargetContainer(aTarget.parent)); case "cmd_bm_properties": case "cmd_bm_rename": case "cmd_bm_sortfolderbyname": case "cmd_bm_sortfolder": return length == 1; case "cmd_bm_setnewbookmarkfolder": if (length != 1) return false; return item0 != "NC:NewBookmarkFolder" && (type0 == "Folder" || type0 == "PersonalToolbarFolder"); case "cmd_bm_setpersonaltoolbarfolder": if (length != 1) return false; return item0 != "NC:PersonalToolbarFolder" && item0 != "NC:BookmarksRoot" && type0 == "Folder"; case "cmd_bm_setnewsearchfolder": if (length != 1) return false; return item0 != "NC:NewSearchFolder" && (type0 == "Folder" || type0 == "PersonalToolbarFolder"); case "cmd_bm_movebookmark": return length > 0 && !aSelection.containsRF; default: return false; } }, doCommand: function (aCommand, aSelection, aTarget) { switch (aCommand) { case "cmd_undo": case "cmd_bm_undo": BookmarksCommand.undoBookmarkTransaction(); break; case "cmd_redo": case "cmd_bm_redo": BookmarksCommand.redoBookmarkTransaction(); break; case "cmd_bm_open": BookmarksCommand.openBookmark(aSelection, "current"); break; case "cmd_bm_openinnewwindow": BookmarksCommand.openBookmark(aSelection, "window"); break; case "cmd_bm_openinnewtab": BookmarksCommand.openBookmark(aSelection, "tab"); break; case "cmd_bm_managefolder": BookmarksCommand.manageFolder(aSelection); break; case "cmd_bm_setnewbookmarkfolder": case "cmd_bm_setpersonaltoolbarfolder": case "cmd_bm_setnewsearchfolder": BookmarksCommand.doBookmarksCommand(aSelection.item[0], NC_NS_CMD+aCommand.substring("cmd_bm_".length), []); break; case "cmd_bm_rename": case "cmd_bm_properties": BookmarksCommand.openBookmarkProperties(aSelection); break; case "cmd_bm_find": BookmarksCommand.findBookmark(); break; case "cmd_bm_cut": BookmarksCommand.cutBookmark(aSelection); break; case "cmd_bm_copy": BookmarksCommand.copyBookmark(aSelection); break; case "cmd_bm_paste": BookmarksCommand.pasteBookmark(aTarget); break; case "cmd_bm_delete": BookmarksCommand.deleteBookmark(aSelection); break; case "cmd_bm_movebookmark": BookmarksCommand.moveBookmark(aSelection); break; case "cmd_bm_newfolder": BookmarksCommand.createNewFolder(aTarget); break; case "cmd_bm_newbookmark": var folder = aTarget.parent.Value; var rv = { newBookmark: null }; openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "", "centerscreen,chrome,modal=yes,dialog=yes,resizable=yes", null, null, folder, null, "newBookmark", rv); break; case "cmd_bm_newseparator": BookmarksCommand.createNewSeparator(aTarget); break; case "cmd_bm_import": BookmarksCommand.importBookmarks(); break; case "cmd_bm_export": BookmarksCommand.exportBookmarks(); break; case "cmd_bm_sortfolderbyname": BookmarksCommand.sortFolderByName(aSelection); break; case "cmd_bm_sortfolder": BookmarksCommand.sortFolder(aSelection); break; default: dump("Bookmark command "+aCommand+" not handled!\n"); } }, onCommandUpdate: function (aSelection, aTarget) { var commands = ["cmd_bm_newbookmark", "cmd_bm_newfolder", "cmd_bm_newseparator", "cmd_bm_properties", "cmd_bm_rename", "cmd_bm_copy", "cmd_bm_paste", "cmd_bm_cut", "cmd_bm_delete", "cmd_bm_setpersonaltoolbarfolder", "cmd_bm_setnewbookmarkfolder", "cmd_bm_setnewsearchfolder", "cmd_bm_movebookmark", "cmd_bm_managefolder", "cmd_bm_sortfolder", "cmd_bm_sortfolderbyname", "cmd_undo", "cmd_redo", "cmd_bm_undo", "cmd_bm_redo"]; for (var i = 0; i < commands.length; ++i) { var commandNode = document.getElementById(commands[i]); if (commandNode) { if (this.isCommandEnabled(commands[i], aSelection, aTarget)) commandNode.removeAttribute("disabled"); else commandNode.setAttribute("disabled", "true"); } } } } function CommandArrayEnumerator (aCommandArray) { this._inner = []; for (var i = 0; i < aCommandArray.length; ++i) this._inner.push(RDF.GetResource(NC_NS_CMD + aCommandArray[i])); this._index = 0; } CommandArrayEnumerator.prototype = { getNext: function () { return this._inner[this._index]; }, hasMoreElements: function () { return this._index < this._inner.length; } }; var BookmarksUtils = { DROP_BEFORE: Components.interfaces.nsITreeView.inDropBefore, DROP_ON : Components.interfaces.nsITreeView.inDropOn, DROP_AFTER : Components.interfaces.nsITreeView.inDropAfter, any: function (aArray) { for (var i=0; i see bug 63370 for details var LOCALESVC = Components.classes["@mozilla.org/intl/nslocaleservice;1"] .getService(Components.interfaces.nsILocaleService); var BUNDLESVC = Components.classes["@mozilla.org/intl/stringbundle;1"] .getService(Components.interfaces.nsIStringBundleService); var bookmarksBundle = "chrome://communicator/locale/bookmarks/bookmarks.properties"; this._bundle = BUNDLESVC.createBundle(bookmarksBundle, LOCALESVC.getApplicationLocale()); var brandBundle = "chrome://global/locale/brand.properties"; this._brandShortName = BUNDLESVC.createBundle(brandBundle, LOCALESVC.getApplicationLocale()) .GetStringFromName("brandShortName"); } var bundle; try { if (!aReplaceString) bundle = this._bundle.GetStringFromName(aStringKey); else if (typeof(aReplaceString) == "string") bundle = this._bundle.formatStringFromName(aStringKey, [aReplaceString], 1); else bundle = this._bundle.formatStringFromName(aStringKey, aReplaceString, aReplaceString.length); } catch (e) { dump("Bookmark bundle "+aStringKey+" not found!\n"); bundle = ""; } bundle = bundle.replace(/%brandShortName%/, this._brandShortName); return bundle; }, ///////////////////////////////////////////////////////////////////////////// // returns the literal targeted by the URI aArcURI for a resource or uri getProperty: function (aInput, aArcURI, aDS) { var node; var arc = RDF.GetResource(aArcURI); if (typeof(aInput) == "string") aInput = RDF.GetResource(aInput); if (!aDS) node = BMDS.GetTarget(aInput, arc, true); else node = aDS .GetTarget(aInput, arc, true); return (node instanceof kRDFRSCIID) || (node instanceof kRDFLITIID) ? node.Value : ""; }, getResource: function (aName) { if (aName == "LastModifiedDate" || aName == "LastVisitDate") { return RDF.GetResource(WEB_NS + aName); } else { return RDF.GetResource(NC_NS + aName); } }, ///////////////////////////////////////////////////////////////////////////// // Determine the rdf:type property for the given resource. resolveType: function (aResource) { var type = this.getProperty(aResource, RDF_NS+"type"); if (type != "") type = type.split("#")[1]; if (type == "Folder") { if (this.isPersonalToolbarFolder(aResource)) type = "PersonalToolbarFolder"; else if (this.isFolderGroup(aResource)) type = "FolderGroup"; } return type; }, ///////////////////////////////////////////////////////////////////////////// // Returns true if aResource is a folder group isFolderGroup: function (aResource) { return this.getProperty(aResource, NC_NS+"FolderGroup") == "true"; }, ///////////////////////////////////////////////////////////////////////////// // Returns true if aResource is the Personal Toolbar Folder isPersonalToolbarFolder: function (aResource) { return this.getProperty(aResource, NC_NS+"FolderType") == "NC:PersonalToolbarFolder"; }, ///////////////////////////////////////////////////////////////////////////// // Returns the folder which 'FolderType' is aProperty getSpecialFolder: function (aProperty) { var sources = BMDS.GetSources(RDF.GetResource(NC_NS+"FolderType"), RDF.GetResource(aProperty), true); var folder = null; if (sources.hasMoreElements()) folder = sources.getNext(); else folder = RDF.GetResource("NC:BookmarksRoot"); return folder; }, ///////////////////////////////////////////////////////////////////////////// // Returns the New Bookmark Folder getNewBookmarkFolder: function() { return this.getSpecialFolder("NC:NewBookmarkFolder"); }, ///////////////////////////////////////////////////////////////////////////// // Returns the New Search Folder getNewSearchFolder: function() { return this.getSpecialFolder("NC:NewSearchFolder"); }, ///////////////////////////////////////////////////////////////////////////// // Returns the container of a given container getParentOfContainer: function(aChild) { var arcsIn = BMDS.ArcLabelsIn(aChild); var containerArc; while (arcsIn.hasMoreElements()) { containerArc = arcsIn.getNext(); if (RDFCU.IsOrdinalProperty(containerArc)) { return BMDS.GetSources(containerArc, aChild, true).getNext() .QueryInterface(kRDFRSCIID); } } return null; }, ///////////////////////////////////////////////////////////////////////////// // Caches frequently used informations about the selection checkSelection: function (aSelection) { if (aSelection.length == 0) return; aSelection.type = new Array(aSelection.length); aSelection.protocol = new Array(aSelection.length); aSelection.isContainer = new Array(aSelection.length); aSelection.isImmutable = new Array(aSelection.length); aSelection.isValid = new Array(aSelection.length); aSelection.containsMutable = false; aSelection.containsPTF = false; aSelection.containsRF = false; var index, item, parent, type, protocol, isContainer, isImmutable, isValid; for (var i=0; i"+itemName+""); data.addDataForFlavour("text/unicode", itemUrl); dataSet.push(data); } return dataSet; }, getSelectionFromXferData: function (aDragSession) { var selection = {}; selection.item = []; selection.parent = []; var trans = Components.classes["@mozilla.org/widget/transferable;1"] .createInstance(Components.interfaces.nsITransferable); trans.addDataFlavor("moz/rdfitem"); trans.addDataFlavor("text/x-moz-url"); trans.addDataFlavor("text/unicode"); var uri, extra, rSource, rParent, parent; for (var i = 0; i < aDragSession.numDropItems; ++i) { var bestFlavour = {}, dataObj = {}, len = {}; aDragSession.getData(trans, i); trans.getAnyTransferData(bestFlavour, dataObj, len); dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsString); if (!dataObj) continue; dataObj = dataObj.data.substring(0, len.value).split("\n"); uri = dataObj[0]; if (dataObj.length > 1 && dataObj[1] != "") extra = dataObj[1]; else extra = null; switch (bestFlavour.value) { case "moz/rdfitem": rSource = RDF.GetResource(uri); parent = extra; break; case "text/x-moz-url": case "text/unicode": rSource = BookmarksUtils.createBookmark(null, uri, null, extra); parent = null; break; } selection.item.push(rSource); if (parent) rParent = RDF.GetResource(parent); else rParent = null; selection.parent.push(rParent); } selection.length = selection.item.length; BookmarksUtils.checkSelection(selection); return selection; }, getTargetFromFolder: function(aResource) { var index = parseInt(this.getProperty(aResource, RDF_NS+"nextVal")); if (isNaN(index)) return {parent: null, index: -1}; else return {parent: aResource, index: index}; }, getSelectionFromResource: function (aItem, aParent) { var selection = {}; selection.length = 1; selection.item = [aItem ]; selection.parent = [aParent]; this.checkSelection(selection); return selection; }, createBookmark: function (aName, aURL, aCharSet, aDefaultName) { if (!aName) { // look up in the history ds to retrieve the name var rSource = RDF.GetResource(aURL); var HISTDS = RDF.GetDataSource("rdf:history"); var nameArc = RDF.GetResource(NC_NS+"Name"); var rName = HISTDS.GetTarget(rSource, nameArc, true); aName = rName ? rName.QueryInterface(kRDFLITIID).Value : aDefaultName; if (!aName) aName = aURL; } if (!aCharSet) { var fw = document.commandDispatcher.focusedWindow; if (fw) aCharSet = fw.document.characterSet; } return BMSVC.createBookmark(aName, aURL, null, null, aCharSet); }, flushDataSource: function () { var remoteDS = BMDS.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource); setTimeout(function () {remoteDS.Flush()}, 100); }, addBookmarkForTabBrowser: function( aTabBrowser, aSelect ) { var tabsInfo = []; var currentTabInfo = { name: "", url: "", charset: null }; const activeBrowser = aTabBrowser.selectedBrowser; const browsers = aTabBrowser.browsers; for (var i = 0; i < browsers.length; ++i) { var webNav = browsers[i].webNavigation; var url = webNav.currentURI.spec; var name = ""; var charset; try { var doc = new XPCNativeWrapper(webNav.document, "title", "characterSet"); name = doc.title || url; charset = doc.characterSet; } catch (e) { name = url; } tabsInfo[i] = { name: name, url: url, charset: charset }; if (browsers[i] == activeBrowser) currentTabInfo = tabsInfo[i]; } openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "", "centerscreen,chrome,dialog=yes,resizable=yes,dependent", currentTabInfo.name, currentTabInfo.url, null, currentTabInfo.charset, "addGroup" + (aSelect ? ",group" : ""), tabsInfo); }, addBookmarkForBrowser: function (aDocShell, aShowDialog) { // Bug 52536: We obtain the URL and title from the nsIWebNavigation // associated with a rather than from a DOMWindow. // This is because when a full page plugin is loaded, there is // no DOMWindow (?) but information about the loaded document // may still be obtained from the webNavigation. var url = aDocShell.currentURI.spec; var title, docCharset = null; try { var doc = new XPCNativeWrapper(aDocShell.document, "title", "characterSet"); title = doc.title || url; docCharset = doc.characterSet; } catch (e) { title = url; } this.addBookmark(url, title, docCharset, aShowDialog); }, // should update the caller, aShowDialog is no more necessary addBookmark: function (aURL, aTitle, aCharset, aShowDialog) { if (aCharset === undefined) { var fw = document.commandDispatcher.focusedWindow; aCharset = fw.document.characterSet; } if (aShowDialog) { openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "", "centerscreen,chrome,dialog=yes,resizable=yes,dependent", aTitle, aURL, null, aCharset); } else { // User has elected to override the file dialog and always file bookmarks // into the default bookmark folder. BMSVC.addBookmarkImmediately(aURL, aTitle, kBMSVCIID.BOOKMARK_DEFAULT_TYPE, aCharset); } }, loadBookmarkBrowser: function (aEvent, aTarget, aDS) { var rSource = RDF.GetResource(aTarget.id); var selection = BookmarksUtils.getSelectionFromResource(rSource); BookmarksCommand.openBookmark(selection, "current", aDS) } } function BookmarkTransaction() { } BookmarkTransaction.prototype = { BATCH_LIMIT : 8, RDFC : null, BMDS : null, beginUpdateBatch: function() { if (this.item.length > this.BATCH_LIMIT) { this.BMDS.beginUpdateBatch(); } }, endUpdateBatch: function() { if (this.item.length > this.BATCH_LIMIT) { this.BMDS.endUpdateBatch(); } }, // nsITransaction method stubs doTransaction: function() {}, undoTransaction: function() {}, redoTransaction: function() { this.doTransaction(); }, get isTransient() { return false; }, merge: function(aTransaction) { return false; }, // debugging helper get wrappedJSObject() { return this; } } function BookmarkInsertTransaction (aAction) { this.type = "insert"; this.action = aAction; this.item = null; this.parent = null; this.index = null; this.isValid = null; } BookmarkInsertTransaction.prototype = { __proto__: BookmarkTransaction.prototype, doTransaction: function () { this.beginUpdateBatch(); for (var i=0; i=0; i--) { if (this.isValid[i]) { container.Init(this.BMDS, this.parent[i]); container.RemoveElementAt(this.index[i], true); } } this.endUpdateBatch(); } } function BookmarkRemoveTransaction (aAction) { this.type = "remove"; this.action = aAction; this.item = null; this.parent = null; this.index = null; this.isValid = null; } BookmarkRemoveTransaction.prototype = { __proto__: BookmarkTransaction.prototype, doTransaction: function () { this.beginUpdateBatch(); for (var i=0; i=0; i--) { if (this.isValid[i]) { this.RDFC.Init(this.BMDS, this.parent[i]); this.RDFC.InsertElementAt(this.item[i], this.index[i], false); } } this.endUpdateBatch(); } } function BookmarkMoveTransaction (aAction, aSelection, aTarget) { this.type = "move"; this.action = aAction; this.selection = aSelection; this.target = aTarget; this.isValid = aSelection.isValid; } BookmarkMoveTransaction.prototype = { __proto__: BookmarkTransaction.prototype, beginUpdateBatch: function() { if (this.selection.length > this.BATCH_LIMIT) { this.BMDS.beginUpdateBatch(); } }, endUpdateBatch: function() { if (this.selection.length > this.BATCH_LIMIT) { this.BMDS.endUpdateBatch(); } }, doTransaction: function () { this.beginUpdateBatch(); BookmarksUtils.removeSelection("move", this.selection); BookmarksUtils.insertSelection("move", this.selection, this.target); this.endUpdateBatch(); }, redoTransaction : function () {} } function BookmarkImportTransaction (aAction) { this.type = "import"; this.action = aAction; this.item = []; this.parent = []; this.index = []; this.isValid = []; } BookmarkImportTransaction.prototype = { __proto__: BookmarkTransaction.prototype, undoTransaction: function () { this.beginUpdateBatch(); for (var i=this.item.length-1; i>=0; i--) { if (this.isValid[i]) { this.RDFC.Init(this.BMDS, this.parent[i]); this.RDFC.RemoveElementAt(this.index[i], true); } } this.endUpdateBatch(); }, redoTransaction: function () { this.beginUpdateBatch(); for (var i=0; iSDDUxbookmarks-tree, bookmarks-tree[type="multi-column"] { -moz-binding : url("chrome://communicator/content/bookmarks/bookmarksTree.xml#bookmarks-tree-full"); } bookmarks-tree[type="single-column"] { -moz-binding : url("chrome://communicator/content/bookmarks/bookmarksTree.xml#bookmarks-tree-name"); } bookmarks-tree[type="folders"] { -moz-binding : url("chrome://communicator/content/bookmarks/bookmarksTree.xml#bookmarks-tree-folders"); }PK wa0W5oo/content/communicator/bookmarks/bookmarksMenu.jsUT qT@SDDUx/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Netscape Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Pierre Chanial * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the NPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ var BookmarksMenu = { _selection:null, _target:null, _orientation:null, ////////////////////////////////////////////////////////////////////////// // Fill a context menu popup with menuitems appropriate for the current // selection. createContextMenu: function (aEvent) { var target = document.popupNode; target.focus() // buttons in the pt have -moz-user-focus: ignore --> this._selection = this.getBTSelection(target); this._orientation = this.getBTOrientation(aEvent, target); this._target = this.getBTTarget(target, this._orientation); BookmarksCommand.createContextMenu(aEvent, this._selection); this.onCommandUpdate(); aEvent.target.addEventListener("mousemove", BookmarksMenuController.onMouseMove, false) }, ///////////////////////////////////////////////////////////////////////// // Clean up after closing the context menu popup destroyContextMenu: function (aEvent) { if (content) content.focus() BookmarksMenuDNDObserver.onDragRemoveFeedBack(document.popupNode); // needed on cancel aEvent.target.removeEventListener("mousemove", BookmarksMenuController.onMouseMove, false) }, ///////////////////////////////////////////////////////////////////////////// // returns the formatted selection from aNode getBTSelection: function (aNode) { var item; switch (aNode.id) { case "bookmarks-ptf": item = "NC:PersonalToolbarFolder"; break; case "BookmarksMenu": item = "NC:BookmarksRoot"; break; default: item = aNode.id; } if (!this.isBTBookmark(item)) return {length:0}; var parent = this.getBTContainer(aNode); var isExpanded = aNode.hasAttribute("open") && aNode.open; var selection = {}; selection.item = [RDF.GetResource(item)]; selection.parent = [RDF.GetResource(parent)]; selection.isExpanded = [isExpanded]; selection.length = selection.item.length; BookmarksUtils.checkSelection(selection); return selection; }, ///////////////////////////////////////////////////////////////////////// // returns the insertion target from aNode getBTTarget: function (aNode, aOrientation) { var item, parent, index; switch (aNode.id) { case "bookmarks-ptf": parent = "NC:PersonalToolbarFolder"; item = BookmarksToolbar.getLastVisibleBookmark(); break; case "BookmarksMenu": parent = "NC:BookmarksRoot"; break; case "bookmarks-button": parent = "NC:BookmarksRoot"; break; case "bookmarks-chevron": parent = "NC:PersonalToolbarFolder"; item = document.getElementById("bookmarks-ptf").lastChild; aOrientation == BookmarksUtils.DROP_AFTER; break; default: if (aOrientation == BookmarksUtils.DROP_ON) parent = aNode.id else { parent = this.getBTContainer(aNode); item = aNode; } } parent = RDF.GetResource(parent); if (aOrientation == BookmarksUtils.DROP_ON) return BookmarksUtils.getTargetFromFolder(parent); item = RDF.GetResource(item.id); RDFC.Init(BMDS, parent); index = RDFC.IndexOf(item); if (aOrientation == BookmarksUtils.DROP_AFTER) ++index; return { parent: parent, index: index }; }, ///////////////////////////////////////////////////////////////////////// // returns the parent resource of a node in the personal toolbar. // this is determined by inspecting the source element and walking up the // DOM tree to find the appropriate containing node. getBTContainer: function (aNode) { var parent; var item = aNode.id; if (!this.isBTBookmark(item)) return "NC:BookmarksRoot" parent = aNode.parentNode.parentNode; parent = parent.id; switch (parent) { case "BookmarksMenu": return "NC:BookmarksRoot"; case "PersonalToolbar": case "bookmarks-chevron": return "NC:PersonalToolbarFolder"; case "bookmarks-button": return "NC:BookmarksRoot"; default: return parent; } }, /////////////////////////////////////////////////////////////////////////// // returns true if the node is a bookmark, a folder or a bookmark separator isBTBookmark: function (aURI) { if (!aURI) return false; var type = BookmarksUtils.resolveType(aURI); return (type == "BookmarkSeparator" || type == "Bookmark" || type == "Folder" || type == "FolderGroup" || type == "PersonalToolbarFolder") }, ///////////////////////////////////////////////////////////////////////// // returns true if the node is a container. --> isBTContainer: function (aTarget) { return aTarget.localName == "menu" || (aTarget.localName == "toolbarbutton" && (aTarget.getAttribute("container") == "true" || aTarget.getAttribute("group") == "true")); }, ///////////////////////////////////////////////////////////////////////// // returns BookmarksUtils.DROP_BEFORE, DROP_ON or DROP_AFTER accordingly // to the event coordinates. Skin authors could break us, we'll cross that // bridge when they turn us 90degrees. --> getBTOrientation: function (aEvent, aTarget) { var target if (!aTarget) target = aEvent.target; else target = aTarget; if (target.localName == "menu" && target.parentNode.localName != "menupopup") return BookmarksUtils.DROP_ON; if (target.id == "bookmarks-ptf" || target.id == "bookmarks-chevron") { return BookmarksUtils.DROP_ON; } var overButtonBoxObject = target.boxObject.QueryInterface(Components.interfaces.nsIBoxObject); var overParentBoxObject = target.parentNode.boxObject.QueryInterface(Components.interfaces.nsIBoxObject); var size, border; var coordValue, clientCoordValue; switch (target.localName) { case "toolbarseparator": case "toolbarbutton": size = overButtonBoxObject.width; coordValue = overButtonBoxObject.x; clientCoordValue = aEvent.clientX; break; case "menuseparator": case "menu": case "menuitem": size = overButtonBoxObject.height; coordValue = overButtonBoxObject.y-overParentBoxObject.y; clientCoordValue = aEvent.clientY; break; default: return BookmarksUtils.DROP_ON; } if (this.isBTContainer(target)) if (target.localName == "toolbarbutton") { // the DROP_BEFORE area excludes the label var iconNode = document.getAnonymousElementByAttribute(target, "class", "toolbarbutton-icon"); border = parseInt(document.defaultView.getComputedStyle(target,"").getPropertyValue("padding-left")) + parseInt(document.defaultView.getComputedStyle(iconNode ,"").getPropertyValue("width")); border = Math.min(size/5,Math.max(border,4)); } else border = size/5; else border = size/2; // in the first region? if (clientCoordValue-coordValue < border) return BookmarksUtils.DROP_BEFORE; // in the last region? if (clientCoordValue-coordValue >= size-border) return BookmarksUtils.DROP_AFTER; // must be in the middle somewhere return BookmarksUtils.DROP_ON; }, ///////////////////////////////////////////////////////////////////////// // expand the folder targeted by the context menu. expandBTFolder: function () { var target = document.popupNode.lastChild; if (document.popupNode.open) target.hidePopup(); else target.showPopup(document.popupNode); }, onCommandUpdate: function () { var selection = this._selection; var target = this._target; BookmarksController.onCommandUpdate(selection, target); if (document.popupNode.id == "bookmarks-ptf") { // disabling 'cut' and 'copy' on the empty area of the personal toolbar var commandNode = document.getElementById("cmd_bm_cut"); commandNode.setAttribute("disabled", "true"); commandNode = document.getElementById("cmd_bm_copy"); commandNode.setAttribute("disabled", "true"); } }, loadBookmark: function (aTarget, aDS) { // Check for invalid bookmarks (most likely a static menu item like "Manage Bookmarks") if (!this.isBTBookmark(aTarget.id)) return; var rSource = RDF.GetResource(aTarget.id); var selection = BookmarksUtils.getSelectionFromResource(rSource); BookmarksCommand.openBookmark(selection, "current", aDS) } } var BookmarksMenuController = { supportsCommand: BookmarksController.supportsCommand, isCommandEnabled: function (aCommand) { // warning: this is not the function called in BookmarksController.onCommandUpdate var selection = BookmarksMenu._selection; var target = BookmarksMenu._target; if (selection) return BookmarksController.isCommandEnabled(aCommand, selection, target); return false; }, doCommand: function (aCommand) { BookmarksMenuDNDObserver.onDragRemoveFeedBack(document.popupNode); var selection = BookmarksMenu._selection; var target = BookmarksMenu._target; switch (aCommand) { case "cmd_bm_expandfolder": BookmarksMenu.expandBTFolder(); break; default: BookmarksController.doCommand(aCommand, selection, target); } }, onMouseMove: function (aEvent) { var command = aEvent.target.getAttribute("command"); var isDisabled = aEvent.target.getAttribute("disabled") if (isDisabled != "true" && (command == "cmd_bm_newfolder" || command == "cmd_bm_paste")) { BookmarksMenuDNDObserver.onDragSetFeedBack(document.popupNode, BookmarksMenu._orientation); } else { BookmarksMenuDNDObserver.onDragRemoveFeedBack(document.popupNode); } } } var BookmarksMenuDNDObserver = { //////////////////// // Public methods // //////////////////// onDragStart: function (aEvent, aXferData, aDragAction) { var target = aEvent.target; // Prevent dragging from an invalid region if (!this.canDrop(aEvent)) return; // Prevent dragging out of menupopups on non Win32 platforms. // a) on Mac drag from menus is generally regarded as being satanic // b) on Linux, this causes an X-server crash, (bug 151336) // c) on Windows, there is no hang or crash associated with this, so we'll leave // the functionality there. if (navigator.platform != "Win32" && target.localName != "toolbarbutton") return; // bail if dragging from the empty area of the bookmarks toolbar if (target.id == "bookmarks-ptf") return // a drag start is fired when leaving an open toolbarbutton(type=menu) // (see bug 143031) if (this.isContainer(target) && target.getAttribute("group") != "true") { if (this.isPlatformNotSupported) return; if (!aEvent.shiftKey && !aEvent.altKey && !aEvent.ctrlKey) return; // menus open on mouse down target.firstChild.hidePopup(); } var selection = BookmarksMenu.getBTSelection(target); aXferData.data = BookmarksUtils.getXferDataFromSelection(selection); }, onDragOver: function(aEvent, aFlavour, aDragSession) { var orientation = BookmarksMenu.getBTOrientation(aEvent) if (aDragSession.canDrop) this.onDragSetFeedBack(aEvent.target, orientation); if (orientation != this.mCurrentDropPosition) { // emulating onDragExit and onDragEnter events since the drop region // has changed on the target. this.onDragExit(aEvent, aDragSession); this.onDragEnter(aEvent, aDragSession); } if (this.isPlatformNotSupported) return; if (this.isTimerSupported) return; this.onDragOverCheckTimers(); }, onDragEnter: function (aEvent, aDragSession) { var target = aEvent.target; var orientation = BookmarksMenu.getBTOrientation(aEvent); if (target.localName == "menupopup" || target.id == "bookmarks-ptf") target = target.parentNode; if (aDragSession.canDrop) { this.onDragSetFeedBack(target, orientation); this.onDragEnterSetTimer(target, aDragSession); } this.mCurrentDragOverTarget = target; this.mCurrentDropPosition = orientation; }, onDragExit: function (aEvent, aDragSession) { var target = aEvent.target; if (target.localName == "menupopup" || target.id == "bookmarks-ptf") target = target.parentNode; this.onDragRemoveFeedBack(target); this.onDragExitSetTimer(target, aDragSession); this.mCurrentDragOverTarget = null; this.mCurrentDropPosition = null; }, onDrop: function (aEvent, aXferData, aDragSession) { var target = aEvent.target; this.onDragRemoveFeedBack(target); var selection = BookmarksUtils.getSelectionFromXferData(aDragSession); var orientation = BookmarksMenu.getBTOrientation(aEvent); var selTarget = BookmarksMenu.getBTTarget(target, orientation); const kDSIID = Components.interfaces.nsIDragService; const kCopyAction = kDSIID.DRAGDROP_ACTION_COPY + kDSIID.DRAGDROP_ACTION_LINK; // hide the 'open in tab' menuseparator because bookmarks // can be inserted after it if they are dropped after the last bookmark // a more comprehensive fix would be in the menupopup template builder var menuTarget = (target.localName == "toolbarbutton" || target.localName == "menu") && orientation == BookmarksUtils.DROP_ON? target.lastChild:target.parentNode; if (menuTarget.hasChildNodes() && menuTarget.lastChild.id == "openintabs-menuitem") { menuTarget.removeChild(menuTarget.lastChild.previousSibling); } if (aDragSession.dragAction & kCopyAction) BookmarksUtils.insertSelection("drag", selection, selTarget); else BookmarksUtils.moveSelection("drag", selection, selTarget); var chevron = document.getElementById("bookmarks-chevron"); if (chevron.getAttribute("open") == "true") { BookmarksToolbar.resizeFunc(null); BookmarksToolbar.updateOverflowMenu(document.getElementById("bookmarks-chevron-popup")); } // show again the menuseparator if (menuTarget.hasChildNodes() && menuTarget.lastChild.id == "openintabs-menuitem") { var element = document.createElementNS(XUL_NS, "menuseparator"); menuTarget.insertBefore(element, menuTarget.lastChild); } }, canDrop: function (aEvent, aDragSession) { var target = aEvent.target; return BookmarksMenu.isBTBookmark(target.id) && target.id != "NC:SystemBookmarksStaticRoot" && target.id.substring(0,5) != "find:" || target.id == "BookmarksMenu" || target.id == "bookmarks-button" || target.id == "bookmarks-chevron" || target.id == "bookmarks-ptf"; }, canHandleMultipleItems: true, getSupportedFlavours: function () { var flavourSet = new FlavourSet(); flavourSet.appendFlavour("moz/rdfitem"); flavourSet.appendFlavour("text/x-moz-url"); flavourSet.appendFlavour("application/x-moz-file", "nsIFile"); flavourSet.appendFlavour("text/unicode"); return flavourSet; }, //////////////////////////////////// // Private methods and properties // //////////////////////////////////// springLoadedMenuDelay: 350, // milliseconds isPlatformNotSupported: navigator.platform.indexOf("Mac") != -1, // see bug 136524 isTimerSupported: navigator.platform.indexOf("Win") == -1, mCurrentDragOverTarget: null, mCurrentDropPosition: null, loadTimer : null, closeTimer : null, loadTarget : null, closeTarget: null, _observers : null, get mObservers () { if (!this._observers) { this._observers = [ document.getElementById("bookmarks-ptf"), document.getElementById("BookmarksMenu").parentNode, document.getElementById("bookmarks-chevron").parentNode, document.getElementById("PersonalToolbar") ] } return this._observers; }, getObserverForNode: function (aNode) { if (!aNode) return null; var node = aNode; var observer; do { for (var i=0; i < this.mObservers.length; i++) { observer = this.mObservers[i]; if (observer == node) return observer; } node = node.parentNode; } while (node != document) return null; }, onDragCloseMenu: function (aNode) { var children = aNode.childNodes; for (var i = 0; i < children.length; i++) { if (this.isContainer(children[i]) && children[i].getAttribute("open") == "true") { this.onDragCloseMenu(children[i].lastChild); if (children[i] != this.mCurrentDragOverTarget || this.mCurrentDropPosition != BookmarksUtils.DROP_ON) children[i].lastChild.hidePopup(); } } }, onDragCloseTarget: function () { var currentObserver = this.getObserverForNode(this.mCurrentDragOverTarget); // close all the menus not hovered by the mouse for (var i=0; i < this.mObservers.length; i++) { if (currentObserver != this.mObservers[i]) this.onDragCloseMenu(this.mObservers[i]); else this.onDragCloseMenu(this.mCurrentDragOverTarget.parentNode); } }, onDragLoadTarget: function (aTarget) { if (!this.mCurrentDragOverTarget) return; // Load the current menu if (this.mCurrentDropPosition == BookmarksUtils.DROP_ON && this.isContainer(aTarget) && aTarget.getAttribute("group") != "true") aTarget.lastChild.showPopup(aTarget); }, onDragOverCheckTimers: function () { var now = new Date().getTime(); if (this.closeTimer && now-this.springLoadedMenuDelay>this.closeTimer) { this.onDragCloseTarget(); this.closeTimer = null; } if (this.loadTimer && (now-this.springLoadedMenuDelay>this.loadTimer)) { this.onDragLoadTarget(this.loadTarget); this.loadTimer = null; } }, onDragEnterSetTimer: function (aTarget, aDragSession) { if (this.isPlatformNotSupported) return; if (this.isTimerSupported) { var targetToBeLoaded = aTarget; clearTimeout(this.loadTimer); if (aTarget == aDragSession.sourceNode) return; var This = this; this.loadTimer=setTimeout(function () {This.onDragLoadTarget(targetToBeLoaded)}, This.springLoadedMenuDelay); } else { var now = new Date().getTime(); this.loadTimer = now; this.loadTarget = aTarget; } }, onDragExitSetTimer: function (aTarget, aDragSession) { if (this.isPlatformNotSupported) return; var This = this; if (this.isTimerSupported) { clearTimeout(this.closeTimer) this.closeTimer=setTimeout(function () {This.onDragCloseTarget()}, This.springLoadedMenuDelay); } else { var now = new Date().getTime(); this.closeTimer = now; this.closeTarget = aTarget; this.loadTimer = null; // If user isn't rearranging within the menu, close it // To do so, we exploit a Mac bug: timeout set during // drag and drop on Windows and Mac are fired only after that the drop is released. // timeouts will pile up, we may have a better approach but for the moment, this one // correctly close the menus after a drop/cancel outside the personal toolbar. // The if statement in the function has been introduced to deal with rare but reproducible // missing Exit events. if (aDragSession.sourceNode.localName != "menuitem" && aDragSession.sourceNode.localName != "menu") setTimeout(function () { if (This.mCurrentDragOverTarget) {This.onDragRemoveFeedBack(This.mCurrentDragOverTarget); This.mCurrentDragOverTarget=null} This.loadTimer=null; This.onDragCloseTarget() }, 0); } }, onDragSetFeedBack: function (aTarget, aOrientation) { switch (aTarget.localName) { case "toolbarseparator": case "toolbarbutton": switch (aOrientation) { case BookmarksUtils.DROP_BEFORE: aTarget.setAttribute("dragover-left", "true"); break; case BookmarksUtils.DROP_AFTER: aTarget.setAttribute("dragover-right", "true"); break; case BookmarksUtils.DROP_ON: aTarget.setAttribute("dragover-top" , "true"); aTarget.setAttribute("dragover-bottom", "true"); aTarget.setAttribute("dragover-left" , "true"); aTarget.setAttribute("dragover-right" , "true"); break; } break; case "menuseparator": case "menu": case "menuitem": switch (aOrientation) { case BookmarksUtils.DROP_BEFORE: aTarget.setAttribute("dragover-top", "true"); break; case BookmarksUtils.DROP_AFTER: aTarget.setAttribute("dragover-bottom", "true"); break; case BookmarksUtils.DROP_ON: break; } break; case "toolbar": var newTarget = BookmarksToolbar.getLastVisibleBookmark(); if (newTarget) newTarget.setAttribute("dragover-right", "true"); break; case "hbox": case "menupopup": break; default: dump("No feedback for: "+aTarget.localName+"\n"); } }, onDragRemoveFeedBack: function (aTarget) { var newTarget; var bt; if (aTarget.id == "PersonalToolbar" || aTarget.id == "bookmarks-ptf") { newTarget = BookmarksToolbar.getLastVisibleBookmark(); if (newTarget) newTarget.removeAttribute("dragover-right"); } else { aTarget.removeAttribute("dragover-left"); aTarget.removeAttribute("dragover-right"); aTarget.removeAttribute("dragover-top"); aTarget.removeAttribute("dragover-bottom"); } }, onDropSetFeedBack: function (aTarget) { //XXX Not yet... }, isContainer: function (aTarget) { return aTarget.localName == "menu" || aTarget.localName == "toolbarbutton" && aTarget.getAttribute("type") == "menu"; } } var BookmarksToolbar = { //////////////////////////////////////////////// // loads a bookmark with the mouse middle button loadBookmarkMiddleClick: function (aEvent, aDS) { if (aEvent.button != 1) return; // unlike for command events, we have to close the menus manually BookmarksMenuDNDObserver.mCurrentDragOverTarget = null; BookmarksMenuDNDObserver.onDragCloseTarget(); BookmarksUtils.loadBookmarkBrowser(aEvent, aEvent.target, aDS); }, ///////////////////////////////////////////////////////////////////////////// // returns the node of the last visible bookmark on the toolbar --> getLastVisibleBookmark: function () { var buttons = document.getElementById("bookmarks-ptf"); var button = buttons.firstChild; if (!button) return null; // empty bookmarks toolbar do { if (button.collapsed) return button.previousSibling; button = button.nextSibling; } while (button) return buttons.lastChild; }, updateOverflowMenu: function (aMenuPopup) { var hbox = document.getElementById("bookmarks-ptf"); for (var i = 0; i < hbox.childNodes.length; i++) { var button = hbox.childNodes[i]; var menu = aMenuPopup.childNodes[i]; if (menu.hidden == button.collapsed) menu.hidden = !menu.hidden; } }, resizeFunc: function(event) { if (!event) // timer callback case BookmarksToolbarRDFObserver._overflowTimerInEffect = false; else if (event.target != document) return; // only interested in chrome resizes var buttons = document.getElementById("bookmarks-ptf"); if (!buttons) return; var chevron = document.getElementById("bookmarks-chevron"); if (!buttons.firstChild) { // No bookmarks means no chevron chevron.collapsed = true; return; } chevron.collapsed = false; var chevronWidth = chevron.boxObject.width; chevron.collapsed = true; var remainingWidth = buttons.boxObject.width; var overflowed = false; for (var i=0; i %bookmarksDTD; ]> null null 0) for (var k = 0; k < rangeCount; ++k) { var rangeMin = {}; var rangeMax = {}; this.treeBoxObject.selection.getRangeAt(k, rangeMin, rangeMax); for (var i = rangeMin.value; i <= rangeMax.value; ++i) { var selectedItem = this.getRowResource(i); var selectedParent = this.getParentResource(i); var isExpanded = this.treeBoxObject.view.isContainerOpen(i) selection.item .push(selectedItem); selection.parent.push(selectedParent); selection.isExpanded.push(isExpanded); } } selection.length = selection.item.length; BookmarksUtils.checkSelection(selection); return selection; ]]> [] = 0) { selection.toggleSelect(index); } } selection.selectEventsSuppressed = false; } ]]> [] [] =0) this.treeBoxObject.selection.toggleSelect(index); } ]]> "(= 0) // if no other row remains. s.select((rangeMin.value >= this.mOuter.treeBuilder.rowCount) ? this.mOuter.treeBuilder.rowCount - 1 : rangeMin.value); break; case "cmd_bm_expandfolder": this.mOuter.treeBoxObject.view.toggleOpenState(this.mOuter.currentIndex); break; case "cmd_bm_selectAll": this.mOuter.treeBoxObject.selection.selectAll(); break; default: BookmarksController.doCommand(aCommand, selection, target); } } }) ]]> 2 1 2 PK h0Gҗ.content/communicator/bookmarks/addBookmark.xulUT KL@SDDUx %brandDTD; %addBookmarkDTD; ]> &perfdescription.label; &systemPrefDescription.label; PK wEB0lPe e -content/communicator/pref/pref-appearance.xulUT B~@[SDDUx %brandDTD; %prefAppearanceDTD; ]> PK or0/content/communicator/pref/pref-applications.xulUT a@[SDDUx PK rC-׶# 3content/communicator/pref/pref-applications-new.xulUT =[SDDUx &findAsYouTypeTip.label; PK !-\ZZ+content/communicator/pref/pref-download.xulUT r=[SDDUx browser.downloadmanager.behavior PK D-0?ll&content/communicator/pref/pref-help.jsUT @[SDDUx// these are keys for resolving the preferences dialog subframe // in terms of the context-sensitive help that should be loaded // from the help button. The "mail_prefs_display" things given // here represent (for the help window itself) the help content. var fm = { "chrome://communicator/content/pref/pref-appearance.xul": "appearance_pref", "chrome://communicator/content/pref/pref-fonts.xul": "appearance_pref_fonts", "chrome://communicator/content/pref/pref-colors.xul": "appearance_pref_colors", "chrome://communicator/content/pref/pref-themes.xul": "appearance_pref_themes", "chrome://content-packs/content/pref-contentpacks.xul": "appearance_pref_content_packs", "chrome://communicator/content/pref/pref-navigator.xul": "navigator_pref_navigator", "chrome://communicator/content/pref/pref-history.xul": "navigator_pref_history", "chrome://communicator/content/pref/pref-languages.xul": "navigator_pref_languages", "chrome://communicator/content/pref/pref-applications.xul": "navigator_pref_helper_applications", "chrome://communicator/content/pref/pref-smart_browsing.xul": "navigator_pref_smart_browsing", "chrome://communicator/content/pref/pref-search.xul": "navigator_pref_internet_searching", "chrome://communicator/content/pref/pref-scripts.xul": "advanced_pref_scripts", "chrome://messenger/content/pref-mailnews.xul": "mail_prefs_general", "chrome://messenger/content/pref-windows.xul": "mail_prefs_windows", "chrome://messenger/content/pref-viewing_messages.xul": "mail_prefs_display", "chrome://messenger/content/pref-notifications.xul": "mail_prefs_notifications", "chrome://messenger/content/messengercompose/pref-composing_messages.xul": "mail_prefs_messages", "chrome://messenger/content/messengercompose/pref-formatting.xul": "mail_prefs_formatting", "chrome://messenger/content/addressbook/pref-addressing.xul": "nav_view", "chrome://messenger/content/pref-labels.xul": "mail-prefs-labels", "chrome://messenger/content/pref-receipts.xul": "mail-prefs-receipts", "chrome://editor/content/pref-composer.xul": "composer_prefs_general", "chrome://editor/content/pref-editing.xul": "composer_prefs_newpage", "chrome://editor/content/pref-toolbars.xul": "composer_prefs_toolbars", "chrome://messenger/content/pref-mailnews.xul": "mail_prefs_general", "chrome://messenger/content/pref-viewing_messages.xul": "mail_prefs_display", "chrome://messenger/content/messengercompose/pref-composing_messages.xul": "mail_prefs_messages", "chrome://messenger/content/messengercompose/pref-formatting.xul": "mail_prefs_formatting", "chrome://messenger/content/addressbook/pref-addressing.xul": "mail_prefs_addressing", "chrome://messenger/content/pref-offline.xul": "mail_prefs_offline", "chrome://communicator/content/pref/pref-security.xul": "sec_gen", "chrome://cookie/content/pref-cookies.xul": "cookies_prefs", "chrome://cookie/content/pref-images.xul": "images_prefs", "chrome://cookie/content/pref-popups.xul": "pop_up_blocking", "chrome://wallet/content/pref-wallet.xul": "forms_prefs", "chrome://pippki/content/pref-masterpass.xul": "passwords_master", "chrome://wallet/content/pref-passwords.xul": "passwords_prefs", "chrome://pippki/content/pref-ssl.xul": "ssl_prefs", "chrome://pippki/content/pref-certs.xul": "certs_prefs", "chrome://pippki/content/pref-validation.xul": "validation_prefs", "chrome://communicator/content/pref/pref-advanced.xul": "advanced_pref_advanced", "chrome://communicator/content/pref/pref-cache.xul": "advanced_pref_cache", "chrome://communicator/content/pref/pref-debug.xul": "debug", "chrome://communicator/content/pref/pref-debug1.xul": "debug_event", "chrome://communicator/content/pref/pref-debug2.xul": "debug_network", "chrome://communicator/content/pref/pref-http.xul": "advanced_http_networking", "chrome://communicator/content/pref/pref-inspector.xul": "inspector", "chrome://communicator/content/pref/pref-download.xul": "navigator_pref_downloads", "chrome://communicator/content/pref/pref-mousewheel.xul": "advanced_pref_mouse_wheel", "chrome://communicator/content/pref/pref-smartupdate.xul": "advanced_pref_installation", "chrome://communicator/content/pref/pref-tabs.xul": "navigator_pref_tabbed_browsing", "chrome://communicator/content/pref/pref-winhooks.xul": "advanced_pref_system", "chrome://communicator/content/pref/pref-proxies.xul": "advanced_pref_proxies", "chrome://communicator/content/pref/pref-keynav.xul": "advanced_pref_keyboard_nav" } function doHelpButton() { var subsrc = document.getElementById("panelFrame").getAttribute("src"); if ( fm[subsrc] ) { openHelp(fm[subsrc]); } else { openHelp('prefs'); } } PK c0C+RՇ)content/communicator/pref/pref-themes.xulUT ĵE@[SDDUx %themesDTD; %regionDTD; ]>
PK XW.4=(content/communicator/pref/pref-debug.xulUT Y>[SDDUx PK !-p; )content/communicator/pref/pref-debug1.xulUT r=[SDDUx PK !-Efd d )content/communicator/pref/pref-debug2.xulUT r=[SDDUx &dirFormat; PK Ad0NhNh'content/communicator/pref/pref-fonts.jsUT G@[SDDUx/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Netscape Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Gervase Markham * Tuukka Tolvanen * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the NPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ var fontEnumerator = null; var globalFonts = null; var fontTypes = ["serif", "sans-serif", "cursive", "fantasy", "monospace"]; var variableSize, fixedSize, minSize, languageList; var languageData = []; var currentLanguage; var gPrefutilitiesBundle; // manual data retrieval function for PrefWindow function GetFields() { var dataObject = parent.hPrefWindow.wsm.dataManager.pageData["chrome://communicator/content/pref/pref-fonts.xul"]; // store data for language independent widgets var lists = ["selectLangs", "proportionalFont"]; for( var i = 0; i < lists.length; i++ ) { if( !( "dataEls" in dataObject ) ) dataObject.dataEls = []; dataObject.dataEls[ lists[i] ] = []; dataObject.dataEls[ lists[i] ].value = document.getElementById( lists[i] ).value; } dataObject.defaultFont = document.getElementById( "proportionalFont" ).value; dataObject.fontDPI = document.getElementById( "screenResolution" ).value; dataObject.useDocFonts = document.getElementById( "browserUseDocumentFonts" ).checked ? 1 : 0; // save current state for language dependent fields and store saveState(); dataObject.languageData = languageData; return dataObject; } // manual data setting function for PrefWindow function SetFields( aDataObject ) { languageData = "languageData" in aDataObject ? aDataObject.languageData : languageData ; currentLanguage = "currentLanguage" in aDataObject ? aDataObject.currentLanguage : null ; var lists = ["selectLangs", "proportionalFont"]; var prefvalue; for( var i = 0; i < lists.length; i++ ) { var element = document.getElementById( lists[i] ); if( "dataEls" in aDataObject ) { element.selectedItem = element.getElementsByAttribute( "value", aDataObject.dataEls[ lists[i] ].value )[0]; } else { var prefstring = element.getAttribute( "prefstring" ); var preftype = element.getAttribute( "preftype" ); if( prefstring && preftype ) { prefvalue = parent.hPrefWindow.getPref( preftype, prefstring ); element.selectedItem = element.getElementsByAttribute( "value", prefvalue )[0]; } } } var screenResolution = document.getElementById( "screenResolution" ); var resolution; if( "fontDPI" in aDataObject ) { resolution = aDataObject.fontDPI; } else { prefvalue = parent.hPrefWindow.getPref( "int", "browser.display.screen_resolution" ); if( prefvalue != "!/!ERROR_UNDEFINED_PREF!/!" ) resolution = prefvalue; else resolution = 96; // If it all goes horribly wrong, fall back on 96. } setResolution( resolution ); if ( parent.hPrefWindow.getPrefIsLocked( "browser.display.screen_resolution" ) ) { screenResolution.disabled = true; } var useDocFontsCheckbox = document.getElementById( "browserUseDocumentFonts" ); if( "useDocFonts" in aDataObject && aDataObject.useDocFonts != undefined ) useDocFontsCheckbox.checked = aDataObject.useDocFonts ? true : false; else { prefvalue = parent.hPrefWindow.getPref( "int", "browser.display.use_document_fonts" ); if( prefvalue != "!/!ERROR_UNDEFINED_PREF!/!" ) useDocFontsCheckbox.checked = prefvalue ? true : false ; } if ( parent.hPrefWindow.getPrefIsLocked( "browser.display.use_document_fonts" ) ) { useDocFontsCheckbox.disabled = true; } } function Startup() { variableSize = document.getElementById( "sizeVar" ); fixedSize = document.getElementById( "sizeMono" ); minSize = document.getElementById( "minSize" ); languageList = document.getElementById( "selectLangs" ); gPrefutilitiesBundle = document.getElementById("bundle_prefutilities"); // register our ok callback function parent.hPrefWindow.registerOKCallbackFunc( saveFontPrefs ); // eventually we should detect the default language and select it by default selectLanguage(); // Allow user to ask the OS for a DPI if we are under X or OS/2 if ((navigator.appVersion.indexOf("X11") != -1) || (navigator.appVersion.indexOf("OS/2") != -1)) { document.getElementById( "systemResolution" ).removeAttribute( "hidden" ); } // Set up the labels for the standard issue resolutions var resolution; resolution = document.getElementById( "screenResolution" ); // Set an attribute on the selected resolution item so we can fall back on // it if an invalid selection is made (select "Other...", hit Cancel) resolution.selectedItem.setAttribute("current", "true"); var defaultResolution; var otherResolution; // On OS/2, 120 is the default system resolution. // 96 is valid, but used only for for 640x480. if (navigator.appVersion.indexOf("OS/2") != -1) { defaultResolution = "120"; otherResolution = "96"; document.getElementById( "arbitraryResolution" ).setAttribute( "hidden", "true" ); document.getElementById( "resolutionSeparator" ).setAttribute( "hidden", "true" ); } else { defaultResolution = "96"; otherResolution = "72"; } var dpi = resolution.getAttribute( "dpi" ); resolution = document.getElementById( "defaultResolution" ); resolution.setAttribute( "value", defaultResolution ); resolution.setAttribute( "label", dpi.replace(/\$val/, defaultResolution ) ); resolution = document.getElementById( "otherResolution" ); resolution.setAttribute( "value", otherResolution ); resolution.setAttribute( "label", dpi.replace(/\$val/, otherResolution ) ); // Get the pref and set up the dialog appropriately. Startup is called // after SetFields so we can't rely on that call to do the business. var prefvalue = parent.hPrefWindow.getPref( "int", "browser.display.screen_resolution" ); if( prefvalue != "!/!ERROR_UNDEFINED_PREF!/!" ) resolution = prefvalue; else resolution = 96; // If it all goes horribly wrong, fall back on 96. setResolution( resolution ); // This prefstring is a contrived pref whose sole purpose is to lock some // elements in this panel. The value of the pref is not used and does not matter. if ( parent.hPrefWindow.getPrefIsLocked( "browser.display.languageList" ) ) { disableAllFontElements(); } } function getFontEnumerator() { if (!fontEnumerator) { fontEnumerator = Components.classes["@mozilla.org/gfx/fontenumerator;1"] .createInstance() .QueryInterface(Components.interfaces.nsIFontEnumerator); } return fontEnumerator; } function listElement( aListID ) { this.listElement = document.getElementById( aListID ); } listElement.prototype = { clearList: function () { // remove the menupopup node child of the menulist. this.listElement.removeChild( this.listElement.firstChild ); }, appendFontNames: function ( aLanguage, aFontType ) { var i; var defaultFont = null; var count = { value: 0 }; var fonts = getFontEnumerator().EnumerateFonts( aLanguage, aFontType, count ); if (fonts.length > 0) { defaultFont = getFontEnumerator().getDefaultFont( aLanguage, aFontType ); } else { // if no specific fonts, relax 'aFontType' and try to get other // fonts for this language so that we can group them on top fonts = getFontEnumerator().EnumerateFonts( aLanguage, "", count ); if (fonts.length > 0) { defaultFont = getFontEnumerator().getDefaultFont( aLanguage, "" ); } } var itemNode = null; var separatorNode = null; var popupNode = document.createElement( "menupopup" ); if (fonts.length > 0) { // always put the default font at the front of the list if (defaultFont) { var label = gPrefutilitiesBundle .getString("labelDefaultFont") .replace(/%font_family%/, defaultFont); itemNode = document.createElement( "menuitem" ); itemNode.setAttribute( "label", label ); itemNode.setAttribute( "value", "" ); // special blank value popupNode.appendChild( itemNode ); separatorNode = document.createElement( "menuseparator" ); popupNode.appendChild( separatorNode ); } for (i = 0; i < fonts.length; i++) { itemNode = document.createElement( "menuitem" ); itemNode.setAttribute( "value", fonts[i] ); itemNode.setAttribute( "label", fonts[i] ); popupNode.appendChild( itemNode ); } } // get all the fonts to complete the font lists if (!globalFonts) { globalFonts = getFontEnumerator().EnumerateAllFonts( count ); } // since the lists are sorted, we can get unique entries by just walking // both lists linearly side-by-side, skipping those values already in // the popup list if (globalFonts.length > fonts.length) { var menuItem = separatorNode ? separatorNode.nextSibling : popupNode.firstChild; var menuValue = menuItem ? menuItem.getAttribute( "value" ) : null; separatorNode = document.createElement( "menuseparator" ); popupNode.appendChild( separatorNode ); for (i = 0; i < globalFonts.length; i++) { if (globalFonts[i] != menuValue) { itemNode = document.createElement( "menuitem" ); itemNode.setAttribute( "value", globalFonts[i] ); itemNode.setAttribute( "label", globalFonts[i] ); popupNode.appendChild( itemNode ); } else { menuItem = menuItem.nextSibling; menuValue = menuItem ? menuItem.getAttribute( "value" ) : null; } } } this.listElement.appendChild( popupNode ); return popupNode.firstChild; } }; function lazyAppendFontNames( i ) { // schedule the build of the next font list if (i+1 < fontTypes.length) { window.setTimeout(lazyAppendFontNames, 100, i+1); } // now build and populate the fonts for the requested font type var defaultItem = null; var selectElement = new listElement( fontTypes[i] ); selectElement.clearList(); try { defaultItem = selectElement.appendFontNames( languageList.value, fontTypes[i] ); } catch(e) { dump("pref-fonts.js: " + e + "\nFailed to build the font list for " + fontTypes[i] + "\n"); return; } // now set the selected font item for the drop down list if (!defaultItem) return; // nothing to select, so no need to bother // the item returned by default is our last resort fall-back var selectedItem = defaultItem; if( languageList.value in languageData ) { // data exists for this language, pre-select items based on this information var dataVal = languageData[languageList.value].types[fontTypes[i]]; if (!dataVal.length) // special blank means the default { selectedItem = defaultItem; } else { var dataEls = selectElement.listElement.getElementsByAttribute( "value", dataVal ); selectedItem = dataEls.length ? dataEls[0] : defaultItem; } } else { try { var fontPrefString = "font.name." + fontTypes[i] + "." + languageList.value; var selectVal = parent.hPrefWindow.pref.getComplexValue( fontPrefString, Components.interfaces.nsISupportsString ).data; var dataEls = selectElement.listElement.getElementsByAttribute( "value", selectVal ); // we need to honor name-list in case name is unavailable if (!dataEls.length) { var fontListPrefString = "font.name-list." + fontTypes[i] + "." + languageList.value; var nameList = parent.hPrefWindow.pref.getComplexValue( fontListPrefString, Components.interfaces.nsISupportsString ).data; var fontNames = nameList.split(","); var stripWhitespace = /^\s*(.*)\s*$/; for (j = 0; j < fontNames.length; j++) { selectVal = fontNames[j].replace(stripWhitespace, "$1"); dataEls = selectElement.listElement.getElementsByAttribute("value", selectVal); if (dataEls.length) break; // exit loop if we find one } } selectedItem = dataEls.length ? dataEls[0] : defaultItem; } catch(e) { selectedItem = defaultItem; } } selectElement.listElement.selectedItem = selectedItem; selectElement.listElement.removeAttribute( "disabled" ); } function saveFontPrefs() { // saving font prefs var dataObject = parent.hPrefWindow.wsm.dataManager.pageData["chrome://communicator/content/pref/pref-fonts.xul"]; var pref = parent.hPrefWindow.pref; for( var language in dataObject.languageData ) { for( var type in dataObject.languageData[language].types ) { var fontPrefString = "font.name." + type + "." + language; var currValue = ""; try { currValue = pref.getComplexValue( fontPrefString, Components.interfaces.nsISupportsString ).data; } catch(e) { } var dataValue = dataObject.languageData[language].types[type]; if( currValue != dataValue ) { if (dataValue) { parent.hPrefWindow.setPref( "string", fontPrefString, dataValue ); } else { // A font name can't be blank. The special blank means the default. // Unset the pref entirely, letting Gfx to decide. GfxXft will use what // Xft says, whereas GfxWin and others will use the built-in settings // that are shipped for font.name and font.name-list. try { // ClearUserPref throws an exception... pref.clearUserPref( fontPrefString ); } catch(e) { } } } } var variableSizePref = "font.size.variable." + language; var fixedSizePref = "font.size.fixed." + language; var minSizePref = "font.minimum-size." + language; var currVariableSize = 12, currFixedSize = 12, minSizeVal = 0; try { currVariableSize = pref.getIntPref( variableSizePref ); currFixedSize = pref.getIntPref( fixedSizePref ); minSizeVal = pref.getIntPref( minSizePref ); } catch(e) { } if( currVariableSize != dataObject.languageData[language].variableSize ) pref.setIntPref( variableSizePref, dataObject.languageData[language].variableSize ); if( currFixedSize != dataObject.languageData[language].fixedSize ) pref.setIntPref( fixedSizePref, dataObject.languageData[language].fixedSize ); if ( minSizeVal != dataObject.languageData[language].minSize ) { pref.setIntPref ( minSizePref, dataObject.languageData[language].minSize ); } } // font scaling var fontDPI = parseInt( dataObject.fontDPI ); var documentFonts = dataObject.useDocFonts; var defaultFont = dataObject.defaultFont; try { var currDPI = pref.getIntPref( "browser.display.screen_resolution" ); var currFonts = pref.getIntPref( "browser.display.use_document_fonts" ); var currDefault = pref.getComplexValue( "font.default", Components.interfaces.nsISupportsString ).data; } catch(e) { } if( currDPI != fontDPI ) pref.setIntPref( "browser.display.screen_resolution", fontDPI ); if( currFonts != documentFonts ) pref.setIntPref( "browser.display.use_document_fonts", documentFonts ); if( currDefault != defaultFont ) { parent.hPrefWindow.setPref( "string", "font.default", defaultFont ); } } function saveState() { for( var i = 0; i < fontTypes.length; i++ ) { // preliminary initialisation if( currentLanguage && !( currentLanguage in languageData ) ) languageData[currentLanguage] = []; if( currentLanguage && !( "types" in languageData[currentLanguage] ) ) languageData[currentLanguage].types = []; // save data for the previous language if( currentLanguage && currentLanguage in languageData && "types" in languageData[currentLanguage] ) languageData[currentLanguage].types[fontTypes[i]] = document.getElementById( fontTypes[i] ).value; } if( currentLanguage && currentLanguage in languageData && "types" in languageData[currentLanguage] ) { languageData[currentLanguage].variableSize = parseInt( variableSize.value ); languageData[currentLanguage].fixedSize = parseInt( fixedSize.value ); languageData[currentLanguage].minSize = parseInt( minSize.value ); } } // Selects size (or the nearest entry that exists in the list) // in the menulist minSize function minSizeSelect(size) { var items = minSize.getElementsByAttribute( "value", size ); if (items.length > 0) minSize.selectedItem = items[0]; else if (size < 6) minSizeSelect(6); else if (size > 24) minSizeSelect(24); else minSizeSelect(size - 1); } function selectLanguage() { // save current state saveState(); if( !currentLanguage ) currentLanguage = languageList.value; else if( currentLanguage == languageList.value ) return; // same as before, nothing changed // lazily populate the successive font lists at 100ms intervals. // (Note: the third parameter to setTimeout() is going to be // passed as argument to the callback function.) window.setTimeout(lazyAppendFontNames, 100, 0); // in the meantime, disable the menu lists for( var i = 0; i < fontTypes.length; i++ ) { var listElement = document.getElementById( fontTypes[i] ); listElement.setAttribute( "value", "" ); listElement.setAttribute( "label", "" ); listElement.setAttribute( "disabled", "true" ); } // and set the font sizes try { var variableSizePref = "font.size.variable." + languageList.value; var sizeVarVal = parent.hPrefWindow.pref.getIntPref( variableSizePref ); variableSize.selectedItem = variableSize.getElementsByAttribute( "value", sizeVarVal )[0]; var fixedSizePref = "font.size.fixed." + languageList.value; var sizeFixedVal = parent.hPrefWindow.pref.getIntPref( fixedSizePref ); fixedSize.selectedItem = fixedSize.getElementsByAttribute( "value", sizeFixedVal )[0]; } catch(e) { } // font size lists can simply default to the first entry var minSizeVal = 0; try { var minSizePref = "font.minimum-size." + languageList.value; minSizeVal = parent.hPrefWindow.pref.getIntPref( minSizePref ); } catch(e) { } minSizeSelect( minSizeVal ); currentLanguage = languageList.value; } function changeScreenResolution() { var screenResolution = document.getElementById("screenResolution"); var userResolution = document.getElementById("userResolution"); var previousSelection = screenResolution.getElementsByAttribute("current", "true")[0]; if (screenResolution.value == "other") { // If the user selects "Other..." we bring up the calibrate screen dialog var rv = { newdpi : 0 }; var calscreen = window.openDialog("chrome://communicator/content/pref/pref-calibrate-screen.xul", "_blank", "modal,chrome,centerscreen,resizable=no,titlebar", rv); if (rv.newdpi != -1) { // They have entered values, and we have a DPI value back var dpi = screenResolution.getAttribute( "dpi" ); setResolution ( rv.newdpi ); previousSelection.removeAttribute("current"); screenResolution.selectedItem.setAttribute("current", "true"); } else { // They've cancelled. We can't leave "Other..." selected, so... // we re-select the previously selected item. screenResolution.selectedItem = previousSelection; } } else if (!(screenResolution.value == userResolution.value)) { // User has selected one of the hard-coded resolutions userResolution.setAttribute("hidden", "true"); previousSelection.removeAttribute("current"); screenResolution.selectedItem.setAttribute("current", "true"); } } function setResolution( resolution ) { // Given a number, if it's equal to a hard-coded resolution we use that, // otherwise we set the userResolution field. var screenResolution = document.getElementById( "screenResolution" ); var userResolution = document.getElementById( "userResolution" ); var items = screenResolution.getElementsByAttribute( "value", resolution ); if (items.length) { // If it's one of the hard-coded values, we'll select it directly screenResolution.selectedItem = items[0]; userResolution.setAttribute( "hidden", "true" ); } else { // Otherwise we need to set up the userResolution field var dpi = screenResolution.getAttribute( "dpi" ); userResolution.setAttribute( "value", resolution ); userResolution.setAttribute( "label", dpi.replace(/\$val/, resolution) ); userResolution.removeAttribute( "hidden" ); screenResolution.selectedItem = userResolution; } } // "Calibrate screen" dialog code function Init() { sizeToContent(); doSetOKCancel(onOK, onCancel); document.getElementById("horizSize").focus(); } function onOK() { // Get value from the dialog to work out dpi var horizSize = parseFloat(document.getElementById("horizSize").value); var units = document.getElementById("units").value; if (!horizSize || horizSize < 0) { // We can't calculate anything without a proper value window.arguments[0].newdpi = -1; return true; } // Convert centimetres to inches. // The magic number is allowed because it's a fundamental constant :-) if (units === "centimetres") { horizSize /= 2.54; } // These shouldn't change, but you can't be too careful. var horizBarLengthPx = document.getElementById("horizRuler").boxObject.width; var horizDPI = parseInt(horizBarLengthPx) / horizSize; // Average the two . window.arguments[0].newdpi = Math.round(horizDPI); return true; } function onCancel() { // We return -1 to show that no value has been given. window.arguments[0].newdpi = -1; return true; } // disable font items, but not the browserUseDocumentFonts checkbox nor the resolution // menulist function disableAllFontElements() { var doc_ids = [ "selectLangs", "proportionalFont", "sizeVar", "serif", "sans-serif", "cursive", "fantasy", "monospace", "sizeMono", "minSize" ]; for (i=0; i PK XC0#   3content/communicator/pref/pref-calibrate-screen.xulUT A @[SDDUx &historyPages.label;