void Text::attach() { #if ENABLE(WML) if (document()->isWMLDocument() && !containsOnlyWhitespace()) { String text = data(); ASSERT(!text.isEmpty()); text = substituteVariableReferences(text, document()); ExceptionCode code = 0; setData(text, code); ASSERT(!code); } #endif createRendererIfNeeded(); CharacterData::attach(); }
void Text::insertedIntoDocument() { CharacterData::insertedIntoDocument(); if (!parentNode()->isWMLElement() || !length()) return; WMLPageState* pageState = wmlPageStateForDocument(document()); if (!pageState->hasVariables()) return; String text = data(); if (!text.impl() || text.impl()->containsOnlyWhitespace()) return; text = substituteVariableReferences(text, document()); ExceptionCode ec; setData(text, ec); }
String substituteVariableReferences(const String& reference, Document* document, WMLVariableEscapingMode escapeMode) { ASSERT(document); if (reference.isEmpty()) return reference; WMLPageState* pageState = wmlPageStateForDocument(document); if (!pageState) return reference; bool isValid = true; String remainingInput = reference; String result; while (!remainingInput.isEmpty()) { ASSERT(isValid); int start = remainingInput.find("$"); if (start == -1) { // Consume all remaining characters, as there's nothing more to substitute result += remainingInput; break; } // Consume all characters until the variable reference beginning result += remainingInput.left(start); remainingInput.remove(0, start); // Transform adjacent dollar signs into a single dollar sign as string literal if (remainingInput[1] == '$') { result += "$"; remainingInput.remove(0, 2); continue; } String variableName; String conversionMode; if (remainingInput[1] == '(') { int referenceEndPosition = remainingInput.find(")"); if (referenceEndPosition == -1) { isValid = false; break; } variableName = remainingInput.substring(2, referenceEndPosition - 2); remainingInput.remove(0, referenceEndPosition + 1); // Determine variable conversion mode string int pos = variableName.find(':'); if (pos != -1) { conversionMode = variableName.substring(pos + 1, variableName.length() - (pos + 1)); variableName = variableName.left(pos); } } else { int length = remainingInput.length(); int referenceEndPosition = 1; for (; referenceEndPosition < length; ++referenceEndPosition) { if (!isValidVariableNameCharacter(remainingInput[referenceEndPosition])) break; } variableName = remainingInput.substring(1, referenceEndPosition - 1); remainingInput.remove(0, referenceEndPosition); } isValid = isValidVariableName(variableName); if (!isValid) break; ASSERT(!variableName.isEmpty()); String variableValue = pageState->getVariable(variableName); if (variableValue.isEmpty()) continue; if (containsVariableReference(variableValue, isValid)) { if (!isValid) break; variableValue = substituteVariableReferences(variableValue, document, escapeMode); continue; } if (!conversionMode.isEmpty()) { // Override default escape mode, if desired WMLVariableEscapingMode specifiedEscapeMode = WMLVariableEscapingNone; if ((isValid = isValidVariableEscapingModeString(conversionMode, specifiedEscapeMode))) escapeMode = specifiedEscapeMode; if (!isValid) break; } switch (escapeMode) { case WMLVariableEscapingNone: break; case WMLVariableEscapingEscape: variableValue = encodeWithURLEscapeSequences(variableValue); break; case WMLVariableEscapingUnescape: variableValue = decodeURLEscapeSequences(variableValue); break; } result += variableValue; ASSERT(isValid); } if (!isValid) { reportWMLError(document, WMLErrorInvalidVariableReference); return reference; } return result; }