mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Carpool checkin, r=brade. Lots of editor UI work, including new Advanced Edit dialog by Ben Goodger. Fixed style sheet loading leaks and implemented override style sheets for editor behavior, which be unloaded for edit mode vs. browser preview mode
This commit is contained in:
parent
f0fdbc6804
commit
d20641b38c
@ -25,7 +25,6 @@
|
||||
#include "pratom.h"
|
||||
#include "prprf.h"
|
||||
#include "nsIComponentManager.h"
|
||||
//#include "nsAppCores.h"
|
||||
#include "nsAppCoresCIDs.h"
|
||||
#include "nsIDOMAppCoresManager.h"
|
||||
|
||||
@ -36,6 +35,12 @@
|
||||
#include "nsIDiskDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsICSSLoader.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
#include "nsIHTMLContentContainer.h"
|
||||
#include "nsIStyleSet.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNeckoUtil.h"
|
||||
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIWebShell.h"
|
||||
@ -63,7 +68,6 @@
|
||||
#include "nsIFindComponent.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsICommonDialogs.h"
|
||||
//#include "nsIDialogParamBlock.h"
|
||||
|
||||
///////////////////////////////////////
|
||||
// Editor Includes
|
||||
@ -149,6 +153,7 @@ nsEditorShell::nsEditorShell()
|
||||
, mSuggestedWordIndex(0)
|
||||
, mDictionaryIndex(0)
|
||||
, mStringBundle(0)
|
||||
, mEditModeStyleSheet(0)
|
||||
{
|
||||
#ifdef APP_DEBUG
|
||||
printf("Created nsEditorShell\n");
|
||||
@ -596,13 +601,122 @@ NS_IMETHODIMP nsEditorShell::ApplyStyleSheet(const PRUnichar *url)
|
||||
|
||||
nsAutoString aURL(url);
|
||||
|
||||
nsCOMPtr<nsIEditorStyleSheets> styleSheetFoobar = do_QueryInterface(mEditor);
|
||||
if (styleSheetFoobar)
|
||||
result = styleSheetFoobar->ApplyStyleSheet(aURL);
|
||||
nsCOMPtr<nsIEditorStyleSheets> styleSheets = do_QueryInterface(mEditor);
|
||||
if (styleSheets)
|
||||
result = styleSheets->ApplyStyleSheet(aURL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Note: This is not undoable action (on purpose!)
|
||||
NS_IMETHODIMP nsEditorShell::SetDisplayMode(PRInt32 aDisplayMode)
|
||||
{
|
||||
// We are already in EditMode
|
||||
if (aDisplayMode == eDisplayModeEdit && mEditModeStyleSheet)
|
||||
return NS_OK;
|
||||
|
||||
if (!mContentAreaWebShell)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = dont_AddRef(GetPresShellFor(mContentAreaWebShell));
|
||||
if (!presShell)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
nsresult rv = presShell->GetDocument(getter_AddRefs(document));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if(!document)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIStyleSet> styleSet;
|
||||
rv = presShell->GetStyleSet(getter_AddRefs(styleSet));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if (!styleSet)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIStyleSheet> styleSheet;
|
||||
if (aDisplayMode == 0)
|
||||
{
|
||||
// Create and load the style sheet for editor content
|
||||
nsAutoString styleURL("chrome://editor/content/EditorContent.css");
|
||||
|
||||
nsCOMPtr<nsIURI>uaURL;
|
||||
#ifndef NECKO
|
||||
rv = NS_NewURL(getter_AddRefs(uaURL), styleURL);
|
||||
#else
|
||||
rv = NS_NewURI(getter_AddRefs(uaURL), styleURL);
|
||||
#endif // NECKO
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr<nsIHTMLContentContainer> container = do_QueryInterface(document);
|
||||
if (!container)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsICSSLoader> cssLoader;
|
||||
rv = container->GetCSSLoader(*getter_AddRefs(cssLoader));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if (!cssLoader)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsICSSStyleSheet>cssStyleSheet;
|
||||
PRBool complete;
|
||||
|
||||
// We use null for the callback and data pointer because
|
||||
// we MUST ONLY load synchronous local files (no @import)
|
||||
rv = cssLoader->LoadAgentSheet(uaURL, *getter_AddRefs(cssStyleSheet), complete, nsnull, nsnull);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
// Synchronous loads should ALWAYS return completed
|
||||
if (!complete || !cssStyleSheet)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Don't need to QI (subclass)
|
||||
styleSheet = cssStyleSheet;
|
||||
if (!styleSheet)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (aDisplayMode >= 1)
|
||||
{
|
||||
if (!mEditModeStyleSheet)
|
||||
{
|
||||
// The edit mode sheet was not previously loaded
|
||||
return NS_OK;
|
||||
}
|
||||
styleSheet = mEditModeStyleSheet;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
switch (aDisplayMode)
|
||||
{
|
||||
case eDisplayModeEdit:
|
||||
styleSet->AppendOverrideStyleSheet(styleSheet);
|
||||
mEditModeStyleSheet = styleSheet;
|
||||
break;
|
||||
case eDisplayModeBrowserPreview:
|
||||
styleSet->RemoveOverrideStyleSheet(mEditModeStyleSheet);
|
||||
mEditModeStyleSheet = 0;
|
||||
break;
|
||||
// Add more modes here, e.g., browser mode with JavaScript turned on?
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// This notifies document observers to rebuild all frames
|
||||
// (this doesn't affect style sheet because it is not a doc sheet)
|
||||
document->SetStyleSheetDisabledState(styleSheet, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsEditorShell::SetBodyAttribute(const PRUnichar *attr, const PRUnichar *value)
|
||||
{
|
||||
nsresult result = NS_NOINTERFACE;
|
||||
@ -819,10 +933,17 @@ nsEditorShell::PrepareDocumentForEditing(nsIURI *aUrl)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//TODO: TEMPORARY -- THIS IS NOT THE RIGHT THING TO DO!
|
||||
nsAutoString styleURL("chrome://editor/content/EditorContent.css");
|
||||
ApplyStyleSheet(styleURL.GetUnicode());
|
||||
nsCOMPtr<nsIEditorStyleSheets> styleSheets = do_QueryInterface(mEditor);
|
||||
if (!styleSheets)
|
||||
return NS_NOINTERFACE;
|
||||
|
||||
// Load style sheet with settings that should never
|
||||
// change, even in "Browser" mode
|
||||
styleSheets->ApplyOverrideStyleSheet("chrome://editor/content/EditorOverride.css");
|
||||
|
||||
// Load the edit mode override style sheet
|
||||
// This will be remove for "Browser" mode
|
||||
SetDisplayMode(eDisplayModeEdit);
|
||||
|
||||
// Force initial focus to the content window -- HOW?
|
||||
// mWebShellWin->SetFocus();
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "nsInterfaceState.h"
|
||||
#include "nsIHTMLEditor.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
|
||||
class nsIBrowserWindow;
|
||||
class nsIWebShell;
|
||||
@ -56,7 +57,7 @@ class nsIOutputStream;
|
||||
class nsISupportsArray;
|
||||
class nsIStringBundleService;
|
||||
class nsIStringBundle;
|
||||
|
||||
class nsIStyleSheet;
|
||||
|
||||
#define NS_EDITORSHELL_CID \
|
||||
{ /* {} */ \
|
||||
@ -207,6 +208,9 @@ class nsEditorShell : public nsIEditorShell,
|
||||
private:
|
||||
// Pointer to localized strings used for UI
|
||||
nsCOMPtr<nsIStringBundle> mStringBundle;
|
||||
// Pointer to the EditorContent style sheet we load/unload
|
||||
// for "Edit Mode"/"Browser mode" display
|
||||
nsCOMPtr<nsIStyleSheet> mEditModeStyleSheet;
|
||||
};
|
||||
|
||||
#endif // nsEditorShell_h___
|
||||
|
@ -2279,9 +2279,11 @@ nsHTMLEditor::GetSelectedElement(const nsString& aTagName, nsIDOMElement** aRetu
|
||||
{
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
res = selection->GetEnumerator(getter_AddRefs(enumerator));
|
||||
// XXX: ERROR_HANDLING unclear what to do here, should an error just be returned if enumerator is null or res failed?
|
||||
if (NS_SUCCEEDED(res) && enumerator)
|
||||
if (NS_SUCCEEDED(res))
|
||||
{
|
||||
if(!enumerator)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
enumerator->First();
|
||||
nsCOMPtr<nsISupports> currentItem;
|
||||
res = enumerator->CurrentItem(getter_AddRefs(currentItem));
|
||||
@ -2716,18 +2718,29 @@ nsHTMLEditor::RemoveStyleSheet(nsICSSStyleSheet* aSheet)
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::ApplyStyleSheet(const nsString& aURL)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::ApplyOverrideStyleSheet(const nsString& aURL)
|
||||
{
|
||||
// XXX: Note that this is not an undo-able action yet!
|
||||
return ApplyDocumentOrOverrideStyleSheet(aURL, PR_TRUE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::ApplyStyleSheet(const nsString& aURL)
|
||||
{
|
||||
return ApplyDocumentOrOverrideStyleSheet(aURL, PR_TRUE);
|
||||
}
|
||||
|
||||
//Note: Loading a document style sheet is undoable, loading an override sheet is not
|
||||
nsresult
|
||||
nsHTMLEditor::ApplyDocumentOrOverrideStyleSheet(const nsString& aURL, PRBool aOverride)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsIURI* uaURL = 0;
|
||||
nsCOMPtr<nsIURI> uaURL;
|
||||
|
||||
#ifndef NECKO
|
||||
rv = NS_NewURL(&uaURL, aURL);
|
||||
rv = NS_NewURL(getter_AddRefs(uaURL), aURL);
|
||||
#else
|
||||
rv = NS_NewURI(&uaURL, aURL);
|
||||
rv = NS_NewURI(getter_AddRefs(uaURL), aURL);
|
||||
#endif // NECKO
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
@ -2739,57 +2752,77 @@ NS_IMETHODIMP nsHTMLEditor::ApplyStyleSheet(const nsString& aURL)
|
||||
rv = ps->GetDocument(getter_AddRefs(document));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (document) {
|
||||
nsCOMPtr<nsIHTMLContentContainer> container = do_QueryInterface(document);
|
||||
if (!document)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (container) {
|
||||
nsICSSLoader *cssLoader = 0;
|
||||
nsICSSStyleSheet *cssStyleSheet = 0;
|
||||
nsCOMPtr<nsIHTMLContentContainer> container = do_QueryInterface(document);
|
||||
if (!container)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsICSSLoader> cssLoader;
|
||||
nsCOMPtr<nsICSSStyleSheet> cssStyleSheet;
|
||||
|
||||
rv = container->GetCSSLoader(cssLoader);
|
||||
rv = container->GetCSSLoader(*getter_AddRefs(cssLoader));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRBool complete;
|
||||
|
||||
if (!cssLoader)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (aOverride) {
|
||||
// We use null for the callback and data pointer because
|
||||
// we MUST ONLY load synchronous local files (no @import)
|
||||
rv = cssLoader->LoadAgentSheet(uaURL, *getter_AddRefs(cssStyleSheet), complete,
|
||||
nsnull, nsnull);
|
||||
|
||||
// Synchronous loads should ALWAYS return completed
|
||||
if (!complete || !cssStyleSheet)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Don't need to QI (subclass)
|
||||
nsCOMPtr<nsIStyleSheet> styleSheet = cssStyleSheet;
|
||||
nsCOMPtr<nsIStyleSet> styleSet;
|
||||
rv = ps->GetStyleSet(getter_AddRefs(styleSet));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (cssLoader) {
|
||||
PRBool complete;
|
||||
if (!styleSet)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
rv = cssLoader->LoadAgentSheet(uaURL, cssStyleSheet, complete,
|
||||
ApplyStyleSheetToPresShellDocument,
|
||||
this);
|
||||
// Add the override style sheet
|
||||
// (This checks if already exists
|
||||
// If yes, it and reads it does)
|
||||
styleSet->AppendOverrideStyleSheet(styleSheet);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (complete) {
|
||||
if (cssStyleSheet) {
|
||||
ApplyStyleSheetToPresShellDocument(cssStyleSheet,
|
||||
this);
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
//
|
||||
// If not complete, we will be notified later
|
||||
// with a call to AddStyleSheetToEditorDocument().
|
||||
//
|
||||
}
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
// This notifies document observers to rebuild all frames
|
||||
// (this doesn't affect style sheet because it is not a doc sheet)
|
||||
document->SetStyleSheetDisabledState(styleSheet, PR_FALSE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
rv = cssLoader->LoadAgentSheet(uaURL, *getter_AddRefs(cssStyleSheet), complete,
|
||||
ApplyStyleSheetToPresShellDocument,
|
||||
this);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (complete) {
|
||||
if (cssStyleSheet) {
|
||||
ApplyStyleSheetToPresShellDocument(cssStyleSheet,this);
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
//
|
||||
// If not complete, we will be notified later
|
||||
// with a call to ApplyStyleSheetToPresShellDocument().
|
||||
//
|
||||
}
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_RELEASE(uaURL);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma mark -
|
||||
#pragma mark --- nsIEditorMailSupport methods ---
|
||||
@ -3526,7 +3559,32 @@ NS_IMETHODIMP nsHTMLEditor::OutputToStream(nsIOutputStream* aOutputStream,
|
||||
|
||||
return encoder->EncodeToStream(aOutputStream);
|
||||
}
|
||||
#if 0
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetTextNearNode(nsIDOMNode *aNode, aNode, PRInt32 aMaxChars, nsString& aOutputString)
|
||||
{
|
||||
if (!aNode)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Create a temporary selection object and
|
||||
// based on the suppled
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
nsresult rv = NS_NewRange(getter_AddRsfs(range))
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if (!range)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
range.SetStart(aNode,0);
|
||||
range.SetEnd(aNode,
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && selection)
|
||||
encoder->SetSelection(selection);
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::DebugUnitTests(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed)
|
||||
@ -3547,7 +3605,6 @@ nsHTMLEditor::DebugUnitTests(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma mark -
|
||||
#pragma mark --- nsIEditorIMESupport overrides ---
|
||||
@ -3606,7 +3663,6 @@ nsHTMLEditor::ReplaceStyleSheet(nsICSSStyleSheet *aNewSheet)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* static callback */
|
||||
void nsHTMLEditor::ApplyStyleSheetToPresShellDocument(nsICSSStyleSheet* aSheet, void *aData)
|
||||
{
|
||||
@ -3617,7 +3673,6 @@ void nsHTMLEditor::ApplyStyleSheetToPresShellDocument(nsICSSStyleSheet* aSheet,
|
||||
{
|
||||
rv = editor->ReplaceStyleSheet(aSheet);
|
||||
}
|
||||
|
||||
// XXX: we lose the return value here. Set a flag in the editor?
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "nsEditor.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsICSSLoader.h"
|
||||
#include "nsITableLayout.h"
|
||||
|
||||
#include "TypeInState.h"
|
||||
@ -120,6 +121,11 @@ public:
|
||||
/* ------------ nsIEditorStyleSheets methods -------------- */
|
||||
|
||||
NS_IMETHOD ApplyStyleSheet(const nsString& aURL);
|
||||
NS_IMETHOD ApplyOverrideStyleSheet(const nsString& aURL);
|
||||
/* Above 2 methods call this with appropriate aOverride value
|
||||
* Not exposed to IDL interface
|
||||
*/
|
||||
nsresult ApplyDocumentOrOverrideStyleSheet(const nsString& aURL, PRBool aOverride);
|
||||
NS_IMETHOD AddStyleSheet(nsICSSStyleSheet* aSheet);
|
||||
NS_IMETHOD RemoveStyleSheet(nsICSSStyleSheet* aSheet);
|
||||
|
||||
@ -172,8 +178,6 @@ public:
|
||||
NS_IMETHOD SetBackgroundColor(const nsString& aColor);
|
||||
NS_IMETHOD SetBodyAttribute(const nsString& aAttr, const nsString& aValue);
|
||||
|
||||
|
||||
|
||||
/* ------------ Overrides of nsEditor interface methods -------------- */
|
||||
|
||||
/** prepare the editor for use */
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "pratom.h"
|
||||
#include "prprf.h"
|
||||
#include "nsIComponentManager.h"
|
||||
//#include "nsAppCores.h"
|
||||
#include "nsAppCoresCIDs.h"
|
||||
#include "nsIDOMAppCoresManager.h"
|
||||
|
||||
@ -36,6 +35,12 @@
|
||||
#include "nsIDiskDocument.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsICSSLoader.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
#include "nsIHTMLContentContainer.h"
|
||||
#include "nsIStyleSet.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNeckoUtil.h"
|
||||
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIWebShell.h"
|
||||
@ -63,7 +68,6 @@
|
||||
#include "nsIFindComponent.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsICommonDialogs.h"
|
||||
//#include "nsIDialogParamBlock.h"
|
||||
|
||||
///////////////////////////////////////
|
||||
// Editor Includes
|
||||
@ -149,6 +153,7 @@ nsEditorShell::nsEditorShell()
|
||||
, mSuggestedWordIndex(0)
|
||||
, mDictionaryIndex(0)
|
||||
, mStringBundle(0)
|
||||
, mEditModeStyleSheet(0)
|
||||
{
|
||||
#ifdef APP_DEBUG
|
||||
printf("Created nsEditorShell\n");
|
||||
@ -596,13 +601,122 @@ NS_IMETHODIMP nsEditorShell::ApplyStyleSheet(const PRUnichar *url)
|
||||
|
||||
nsAutoString aURL(url);
|
||||
|
||||
nsCOMPtr<nsIEditorStyleSheets> styleSheetFoobar = do_QueryInterface(mEditor);
|
||||
if (styleSheetFoobar)
|
||||
result = styleSheetFoobar->ApplyStyleSheet(aURL);
|
||||
nsCOMPtr<nsIEditorStyleSheets> styleSheets = do_QueryInterface(mEditor);
|
||||
if (styleSheets)
|
||||
result = styleSheets->ApplyStyleSheet(aURL);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Note: This is not undoable action (on purpose!)
|
||||
NS_IMETHODIMP nsEditorShell::SetDisplayMode(PRInt32 aDisplayMode)
|
||||
{
|
||||
// We are already in EditMode
|
||||
if (aDisplayMode == eDisplayModeEdit && mEditModeStyleSheet)
|
||||
return NS_OK;
|
||||
|
||||
if (!mContentAreaWebShell)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = dont_AddRef(GetPresShellFor(mContentAreaWebShell));
|
||||
if (!presShell)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
nsresult rv = presShell->GetDocument(getter_AddRefs(document));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if(!document)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIStyleSet> styleSet;
|
||||
rv = presShell->GetStyleSet(getter_AddRefs(styleSet));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if (!styleSet)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIStyleSheet> styleSheet;
|
||||
if (aDisplayMode == 0)
|
||||
{
|
||||
// Create and load the style sheet for editor content
|
||||
nsAutoString styleURL("chrome://editor/content/EditorContent.css");
|
||||
|
||||
nsCOMPtr<nsIURI>uaURL;
|
||||
#ifndef NECKO
|
||||
rv = NS_NewURL(getter_AddRefs(uaURL), styleURL);
|
||||
#else
|
||||
rv = NS_NewURI(getter_AddRefs(uaURL), styleURL);
|
||||
#endif // NECKO
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr<nsIHTMLContentContainer> container = do_QueryInterface(document);
|
||||
if (!container)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsICSSLoader> cssLoader;
|
||||
rv = container->GetCSSLoader(*getter_AddRefs(cssLoader));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if (!cssLoader)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsICSSStyleSheet>cssStyleSheet;
|
||||
PRBool complete;
|
||||
|
||||
// We use null for the callback and data pointer because
|
||||
// we MUST ONLY load synchronous local files (no @import)
|
||||
rv = cssLoader->LoadAgentSheet(uaURL, *getter_AddRefs(cssStyleSheet), complete, nsnull, nsnull);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
// Synchronous loads should ALWAYS return completed
|
||||
if (!complete || !cssStyleSheet)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Don't need to QI (subclass)
|
||||
styleSheet = cssStyleSheet;
|
||||
if (!styleSheet)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (aDisplayMode >= 1)
|
||||
{
|
||||
if (!mEditModeStyleSheet)
|
||||
{
|
||||
// The edit mode sheet was not previously loaded
|
||||
return NS_OK;
|
||||
}
|
||||
styleSheet = mEditModeStyleSheet;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
switch (aDisplayMode)
|
||||
{
|
||||
case eDisplayModeEdit:
|
||||
styleSet->AppendOverrideStyleSheet(styleSheet);
|
||||
mEditModeStyleSheet = styleSheet;
|
||||
break;
|
||||
case eDisplayModeBrowserPreview:
|
||||
styleSet->RemoveOverrideStyleSheet(mEditModeStyleSheet);
|
||||
mEditModeStyleSheet = 0;
|
||||
break;
|
||||
// Add more modes here, e.g., browser mode with JavaScript turned on?
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// This notifies document observers to rebuild all frames
|
||||
// (this doesn't affect style sheet because it is not a doc sheet)
|
||||
document->SetStyleSheetDisabledState(styleSheet, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsEditorShell::SetBodyAttribute(const PRUnichar *attr, const PRUnichar *value)
|
||||
{
|
||||
nsresult result = NS_NOINTERFACE;
|
||||
@ -819,10 +933,17 @@ nsEditorShell::PrepareDocumentForEditing(nsIURI *aUrl)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//TODO: TEMPORARY -- THIS IS NOT THE RIGHT THING TO DO!
|
||||
nsAutoString styleURL("chrome://editor/content/EditorContent.css");
|
||||
ApplyStyleSheet(styleURL.GetUnicode());
|
||||
nsCOMPtr<nsIEditorStyleSheets> styleSheets = do_QueryInterface(mEditor);
|
||||
if (!styleSheets)
|
||||
return NS_NOINTERFACE;
|
||||
|
||||
// Load style sheet with settings that should never
|
||||
// change, even in "Browser" mode
|
||||
styleSheets->ApplyOverrideStyleSheet("chrome://editor/content/EditorOverride.css");
|
||||
|
||||
// Load the edit mode override style sheet
|
||||
// This will be remove for "Browser" mode
|
||||
SetDisplayMode(eDisplayModeEdit);
|
||||
|
||||
// Force initial focus to the content window -- HOW?
|
||||
// mWebShellWin->SetFocus();
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "nsInterfaceState.h"
|
||||
#include "nsIHTMLEditor.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
|
||||
class nsIBrowserWindow;
|
||||
class nsIWebShell;
|
||||
@ -56,7 +57,7 @@ class nsIOutputStream;
|
||||
class nsISupportsArray;
|
||||
class nsIStringBundleService;
|
||||
class nsIStringBundle;
|
||||
|
||||
class nsIStyleSheet;
|
||||
|
||||
#define NS_EDITORSHELL_CID \
|
||||
{ /* {} */ \
|
||||
@ -207,6 +208,9 @@ class nsEditorShell : public nsIEditorShell,
|
||||
private:
|
||||
// Pointer to localized strings used for UI
|
||||
nsCOMPtr<nsIStringBundle> mStringBundle;
|
||||
// Pointer to the EditorContent style sheet we load/unload
|
||||
// for "Edit Mode"/"Browser mode" display
|
||||
nsCOMPtr<nsIStyleSheet> mEditModeStyleSheet;
|
||||
};
|
||||
|
||||
#endif // nsEditorShell_h___
|
||||
|
40
editor/composer/src/res/EditorOverride.css
Normal file
40
editor/composer/src/res/EditorOverride.css
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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):
|
||||
*/
|
||||
|
||||
/* Styles to alter look of things in the Editor content window
|
||||
* that should NOT be removed when we display in completely WYSIWYG
|
||||
* "Browser Preview" mode.
|
||||
* Anything that should change, like appearance of table borders
|
||||
* and Named Anchors, should be placed in EditorContent.css instead of here.
|
||||
*/
|
||||
|
||||
/* Override the browser's pointer cursor over links */
|
||||
a:link, a:visited, a:active, a:out-of-date {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
a:link img, a:visited img, a:active img,
|
||||
a:out-of-date img, img[usemap], object[usemap] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,11 @@ interface nsIEditorShell : nsISupports
|
||||
eDocumentStatusUnmodified,
|
||||
eDocumentStatusModified
|
||||
};
|
||||
|
||||
enum {
|
||||
eDisplayModeEdit,
|
||||
eDisplayModeBrowserPreview
|
||||
};
|
||||
%}
|
||||
readonly attribute boolean documentModified;
|
||||
readonly attribute boolean documentIsEmpty;
|
||||
@ -285,6 +290,17 @@ interface nsIEditorShell : nsISupports
|
||||
void SetBackgroundColor(in wstring color);
|
||||
|
||||
void ApplyStyleSheet(in wstring url);
|
||||
|
||||
/** Set the display mode for editing
|
||||
* @param displayMode
|
||||
* 0 (eDisplayModeEdit) Use extra CSS style
|
||||
* (from override styles in EditorContent.css)
|
||||
* to show named anchors, table borders, etc for editing
|
||||
* 1 (eDisplayModeBrowserPreview) "WYSIWIG" or Preview mode
|
||||
* that looks exactly like the browser display except
|
||||
* for certain behaviors like cursor style over links, etc.
|
||||
*/
|
||||
void SetDisplayMode(in PRInt32 displayMode);
|
||||
|
||||
/* Output.
|
||||
* format is mime type, e.g. text/html;
|
||||
|
@ -2279,9 +2279,11 @@ nsHTMLEditor::GetSelectedElement(const nsString& aTagName, nsIDOMElement** aRetu
|
||||
{
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
res = selection->GetEnumerator(getter_AddRefs(enumerator));
|
||||
// XXX: ERROR_HANDLING unclear what to do here, should an error just be returned if enumerator is null or res failed?
|
||||
if (NS_SUCCEEDED(res) && enumerator)
|
||||
if (NS_SUCCEEDED(res))
|
||||
{
|
||||
if(!enumerator)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
enumerator->First();
|
||||
nsCOMPtr<nsISupports> currentItem;
|
||||
res = enumerator->CurrentItem(getter_AddRefs(currentItem));
|
||||
@ -2716,18 +2718,29 @@ nsHTMLEditor::RemoveStyleSheet(nsICSSStyleSheet* aSheet)
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsHTMLEditor::ApplyStyleSheet(const nsString& aURL)
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::ApplyOverrideStyleSheet(const nsString& aURL)
|
||||
{
|
||||
// XXX: Note that this is not an undo-able action yet!
|
||||
return ApplyDocumentOrOverrideStyleSheet(aURL, PR_TRUE);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::ApplyStyleSheet(const nsString& aURL)
|
||||
{
|
||||
return ApplyDocumentOrOverrideStyleSheet(aURL, PR_TRUE);
|
||||
}
|
||||
|
||||
//Note: Loading a document style sheet is undoable, loading an override sheet is not
|
||||
nsresult
|
||||
nsHTMLEditor::ApplyDocumentOrOverrideStyleSheet(const nsString& aURL, PRBool aOverride)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsIURI* uaURL = 0;
|
||||
nsCOMPtr<nsIURI> uaURL;
|
||||
|
||||
#ifndef NECKO
|
||||
rv = NS_NewURL(&uaURL, aURL);
|
||||
rv = NS_NewURL(getter_AddRefs(uaURL), aURL);
|
||||
#else
|
||||
rv = NS_NewURI(&uaURL, aURL);
|
||||
rv = NS_NewURI(getter_AddRefs(uaURL), aURL);
|
||||
#endif // NECKO
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
@ -2739,57 +2752,77 @@ NS_IMETHODIMP nsHTMLEditor::ApplyStyleSheet(const nsString& aURL)
|
||||
rv = ps->GetDocument(getter_AddRefs(document));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (document) {
|
||||
nsCOMPtr<nsIHTMLContentContainer> container = do_QueryInterface(document);
|
||||
if (!document)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (container) {
|
||||
nsICSSLoader *cssLoader = 0;
|
||||
nsICSSStyleSheet *cssStyleSheet = 0;
|
||||
nsCOMPtr<nsIHTMLContentContainer> container = do_QueryInterface(document);
|
||||
if (!container)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsICSSLoader> cssLoader;
|
||||
nsCOMPtr<nsICSSStyleSheet> cssStyleSheet;
|
||||
|
||||
rv = container->GetCSSLoader(cssLoader);
|
||||
rv = container->GetCSSLoader(*getter_AddRefs(cssLoader));
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRBool complete;
|
||||
|
||||
if (!cssLoader)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
if (aOverride) {
|
||||
// We use null for the callback and data pointer because
|
||||
// we MUST ONLY load synchronous local files (no @import)
|
||||
rv = cssLoader->LoadAgentSheet(uaURL, *getter_AddRefs(cssStyleSheet), complete,
|
||||
nsnull, nsnull);
|
||||
|
||||
// Synchronous loads should ALWAYS return completed
|
||||
if (!complete || !cssStyleSheet)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Don't need to QI (subclass)
|
||||
nsCOMPtr<nsIStyleSheet> styleSheet = cssStyleSheet;
|
||||
nsCOMPtr<nsIStyleSet> styleSet;
|
||||
rv = ps->GetStyleSet(getter_AddRefs(styleSet));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (cssLoader) {
|
||||
PRBool complete;
|
||||
if (!styleSet)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
rv = cssLoader->LoadAgentSheet(uaURL, cssStyleSheet, complete,
|
||||
ApplyStyleSheetToPresShellDocument,
|
||||
this);
|
||||
// Add the override style sheet
|
||||
// (This checks if already exists
|
||||
// If yes, it and reads it does)
|
||||
styleSet->AppendOverrideStyleSheet(styleSheet);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (complete) {
|
||||
if (cssStyleSheet) {
|
||||
ApplyStyleSheetToPresShellDocument(cssStyleSheet,
|
||||
this);
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
//
|
||||
// If not complete, we will be notified later
|
||||
// with a call to AddStyleSheetToEditorDocument().
|
||||
//
|
||||
}
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
// This notifies document observers to rebuild all frames
|
||||
// (this doesn't affect style sheet because it is not a doc sheet)
|
||||
document->SetStyleSheetDisabledState(styleSheet, PR_FALSE);
|
||||
}
|
||||
}
|
||||
else {
|
||||
rv = cssLoader->LoadAgentSheet(uaURL, *getter_AddRefs(cssStyleSheet), complete,
|
||||
ApplyStyleSheetToPresShellDocument,
|
||||
this);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (complete) {
|
||||
if (cssStyleSheet) {
|
||||
ApplyStyleSheetToPresShellDocument(cssStyleSheet,this);
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
//
|
||||
// If not complete, we will be notified later
|
||||
// with a call to ApplyStyleSheetToPresShellDocument().
|
||||
//
|
||||
}
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
else
|
||||
rv = NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
NS_RELEASE(uaURL);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma mark -
|
||||
#pragma mark --- nsIEditorMailSupport methods ---
|
||||
@ -3526,7 +3559,32 @@ NS_IMETHODIMP nsHTMLEditor::OutputToStream(nsIOutputStream* aOutputStream,
|
||||
|
||||
return encoder->EncodeToStream(aOutputStream);
|
||||
}
|
||||
#if 0
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::GetTextNearNode(nsIDOMNode *aNode, aNode, PRInt32 aMaxChars, nsString& aOutputString)
|
||||
{
|
||||
if (!aNode)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
// Create a temporary selection object and
|
||||
// based on the suppled
|
||||
nsCOMPtr<nsIDOMSelection> selection;
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
nsresult rv = NS_NewRange(getter_AddRsfs(range))
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if (!range)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
range.SetStart(aNode,0);
|
||||
range.SetEnd(aNode,
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) && selection)
|
||||
encoder->SetSelection(selection);
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLEditor::DebugUnitTests(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed)
|
||||
@ -3547,7 +3605,6 @@ nsHTMLEditor::DebugUnitTests(PRInt32 *outNumTests, PRInt32 *outNumTestsFailed)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef XP_MAC
|
||||
#pragma mark -
|
||||
#pragma mark --- nsIEditorIMESupport overrides ---
|
||||
@ -3606,7 +3663,6 @@ nsHTMLEditor::ReplaceStyleSheet(nsICSSStyleSheet *aNewSheet)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* static callback */
|
||||
void nsHTMLEditor::ApplyStyleSheetToPresShellDocument(nsICSSStyleSheet* aSheet, void *aData)
|
||||
{
|
||||
@ -3617,7 +3673,6 @@ void nsHTMLEditor::ApplyStyleSheetToPresShellDocument(nsICSSStyleSheet* aSheet,
|
||||
{
|
||||
rv = editor->ReplaceStyleSheet(aSheet);
|
||||
}
|
||||
|
||||
// XXX: we lose the return value here. Set a flag in the editor?
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "nsEditor.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsICSSLoader.h"
|
||||
#include "nsITableLayout.h"
|
||||
|
||||
#include "TypeInState.h"
|
||||
@ -120,6 +121,11 @@ public:
|
||||
/* ------------ nsIEditorStyleSheets methods -------------- */
|
||||
|
||||
NS_IMETHOD ApplyStyleSheet(const nsString& aURL);
|
||||
NS_IMETHOD ApplyOverrideStyleSheet(const nsString& aURL);
|
||||
/* Above 2 methods call this with appropriate aOverride value
|
||||
* Not exposed to IDL interface
|
||||
*/
|
||||
nsresult ApplyDocumentOrOverrideStyleSheet(const nsString& aURL, PRBool aOverride);
|
||||
NS_IMETHOD AddStyleSheet(nsICSSStyleSheet* aSheet);
|
||||
NS_IMETHOD RemoveStyleSheet(nsICSSStyleSheet* aSheet);
|
||||
|
||||
@ -172,8 +178,6 @@ public:
|
||||
NS_IMETHOD SetBackgroundColor(const nsString& aColor);
|
||||
NS_IMETHOD SetBodyAttribute(const nsString& aAttr, const nsString& aValue);
|
||||
|
||||
|
||||
|
||||
/* ------------ Overrides of nsEditor interface methods -------------- */
|
||||
|
||||
/** prepare the editor for use */
|
||||
|
@ -39,10 +39,24 @@ public:
|
||||
/** load and apply the style sheet, specified by aURL, to
|
||||
* the editor's document. This can involve asynchronous
|
||||
* network I/O
|
||||
* @param aURL The style sheet to be loaded and applied.
|
||||
* @param aURL The style sheet to be loaded and applied.
|
||||
*/
|
||||
NS_IMETHOD ApplyStyleSheet(const nsString& aURL)=0;
|
||||
|
||||
/** load and apply an Override style sheet, specified by aURL, to
|
||||
* the editor's document.
|
||||
* IMPORTANT: This is assumed to be synchronous:
|
||||
* URL is a local file with no @import used
|
||||
* This action is not undoable.
|
||||
* It is not intended for use by "user", only editor developers
|
||||
* to change display behavior for editing (like showing special cursors)
|
||||
* that will not be affected by loading other "document" style sheets
|
||||
* loaded using ApplyStyleSheet.
|
||||
*
|
||||
* @param aURL The style sheet to be loaded and applied.
|
||||
*/
|
||||
NS_IMETHOD ApplyOverrideStyleSheet(const nsString& aURL)=0;
|
||||
|
||||
/** Add the given Style Sheet to the editor's document
|
||||
* This is always synchronous
|
||||
* @param aSheet The style sheet to be applied.
|
||||
|
@ -364,7 +364,6 @@ public:
|
||||
*
|
||||
*/
|
||||
NS_IMETHOD SetBodyAttribute(const nsString& aAttr, const nsString& aValue)=0;
|
||||
|
||||
};
|
||||
|
||||
#endif // nsIHTMLEditor_h__
|
||||
|
@ -153,9 +153,7 @@
|
||||
<titledbutton id="namedAnchorButton"/>
|
||||
|
||||
<html:div class="separator" align="vertical" />
|
||||
|
||||
<spring flex="100%"/>
|
||||
<titledbutton id="DisplayStyleButton"/>
|
||||
</toolbar>
|
||||
|
||||
<toolbar id="FormatToolbar">
|
||||
@ -207,6 +205,21 @@
|
||||
|
||||
<html:iframe type="content-primary" id="content-frame" src="about:blank" flex="100%"/>
|
||||
|
||||
<box align="horizontal" id="DisplayModeBar">
|
||||
<spring class="spacer"/>
|
||||
<!-- This is a pain: can't use CSS margin to add extra space above text? -->
|
||||
<box align="vertical">
|
||||
<spring style="height: 2px"/>
|
||||
<html:div>&displayMode.label;</html:div>
|
||||
</box>
|
||||
<spring class="spacer"/>
|
||||
<titledbutton id="EditModeButton" class="DisplayModeButton" selected="1" value="&editModeButton.label;" onclick="EditorSetDisplayStyle(0)"/>
|
||||
<titledbutton id="BrowserModeButton" class="DisplayModeButton" selected="0" value="&browserModeButton.label;" onclick="EditorSetDisplayStyle(1)"/>
|
||||
<html:div class="VerticalSeparator"/>
|
||||
<!-- <html:div id="LeftGrayBorder"/> -->
|
||||
<spring flex="100%"/>
|
||||
</box>
|
||||
|
||||
<!-- status bar, from editorOverlay.xul -->
|
||||
<box id="EditorStatusBar" />
|
||||
</box>
|
||||
|
@ -24,7 +24,7 @@
|
||||
var editorShell;
|
||||
var toolbar;
|
||||
var documentModified;
|
||||
var EditorDisplayStyle = true;
|
||||
var EditorDisplayMode = 0; // Normal Editor mode
|
||||
|
||||
var gTagToFormat = {
|
||||
"P" : "Normal", // these should really be entities. Not sure how to do that from JS
|
||||
@ -508,6 +508,8 @@ function EditorRemoveLinks()
|
||||
|
||||
function EditorApplyStyleSheet(styleSheetURL)
|
||||
{
|
||||
// Second param is true for "override" type of sheet
|
||||
// We don't let users use that option
|
||||
editorShell.ApplyStyleSheet(styleSheetURL);
|
||||
contentWindow.focus();
|
||||
}
|
||||
@ -767,24 +769,19 @@ function EditorAlign(align)
|
||||
contentWindow.focus();
|
||||
}
|
||||
|
||||
function EditorToggleDisplayStyle()
|
||||
function EditorSetDisplayStyle(mode)
|
||||
{
|
||||
if (EditorDisplayStyle) {
|
||||
EditorDisplayStyle = false;
|
||||
styleSheet = "resource:/res/ua.css";
|
||||
buttonText = editorShell.GetString("EditMode");
|
||||
}
|
||||
else {
|
||||
EditorDisplayStyle = true;
|
||||
styleSheet = "chrome://editor/content/EditorContent.css"
|
||||
buttonText = editorShell.GetString("Preview");
|
||||
}
|
||||
//TODO: THIS IS NOT THE RIGHT THING TO DO!
|
||||
EditorApplyStyleSheet(styleSheet);
|
||||
|
||||
button = document.getElementById("DisplayStyleButton");
|
||||
if (button)
|
||||
button.setAttribute("value",buttonText);
|
||||
EditorDisplayMode = mode;
|
||||
editorShell.SetDisplayMode(mode);
|
||||
editButton = document.getElementById("EditModeButton");
|
||||
browserButton = document.getElementById("BrowserModeButton");
|
||||
var editSelected = 0;
|
||||
var browserSelected = 0;
|
||||
if (mode == 0) editSelected = 1;
|
||||
if (mode == 1) browserSelected = 1;
|
||||
dump(editButton+browserButton+" Display mode: EditSelected="+editSelected+" BrowserSelected="+browserSelected+"\n");
|
||||
editButton.setAttribute("selected",Number(editSelected));
|
||||
browserButton.setAttribute("selected",Number(browserSelected));
|
||||
}
|
||||
|
||||
function EditorPrintPreview()
|
||||
@ -833,14 +830,6 @@ function OnCreateAlignmentPopup()
|
||||
|
||||
// --------------------------- Debug stuff ---------------------------
|
||||
|
||||
function EditorApplyStyleSheet(url)
|
||||
{
|
||||
if (editorShell)
|
||||
{
|
||||
editorShell.ApplyStyleSheet(url);
|
||||
}
|
||||
}
|
||||
|
||||
function EditorExecuteScript(fileSpec)
|
||||
{
|
||||
fileSpec.openStreamForReading();
|
||||
|
@ -20,34 +20,15 @@
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* Styles to alter look of things in the Editor content window */
|
||||
|
||||
/* Override the browser's pointer cursor over links */
|
||||
a:link, a:visited, a:active, a:out-of-date {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
a:link img, a:visited img, a:active img,
|
||||
a:out-of-date img, img[usemap], object[usemap] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
|
||||
/* new feature, not implemented yet
|
||||
|
||||
a[name] {
|
||||
display: inline-block;
|
||||
min-width: 10px;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background-image: url(chrome://editor/skin/images/ED_Left.gif);
|
||||
border: 1px solid blue;
|
||||
cursor: default;
|
||||
}
|
||||
/* Styles to alter look of things in the Editor content window
|
||||
* for the "Normal Edit Mode" These settings will be removed
|
||||
* when we display in completely WYSIWYG "Browser Preview" mode
|
||||
* Anything that should never change, like cursors, should be
|
||||
* place in EditorOverride.css, instead of here.
|
||||
*/
|
||||
|
||||
a[name] {
|
||||
padding-left: 10px;
|
||||
padding-left: 20px;
|
||||
background: url(chrome://editor/skin/images/ED_Left.gif) 5px 50% no-repeat;
|
||||
}
|
||||
|
||||
|
40
editor/ui/composer/content/EditorOverride.css
Normal file
40
editor/ui/composer/content/EditorOverride.css
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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):
|
||||
*/
|
||||
|
||||
/* Styles to alter look of things in the Editor content window
|
||||
* that should NOT be removed when we display in completely WYSIWYG
|
||||
* "Browser Preview" mode.
|
||||
* Anything that should change, like appearance of table borders
|
||||
* and Named Anchors, should be placed in EditorContent.css instead of here.
|
||||
*/
|
||||
|
||||
/* Override the browser's pointer cursor over links */
|
||||
a:link, a:visited, a:active, a:out-of-date {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
a:link img, a:visited img, a:active img,
|
||||
a:out-of-date img, img[usemap], object[usemap] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,7 @@ EditorInitPage.html
|
||||
EditorInitPagePlain.html
|
||||
EditorStyles1.css
|
||||
EditorContent.css
|
||||
EditorOverride.css
|
||||
editorOverlay.js
|
||||
editorOverlay.xul
|
||||
sidebar-editor.rdf
|
||||
|
@ -33,6 +33,7 @@ EXPORT_RESOURCE_CONTENT = \
|
||||
$(srcdir)/EditorInitPagePlain.html \
|
||||
$(srcdir)/EditorStyles1.css \
|
||||
$(srcdir)/EditorContent.css \
|
||||
$(srcdir)/EditorOverride.css \
|
||||
$(srcdir)/sidebar-editor.rdf \
|
||||
$(srcdir)/sidebar-editor.xul \
|
||||
$(srcdir)/sb-bookmarks-panel.xul \
|
||||
|
@ -616,9 +616,6 @@
|
||||
<titledbutton id="linkButton" src="&linkIcon.url;" value="&linkToolbarCmd.label;" onclick="EditorInsertLink()"/>
|
||||
<titledbutton id="namedAnchorButton" src="&targetIcon.url;" value="&anchorToolbarCmd.label;" onclick="EditorInsertNamedAnchor()"/>
|
||||
|
||||
<titledbutton id="DisplayStyleButton" src="&previewIcon.url;" value="&previewToolbarCmd.label;" onclick="EditorToggleDisplayStyle()"/>
|
||||
|
||||
|
||||
<!-- Formatting toolbar items -->
|
||||
<titledbutton style="width:68pt" id="ParagraphPopupButton" value="¶graphToolbarMenu.label;" class="popup" align="left" popupanchor="bottomleft">
|
||||
<observes element="Editor:Paragraph:Format" attribute="format" onbroadcast="onParagraphFormatChange()"/>
|
||||
|
@ -27,6 +27,7 @@ install::
|
||||
$(MAKE_INSTALL) EditorInitPagePlain.html $(DIST)\bin\chrome\editor\content\default
|
||||
$(MAKE_INSTALL) EditorStyles1.css $(DIST)\bin\chrome\editor\content\default
|
||||
$(MAKE_INSTALL) EditorContent.css $(DIST)\bin\chrome\editor\content\default
|
||||
$(MAKE_INSTALL) EditorOverride.css $(DIST)\bin\chrome\editor\content\default
|
||||
$(MAKE_INSTALL) sidebar-editor.rdf $(DIST)\bin\chrome\editor\content\default
|
||||
$(MAKE_INSTALL) sidebar-editor.xul $(DIST)\bin\chrome\editor\content\default
|
||||
$(MAKE_INSTALL) sb-bookmarks-panel.xul $(DIST)\bin\chrome\editor\content\default
|
||||
@ -48,6 +49,7 @@ clobber::
|
||||
rm -f $(DIST)\bin\chrome\editor\content\default\EditorInitPagePlain.html
|
||||
rm -f $(DIST)\bin\chrome\editor\content\default\EditorStyles1.css
|
||||
rm -f $(DIST)\bin\chrome\editor\content\default\EditorContent.css
|
||||
rm -f $(DIST)\bin\chrome\editor\content\default\EditorOverride.css
|
||||
rm -f $(DIST)\bin\chrome\editor\content\default\sidebar-editor.rdf
|
||||
rm -f $(DIST)\bin\chrome\editor\content\default\sidebar-editor.xul
|
||||
rm -f $(DIST)\bin\chrome\editor\content\default\sb-bookmarks-panel.xul
|
||||
|
@ -41,3 +41,7 @@
|
||||
<!ENTITY helpMenu.label "Help">
|
||||
<!ENTITY aboutCmd.label ".About">
|
||||
|
||||
<!-- Display Mode Toolbar -->
|
||||
<!ENTITY displayMode.label "Display Mode:">
|
||||
<!ENTITY editModeButton.label "Normal Editing">
|
||||
<!ENTITY browserModeButton.label "Edit in Browser Layout">
|
||||
|
@ -33,6 +33,8 @@ EmptyHREFError=You must enter or choose<br>a location (URL) to create a new link
|
||||
LinkText=Link text:
|
||||
EnterLinkText=Enter text to display for the link:
|
||||
EmptyLinkTextError=You must enter some text for this link.
|
||||
HeadingsCaption=Headings:
|
||||
NamedAnchorsCaption=NamedAnchors:
|
||||
ValidateNumber1=The number you entered (
|
||||
ValidateNumber2=) is outside of allowed range.<br>Please enter a number between
|
||||
ValidateNumber3=and
|
||||
|
@ -32,12 +32,21 @@ toolbox#EditorToolbars {
|
||||
|
||||
box#EditorStatusBar {
|
||||
min-width: 50px;
|
||||
border-top: 1px solid darkgray;
|
||||
}
|
||||
|
||||
box#EditorProgessBox {
|
||||
min-width:30px;
|
||||
}
|
||||
|
||||
box#DisplayModeBar {
|
||||
margin-top: -2px;
|
||||
border-top: 1px solid black;
|
||||
min-width:30px;
|
||||
/* temporary - testing background */
|
||||
background-color: inherit; /*#99CCCC; */
|
||||
}
|
||||
|
||||
window.popup {
|
||||
border: 2px outset;
|
||||
}
|
||||
@ -90,6 +99,29 @@ titledbutton#underlineButton {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
titledbutton[class~=DisplayModeButton] {
|
||||
padding: 1px 4px 0px 4px;
|
||||
margin: 0px;
|
||||
border-width: 1px;
|
||||
border: 1px solid transparent;
|
||||
border-left: 1px solid darkgray;
|
||||
}
|
||||
|
||||
/* Color must be same as above for Display */
|
||||
div.VerticalSeparator {
|
||||
height: 100%;
|
||||
max-width: 1px;
|
||||
border-left: 1px solid darkgray;
|
||||
/* margin: 1px; 0px; */
|
||||
}
|
||||
|
||||
titledbutton[class~=DisplayModeButton][selected="1"] {
|
||||
border: 1px white outset;
|
||||
padding: 2px 4px 0px 4px;
|
||||
margin: -2px 0px 0px 0px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
button.PopupButton {
|
||||
align: left;
|
||||
margin: 0px;
|
||||
@ -130,5 +162,17 @@ titledbutton[toggled="1"] {
|
||||
border: 1px white inset;
|
||||
}
|
||||
|
||||
|
||||
// Override the browser's pointer cursor over links
|
||||
a { cursor: default; }
|
||||
|
||||
/* Messenger uses this -- IT SHOULD BE IN XUL.CSS */
|
||||
spring.spacer {
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
}
|
||||
|
||||
spring.bigspacer {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
95
editor/ui/dialogs/content/EdAECSSAttributes.js
Normal file
95
editor/ui/dialogs/content/EdAECSSAttributes.js
Normal file
@ -0,0 +1,95 @@
|
||||
|
||||
// build attribute list in tree form from element attributes
|
||||
function BuildCSSAttributeTable()
|
||||
{
|
||||
dump("populating CSS Attributes tree\n");
|
||||
dump("elStyle: " + element.getAttribute("style") + "\n");
|
||||
var style = element.getAttribute("style");
|
||||
if(style == undefined || style == "")
|
||||
{
|
||||
dump("no style attributes to add\n");
|
||||
return false;
|
||||
}
|
||||
if(style.indexOf(";") == -1) {
|
||||
if(style.indexOf(":") != -1) {
|
||||
name = TrimString(nvpairs.split(":")[0]);
|
||||
value = TrimString(nvpairs.split(":")[1]);
|
||||
if(!AddCSSAttribute(name,value)) {
|
||||
dump("Failed to add CSS attribute: " + i + "\n");
|
||||
}
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
nvpairs = style.split(";");
|
||||
for(i = 0; i < nvpairs.length; i++)
|
||||
{
|
||||
if(nvpairs[i].indexOf(":") != -1) {
|
||||
name = TrimString(nvpairs[i].split(":")[0]);
|
||||
value = TrimString(nvpairs[i].split(":")[1]);
|
||||
if(!AddCSSAttribute(name,value)) {
|
||||
dump("Failed to add CSS attribute: " + i + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function AddCSSAttribute(name,value)
|
||||
{
|
||||
var treekids = document.getElementById("CSSAList");
|
||||
if(!CheckAttributeNameSimilarity(name, CSSAttrs)) {
|
||||
dump("repeated CSS attribute, ignoring\n");
|
||||
return false;
|
||||
}
|
||||
CSSAttrs[CSSAttrs.length] = name;
|
||||
|
||||
var treeitem = document.createElement("treeitem");
|
||||
var treerow = document.createElement("treerow");
|
||||
var attrcell = document.createElement("treecell");
|
||||
var attrcontent = document.createTextNode(name.toLowerCase());
|
||||
attrcell.appendChild(attrcontent);
|
||||
treerow.appendChild(attrcell);
|
||||
var valcell = document.createElement("treecell");
|
||||
valcell.setAttribute("class","value");
|
||||
var valField = document.createElement("html:input");
|
||||
var attrValue = value;
|
||||
valField.setAttribute("type","text");
|
||||
valField.setAttribute("id",name.toLowerCase());
|
||||
valField.setAttribute("value",attrValue);
|
||||
valField.setAttribute("flex","100%");
|
||||
valField.setAttribute("class","AttributesCell");
|
||||
valcell.appendChild(valField);
|
||||
treerow.appendChild(valcell);
|
||||
treeitem.appendChild(treerow);
|
||||
treekids.appendChild(treeitem);
|
||||
return true;
|
||||
}
|
||||
|
||||
// add an attribute to the tree widget
|
||||
function onAddCSSAttribute()
|
||||
{
|
||||
var name = dialog.AddCSSAttributeNameInput.value;
|
||||
var value = TrimString(dialog.AddCSSAttributeValueInput.value);
|
||||
|
||||
if(name == "")
|
||||
return;
|
||||
|
||||
// WHAT'S GOING ON? NAME ALWAYS HAS A VALUE OF accented "a"???
|
||||
dump(name+"= New Attribute Name - SHOULD BE EMPTY\n");
|
||||
|
||||
if(AddCSSAttribute(name,value)) {
|
||||
dialog.AddCSSAttributeNameInput.value = "";
|
||||
dialog.AddCSSAttributeValueInput.value = "";
|
||||
}
|
||||
dialog.AddCSSAttributeNameInput.focus();
|
||||
}
|
||||
|
||||
// does enabling based on any user input.
|
||||
function doCSSEnabling()
|
||||
{
|
||||
var name = TrimString(dialog.AddCSSAttributeNameInput.value).toLowerCase();
|
||||
if( name == "" || !CheckAttributeNameSimilarity(name,CSSAttrs)) {
|
||||
dialog.AddCSSAttribute.setAttribute("disabled","true");
|
||||
} else {
|
||||
dialog.AddCSSAttribute.removeAttribute("disabled");
|
||||
}
|
||||
}
|
95
editor/ui/dialogs/content/EdAEHTMLAttributes.js
Normal file
95
editor/ui/dialogs/content/EdAEHTMLAttributes.js
Normal file
@ -0,0 +1,95 @@
|
||||
|
||||
// build attribute list in tree form from element attributes
|
||||
function BuildHTMLAttributeTable()
|
||||
{
|
||||
dump("NODENAME: " + element.nodeName + "\n");
|
||||
var nodeMap = element.attributes;
|
||||
var nodeMapCount = nodeMap.length;
|
||||
var treekids = document.getElementById("HTMLAList");
|
||||
|
||||
if(nodeMapCount > 0) {
|
||||
for(i = 0; i < nodeMapCount; i++)
|
||||
{
|
||||
if(!CheckAttributeNameSimilarity(nodeMap[i].nodeName, JSEAttrs) ||
|
||||
IsEventHandler(nodeMap[i].nodeName) ||
|
||||
TrimString(nodeMap[i].nodeName.toLowerCase()) == "style") {
|
||||
dump("repeated property, JS event handler or style property!\n");
|
||||
continue; // repeated attribute, ignore this one and go to next
|
||||
}
|
||||
HTMLAttrs[i] = nodeMap[i].nodeName;
|
||||
var treeitem = document.createElement("treeitem");
|
||||
var treerow = document.createElement("treerow");
|
||||
var attrcell = document.createElement("treecell");
|
||||
var attrcontent = document.createTextNode(nodeMap[i].nodeName.toUpperCase());
|
||||
attrcell.appendChild(attrcontent);
|
||||
treerow.appendChild(attrcell);
|
||||
var valcell = document.createElement("treecell");
|
||||
valcell.setAttribute("class","value");
|
||||
var valField = document.createElement("html:input");
|
||||
var attrValue = element.getAttribute(nodeMap[i].nodeName);
|
||||
valField.setAttribute("type","text");
|
||||
valField.setAttribute("id",nodeMap[i].nodeName.toLowerCase());
|
||||
valField.setAttribute("value",attrValue);
|
||||
valField.setAttribute("flex","100%");
|
||||
valField.setAttribute("class","AttributesCell");
|
||||
valcell.appendChild(valField);
|
||||
treerow.appendChild(valcell);
|
||||
treeitem.appendChild(treerow);
|
||||
treekids.appendChild(treeitem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function AddHTMLAttribute(name,value)
|
||||
{
|
||||
HTMLAttrs[HTMLAttrs.length] = name;
|
||||
var treekids = document.getElementById("HTMLAList");
|
||||
var treeitem = document.createElement("treeitem");
|
||||
var treerow = document.createElement("treerow");
|
||||
var attrcell = document.createElement("treecell");
|
||||
var attrcontent = document.createTextNode(name.toUpperCase());
|
||||
attrcell.appendChild(attrcontent);
|
||||
treerow.appendChild(attrcell);
|
||||
var valcell = document.createElement("treecell");
|
||||
valcell.setAttribute("class","value");
|
||||
var valField = document.createElement("html:input");
|
||||
valField.setAttribute("type","text");
|
||||
valField.setAttribute("id",name);
|
||||
valField.setAttribute("value",value);
|
||||
valField.setAttribute("flex","100%");
|
||||
valField.setAttribute("class","AttributesCell");
|
||||
valcell.appendChild(valField);
|
||||
treerow.appendChild(valcell);
|
||||
treeitem.appendChild(treerow);
|
||||
treekids.appendChild(treeitem);
|
||||
return true;
|
||||
}
|
||||
|
||||
// add an attribute to the tree widget
|
||||
function onAddHTMLAttribute()
|
||||
{
|
||||
var name = dialog.AddHTMLAttributeNameInput.value;
|
||||
var value = TrimString(dialog.AddHTMLAttributeValueInput.value);
|
||||
if(name == "")
|
||||
return;
|
||||
|
||||
// WHAT'S GOING ON? NAME ALWAYS HAS A VALUE OF accented "a"???
|
||||
dump(name+"= New Attribute Name - SHOULD BE EMPTY\n");
|
||||
|
||||
if(AddHTMLAttribute(name,value)) {
|
||||
dialog.AddHTMLAttributeNameInput.value = "";
|
||||
dialog.AddHTMLAttributeValueInput.value = "";
|
||||
}
|
||||
dialog.AddHTMLAttributeNameInput.focus();
|
||||
}
|
||||
|
||||
// does enabling based on any user input.
|
||||
function doHTMLEnabling()
|
||||
{
|
||||
var name = TrimString(dialog.AddHTMLAttributeNameInput.value).toLowerCase();
|
||||
if( name == "" || !CheckAttributeNameSimilarity(name,HTMLAttrs)) {
|
||||
dialog.AddHTMLAttribute.setAttribute("disabled","true");
|
||||
} else {
|
||||
dialog.AddHTMLAttribute.removeAttribute("disabled");
|
||||
}
|
||||
}
|
104
editor/ui/dialogs/content/EdAEJSEAttributes.js
Normal file
104
editor/ui/dialogs/content/EdAEJSEAttributes.js
Normal file
@ -0,0 +1,104 @@
|
||||
// build attribute list in tree form from element attributes
|
||||
function BuildJSEAttributeTable()
|
||||
{
|
||||
dump("Loading event handlers list...\n");
|
||||
var nodeMap = element.attributes;
|
||||
var nodeMapCount = nodeMap.length;
|
||||
var treekids = document.getElementById("JSEAList");
|
||||
|
||||
dump("nmc: " + nodeMapCount + "\n");
|
||||
if(nodeMapCount > 0) {
|
||||
for(var i = 0; i < nodeMapCount; i++)
|
||||
{
|
||||
if(!CheckAttributeNameSimilarity(nodeMap[i].nodeName, JSEAttrs)) {
|
||||
dump("repeated JS handler!\n");
|
||||
continue; // repeated attribute, ignore this one and go to next
|
||||
}
|
||||
if(!IsEventHandler(nodeMap[i].nodeName)) {
|
||||
dump("not an event handler\n");
|
||||
continue; // attribute isn't an event handler.
|
||||
}
|
||||
JSEAttrs[i] = nodeMap[i].nodeName;
|
||||
var treeitem = document.createElement("treeitem");
|
||||
var treerow = document.createElement("treerow");
|
||||
var attrcell = document.createElement("treecell");
|
||||
var attrcontent = document.createTextNode(nodeMap[i].nodeName.toLowerCase());
|
||||
attrcell.appendChild(attrcontent);
|
||||
treerow.appendChild(attrcell);
|
||||
var valcell = document.createElement("treecell");
|
||||
valcell.setAttribute("class","value");
|
||||
var valField = document.createElement("html:input");
|
||||
var attrValue = element.getAttribute(nodeMap[i].nodeName);
|
||||
valField.setAttribute("type","text");
|
||||
valField.setAttribute("id",nodeMap[i].nodeName.toLowerCase());
|
||||
valField.setAttribute("value",attrValue);
|
||||
valField.setAttribute("flex","100%");
|
||||
valField.setAttribute("class","AttributesCell");
|
||||
valcell.appendChild(valField);
|
||||
treerow.appendChild(valcell);
|
||||
treeitem.appendChild(treerow);
|
||||
treekids.appendChild(treeitem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function IsEventHandler(which)
|
||||
{
|
||||
var handlerName = which.toLowerCase();
|
||||
var firstTwo = handlerName.substring(0,2);
|
||||
if(firstTwo == "on")
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function AddJSEAttribute(name,value)
|
||||
{
|
||||
JSEAttrs[JSEAttrs.length] = name;
|
||||
var treekids = document.getElementById("JSEAList");
|
||||
var treeitem = document.createElement("treeitem");
|
||||
var treerow = document.createElement("treerow");
|
||||
var attrcell = document.createElement("treecell");
|
||||
var attrcontent = document.createTextNode(name.toLowerCase());
|
||||
attrcell.appendChild(attrcontent);
|
||||
treerow.appendChild(attrcell);
|
||||
var valcell = document.createElement("treecell");
|
||||
valcell.setAttribute("class","value");
|
||||
var valField = document.createElement("html:input");
|
||||
valField.setAttribute("type","text");
|
||||
valField.setAttribute("id",name);
|
||||
valField.setAttribute("value",value);
|
||||
valField.setAttribute("flex","100%");
|
||||
valField.setAttribute("class","AttributesCell");
|
||||
valcell.appendChild(valField);
|
||||
treerow.appendChild(valcell);
|
||||
treeitem.appendChild(treerow);
|
||||
treekids.appendChild(treeitem);
|
||||
}
|
||||
|
||||
// add an attribute to the tree widget
|
||||
function onAddJSEAttribute()
|
||||
{
|
||||
var name = dialog.AddJSEAttributeNameInput.value;
|
||||
var value = TrimString(dialog.AddJSEAttributeValueInput.value);
|
||||
if(name == "")
|
||||
return;
|
||||
// WHAT'S GOING ON? NAME ALWAYS HAS A VALUE OF accented "a"???
|
||||
dump(name+"= New Attribute Name - SHOULD BE EMPTY\n");
|
||||
if(AddJSEAttribute(name,value)) {
|
||||
dialog.AddJSEAttributeNameInput.value = "";
|
||||
dialog.AddJSEAttributeValueInput.value = "";
|
||||
}
|
||||
dialog.AddJSEAttributeNameInput.focus();
|
||||
}
|
||||
|
||||
// does enabling based on any user input.
|
||||
function doJSEEnabling()
|
||||
{
|
||||
var name = TrimString(dialog.AddJSEAttributeNameInput.value).toLowerCase();
|
||||
if( name == "" || !CheckAttributeNameSimilarity(name,JSEAttrs)) {
|
||||
dialog.AddJSEAttribute.setAttribute("disabled","true");
|
||||
} else {
|
||||
dialog.AddJSEAttribute.removeAttribute("disabled");
|
||||
}
|
||||
}
|
@ -21,17 +21,18 @@
|
||||
* Ben Goodger
|
||||
*/
|
||||
|
||||
/************** GLOBALS **************/
|
||||
var tagname = null;
|
||||
var element = null;
|
||||
|
||||
//Cancel() is in EdDialogCommon.js
|
||||
// Note: This dialog
|
||||
var tagname;
|
||||
var element;
|
||||
var elAttrs = new Array();
|
||||
var HTMLAttrs = []; // html attributes
|
||||
var CSSAttrs = []; // css attributes
|
||||
var JSEAttrs = []; // js events
|
||||
|
||||
// dialog initialization code
|
||||
/************** INITIALISATION && SETUP **************/
|
||||
function Startup()
|
||||
{
|
||||
dump("START DLG\n");
|
||||
dump("Welcome to EdAdvancedEdit '99 \n");
|
||||
// This is the return value for the parent,
|
||||
// who only needs to know if OK was clicked
|
||||
window.opener.AdvancedEditOK = false;
|
||||
@ -59,163 +60,92 @@ function Startup()
|
||||
|
||||
// Create dialog object to store controls for easy access
|
||||
dialog = new Object;
|
||||
dialog.AddAttributeNameInput = document.getElementById("AddAttributeNameInput");
|
||||
dialog.AddAttributeValueInput = document.getElementById("AddAttributeValueInput");
|
||||
dialog.AddAttribute = document.getElementById("AddAttribute");
|
||||
dialog.AddHTMLAttributeNameInput = document.getElementById("AddHTMLAttributeNameInput");
|
||||
dialog.AddHTMLAttributeValueInput = document.getElementById("AddHTMLAttributeValueInput");
|
||||
dialog.AddHTMLAttribute = document.getElementById("AddHTMLAttribute");
|
||||
dialog.AddCSSAttributeNameInput = document.getElementById("AddCSSAttributeNameInput");
|
||||
dialog.AddCSSAttributeValueInput = document.getElementById("AddCSSAttributeValueInput");
|
||||
dialog.AddCSSAttribute = document.getElementById("AddCSSAttribute");
|
||||
dialog.AddJSEAttributeNameInput = document.getElementById("AddJSEAttributeNameInput");
|
||||
dialog.AddJSEAttributeValueInput = document.getElementById("AddJSEAttributeValueInput");
|
||||
dialog.AddJSEAttribute = document.getElementById("AddJSEAttribute");
|
||||
|
||||
// build an attribute tree
|
||||
BuildAttributeTable();
|
||||
// build the attribute trees
|
||||
BuildHTMLAttributeTable();
|
||||
BuildCSSAttributeTable();
|
||||
BuildJSEAttributeTable();
|
||||
window.sizeToContent();
|
||||
}
|
||||
|
||||
// build attribute list in tree form from element attributes
|
||||
function BuildAttributeTable()
|
||||
{
|
||||
dump("NODENAME: " + element.nodeName + "\n");
|
||||
var nodeMap = element.attributes;
|
||||
var nodeMapCount = nodeMap.length;
|
||||
var treekids = document.getElementById("attributelist");
|
||||
|
||||
if(nodeMapCount > 0) {
|
||||
for(i = 0; i < nodeMapCount; i++)
|
||||
{
|
||||
if(!CheckAttributeNameSimilarity(nodeMap[i].nodeName)) {
|
||||
dump("repeated attribute!\n");
|
||||
continue; // repeated attribute, ignore this one and go to next
|
||||
}
|
||||
elAttrs[i] = nodeMap[i].nodeName;
|
||||
var treeitem = document.createElement("treeitem");
|
||||
var treerow = document.createElement("treerow");
|
||||
var attrcell = document.createElement("treecell");
|
||||
var attrcontent = document.createTextNode(nodeMap[i].nodeName.toUpperCase());
|
||||
attrcell.appendChild(attrcontent);
|
||||
treerow.appendChild(attrcell);
|
||||
var valcell = document.createElement("treecell");
|
||||
valcell.setAttribute("class","value");
|
||||
var valField = document.createElement("html:input");
|
||||
var attrValue = element.getAttribute(nodeMap[i].nodeName);
|
||||
valField.setAttribute("type","text");
|
||||
valField.setAttribute("id",nodeMap[i].nodeName.toLowerCase());
|
||||
valField.setAttribute("value",attrValue);
|
||||
valField.setAttribute("flex","100%");
|
||||
valField.setAttribute("class","AttributesCell");
|
||||
valcell.appendChild(valField);
|
||||
treerow.appendChild(valcell);
|
||||
treeitem.appendChild(treerow);
|
||||
treekids.appendChild(treeitem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add an attribute to the tree widget
|
||||
function onAddAttribute()
|
||||
{
|
||||
//var name = TrimString(dialog.AddAttributeNameInput.value);
|
||||
name = dialog.AddAttributeNameInput.value;
|
||||
var value = TrimString(dialog.AddAttributeValueInput.value);
|
||||
|
||||
// Must have a name to be able to add (Value may be empty)
|
||||
if(name == "")
|
||||
return;
|
||||
|
||||
// WHAT'S GOING ON? NAME ALWAYS HAS A VALUE OF accented "a"???
|
||||
dump(name+"= New Attribute Name - SHOULD BE EMPTY\n");
|
||||
// for..in loop, typeof, /^on/ match
|
||||
|
||||
|
||||
elAttrs[elAttrs.length] = name;
|
||||
|
||||
// TODO: Add a new text + editbox to the treewidget editing list
|
||||
var treekids = document.getElementById("attributelist");
|
||||
var treeitem = document.createElement("treeitem");
|
||||
var treerow = document.createElement("treerow");
|
||||
var attrcell = document.createElement("treecell");
|
||||
var attrcontent = document.createTextNode(name.toUpperCase());
|
||||
attrcell.appendChild(attrcontent);
|
||||
treerow.appendChild(attrcell);
|
||||
var valcell = document.createElement("treecell");
|
||||
valcell.setAttribute("class","value");
|
||||
var valField = document.createElement("html:input");
|
||||
valField.setAttribute("type","text");
|
||||
valField.setAttribute("id",name);
|
||||
valField.setAttribute("value",value);
|
||||
valField.setAttribute("flex","100%");
|
||||
valField.setAttribute("class","AttributesCell");
|
||||
valcell.appendChild(valField);
|
||||
treerow.appendChild(valcell);
|
||||
treeitem.appendChild(treerow);
|
||||
treekids.appendChild(treeitem);
|
||||
dialog.AddAttributeNameInput.value = "";
|
||||
dialog.AddAttributeValueInput.value = "";
|
||||
|
||||
// Set focus to the value edit field just added:
|
||||
valField.focus();
|
||||
|
||||
//Clear the edit boxes
|
||||
dialog.AddAttributeNameInput.value = "";
|
||||
dialog.AddAttributeValueInput.value = "";
|
||||
}
|
||||
|
||||
// shut the dialog, apply changes and tidy up
|
||||
function onOK()
|
||||
{
|
||||
dump("in onOK\n")
|
||||
UpdateObject(); // call UpdateObject fn to update element in document
|
||||
window.opener.AdvancedEditOK = true;
|
||||
window.opener.globalElement = element;
|
||||
return true; // do close the window
|
||||
}
|
||||
|
||||
// updates the element object with values set in the tree.
|
||||
// TODO: make this work for many objects, so the "vicinity diagram"
|
||||
// can be used.
|
||||
// function EdAvancedEdit.js::<UpdateObject>
|
||||
// Updates the copy of the page object with the data set in this dialog.
|
||||
function UpdateObject()
|
||||
{
|
||||
var treekids = document.getElementById("attributelist");
|
||||
for(i = 0; i < treekids.childNodes.length; i++)
|
||||
dump("in UpdateObject\n");
|
||||
var HTMLAList = document.getElementById("HTMLAList");
|
||||
var CSSAList = document.getElementById("CSSAList");
|
||||
var JSEAList = document.getElementById("JSEAList");
|
||||
|
||||
// HTML ATTRIBUTES
|
||||
for(var i = 0; i < HTMLAList.childNodes.length; i++)
|
||||
{
|
||||
var item = treekids.childNodes[i];
|
||||
var name = item.firstChild.firstChild.firstChild.nodeValue;
|
||||
var item = HTMLAList.childNodes[i];
|
||||
var name = TrimString(item.firstChild.firstChild.firstChild.nodeValue);
|
||||
var value = TrimString(item.firstChild.lastChild.firstChild.value);
|
||||
dump("HTML Attrs: n: " + name + "; v: " + value + "\n");
|
||||
element.setAttribute(name,value);
|
||||
}
|
||||
// CSS ATTRIBUTES
|
||||
var styleString = "";
|
||||
for(var i = 0; i < CSSAList.childNodes.length; i++)
|
||||
{
|
||||
var item = CSSAList.childNodes[i];
|
||||
var name = TrimString(item.firstChild.firstChild.firstChild.nodeValue);
|
||||
var value = TrimString(item.firstChild.lastChild.firstChild.value);
|
||||
if(name.lastIndexOf(":") == (name.length - 1) && name.length > 0)
|
||||
name = name.substring(0,name.length-1);
|
||||
if(value.lastIndexOf(";") == (value.length - 1) && value.length > 0)
|
||||
value = name.substring(0,value.length-1);
|
||||
if(i == (CSSAList.childNodes.length - 1))
|
||||
styleString += name + ": " + value + ";"; // last property
|
||||
else
|
||||
styleString += name + ": " + value + "; ";
|
||||
}
|
||||
dump("stylestring: ||" + styleString + "||\n");
|
||||
var name = "width";
|
||||
if(styleString.length > 0) {
|
||||
element.setAttribute(name,styleString);
|
||||
}
|
||||
// JS EVENT HANDLERS
|
||||
for(var i = 0; i < JSEAList.childNodes.length; i++)
|
||||
{
|
||||
var item = JSEAList.childNodes[i];
|
||||
name = TrimString(item.firstChild.firstChild.firstChild.nodeValue);
|
||||
value = TrimString(item.firstChild.lastChild.firstChild.value);
|
||||
element.setAttribute(name,value);
|
||||
}
|
||||
}
|
||||
|
||||
// checks to see if any other attributes by the same name as the arg supplied
|
||||
// already exist.
|
||||
function CheckAttributeNameSimilarity(attName)
|
||||
function CheckAttributeNameSimilarity(attName, attArray)
|
||||
{
|
||||
for(i = 0; i < elAttrs.length; i++)
|
||||
for(var i = 0; i < attArray.length; i++)
|
||||
{
|
||||
if(attName == elAttrs[i])
|
||||
if(attName == attArray[i])
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// does enabling based on any user input.
|
||||
function doOverallEnabling()
|
||||
{
|
||||
var name = TrimString(dialog.AddAttributeNameInput.value);
|
||||
if( name == "" || !CheckAttributeNameSimilarity(name)) {
|
||||
dialog.AddAttribute.setAttribute("disabled","true");
|
||||
} else {
|
||||
dialog.AddAttribute.removeAttribute("disabled");
|
||||
}
|
||||
}
|
||||
|
||||
function doSort()
|
||||
{
|
||||
/* UpdateObject();
|
||||
var treekids = document.getElementById("attributelist");
|
||||
var nameArray = []
|
||||
for(i = 0; i < treekids.childNodes.length; i++)
|
||||
{
|
||||
var item = treekids.childNodes[i];
|
||||
nameArray[i] = item.firstChild.firstChild.firstChild.nodeValue;
|
||||
}
|
||||
nameArray.sort(posval);
|
||||
dump("nameArray: " + nameArray + "\n");
|
||||
nameArray.sort(negval);
|
||||
dump("nameArray: " + nameArray + "\n");
|
||||
*/
|
||||
}
|
||||
|
||||
|
@ -39,51 +39,132 @@
|
||||
|
||||
<!-- Methods common to all editor dialogs -->
|
||||
<html:script language="JavaScript" src="chrome://editor/content/EdDialogCommon.js"/>
|
||||
<!-- global dialog functions -->
|
||||
<html:script language="JavaScript" src="chrome://editor/content/EdAdvancedEdit.js"/>
|
||||
<!-- element page functions -->
|
||||
<html:script language="JavaScript" src="chrome://editor/content/EdAEHTMLAttributes.js"/>
|
||||
<html:script language="JavaScript" src="chrome://editor/content/EdAECSSAttributes.js"/>
|
||||
<html:script language="JavaScript" src="chrome://editor/content/EdAEJSEAttributes.js"/>
|
||||
|
||||
<html:script language="JavaScript" src="chrome://global/content/dialogOverlay.js" />
|
||||
|
||||
<broadcaster id="args" value=""/>
|
||||
|
||||
<keyset id="keyset"/>
|
||||
|
||||
<box align="horizontal">
|
||||
<html:label flex="100%">¤tattributesfor.label;</html:label>
|
||||
<html:div flex="100%" id="tagLabel"/>
|
||||
</box>
|
||||
<spring class="spacer"/>
|
||||
<box>
|
||||
<tree id="AttributesTree" class="AttributesTree" flex="100%">
|
||||
<tabcontrol align="vertical">
|
||||
<tabbox>
|
||||
<tab>&tabHTML.label;</tab>
|
||||
<tab>&tabCSS.label;</tab>
|
||||
<tab>&tabJSE.label;</tab>
|
||||
</tabbox>
|
||||
<tabpanel>
|
||||
<!-- CSS Properties -->
|
||||
<box class="tabpanel" flex="100%" align="vertical">
|
||||
<tree id="HTMLATree" class="AttributesTree" flex="100%">
|
||||
<treecol width="20%"/>
|
||||
<treecol width="80%"/>
|
||||
<treehead>
|
||||
<treerow>
|
||||
<treecell onclick="doSort()">&tree.attributeHeader.label;</treecell>
|
||||
<treecell>&tree.valueHeader.label;</treecell>
|
||||
</treerow>
|
||||
<treerow>
|
||||
<treecell>&tree.attributeHeader.label;</treecell>
|
||||
<treecell>&tree.valueHeader.label;</treecell>
|
||||
</treerow>
|
||||
</treehead>
|
||||
<treechildren id="attributelist"/>
|
||||
</tree>
|
||||
</box>
|
||||
<treechildren id="HTMLAList"/>
|
||||
</tree>
|
||||
<box align="vertical">
|
||||
<spring class="spacer"/>
|
||||
<html:fieldset>
|
||||
<html:legend>&AddHTMLAttributeLabel.label;</html:legend>
|
||||
<box align="horizontal">
|
||||
<html:label for="AddHTMLAttributeNameInput"> &AttName.label;</html:label>
|
||||
<box align="horizontal" flex="100%">
|
||||
<html:div><html:input type="text" id="AddHTMLAttributeNameInput" onkeyup="doHTMLEnabling()" onmouseup="doHTMLEnabling()"/></html:div>
|
||||
<spring class="spacer"/>
|
||||
</box>
|
||||
<html:label for="AddHTMLAttributeValueInput"> &AttValue.label;</html:label>
|
||||
<box align="horizontal" flex="100%">
|
||||
<html:div><html:input type="text" id="AddHTMLAttributeValueInput"/></html:div>
|
||||
<spring flex="100%" class="spacer"/>
|
||||
<html:div><titledbutton class="hspaced" id="AddHTMLAttribute" onclick="onAddHTMLAttribute()" value="&AddAttributeButton.label;" disabled="true"/></html:div>
|
||||
</box>
|
||||
</box>
|
||||
</html:fieldset>
|
||||
</box>
|
||||
</box>
|
||||
<!-- JavaScript Event Handlers -->
|
||||
<box class="tabpanel" flex="100%" align="vertical">
|
||||
<tree id="JSEATree" class="AttributesTree" flex="100%">
|
||||
<treecol width="20%"/>
|
||||
<treecol width="80%"/>
|
||||
<treehead>
|
||||
<treerow>
|
||||
<treecell>&tree.attributeHeader.label;</treecell>
|
||||
<treecell>&tree.valueHeader.label;</treecell>
|
||||
</treerow>
|
||||
</treehead>
|
||||
<treechildren id="JSEAList"/>
|
||||
</tree>
|
||||
<box align="vertical">
|
||||
<spring class="spacer"/>
|
||||
<html:fieldset>
|
||||
<html:legend>&AddJSEAttributeLabel.label;</html:legend>
|
||||
<box align="horizontal">
|
||||
<html:label for="JSEAddAttributeNameInput"> &AttName.label;</html:label>
|
||||
<box align="horizontal" flex="100%">
|
||||
<html:div><html:input type="text" id="AddJSEAttributeNameInput" onkeyup="doJSEEnabling()" onmouseup="doJSEEnabling()"/></html:div>
|
||||
<spring class="spacer"/>
|
||||
</box>
|
||||
<html:label for="AddJSEAttributeValueInput"> &AttValue.label;</html:label>
|
||||
<box align="horizontal" flex="100%">
|
||||
<html:div><html:input type="text" id="AddJSEAttributeValueInput"/></html:div>
|
||||
<spring flex="100%" class="spacer"/>
|
||||
<html:div><titledbutton class="hspaced" id="AddJSEAttribute" onclick="onAddJSEAttribute()" value="&AddAttributeButton.label;" disabled="true"/></html:div>
|
||||
</box>
|
||||
</box>
|
||||
</html:fieldset>
|
||||
</box>
|
||||
</box>
|
||||
<!-- HTML Attributes -->
|
||||
<box class="tabpanel" flex="100%" align="vertical">
|
||||
<tree id="CSSATree" class="AttributesTree" flex="100%">
|
||||
<treecol width="20%"/>
|
||||
<treecol width="80%"/>
|
||||
<treehead>
|
||||
<treerow>
|
||||
<treecell>&tree.attributeHeader.label;</treecell>
|
||||
<treecell>&tree.valueHeader.label;</treecell>
|
||||
</treerow>
|
||||
</treehead>
|
||||
<treechildren id="CSSAList"/>
|
||||
</tree>
|
||||
<box align="vertical">
|
||||
<spring class="spacer"/>
|
||||
<html:fieldset>
|
||||
<html:legend>&AddCSSAttributeLabel.label;</html:legend>
|
||||
<box align="horizontal">
|
||||
<html:label for="AddCSSAttributeNameInput"> &AttName.label;</html:label>
|
||||
<box align="horizontal" flex="100%">
|
||||
<html:div><html:input type="text" id="AddCSSAttributeNameInput" onkeyup="doCSSEnabling()" onmouseup="doCSSEnabling()"/></html:div>
|
||||
<spring class="spacer"/>
|
||||
</box>
|
||||
<html:label for="AddCSSAttributeValueInput"> &AttValue.label;</html:label>
|
||||
<box align="horizontal" flex="100%">
|
||||
<html:div><html:input type="text" id="AddCSSAttributeValueInput"/></html:div>
|
||||
<spring flex="100%" class="spacer"/>
|
||||
<html:div><titledbutton class="hspaced" id="AddCSSAttribute" onclick="onAddCSSAttribute()" value="&AddAttributeButton.label;" disabled="true"/></html:div>
|
||||
</box>
|
||||
</box>
|
||||
</html:fieldset>
|
||||
</box>
|
||||
</box>
|
||||
|
||||
</tabpanel>
|
||||
</tabcontrol>
|
||||
|
||||
<box align="vertical">
|
||||
<spring class="spacer"/>
|
||||
<html:fieldset>
|
||||
<html:legend>&AddAttributeLabel.label;</html:legend>
|
||||
<box align="horizontal">
|
||||
<html:label for="AddAttributeNameInput"> &AttName.label;</html:label>
|
||||
<box align="horizontal" flex="100%">
|
||||
<html:div><html:input type="text" id="AddAttributeNameInput" onkeyup="doOverallEnabling()" onmouseup="doOverallEnabling()"/></html:div>
|
||||
<spring class="spacer"/>
|
||||
</box>
|
||||
<html:label for="AddAttributeValueInput"> &AttValue.label;</html:label>
|
||||
<box align="horizontal" flex="100%">
|
||||
<html:div><html:input type="text" id="AddAttributeValueInput"/></html:div>
|
||||
<spring flex="100%" class="spacer"/>
|
||||
<html:div><titledbutton class="hspaced" id="AddAttribute" onclick="onAddAttribute()" value="&AddAttributeButton.label;" disabled="true"/></html:div>
|
||||
</box>
|
||||
</box>
|
||||
</html:fieldset>
|
||||
</box>
|
||||
<box align="horizontal">
|
||||
<html:div style="margin-top: 0.5em"><titledbutton value="&HTMLReference.label;"/></html:div>
|
||||
<spring flex="100%"/>
|
||||
|
@ -47,7 +47,7 @@
|
||||
<xul:keyset id="keyset"/>
|
||||
|
||||
<xul:box>
|
||||
<label id="srcMessage"> &sourceEditField.label; </label>
|
||||
<label id="srcMessage"/>
|
||||
</xul:box>
|
||||
<xul:box>
|
||||
<textarea rows="6" cols="50" id="srcInput" />
|
||||
|
@ -61,23 +61,28 @@ function Startup()
|
||||
// Initialize all widgets with image attributes
|
||||
InitDialog();
|
||||
|
||||
|
||||
// Set initial number to 1 row, 2 columns:
|
||||
// Note, these are not attributes on the table,
|
||||
// so don't put them in InitDialog(),
|
||||
// else the user's values will be trashed when they use
|
||||
// the Advanced Edit dialog
|
||||
dialog.rowsInput.value = 1;
|
||||
dialog.columnsInput.value = 2;
|
||||
|
||||
dialog.rowsInput.focus();
|
||||
}
|
||||
|
||||
// Set dialog widgets with attribute data
|
||||
// We get them from globalElement copy so this can be used
|
||||
// by AdvancedEdit(), which is shared by all property dialogs
|
||||
function InitData()
|
||||
function InitDialog()
|
||||
{
|
||||
// Get default attributes set on the created table:
|
||||
// Get the width attribute of the element, stripping out "%"
|
||||
// This sets contents of button text and "percentChar" variable
|
||||
dialog.widthInput.value = InitPixelOrPercentPopupButton(globalElement, "width", "pixelOrPercentButton");
|
||||
dialog.borderInput.value = globalElement.getAttribute("border");
|
||||
|
||||
// Set default number to 1 row, 2 columns:
|
||||
dialog.rowsInput.value = 1;
|
||||
dialog.columnsInput.value = 2;
|
||||
}
|
||||
|
||||
// Get and validate data from widgets.
|
||||
|
@ -30,6 +30,11 @@ var hrefInput;
|
||||
var linkMessage;
|
||||
var href;
|
||||
var newLinkText;
|
||||
var HeadingsIndex = -1;
|
||||
var NamedAnchorsIndex = -1;
|
||||
var NamedAnchorsList = 0;
|
||||
var HNodeArray;
|
||||
var StartIndexOfHeadings = 1;
|
||||
|
||||
// NOTE: Use "href" instead of "a" to distinguish from Named Anchor
|
||||
// The returned node is has an "a" tagName
|
||||
@ -144,6 +149,9 @@ function Startup()
|
||||
// Make a copy to use for AdvancedEdit and onSaveDefault
|
||||
globalElement = anchorElement.cloneNode(false);
|
||||
|
||||
// Get the list of existing named anchors and headings
|
||||
FillNamedAnchorList();
|
||||
|
||||
// Set data for the dialog controls
|
||||
InitDialog();
|
||||
|
||||
@ -192,6 +200,41 @@ function RemoveLink()
|
||||
hrefInput.value = "";
|
||||
}
|
||||
|
||||
function FillNamedAnchorList()
|
||||
{
|
||||
NamedAnchorNodeList = editorShell.editorDocument.anchors;
|
||||
var headingList = editorShell.editorDocument.getElementsByTagName("h2");
|
||||
dump(headingList+" Count= "+headingList.length+"\n");
|
||||
if (headingList.length > 0) {
|
||||
dump("HELLO\n");
|
||||
var heading = headingList.item(0);
|
||||
|
||||
var range = editorShell.editorDocument.createRange();
|
||||
range.setStart(heading,0);
|
||||
var lastChildIndex = heading.childNodes.length;
|
||||
range.setEnd(heading,lastChildIndex);
|
||||
var text = range.toString();
|
||||
dump("Range:"+range+" LastChildIndex = "+lastChildIndex+"\nText: "+text+"\n");
|
||||
}
|
||||
}
|
||||
|
||||
function SelectNamedAnchor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function AnchorNameExists(name)
|
||||
{
|
||||
if (NamedAnchorsList) {
|
||||
for (i=0; i < NamedAnchorsList.length; i++) {
|
||||
if (NamedAnchorsList[i].name == name)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Get and validate data from widgets.
|
||||
// Set attributes on globalElement so they can be accessed by AdvancedEdit()
|
||||
function ValidateData()
|
||||
|
@ -50,24 +50,29 @@
|
||||
<label id="linkTextCaption" for="linkTextMessage"> &LinkText.label; </label>
|
||||
<div id="linkTextMessage" style="margin-left: 3em">[replace this]</div>
|
||||
<input type="text" size="25" length="25" id="linkTextInput"/>
|
||||
<xul:spring class="bigspacer"/>
|
||||
<xul:spring class="spacer"/>
|
||||
|
||||
<fieldset><legend align="left"> &LinkURLFieldset.label; </legend>
|
||||
<xul:box align="vertical" style="width: 100%; height: 100%">
|
||||
<xul:box align="horizontal">
|
||||
<div> &LinkURLEditField.label;</div>
|
||||
<xul:spring flex="100%"/>
|
||||
<xul:titledbutton class="hspaced" id="RemoveLink" onclick="RemoveLink()" value="&RemoveLinkButton.label;"/>
|
||||
<div><xul:titledbutton id="RemoveLink" onclick="RemoveLink()" value="&RemoveLinkButton.label;"/>
|
||||
</div>
|
||||
</xul:box>
|
||||
<xul:box align="horizontal">
|
||||
<input type="text" size="25" length="25" id="hrefInput"></input>
|
||||
<xul:spring flex="100%"/>
|
||||
<!-- The div prevents button from being the same height as the input field -->
|
||||
<div><xul:titledbutton class="hspaced" id="ChooseFile" onclick="ChooseFile()" value="&LinkChooseFileButton.label;"/></div>
|
||||
<div><xul:titledbutton id="ChooseFile1" onclick="ChooseFile()" value="&LinkChooseFileButton.label;"/></div>
|
||||
</xul:box>
|
||||
</xul:box>
|
||||
<xul:spring class="spacer"/>
|
||||
<div>&NamedAnchorMsg.label;</div>
|
||||
<select id="NamedAnchorList" style="min-width: 15em; max-width: 25em" size="5" onchange="SelectNamedAnchor()"/>
|
||||
</fieldset>
|
||||
</xul:box>
|
||||
|
||||
<!-- from EdDialogOverlay -->
|
||||
<xul:box id="AdvancedEditButton"/>
|
||||
<!-- from global dialogOverlay -->
|
||||
|
@ -47,6 +47,8 @@ function Startup()
|
||||
StartingNumberInput = document.getElementById("StartingNumber");
|
||||
StartingNumberLabel = document.getElementById("StartingNumberLabel");
|
||||
|
||||
// Try to get an existing list
|
||||
//
|
||||
InitDialog();
|
||||
ListStyleList.focus();
|
||||
}
|
||||
|
@ -47,6 +47,8 @@
|
||||
|
||||
<label class="spacedtext" for="nameInput"> &anchorNameEditField.label; </label>
|
||||
<input type="text" id="nameInput" size="30" maxlength="255" />
|
||||
<div>&noSpacesMsg.label;</div>
|
||||
<xul:spring class="spacer"/>
|
||||
<!-- from EdDialogOverlay -->
|
||||
<xul:box id="AdvancedEditButton"/>
|
||||
<!-- from global dialogOverlay -->
|
||||
|
@ -48,3 +48,6 @@ EdAdvancedEdit.xul
|
||||
EdAdvancedEdit.js
|
||||
EdListProps.xul
|
||||
EdListProps.js
|
||||
EdAECSSAttributes.js
|
||||
EdAEHTMLAttributes.js
|
||||
EdAEJSEAttributes.js
|
||||
|
@ -49,6 +49,9 @@ EXPORT_RESOURCE_CONTENT = \
|
||||
$(srcdir)/EdDialogOverlay.xul \
|
||||
$(srcdir)/EdAdvancedEdit.xul \
|
||||
$(srcdir)/EdAdvancedEdit.js \
|
||||
$(srcdir)/EdAECSSAttributes.js \
|
||||
$(srcdir)/EdAEHTMLAttributes.js \
|
||||
$(srcdir)/EdAEJSEAttributes.js \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -46,6 +46,9 @@ install::
|
||||
$(MAKE_INSTALL) EdAdvancedEdit.js $(DIST)\bin\chrome\editor\content\default
|
||||
$(MAKE_INSTALL) EdListProps.xul $(DIST)\bin\chrome\editor\content\default
|
||||
$(MAKE_INSTALL) EdListProps.js $(DIST)\bin\chrome\editor\content\default
|
||||
$(MAKE_INSTALL) EdAECSSAttributes.js $(DIST)\bin\chrome\editor\content\default
|
||||
$(MAKE_INSTALL) EdAEHTMLAttributes.js $(DIST)\bin\chrome\editor\content\default
|
||||
$(MAKE_INSTALL) EdAEJSEAttributes.js $(DIST)\bin\chrome\editor\content\default
|
||||
|
||||
|
||||
clobber::
|
||||
@ -75,3 +78,6 @@ clobber::
|
||||
rm -f $(DIST)\bin\chrome\editor\content\default\EdAdvancedEdit.js
|
||||
rm -f $(DIST)\bin\chrome\editor\content\default\EdListProps.xul
|
||||
rm -f $(DIST)\bin\chrome\editor\content\default\EdListProps.js
|
||||
rm -f $(DIST)\bin\chrome\editor\content\default\EdAECSSAttributes.js
|
||||
rm -f $(DIST)\bin\chrome\editor\content\default\EdAEHTMLAttributes.js
|
||||
rm -f $(DIST)\bin\chrome\editor\content\default\EdAEJSEAttributes.js
|
||||
|
@ -30,3 +30,10 @@
|
||||
<!ENTITY currentattributesfor.label "Current attributes for: ">
|
||||
<!ENTITY tree.attributeHeader.label "Attribute">
|
||||
<!ENTITY tree.valueHeader.label "Value">
|
||||
<!ENTITY tabHTML.label "HTML Attributes">
|
||||
<!ENTITY tabCSS.label "Style/Appearance">
|
||||
<!ENTITY tabJSE.label "JavaScript Events">
|
||||
|
||||
<!ENTITY AddJSEAttributeLabel.label "Add a JavaScript Event Handler">
|
||||
<!ENTITY AddHTMLAttributeLabel.label "Add a HTML Attribute">
|
||||
<!ENTITY AddCSSAttributeLabel.label "Add a CSS/Style Attribute">
|
@ -22,4 +22,6 @@
|
||||
|
||||
<!ENTITY windowTitle.label "Named Anchor Properties">
|
||||
<!ENTITY anchorNameEditField.label "Anchor Name:">
|
||||
<!ENTITY noSpacesMsg.label "(Spaces are not allowed.)">
|
||||
|
||||
|
||||
|
@ -22,6 +22,5 @@
|
||||
|
||||
<!-- Window title -->
|
||||
<!ENTITY windowTitle.label "Insert HTML">
|
||||
|
||||
<!ENTITY sourceFieldset.label "HTML Source">
|
||||
<!ENTITY sourceEditField.label "Enter HTML source to insert:">
|
||||
<!ENTITY sourceEditField.label "Enter HTML tags and text:">
|
||||
<!ENTITY example.label "Hello World!">
|
||||
|
@ -38,3 +38,7 @@
|
||||
<!ENTITY LinkURLEditField.label "Enter a web page location or local file:">
|
||||
<!ENTITY LinkChooseFileButton.label "Choose File...">
|
||||
<!ENTITY RemoveLinkButton.label "Remove Link">
|
||||
<!ENTITY NamedAnchorMsg.label "Or select a named anchor or heading:">
|
||||
<!ENTITY NamedAnchorMsg.label "Create named anchors and/or headings and they will appear in this list">
|
||||
|
||||
|
||||
|
@ -36,7 +36,130 @@ window{
|
||||
|
||||
}
|
||||
|
||||
/* THIS SHOULD BE KILLED. NO SPECIAL TITLED BUTTONS SHOULD BE USED! */
|
||||
tab {
|
||||
padding: 0px 3px;
|
||||
}
|
||||
|
||||
titledbutton.popup {
|
||||
|
||||
list-style-image: url(resource:/res/toolbar/TB_popup.gif);
|
||||
width: auto;
|
||||
display: inline;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
border: 1px outset white;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
titledbutton.popup:hover {
|
||||
background-color: inherit;
|
||||
background-image: inherit;
|
||||
border: 1px outset white;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
titledbutton.popup:active {
|
||||
|
||||
text-decoration: none;
|
||||
border: 1px outset white;
|
||||
color: none;
|
||||
color: black; /* why is color set twice? */
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
|
||||
}
|
||||
|
||||
|
||||
titledbutton.popup[disabled="true"] {
|
||||
|
||||
background-color: inherit;
|
||||
background-image: inherit;
|
||||
border : 1px solid #999999;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
color: #999999;
|
||||
text-decoration: none;
|
||||
image-opacity: 25%;
|
||||
}
|
||||
|
||||
titledbutton.popup[disabled="true"]:hover {
|
||||
|
||||
background-color: inherit;
|
||||
background-image: inherit;
|
||||
border : 1px solid #999999;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
color: #999999;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
titledbutton.popup[disabled="true"]:active {
|
||||
|
||||
background-color: inherit;
|
||||
background-image: inherit;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
border : 1px solid #999999;
|
||||
color: #999999;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
titledbutton.dropdown {
|
||||
|
||||
width: 100%;
|
||||
display: inline;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
border: none;
|
||||
font: inherit;
|
||||
background-repeat: no-repeat;
|
||||
background-color: inherit;
|
||||
color: black;
|
||||
|
||||
|
||||
}
|
||||
|
||||
titledbutton.dropdown:hover {
|
||||
|
||||
width: 100%;
|
||||
display: inline;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
border: none;
|
||||
font: inherit;
|
||||
background-repeat: no-repeat;
|
||||
background-color: #666699;
|
||||
color: white;
|
||||
|
||||
|
||||
}
|
||||
|
||||
titledbutton.dropdown:active {
|
||||
|
||||
width: 100%;
|
||||
display: inline;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
border: none;
|
||||
font: inherit;
|
||||
background-repeat: no-repeat;
|
||||
background-color: #666699;
|
||||
|
||||
|
||||
}
|
||||
|
||||
titledbutton.select {
|
||||
|
||||
width: 100%;
|
||||
@ -87,7 +210,7 @@ titledbutton.select:active {
|
||||
|
||||
}
|
||||
|
||||
/* Subtle changes, like a little more space, is OK */
|
||||
|
||||
/* Don't mess with top and bottom margin! */
|
||||
|
||||
titledbutton[class=~spaced] {
|
||||
@ -95,6 +218,8 @@ titledbutton[class=~spaced] {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* This assumes 1px is shifted to the border
|
||||
|
||||
|
||||
|
||||
|
||||
@ -183,29 +308,30 @@ titledbutton.MsgButton {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
/* What is this for!
|
||||
|
||||
menupopup {
|
||||
|
||||
font: inherit;
|
||||
visibility: hidden;
|
||||
background-color: #CCCCDD;
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
border: 1px white outset;
|
||||
}
|
||||
*/
|
||||
|
||||
select.ComboBox {
|
||||
/*
|
||||
EXPERIMENTAL: This ADDS an outset border,
|
||||
but doesn't affect inset border of item and trigger button!
|
||||
select.combobox {
|
||||
|
||||
font-family: Sans-Serif;
|
||||
font-size: 8pt;
|
||||
border-top: 2px;
|
||||
border-left: 4px;
|
||||
border-right: 2px;
|
||||
border-style: outset;
|
||||
*/
|
||||
}
|
||||
|
||||
select.SpellCheckList, select.SpellCheckLanguage, input.SpellCheckWord {
|
||||
|
||||
width: 20em;
|
||||
/* border-style: inset; */
|
||||
border-style: inset;
|
||||
background-color: #CCCCCC; /* not working on Macintosh */
|
||||
}
|
||||
|
||||
@ -501,7 +627,6 @@ spring.bigspacer {
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
/* From Ben Goodger (originally EdAdvancedEdit.css) */
|
||||
div.spacer [align~=horizontal] {
|
||||
border : 1px inset white;
|
||||
height : 2px;
|
||||
@ -587,7 +712,7 @@ input.AttributesCell {
|
||||
border : none;
|
||||
height : 100%;
|
||||
}
|
||||
|
||||
/*
|
||||
input.AttributesCell:active {
|
||||
border: 1px white inset;
|
||||
}
|
||||
@ -595,33 +720,15 @@ input.AttributesCell:active {
|
||||
input.AttributesCell:hover {
|
||||
border: 1px white inset;
|
||||
}
|
||||
*/
|
||||
|
||||
/* From Ben Goodger (originally EdTableProps.css) */
|
||||
box.header {
|
||||
/* background-color: #7777A4;*/
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
box.header > div {
|
||||
color: #000000;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
box.panel {
|
||||
border: 1px outset white;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
fieldset.holder {
|
||||
width: 350px;
|
||||
|
||||
/* Always use the arrow cursor, except in input widget */
|
||||
*,p,div,legend,box {cursor: pointer;}
|
||||
button { cursor: crosshair; }
|
||||
|
||||
input[type=text], input[type=textarea] {
|
||||
cursor: text;
|
||||
treecell input:hover {
|
||||
background-color : #ECECEC;
|
||||
font-weight : bold;
|
||||
border : 2px solid #666699;
|
||||
}
|
||||
|
||||
box.tabpanel {
|
||||
border: 1px outset #CCCCDD;
|
||||
padding: 10px;
|
||||
}
|
Loading…
Reference in New Issue
Block a user