/*******************************************************************************
* Copyright (c) 2009, Adobe Systems Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* · Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* · Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* · Neither the name of Adobe Systems Incorporated nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
package com.adobe.dp.epub.ops;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Stack;
import com.adobe.dp.css.CSSParser;
import com.adobe.dp.css.CSSStylesheet;
import com.adobe.dp.css.Selector;
import com.adobe.dp.css.SelectorRule;
import com.adobe.dp.epub.ncx.TOCEntry;
import com.adobe.dp.epub.util.TOCLevel;
import com.adobe.dp.xml.util.SMapImpl;
public class HTMLElement extends Element {
static HashSet sectionElements;
static HashSet nonbreakable;
static Hashtable peelingBonus;
static CSSStylesheet builtInStylesheet;
boolean forceChapterBreak;
String title;
String dir;
static {
HashSet be = new HashSet();
be.add("div");
be.add("body");
be.add("table");
be.add("tr");
be.add("ul");
be.add("ol");
be.add("dl");
sectionElements = be;
HashSet nb = new HashSet();
nb.add("table");
nb.add("ol");
nb.add("ul");
nb.add("dl");
nonbreakable = nb;
Hashtable pb = new Hashtable();
pb.put("h1", new Integer(8000));
pb.put("h2", new Integer(8000));
pb.put("h3", new Integer(5000));
pb.put("h4", new Integer(3000));
pb.put("h5", new Integer(2000));
pb.put("h6", new Integer(1500));
pb.put("div", new Integer(1500));
pb.put("p", new Integer(500));
pb.put("dl", new Integer(0));
pb.put("ul", new Integer(0));
pb.put("ol", new Integer(0));
pb.put("blockquote", new Integer(0));
pb.put("pre", new Integer(0));
peelingBonus = pb;
InputStream in = HTMLElement.class.getResourceAsStream("XHTMLStyles.css");
if (in != null) {
try {
CSSParser parser = new CSSParser();
builtInStylesheet = parser.readStylesheet(in);
} catch (Exception e) {
e.printStackTrace();
}
}
}
HTMLElement(OPSDocument document, String name) {
super(document, name);
}
public void setForceChapterBreak(boolean fcb) {
forceChapterBreak = fcb;
}
public String getNamespaceURI() {
return OPSDocument.xhtmlns;
}
Element cloneElementShallow(OPSDocument newDoc) {
HTMLElement e = new HTMLElement(newDoc, getElementName());
e.className = className;
e.cascade = cascade;
e.lang = lang;
e.title = title;
return e;
}
protected Object getBuiltInProperty(String propName) {
if (builtInStylesheet != null) {
Selector selector = builtInStylesheet.getSimpleSelector(elementName, null);
SelectorRule rule = builtInStylesheet.getRuleForSelector(selector, false);
if (rule != null)
return rule.get(propName);
}
return null;
}
boolean isSection() {
return sectionElements.contains(elementName);
}
boolean forcePeel() {
return forceChapterBreak;
}
int getPeelingBonus() {
Integer bonus = (Integer) peelingBonus.get(elementName);
if (bonus == null)
return -1;
int bv = bonus.intValue();
if (selfRef != null) {
int usage = selfRef.getUsage();
if ((usage & XRef.USAGE_PAGE) != 0) {
bv += 10000;
// System.out.println("-- page --");
} else if ((usage & XRef.USAGE_TOC) != 0)
if (bv < 5000)
bv = 5000;
}
return bv;
}
public void generateTOCFromHeadings(Stack headings, int depth) {
if (elementName.startsWith("h") && elementName.length() == 2 && Character.isDigit(elementName.charAt(1))) {
int headingLevel = elementName.charAt(1) - '0';
TOCLevel level;
while (true) {
level = (TOCLevel) headings.pop();
if (headings.isEmpty() || level.getHeadingLevel() < headingLevel) {
headings.push(level);
break;
}
}
if (headings.size() < depth + 1) {
String title = getText();
TOCEntry entry = new TOCEntry(title, getSelfRef());
level.getTOCEntry().add(entry);
TOCLevel myLevel = new TOCLevel(headingLevel, entry);
headings.push(myLevel);
}
}
super.generateTOCFromHeadings(headings, depth);
}
boolean makeNSDefault() {
return elementName.equals("body");
}
boolean canPeelChild() {
return !nonbreakable.contains(elementName);
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDir() {
return dir;
}
public void setDir(String dir) {
this.dir = dir;
}
SMapImpl getAttributes() {
SMapImpl attrs = super.getAttributes();
if (title != null)
attrs.put(null, "title", title);
if (dir != null)
attrs.put(null, "dir", dir);
return attrs;
}
}