262 lines
6.9 KiB
C++
262 lines
6.9 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* 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 Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
|
|
|
|
|
|
#include "nsMarkupDocument.h"
|
|
#include "nsIContent.h"
|
|
#include "nsIURL.h"
|
|
#include "nsIDOMElement.h"
|
|
|
|
#include "nsCSSProps.h"
|
|
#include "nsICSSStyleSheet.h"
|
|
#include "nsICSSStyleRule.h"
|
|
#include "nsICSSDeclaration.h"
|
|
#include "nsIHTMLCSSStyleSheet.h"
|
|
#include "nsHTMLValue.h"
|
|
#include "nsXIFConverter.h"
|
|
|
|
#include "nsIPresShell.h"
|
|
|
|
static NS_DEFINE_IID(kIContentIID, NS_ICONTENT_IID);
|
|
static NS_DEFINE_IID(kICSSStyleSheetIID, NS_ICSS_STYLE_SHEET_IID);
|
|
|
|
|
|
|
|
nsMarkupDocument::nsMarkupDocument() : nsDocument()
|
|
{
|
|
}
|
|
|
|
nsMarkupDocument::~nsMarkupDocument()
|
|
{
|
|
}
|
|
|
|
// XXX Temp hack: moved from nsDocument to fix circular linkage problem...
|
|
extern NS_LAYOUT nsresult
|
|
NS_NewPresShell(nsIPresShell** aInstancePtrResult);
|
|
|
|
NS_IMETHODIMP
|
|
nsMarkupDocument::CreateShell(nsIPresContext* aContext,
|
|
nsIViewManager* aViewManager,
|
|
nsIStyleSet* aStyleSet,
|
|
nsIPresShell** aInstancePtrResult)
|
|
{
|
|
NS_PRECONDITION(nsnull != aInstancePtrResult, "null ptr");
|
|
if (nsnull == aInstancePtrResult) {
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
nsIPresShell* shell;
|
|
nsresult rv = NS_NewPresShell(&shell);
|
|
if (NS_OK != rv) {
|
|
return rv;
|
|
}
|
|
|
|
if (NS_OK != (rv = shell->Init(this, aContext, aViewManager, aStyleSet))) {
|
|
NS_RELEASE(shell);
|
|
return rv;
|
|
}
|
|
|
|
// Note: we don't hold a ref to the shell (it holds a ref to us)
|
|
mPresShells.AppendElement(shell);
|
|
*aInstancePtrResult = shell;
|
|
return NS_OK;
|
|
}
|
|
|
|
/**
|
|
* Converts a CSS selector to XIF
|
|
*
|
|
* @update gpk 01/17/1998
|
|
* @param aConverter -- the XIFConverter where all output is being written
|
|
* @param aSelector -- the Object to be converted to XIF
|
|
*/
|
|
void nsMarkupDocument::CSSSelectorsToXIF(nsXIFConverter& aConverter, nsICSSStyleRule& aRule)
|
|
{
|
|
nsAutoString selectors;
|
|
|
|
aRule.GetSourceSelectorText(selectors);
|
|
aConverter.BeginCSSSelectors();
|
|
|
|
aConverter.AddCSSSelectors(selectors);
|
|
|
|
aConverter.EndCSSSelectors();
|
|
}
|
|
|
|
|
|
/**
|
|
* Converts a CSS Declaration to XIF
|
|
*
|
|
* @update gpk 01/17/1998
|
|
* @param aConverter -- the XIFConverter where all output is being written
|
|
* @param aDeclaration -- the Object to be converted to XIF
|
|
*/
|
|
void nsMarkupDocument::CSSDeclarationToXIF(nsXIFConverter& aConverter, nsICSSDeclaration& aDeclaration)
|
|
{
|
|
nsAutoString list;
|
|
nsAutoString decl;
|
|
|
|
aConverter.BeginCSSDeclarationList();
|
|
aDeclaration.ToString(list);
|
|
|
|
PRInt32 start = 0;
|
|
PRInt32 semiColon = list.FindChar(';');
|
|
|
|
while (-1 < semiColon) {
|
|
decl.Truncate();
|
|
list.Mid(decl, start, semiColon - start);
|
|
|
|
if (0 == decl.Compare("/*", PR_FALSE, 2)) {
|
|
// XXX need to append comment
|
|
}
|
|
else {
|
|
PRInt32 colon = decl.FindChar(':');
|
|
nsAutoString property;
|
|
nsAutoString value;
|
|
|
|
aConverter.BeginCSSDeclaration();
|
|
if (-1 < colon) {
|
|
decl.Left(property, colon);
|
|
property.StripWhitespace();
|
|
decl.Right(value, (decl.Length() - colon) - 2);
|
|
aConverter.AddCSSDeclaration(property, value);
|
|
}
|
|
|
|
aConverter.EndCSSDeclaration();
|
|
}
|
|
|
|
start = ++semiColon;
|
|
semiColon = list.FindChar(';', PR_FALSE,start);
|
|
}
|
|
aConverter.EndCSSDeclarationList();
|
|
}
|
|
|
|
|
|
/**
|
|
* Converts the CSS Stylesheets in this document to XIF
|
|
*
|
|
* @update gpk 01/17/1998
|
|
* @param aConverter -- the XIFConverter where all output is being written
|
|
* @param aDeclaration -- the Object to be converted to XIF
|
|
*/
|
|
void nsMarkupDocument::StyleSheetsToXIF(nsXIFConverter& aConverter)
|
|
{
|
|
|
|
PRInt32 count = GetNumberOfStyleSheets();
|
|
|
|
for (PRInt32 indx = 0; indx < count; indx++)
|
|
{
|
|
nsIStyleSheet* sheet = GetStyleSheetAt(indx);
|
|
nsICSSStyleSheet* cssSheet = nsnull;
|
|
|
|
if (sheet != nsnull)
|
|
{
|
|
nsIURI* sheetURL = nsnull;
|
|
sheet->GetURL(sheetURL);
|
|
|
|
if (nsnull == sheetURL) {
|
|
break;
|
|
}
|
|
PRBool eq;
|
|
nsresult rv = sheetURL->Equals(mDocumentURL, &eq);
|
|
if (NS_FAILED(rv) || !eq)
|
|
{
|
|
NS_RELEASE(sheetURL);
|
|
break;
|
|
}
|
|
NS_RELEASE(sheetURL);
|
|
|
|
nsresult isCss = sheet->QueryInterface(kICSSStyleSheetIID, (void**)&cssSheet);
|
|
if ((isCss == NS_OK) && (cssSheet != nsnull))
|
|
{
|
|
PRInt32 ruleCount;
|
|
PRInt32 ruleIndex;
|
|
nsICSSRule* rule = nsnull;
|
|
|
|
cssSheet->StyleRuleCount(ruleCount);
|
|
if (ruleCount > 0)
|
|
{
|
|
aConverter.BeginCSSStyleSheet();
|
|
for (ruleIndex = 0; ruleIndex < ruleCount; ruleIndex++)
|
|
{
|
|
if (NS_OK == cssSheet->GetStyleRuleAt(ruleIndex, rule))
|
|
{
|
|
aConverter.BeginCSSRule();
|
|
|
|
if (nsnull != rule)
|
|
{
|
|
PRInt32 type;
|
|
rule->GetType(type);
|
|
if (nsICSSRule::STYLE_RULE == type) {
|
|
nsICSSStyleRule* styleRule = (nsICSSStyleRule*)rule;
|
|
CSSSelectorsToXIF(aConverter,*styleRule);
|
|
|
|
nsICSSDeclaration* declaration = styleRule->GetDeclaration();
|
|
if (nsnull != declaration)
|
|
CSSDeclarationToXIF(aConverter,*declaration);
|
|
|
|
NS_IF_RELEASE(declaration);
|
|
}
|
|
// XXX other rule types
|
|
NS_IF_RELEASE(rule);
|
|
} // ruleAt
|
|
|
|
aConverter.EndCSSRule();
|
|
} // for loop
|
|
}
|
|
aConverter.EndCSSStyleSheet();
|
|
} // if ruleCount > 0
|
|
NS_RELEASE(cssSheet);
|
|
} // css_sheet
|
|
NS_RELEASE(sheet);
|
|
} // sheet
|
|
}
|
|
}
|
|
|
|
|
|
void nsMarkupDocument::FinishConvertToXIF(nsXIFConverter& aConverter, nsIDOMNode* aNode)
|
|
{
|
|
nsIContent* content = nsnull;
|
|
nsresult isContent = aNode->QueryInterface(kIContentIID, (void**)&content);
|
|
PRBool isSynthetic = PR_TRUE;
|
|
|
|
if (NS_OK == isContent)
|
|
{
|
|
content->IsSynthetic(isSynthetic);
|
|
if (PR_FALSE == isSynthetic)
|
|
{
|
|
nsIAtom* tag;
|
|
content->GetTag(tag);
|
|
if (tag != nsnull)
|
|
{
|
|
nsString str;
|
|
tag->ToString(str);
|
|
if (str.EqualsIgnoreCase("Head"))
|
|
StyleSheetsToXIF(aConverter);
|
|
NS_RELEASE(tag);
|
|
}
|
|
}
|
|
}
|
|
nsDocument::FinishConvertToXIF(aConverter,aNode);
|
|
}
|
|
|
|
|