blob: 818be8333eefcbe0f3ad620d5cbc7093bfa8c14c [file] [log] [blame]
package org.eclipse.jst.pagedesigner.properties.celleditors;
import org.eclipse.wst.css.core.internal.parser.CSSSourceParser;
import org.eclipse.wst.css.core.internal.provisional.adapters.IStyleDeclarationAdapter;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel;
import org.eclipse.wst.sse.core.internal.ltk.parser.RegionParser;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.core.internal.provisional.events.IStructuredDocumentListener;
import org.eclipse.wst.sse.core.internal.provisional.events.NewDocumentEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionChangedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentRegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegionList;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.css.CSSStyleDeclaration;
/**
* CSS style adapter for tags where the attribute name is not "style"
* <p>
* Basically a copy of StyleAttrAdapter with a few mods
*/
@SuppressWarnings("deprecation")
public class TagStyleAttrAdapter extends AbstractCSSModelAdapter implements IStructuredDocumentListener, IStyleDeclarationAdapter {
private boolean ignoreNotification = false;
private String _styleAttrName;
/**
* @param attrName
*/
TagStyleAttrAdapter(final String attrName) {
super();
_styleAttrName = attrName;
}
/**
*/
public ICSSModel getModel() {
ICSSModel model = getExistingModel();
if (model == null && isModelNecessary()) {
model = createModel();
if (model == null)
return null;
IStructuredDocument structuredDocument = model.getStructuredDocument();
if (structuredDocument == null)
return null;
RegionParser parser = structuredDocument.getParser();
if (parser instanceof CSSSourceParser) {
((CSSSourceParser)parser).setParserMode(CSSSourceParser.MODE_DECLARATION);
} else {
return null;
}
structuredDocument.addDocumentChangedListener(this);
setModel(model); // need to set before valueChanged()
valueChanged();
}
if (model != null && !isModelNecessary()) {
model = null;
valueChanged();
}
return model;
}
/**
*/
public CSSStyleDeclaration getStyle() {
ICSSModel model = getModel();
if (model == null)
return null;
return (CSSStyleDeclaration) model.getDocument();
}
/**
* Allowing the INodeAdapter to compare itself against the type
* allows it to return true in more than one case.
*/
public boolean isAdapterForType(Object type) {
return (type == IStyleDeclarationAdapter.class);
}
/**
*/
public void newModel(NewDocumentEvent event) {
if (event == null)
return;
if (event.getOriginalRequester() == this)
return;
setValue();
}
/**
*/
public void noChange(NoChangeEvent structuredDocumentEvent) {//
}
/**
*/
public void nodesReplaced(StructuredDocumentRegionsReplacedEvent event) {
if (event == null)
return;
if (event.getOriginalRequester() == this)
return;
setValue();
}
/**
*/
public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {
if (this.ignoreNotification)
return;
if (eventType != INodeNotifier.CHANGE)
return;
Attr attr = (Attr) changedFeature;
if (attr == null)
return;
String name = attr.getName();
if (name.equalsIgnoreCase(_styleAttrName)) {
valueChanged();
}
}
/**
*/
public void regionChanged(RegionChangedEvent event) {
if (event == null)
return;
if (event.getOriginalRequester() == this)
return;
setValue();
}
/**
*/
public void regionsReplaced(RegionsReplacedEvent event) {
if (event == null)
return;
if (event.getOriginalRequester() == this)
return;
setValue();
}
/**
*/
private void setValue() {
Element element = getElement();
if (element == null)
return;
ICSSModel model = getExistingModel();
if (model == null)
return;
IStructuredDocument structuredDocument = model.getStructuredDocument();
if (structuredDocument == null)
return;
String value = null;
IStructuredDocumentRegionList flatNodes = structuredDocument.getRegionList();
if (flatNodes != null) {
int count = flatNodes.getLength();
if (count > 0) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < count; i++) {
IStructuredDocumentRegion flatNode = flatNodes.item(i);
if (flatNode == null)
continue;
buffer.append(flatNode.getText());
}
value = buffer.toString();
}
}
this.ignoreNotification = true;
if (value == null || value.length() == 0) {
element.removeAttribute(_styleAttrName);
}
else {
Attr attr = element.getAttributeNode(_styleAttrName);
if (attr != null) {
((IDOMNode) attr).setValueSource(value);
}
else {
Document document = element.getOwnerDocument();
attr = document.createAttribute(_styleAttrName);
((IDOMNode) attr).setValueSource(value);
element.setAttributeNode(attr);
}
}
this.ignoreNotification = false;
notifyStyleChanged(element);
}
/**
*/
private void valueChanged() {
Element element = getElement();
if (element == null)
return;
if (!isModelNecessary()) { // removed
setModel(null);
notifyStyleChanged(element);
return;
}
ICSSModel model = getExistingModel();
if (model == null)
return; // defer
IStructuredDocument structuredDocument = model.getStructuredDocument();
if (structuredDocument == null)
return; // error
String value = null;
Attr attr = element.getAttributeNode(_styleAttrName);
if (attr != null)
value = ((IDOMNode) attr).getValueSource();
structuredDocument.setText(this, value);
notifyStyleChanged(element);
}
/**
* @return boolean
*/
private boolean isModelNecessary() {
return getElement() != null;
}
}