下面列出了org.jsoup.nodes.Document#createShell ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
static Document parse(String html) {
try {
/*
org.jsoup.UncheckedIOException: java.io.IOException: Input is binary and unsupported
at org.jsoup.parser.CharacterReader.<init>(SourceFile:38)
at org.jsoup.parser.CharacterReader.<init>(SourceFile:43)
at org.jsoup.parser.TreeBuilder.initialiseParse(SourceFile:38)
at org.jsoup.parser.HtmlTreeBuilder.initialiseParse(SourceFile:65)
at org.jsoup.parser.TreeBuilder.parse(SourceFile:46)
at org.jsoup.parser.Parser.parse(SourceFile:107)
at org.jsoup.Jsoup.parse(SourceFile:58)
*/
return Jsoup.parse(html.replace("\0", ""));
} catch (OutOfMemoryError ex) {
Log.e(ex);
Document document = Document.createShell("");
Element strong = document.createElement("strong");
strong.text(Log.formatThrowable(ex));
document.body().appendChild(strong);
return document;
}
}
@Test
public void should_restoreIndexHtmlTitle() {
AppShellRegistry registry = new AppShellRegistry();
mocks.setAppShellRegistry(registry);
VaadinRequest request = mocks.createRequest(mocks, "/foo");
Document document = Document.createShell("");
org.jsoup.nodes.Element title = document.createElement("title");
title.appendText("index-html-title");
document.head().appendChild(title);
registry.modifyIndexHtml(document, request);
ui.navigate("empty");
assertNull(ui.getInternals().getTitle());
ui.navigate("dirty");
assertEquals("index-html-title", ui.getInternals().getTitle());
}
static Document sanitizeCompose(Context context, String html, boolean show_images) {
try {
Document parsed = JsoupEx.parse(html);
return sanitize(context, parsed, false, show_images);
} catch (Throwable ex) {
// OutOfMemoryError
Log.e(ex);
Document document = Document.createShell("");
Element strong = document.createElement("strong");
strong.text(Log.formatThrowable(ex));
document.body().appendChild(strong);
return document;
}
}
static Document sanitizeView(Context context, Document parsed, boolean show_images) {
try {
return sanitize(context, parsed, true, show_images);
} catch (Throwable ex) {
// OutOfMemoryError
Log.e(ex);
Document document = Document.createShell("");
Element strong = document.createElement("strong");
strong.text(Log.formatThrowable(ex));
document.body().appendChild(strong);
return document;
}
}
@Before
public void setup() throws Exception {
logger = mockLog(VaadinAppShellInitializer.class);
assertNull(getDevModeHandler());
servletContext = Mockito.mock(ServletContext.class);
mocks = new MockServletServiceSessionSetup();
service = mocks.getService();
Mockito.when(servletContext.getAttribute(Mockito.anyString()))
.then(invocationOnMock -> attributeMap
.get(invocationOnMock.getArguments()[0].toString()));
Mockito.doAnswer(invocationOnMock -> attributeMap.put(
invocationOnMock.getArguments()[0].toString(),
invocationOnMock.getArguments()[1])).when(servletContext)
.setAttribute(Mockito.anyString(), Mockito.any());
ServletRegistration registration = Mockito
.mock(ServletRegistration.class);
context = new VaadinServletContext(servletContext);
initParams = new HashMap<>();
Mockito.when(registration.getInitParameters()).thenReturn(initParams);
classes = new HashSet<>();
Map<String, ServletRegistration> registry = new HashMap<>();
registry.put("foo", registration);
Mockito.when(servletContext.getServletRegistrations())
.thenReturn((Map) registry);
Mockito.when(servletContext.getInitParameterNames())
.thenReturn(Collections.emptyEnumeration());
initializer = new VaadinAppShellInitializer();
document = Document.createShell("");
pushConfiguration = Mockito.mock(PushConfiguration.class);
}
@Test
public void toAndFromJsoup() {
final String EXPECTED_TEXT_1 = "Some text";
final String EXPECTED_TEXT_2 = "Other text";
Element originalElement = ElementFactory.createDiv();
originalElement.appendChild(ElementFactory.createParagraph(EXPECTED_TEXT_1)
.appendChild(ElementFactory.createDiv(EXPECTED_TEXT_2)));
Document jDocument = Document.createShell("http://example.com");
Node jNode = ElementUtil.toJsoup(jDocument, originalElement);
Optional<Element> optionalElement = ElementUtil.fromJsoup(jNode);
Assert.assertTrue("Element should have been created from jNode",
optionalElement.isPresent());
Element recreatedElement = optionalElement.get();
// root
Assert.assertEquals("Root element should be div", "div",
recreatedElement.getTag());
// child
Assert.assertEquals("Child element should be a paragraph", "p",
recreatedElement.getChild(0).getTag());
Assert.assertEquals("Child element should have text", EXPECTED_TEXT_1,
recreatedElement.getChild(0).getText());
// grand-child (#1, since #0 is the text node)
Assert.assertEquals("Grand-child element should be a div", "div",
recreatedElement.getChild(0).getChild(1).getTag());
Assert.assertEquals("Grand-child element should have text",
EXPECTED_TEXT_2,
recreatedElement.getChild(0).getChild(1).getText());
}
/**
* Parse a fragment of HTML into the {@code body} of a Document.
*
* @param bodyHtml fragment of HTML
* @param baseUri base URI of document (i.e. original fetch location), for resolving relative URLs.
*
* @return Document, with empty head, and HTML parsed into body
*/
public static Document parseBodyFragment(String bodyHtml, String baseUri) {
Document doc = Document.createShell(baseUri);
Element body = doc.body();
List<Node> nodeList = parseFragment(bodyHtml, body, baseUri);
Node[] nodes = nodeList.toArray(new Node[nodeList.size()]); // the node list gets modified when re-parented
for (int i = nodes.length - 1; i > 0; i--) {
nodes[i].remove();
}
for (Node node : nodes) {
body.appendChild(node);
}
return doc;
}
public boolean isValidBodyHtml(String bodyHtml) {
Document clean = Document.createShell("");
Document dirty = Document.createShell("");
ParseErrorList errorList = ParseErrorList.tracking(1);
List<Node> nodes = Parser.parseFragment(bodyHtml, dirty.body(), "", errorList);
dirty.body().insertChildren(0, nodes);
int numDiscarded = copySafeNodes(dirty.body(), clean.body());
return numDiscarded == 0 && errorList.size() == 0;
}
/**
* Parse a fragment of HTML into the {@code body} of a Document.
*
* @param bodyHtml fragment of HTML
* @param baseUri base URI of document (i.e. original fetch location), for resolving relative URLs.
*
* @return Document, with empty head, and HTML parsed into body
*/
public static Document parseBodyFragment(String bodyHtml, String baseUri) {
Document doc = Document.createShell(baseUri);
Element body = doc.body();
List<Node> nodeList = parseFragment(bodyHtml, body, baseUri);
Node[] nodes = nodeList.toArray(new Node[nodeList.size()]); // the node list gets modified when re-parented
for (int i = nodes.length - 1; i > 0; i--) {
nodes[i].remove();
}
for (Node node : nodes) {
body.appendChild(node);
}
return doc;
}
@Test
public void testCreatesValidProlog() {
Document document = Document.createShell("");
document.outputSettings().syntax(Syntax.xml);
document.charset(Charset.forName("utf-8"));
assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<html>\n" +
" <head></head>\n" +
" <body></body>\n" +
"</html>", document.outerHtml());
}
public boolean isValidBodyHtml(String bodyHtml) {
Document clean = Document.createShell("");
Document dirty = Document.createShell("");
ParseErrorList errorList = ParseErrorList.tracking(1);
List<Node> nodes = Parser.parseFragment(bodyHtml, dirty.body(), "", errorList);
dirty.body().insertChildren(0, nodes);
int numDiscarded = copySafeNodes(dirty.body(), clean.body());
return numDiscarded == 0 && errorList.size() == 0;
}
/**
* Parse a fragment of HTML into the {@code body} of a Document.
*
* @param bodyHtml fragment of HTML
* @param baseUri base URI of document (i.e. original fetch location), for resolving relative URLs.
*
* @return Document, with empty head, and HTML parsed into body
*/
public static Document parseBodyFragment(String bodyHtml, String baseUri) {
Document doc = Document.createShell(baseUri);
Element body = doc.body();
List<Node> nodeList = parseFragment(bodyHtml, body, baseUri);
Node[] nodes = nodeList.toArray(new Node[nodeList.size()]); // the node list gets modified when re-parented
for (int i = nodes.length - 1; i > 0; i--) {
nodes[i].remove();
}
for (Node node : nodes) {
body.appendChild(node);
}
return doc;
}
@Test
public void testCreatesValidProlog() {
Document document = Document.createShell("");
document.outputSettings().syntax(Syntax.xml);
document.charset(Charset.forName("utf-8"));
assertEquals("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<html>\n" +
" <head></head>\n" +
" <body></body>\n" +
"</html>", document.outerHtml());
}
/**
* Parse a fragment of HTML into the {@code body} of a Document.
*
* @param bodyHtml fragment of HTML
* @param baseUri base URI of document (i.e. original fetch location), for resolving relative URLs.
*
* @return Document, with empty head, and HTML parsed into body
*/
public static Document parseBodyFragment(String bodyHtml, String baseUri) {
Document doc = Document.createShell(baseUri);
Element body = doc.body();
List<Node> nodeList = parseFragment(bodyHtml, body, baseUri);
Node[] nodes = nodeList.toArray(new Node[nodeList.size()]); // the node list gets modified when re-parented
for (Node node : nodes) {
body.appendChild(node);
}
return doc;
}
/**
Determines if the input document <b>body</b>is valid, against the whitelist. It is considered valid if all the tags and attributes
in the input HTML are allowed by the whitelist, and that there is no content in the <code>head</code>.
<p>
This method can be used as a validator for user input. An invalid document will still be cleaned successfully
using the {@link #clean(Document)} document. If using as a validator, it is recommended to still clean the document
to ensure enforced attributes are set correctly, and that the output is tidied.
</p>
@param dirtyDocument document to test
@return true if no tags or attributes need to be removed; false if they do
*/
public boolean isValid(Document dirtyDocument) {
Validate.notNull(dirtyDocument);
Document clean = Document.createShell(dirtyDocument.baseUri());
int numDiscarded = copySafeNodes(dirtyDocument.body(), clean.body());
return numDiscarded == 0
&& dirtyDocument.head().childNodes().size() == 0; // because we only look at the body, but we start from a shell, make sure there's nothing in the head
}
/**
Determines if the input document <b>body</b>is valid, against the whitelist. It is considered valid if all the tags and attributes
in the input HTML are allowed by the whitelist, and that there is no content in the <code>head</code>.
<p>
This method can be used as a validator for user input. An invalid document will still be cleaned successfully
using the {@link #clean(Document)} document. If using as a validator, it is recommended to still clean the document
to ensure enforced attributes are set correctly, and that the output is tidied.
</p>
@param dirtyDocument document to test
@return true if no tags or attributes need to be removed; false if they do
*/
public boolean isValid(Document dirtyDocument) {
Validate.notNull(dirtyDocument);
Document clean = Document.createShell(dirtyDocument.baseUri());
int numDiscarded = copySafeNodes(dirtyDocument.body(), clean.body());
return numDiscarded == 0
&& dirtyDocument.head().childNodes().size() == 0; // because we only look at the body, but we start from a shell, make sure there's nothing in the head
}
/**
* Loads CSS from assets folder according to selected theme.
* Fragment should be in attached state for this
*
* @param context context to retrieve theme properties from
* @param url base url of page
* @param htmlContent page with content to splatter color on...
* @return html string
*/
public static String getWebWithCss(@NonNull Context context, @NonNull String url, @Nullable String htmlContent) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
final String theme = prefs.getString("app.theme", "light");
Document doc = Document.createShell(url);
doc.head().append("<link rel=\"stylesheet\" href=\"file:///android_asset/css/" + theme + ".css\" type=\"text/css\" media=\"all\" title=\"Standard\"/>");
return doc.html().replace("<body>", "<body>" + htmlContent); // ugly hack, huh? Well, why don't you come up with something?
}