Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: sky/engine/core/html/parser/HTMLConstructionSite.cpp

Issue 867963006: Add the <t> element and ignore whitespace outside it. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Do it for a whole subtree. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * Copyright (C) 2011 Apple Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 if (it.isBreak(proposedBreakIndex - currentPosition)) 133 if (it.isBreak(proposedBreakIndex - currentPosition))
134 return proposedBreakIndex; 134 return proposedBreakIndex;
135 135
136 int adjustedBreakIndexInSubstring = it.preceding(proposedBreakIndex - curren tPosition); 136 int adjustedBreakIndexInSubstring = it.preceding(proposedBreakIndex - curren tPosition);
137 if (adjustedBreakIndexInSubstring > 0) 137 if (adjustedBreakIndexInSubstring > 0)
138 return currentPosition + adjustedBreakIndexInSubstring; 138 return currentPosition + adjustedBreakIndexInSubstring;
139 // We failed to find a breakable point, let the caller figure out what to do . 139 // We failed to find a breakable point, let the caller figure out what to do .
140 return 0; 140 return 0;
141 } 141 }
142 142
143 static String atomizeIfAllWhitespace(const String& string, WhitespaceMode whites paceMode)
144 {
145 // Strings composed entirely of whitespace are likely to be repeated.
146 // Turn them into AtomicString so we share a single string for each.
147 if (whitespaceMode == AllWhitespace || (whitespaceMode == WhitespaceUnknown && isAllWhitespace(string)))
148 return AtomicString(string).string();
149 return string;
150 }
151
152 void HTMLConstructionSite::flushPendingText() 143 void HTMLConstructionSite::flushPendingText()
153 { 144 {
154 if (m_pendingText.isEmpty()) 145 if (m_pendingText.isEmpty())
155 return; 146 return;
156 147
157 PendingText pendingText; 148 PendingText pendingText;
158 // Hold onto the current pending text on the stack so that queueTask doesn't recurse infinitely. 149 // Hold onto the current pending text on the stack so that queueTask doesn't recurse infinitely.
159 m_pendingText.swap(pendingText); 150 m_pendingText.swap(pendingText);
160 ASSERT(m_pendingText.isEmpty()); 151 ASSERT(m_pendingText.isEmpty());
161 152
162 // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is n ecessary 153 // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is n ecessary
163 // for performance, see: https://bugs.webkit.org/show_bug.cgi?id=55898 154 // for performance, see: https://bugs.webkit.org/show_bug.cgi?id=55898
164 unsigned lengthLimit = textLengthLimitForContainer(*pendingText.parent); 155 unsigned lengthLimit = textLengthLimitForContainer(*pendingText.parent);
165 156
166 unsigned currentPosition = 0; 157 unsigned currentPosition = 0;
167 const StringBuilder& string = pendingText.stringBuilder; 158 const StringBuilder& string = pendingText.stringBuilder;
168 while (currentPosition < string.length()) { 159 while (currentPosition < string.length()) {
169 unsigned proposedBreakIndex = std::min(currentPosition + lengthLimit, st ring.length()); 160 unsigned proposedBreakIndex = std::min(currentPosition + lengthLimit, st ring.length());
170 unsigned breakIndex = findBreakIndexBetween(string, currentPosition, pro posedBreakIndex); 161 unsigned breakIndex = findBreakIndexBetween(string, currentPosition, pro posedBreakIndex);
171 ASSERT(breakIndex <= string.length()); 162 ASSERT(breakIndex <= string.length());
172 String substring = string.substring(currentPosition, breakIndex - curren tPosition); 163 String substring = string.substring(currentPosition, breakIndex - curren tPosition);
173 substring = atomizeIfAllWhitespace(substring, pendingText.whitespaceMode ); 164
165 ASSERT(breakIndex > currentPosition);
166 ASSERT(breakIndex - currentPosition == substring.length());
167 currentPosition = breakIndex;
168
169 if (isAllWhitespace(substring)) {
170 // Ignore whitespace nodes not inside inside a <t>. If we're splitti ng
171 // a text node this isn't really a whitespace node and we can't igno re
172 // it either.
173 if (!m_openElements.preserveWhiteSpace() && string.length() == subst ring.length())
174 continue;
175
176 // Strings composed entirely of whitespace are likely to be repeated .
177 // Turn them into AtomicString so we share a single string for each.
178 substring = AtomicString(substring).string();
179 }
174 180
175 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertText); 181 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::InsertText);
176 task.parent = pendingText.parent; 182 task.parent = pendingText.parent;
177 task.child = Text::create(task.parent->document(), substring); 183 task.child = Text::create(task.parent->document(), substring);
178 queueTask(task); 184 queueTask(task);
179
180 ASSERT(breakIndex > currentPosition);
181 ASSERT(breakIndex - currentPosition == substring.length());
182 ASSERT(toText(task.child.get())->length() == substring.length()); 185 ASSERT(toText(task.child.get())->length() == substring.length());
183 currentPosition = breakIndex;
184 } 186 }
185 } 187 }
186 188
187 void HTMLConstructionSite::queueTask(const HTMLConstructionSiteTask& task) 189 void HTMLConstructionSite::queueTask(const HTMLConstructionSiteTask& task)
188 { 190 {
189 flushPendingText(); 191 flushPendingText();
190 ASSERT(m_pendingText.isEmpty()); 192 ASSERT(m_pendingText.isEmpty());
191 m_taskQueue.append(task); 193 m_taskQueue.append(task);
192 } 194 }
193 195
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 } 292 }
291 293
292 void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token) 294 void HTMLConstructionSite::insertScriptElement(AtomicHTMLToken* token)
293 { 295 {
294 RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(ownerDocumentF orCurrentNode()); 296 RefPtr<HTMLScriptElement> element = HTMLScriptElement::create(ownerDocumentF orCurrentNode());
295 setAttributes(element.get(), token); 297 setAttributes(element.get(), token);
296 attachLater(currentNode(), element); 298 attachLater(currentNode(), element);
297 m_openElements.push(element.release()); 299 m_openElements.push(element.release());
298 } 300 }
299 301
300 void HTMLConstructionSite::insertTextNode(const String& string, WhitespaceMode w hitespaceMode) 302 void HTMLConstructionSite::insertTextNode(const String& string)
301 { 303 {
302 HTMLConstructionSiteTask dummyTask(HTMLConstructionSiteTask::Insert); 304 HTMLConstructionSiteTask dummyTask(HTMLConstructionSiteTask::Insert);
303 dummyTask.parent = currentNode(); 305 dummyTask.parent = currentNode();
304 306
305 // FIXME: This probably doesn't need to be done both here and in insert(Task ). 307 // FIXME: This probably doesn't need to be done both here and in insert(Task ).
306 if (isHTMLTemplateElement(*dummyTask.parent)) 308 if (isHTMLTemplateElement(*dummyTask.parent))
307 dummyTask.parent = toHTMLTemplateElement(dummyTask.parent.get())->conten t(); 309 dummyTask.parent = toHTMLTemplateElement(dummyTask.parent.get())->conten t();
308 310
309 // Unclear when parent != case occurs. Somehow we insert text into two separ ate 311 // Unclear when parent != case occurs. Somehow we insert text into two separ ate
310 // nodes while processing the same Token. When it happens we have to flush t he 312 // nodes while processing the same Token. When it happens we have to flush t he
311 // pending text into the task queue before making more. 313 // pending text into the task queue before making more.
312 if (!m_pendingText.isEmpty() && (m_pendingText.parent != dummyTask.parent)) 314 if (!m_pendingText.isEmpty() && (m_pendingText.parent != dummyTask.parent))
313 flushPendingText(); 315 flushPendingText();
314 m_pendingText.append(dummyTask.parent, string, whitespaceMode); 316 m_pendingText.append(dummyTask.parent, string);
315 } 317 }
316 318
317 PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken* token, const AtomicString& namespaceURI) 319 PassRefPtr<Element> HTMLConstructionSite::createElement(AtomicHTMLToken* token, const AtomicString& namespaceURI)
318 { 320 {
319 QualifiedName tagName(token->name()); 321 QualifiedName tagName(token->name());
320 RefPtr<Element> element = ownerDocumentForCurrentNode().createElement(tagNam e, true); 322 RefPtr<Element> element = ownerDocumentForCurrentNode().createElement(tagNam e, true);
321 setAttributes(element.get(), token); 323 setAttributes(element.get(), token);
322 return element.release(); 324 return element.release();
323 } 325 }
324 326
325 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode() 327 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode()
326 { 328 {
327 if (isHTMLTemplateElement(*currentNode())) 329 if (isHTMLTemplateElement(*currentNode()))
328 return toHTMLTemplateElement(currentElement())->content()->document(); 330 return toHTMLTemplateElement(currentElement())->content()->document();
329 return currentNode()->document(); 331 return currentNode()->document();
330 } 332 }
331 333
332 PassRefPtr<HTMLElement> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token) 334 PassRefPtr<HTMLElement> HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token)
333 { 335 {
334 Document& document = ownerDocumentForCurrentNode(); 336 Document& document = ownerDocumentForCurrentNode();
335 RefPtr<HTMLElement> element = HTMLElementFactory::createHTMLElement(token->n ame(), document, true); 337 RefPtr<HTMLElement> element = HTMLElementFactory::createHTMLElement(token->n ame(), document, true);
336 setAttributes(element.get(), token); 338 setAttributes(element.get(), token);
337 return element.release(); 339 return element.release();
338 } 340 }
339 341
340 } 342 }
OLDNEW
« no previous file with comments | « sky/engine/core/html/parser/HTMLConstructionSite.h ('k') | sky/engine/core/html/parser/HTMLElementStack.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698