void AudioParamTimeline::cancelScheduledValues(double startTime, ExceptionState& exceptionState) { ASSERT(isMainThread()); if (!std::isfinite(startTime)) { exceptionState.throwDOMException( InvalidStateError, "Time must be a finite number: " + String::number(startTime)); } MutexLocker locker(m_eventsLock); // Remove all events starting at startTime. for (unsigned i = 0; i < m_events.size(); ++i) { if (m_events[i].time() >= startTime) { m_events.remove(i, m_events.size() - i); break; } } }
bool FontFaceSet::deleteForBinding(ScriptState*, FontFace* fontFace, ExceptionState& exceptionState) { if (!inActiveDocumentContext()) return false; if (!fontFace) { exceptionState.throwTypeError("The argument is not a FontFace."); return false; } WillBeHeapListHashSet<RefPtrWillBeMember<FontFace>>::iterator it = m_nonCSSConnectedFaces.find(fontFace); if (it != m_nonCSSConnectedFaces.end()) { m_nonCSSConnectedFaces.remove(it); CSSFontSelector* fontSelector = document()->styleEngine().fontSelector(); fontSelector->fontFaceCache()->removeFontFace(fontFace, false); if (fontFace->loadStatus() == FontFace::Loading) removeFromLoadingFonts(fontFace); fontSelector->fontFaceInvalidated(); return true; } return false; }
void FileWriterSync::write(Blob* data, ExceptionState& exceptionState) { ASSERT(writer()); ASSERT(m_complete); if (!data) { exceptionState.throwDOMException(TypeMismatchError, FileError::typeMismatchErrorMessage); return; } prepareForWrite(); writer()->write(position(), data->uuid()); ASSERT(m_complete); if (m_error) { FileError::throwDOMException(exceptionState, m_error); return; } setPosition(position() + data->size()); if (position() > length()) setLength(position()); }
void IDBTransaction::abort(ExceptionState& es) { if (m_state == Finishing || m_state == Finished) { es.throwDOMException(InvalidStateError, IDBDatabase::transactionFinishedErrorMessage); return; } m_state = Finishing; if (!m_contextStopped) { while (!m_requestList.isEmpty()) { RefPtr<IDBRequest> request = *m_requestList.begin(); m_requestList.remove(request); request->abort(); } } RefPtr<IDBTransaction> selfRef = this; backendDB()->abort(m_id); }
void IDBCursor::continueFunction(IDBKey* key, IDBKey* primaryKey, ExceptionState& exceptionState) { ASSERT(!primaryKey || (key && primaryKey)); if (m_transaction->isFinished() || m_transaction->isFinishing()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionFinishedErrorMessage); return; } if (!m_transaction->isActive()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionInactiveErrorMessage); return; } if (!m_gotValue) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::noValueErrorMessage); return; } if (isDeleted()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::sourceDeletedErrorMessage); return; } if (key) { ASSERT(m_key); if (m_direction == WebIDBCursorDirectionNext || m_direction == WebIDBCursorDirectionNextNoDuplicate) { const bool ok = m_key->isLessThan(key) || (primaryKey && m_key->isEqual(key) && m_primaryKey->isLessThan(primaryKey)); if (!ok) { exceptionState.throwDOMException(DataError, "The parameter is less than or equal to this cursor's position."); return; } } else { const bool ok = key->isLessThan(m_key.get()) || (primaryKey && key->isEqual(m_key.get()) && primaryKey->isLessThan(m_primaryKey.get())); if (!ok) { exceptionState.throwDOMException(DataError, "The parameter is greater than or equal to this cursor's position."); return; } } } // FIXME: We're not using the context from when continue was called, which means the callback // will be on the original context openCursor was called on. Is this right? m_request->setPendingCursor(this); m_gotValue = false; m_backend->continueFunction(key, primaryKey, WebIDBCallbacksImpl::create(m_request).leakPtr()); }
PassRefPtrWillBeRawPtr<FontFaceSet> FontFaceSet::addForBinding(ScriptState*, FontFace* fontFace, ExceptionState& exceptionState) { if (!inActiveDocumentContext()) return this; if (!fontFace) { exceptionState.throwTypeError("The argument is not a FontFace."); return this; } if (m_nonCSSConnectedFaces.contains(fontFace)) return this; if (isCSSConnectedFontFace(fontFace)) return this; CSSFontSelector* fontSelector = document()->styleEngine().fontSelector(); m_nonCSSConnectedFaces.add(fontFace); fontSelector->fontFaceCache()->addFontFace(fontSelector, fontFace, false); if (fontFace->loadStatus() == FontFace::Loading) addToLoadingFonts(fontFace); fontSelector->fontFaceInvalidated(); return this; }
PassRefPtr<Database> DOMWindowWebDatabase::openDatabase(DOMWindow& window, const String& name, const String& version, const String& displayName, unsigned long estimatedSize, PassOwnPtr<DatabaseCallback> creationCallback, ExceptionState& exceptionState) { if (!window.isCurrentlyDisplayedInFrame()) return nullptr; RefPtr<Database> database = nullptr; DatabaseManager& dbManager = DatabaseManager::manager(); DatabaseError error = DatabaseError::None; if (RuntimeEnabledFeatures::databaseEnabled() && window.document()->securityOrigin()->canAccessDatabase()) { String errorMessage; database = dbManager.openDatabase(window.document(), name, version, displayName, estimatedSize, creationCallback, error, errorMessage); ASSERT(database || error != DatabaseError::None); if (error != DatabaseError::None) DatabaseManager::throwExceptionForDatabaseError(error, errorMessage, exceptionState); } else { exceptionState.throwSecurityError("Access to the WebDatabase API is denied in this context."); } return database; }
void StereoPannerHandler::setChannelCount(unsigned long channelCount, ExceptionState& exceptionState) { DCHECK(isMainThread()); BaseAudioContext::AutoLocker locker(context()); // A PannerNode only supports 1 or 2 channels if (channelCount > 0 && channelCount <= 2) { if (m_channelCount != channelCount) { m_channelCount = channelCount; if (internalChannelCountMode() != Max) updateChannelsForInputs(); } } else { exceptionState.throwDOMException( NotSupportedError, ExceptionMessages::indexOutsideRange<unsigned long>( "channelCount", channelCount, 1, ExceptionMessages::InclusiveBound, 2, ExceptionMessages::InclusiveBound)); } }
void RTCPeerConnection::removeStream(PassRefPtr<MediaStream> prpStream, ExceptionState& exceptionState) { if (throwExceptionIfSignalingStateClosed(m_signalingState, exceptionState)) return; if (!prpStream) { exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "MediaStream")); return; } RefPtr<MediaStream> stream = prpStream; size_t pos = m_localStreams.find(stream); if (pos == kNotFound) return; m_localStreams.remove(pos); m_peerHandler->removeStream(stream->descriptor()); }
float SVGLengthContext::convertValueFromPercentageToUserUnits(float value, SVGLengthMode mode, ExceptionState& exceptionState) const { FloatSize viewportSize; if (!determineViewport(viewportSize)) { exceptionState.throwDOMException(NotSupportedError, "The viewport could not be determined."); return 0; } switch (mode) { case LengthModeWidth: return value * viewportSize.width(); case LengthModeHeight: return value * viewportSize.height(); case LengthModeOther: return value * sqrtf(viewportSize.diagonalLengthSquared() / 2); }; ASSERT_NOT_REACHED(); return 0; }
bool DOMMatrixReadOnly::validateAndFixup(DOMMatrixInit& other, ExceptionState& exceptionState) { if (other.hasA() && other.hasM11() && other.a() != other.m11()) { exceptionState.throwTypeError(getErrorMessage("a", "m11")); return false; } if (other.hasB() && other.hasM12() && other.b() != other.m12()) { exceptionState.throwTypeError(getErrorMessage("b", "m12")); return false; } if (other.hasC() && other.hasM21() && other.c() != other.m21()) { exceptionState.throwTypeError(getErrorMessage("c", "m21")); return false; } if (other.hasD() && other.hasM22() && other.d() != other.m22()) { exceptionState.throwTypeError(getErrorMessage("d", "m22")); return false; } if (other.hasE() && other.hasM41() && other.e() != other.m41()) { exceptionState.throwTypeError(getErrorMessage("e", "m41")); return false; } if (other.hasF() && other.hasM42() && other.f() != other.m42()) { exceptionState.throwTypeError(getErrorMessage("f", "m42")); return false; } if (other.hasIs2D() && other.is2D() && (other.m31() || other.m32() || other.m13() || other.m23() || other.m43() || other.m14() || other.m24() || other.m34() || other.m33() != 1 || other.m44() != 1)) { exceptionState.throwTypeError( "The is2D member is set to true but the input matrix is 3d matrix."); return false; } setDictionaryMembers(other); if (!other.hasIs2D()) { bool is2D = !(other.m31() || other.m32() || other.m13() || other.m23() || other.m43() || other.m14() || other.m24() || other.m34() || other.m33() != 1 || other.m44() != 1); other.setIs2D(is2D); } return true; }
void InternalSettings::setDisplayModeOverride(const String& displayMode, ExceptionState& exceptionState) { InternalSettingsGuardForSettings(); String token = displayMode.stripWhiteSpace(); WebDisplayMode mode = WebDisplayModeBrowser; if (token == "browser") mode = WebDisplayModeBrowser; else if (token == "minimal-ui") mode = WebDisplayModeMinimalUi; else if (token == "standalone") mode = WebDisplayModeStandalone; else if (token == "fullscreen") mode = WebDisplayModeFullscreen; else exceptionState.throwDOMException( SyntaxError, "The display-mode token ('" + token + ")' is invalid."); settings()->setDisplayModeOverride(mode); }
void InternalSettings::setTextTrackKindUserPreference( const String& preference, ExceptionState& exceptionState) { InternalSettingsGuardForSettings(); String token = preference.stripWhiteSpace(); TextTrackKindUserPreference userPreference = TextTrackKindUserPreference::Default; if (token == "default") userPreference = TextTrackKindUserPreference::Default; else if (token == "captions") userPreference = TextTrackKindUserPreference::Captions; else if (token == "subtitles") userPreference = TextTrackKindUserPreference::Subtitles; else exceptionState.throwDOMException( SyntaxError, "The user preference for text track kind " + preference + ")' is invalid."); settings()->setTextTrackKindUserPreference(userPreference); }
void WebCLProgram::release(ExceptionState& es) { cl_int err = 0; if (m_cl_program == NULL) { printf("Error: Invalid program object\n"); es.throwWebCLException( WebCLException::INVALID_DEVICE, WebCLException::invalidDeviceMessage); return; } err = clReleaseProgram(m_cl_program); if (err != CL_SUCCESS) { WebCLException::throwException(err, es); } else { m_cl_program = NULL; isReleased = true; return; } return; }
void SVGLengthList::parseInternal(const CharType*& ptr, const CharType* end, ExceptionState& exceptionState) { clear(); while (ptr < end) { const CharType* start = ptr; while (ptr < end && *ptr != ',' && !isHTMLSpace<CharType>(*ptr)) ptr++; if (ptr == start) break; RefPtr<SVGLength> length = SVGLength::create(m_mode); String valueString(start, ptr - start); if (valueString.isEmpty()) return; length->setValueAsString(valueString, exceptionState); if (exceptionState.hadException()) return; append(length); skipOptionalSVGSpacesOrDelimiter(ptr, end); } }
void MediaController::setPlaybackRate(double rate, ExceptionState& exceptionState) { // FIXME: generated bindings should check isfinite: http://crbug.com/354298 if (!std::isfinite(rate)) { exceptionState.throwTypeError(ExceptionMessages::notAFiniteNumber(rate)); return; } if (m_clock->playRate() == rate) return; // The playbackRate attribute, on setting, must set the MediaController's media controller // playback rate to the new value, m_clock->setPlayRate(rate); for (size_t index = 0; index < m_mediaElements.size(); ++index) m_mediaElements[index]->updatePlaybackRate(); // then queue a task to fire a simple event named ratechange at the MediaController. scheduleEvent(EventTypeNames::ratechange); }
PassRefPtrWillBeRawPtr<Range> DOMSelection::getRangeAt(int index, ExceptionState& exceptionState) { if (!m_frame) return nullptr; if (index < 0 || index >= rangeCount()) { exceptionState.throwDOMException(IndexSizeError, String::number(index) + " is not a valid index."); return nullptr; } // If you're hitting this, you've added broken multi-range selection support ASSERT(rangeCount() == 1); Position anchor = anchorPosition(visibleSelection()); if (!anchor.anchorNode()->isInShadowTree()) return m_frame->selection().firstRange(); if (!visibleSelection().isBaseFirst()) return Range::create(*anchor.document(), focusNode(), focusOffset(), shadowAdjustedNode(anchor), anchorOffset()); return Range::create(*anchor.document(), shadowAdjustedNode(anchor), anchorOffset(), focusNode(), focusOffset()); }
void HTMLElement::setOuterText(const String &text, ExceptionState& es) { if (ieForbidsInsertHTML()) { es.throwDOMException(NoModificationAllowedError); return; } if (hasLocalName(colTag) || hasLocalName(colgroupTag) || hasLocalName(framesetTag) || hasLocalName(headTag) || hasLocalName(htmlTag) || hasLocalName(tableTag) || hasLocalName(tbodyTag) || hasLocalName(tfootTag) || hasLocalName(theadTag) || hasLocalName(trTag)) { es.throwDOMException(NoModificationAllowedError); return; } ContainerNode* parent = parentNode(); if (!parent) { es.throwDOMException(NoModificationAllowedError); return; } RefPtr<Node> prev = previousSibling(); RefPtr<Node> next = nextSibling(); RefPtr<Node> newChild; // Convert text to fragment with <br> tags instead of linebreaks if needed. if (text.contains('\r') || text.contains('\n')) newChild = textToFragment(text, es); else newChild = Text::create(document(), text); if (!this || !parentNode()) es.throwDOMException(HierarchyRequestError); if (es.hadException()) return; parent->replaceChild(newChild.release(), this, es); RefPtr<Node> node = next ? next->previousSibling() : 0; if (!es.hadException() && node && node->isTextNode()) mergeWithNextTextNode(node.release(), es); if (!es.hadException() && prev && prev->isTextNode()) mergeWithNextTextNode(prev.release(), es); }
Pattern::RepeatMode CanvasPattern::parseRepetitionType( const String& type, ExceptionState& exceptionState) { if (type.isEmpty() || type == "repeat") return Pattern::RepeatModeXY; if (type == "no-repeat") return Pattern::RepeatModeNone; if (type == "repeat-x") return Pattern::RepeatModeX; if (type == "repeat-y") return Pattern::RepeatModeY; exceptionState.throwDOMException( SyntaxError, "The provided type ('" + type + "') is not one of 'repeat', 'no-repeat', 'repeat-x', or 'repeat-y'."); return Pattern::RepeatModeNone; }
void V8NodeOrNodeList::toImpl(v8::Isolate* isolate, v8::Local<v8::Value> v8Value, NodeOrNodeList& impl, UnionTypeConversionMode conversionMode, ExceptionState& exceptionState) { if (v8Value.IsEmpty()) return; if (conversionMode == UnionTypeConversionMode::Nullable && isUndefinedOrNull(v8Value)) return; if (V8Node::hasInstance(v8Value, isolate)) { Node* cppValue = V8Node::toImpl(v8::Local<v8::Object>::Cast(v8Value)); impl.setNode(cppValue); return; } if (V8NodeList::hasInstance(v8Value, isolate)) { NodeList* cppValue = V8NodeList::toImpl(v8::Local<v8::Object>::Cast(v8Value)); impl.setNodeList(cppValue); return; } exceptionState.throwTypeError("The provided value is not of type '(Node or NodeList)'"); }
void AnimationPlayer::finish(ExceptionState& exceptionState) { PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); if (!m_playbackRate || playStateInternal() == Idle) { return; } if (m_playbackRate > 0 && sourceEnd() == std::numeric_limits<double>::infinity()) { exceptionState.throwDOMException(InvalidStateError, "AnimationPlayer has source content whose end time is infinity."); return; } double newCurrentTime = m_playbackRate < 0 ? 0 : sourceEnd(); setCurrentTimeInternal(newCurrentTime, TimingUpdateOnDemand); if (!paused()) { m_startTime = calculateStartTime(newCurrentTime); } m_currentTimePending = false; ASSERT(finished()); }
void HTMLElement::setOuterText(const String& text, ExceptionState& exceptionState) { if (ieForbidsInsertHTML()) { exceptionState.throwDOMException(NoModificationAllowedError, "The '" + localName() + "' element does not support text insertion."); return; } if (shouldProhibitSetInnerOuterText(*this)) { exceptionState.throwDOMException(NoModificationAllowedError, "The '" + localName() + "' element does not support text insertion."); return; } ContainerNode* parent = parentNode(); if (!parent) { exceptionState.throwDOMException(NoModificationAllowedError, "The element has no parent."); return; } RefPtrWillBeRawPtr<Node> prev = previousSibling(); RefPtrWillBeRawPtr<Node> next = nextSibling(); RefPtrWillBeRawPtr<Node> newChild = nullptr; // Convert text to fragment with <br> tags instead of linebreaks if needed. if (text.contains('\r') || text.contains('\n')) newChild = textToFragment(text, exceptionState); else newChild = Text::create(document(), text); // textToFragment might cause mutation events. if (!parentNode()) exceptionState.throwDOMException(HierarchyRequestError, "The element has no parent."); if (exceptionState.hadException()) return; parent->replaceChild(newChild.release(), this, exceptionState); RefPtrWillBeRawPtr<Node> node = next ? next->previousSibling() : nullptr; if (!exceptionState.hadException() && node && node->isTextNode()) mergeWithNextTextNode(toText(node.get()), exceptionState); if (!exceptionState.hadException() && prev && prev->isTextNode()) mergeWithNextTextNode(toText(prev.get()), exceptionState); }
void WebCLEvent::release(ExceptionState& es) { cl_int err = 0; if (m_cl_Event == NULL) { printf("Error: Invalid CL Event\n"); es.throwWebCLException( WebCLException::INVALID_EVENT, WebCLException::invalidEventMessage); return; } err = clReleaseEvent(m_cl_Event); if (err != CL_SUCCESS) { WebCLException::throwException(err, es); } else { isReleased = true; m_cl_Event = NULL; return; } return; }
void SVGPointList::setValueAsString(const String& value, ExceptionState& exceptionState) { if (value.isEmpty()) { clear(); return; } bool valid = false; if (value.is8Bit()) { const LChar* ptr = value.characters8(); const LChar* end = ptr + value.length(); valid = parse(ptr, end); } else { const UChar* ptr = value.characters16(); const UChar* end = ptr + value.length(); valid = parse(ptr, end); } if (!valid) exceptionState.throwDOMException(SyntaxError, "Problem parsing points=\""+value+"\""); }
float SVGLengthContext::convertValueFromPercentageToUserUnits(float value, SVGLengthMode mode, ExceptionState& es) const { float width = 0; float height = 0; if (!determineViewport(width, height)) { es.throwDOMException(NotSupportedError); return 0; } switch (mode) { case LengthModeWidth: return value * width; case LengthModeHeight: return value * height; case LengthModeOther: return value * sqrtf((width * width + height * height) / 2); }; ASSERT_NOT_REACHED(); return 0; }
void Blob::close(ExecutionContext* executionContext, ExceptionState& exceptionState) { if (hasBeenClosed()) { exceptionState.throwDOMException(InvalidStateError, "Blob has been closed."); return; } // Dereferencing a Blob that has been closed should result in // a network error. Revoke URLs registered against it through // its UUID. DOMURL::revokeObjectUUID(executionContext, uuid()); // A Blob enters a 'readability state' of closed, where it will report its // size as zero. Blob and FileReader operations now throws on // being passed a Blob in that state. Downstream uses of closed Blobs // (e.g., XHR.send()) consider them as empty. OwnPtr<BlobData> blobData = BlobData::create(); blobData->setContentType(type()); m_blobDataHandle = BlobDataHandle::create(blobData.release(), 0); m_hasBeenClosed = true; }
void IDBTransaction::abort(ExceptionState& exceptionState) { if (m_state == Finishing || m_state == Finished) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::transactionFinishedErrorMessage); return; } m_state = Finishing; if (m_contextStopped) return; while (!m_requestList.isEmpty()) { IDBRequest* request = *m_requestList.begin(); m_requestList.remove(request); request->abort(); } if (backendDB()) backendDB()->abort(m_id); }
PassRefPtrWillBeRawPtr<IDBRequest> IDBCursor::update(ExecutionContext* executionContext, ScriptValue& value, ExceptionState& exceptionState) { IDB_TRACE("IDBCursor::update"); if (!m_gotValue) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::noValueErrorMessage); return nullptr; } if (isKeyCursor()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::isKeyCursorErrorMessage); return nullptr; } if (isDeleted()) { exceptionState.throwDOMException(InvalidStateError, IDBDatabase::sourceDeletedErrorMessage); return nullptr; } if (m_transaction->isFinished() || m_transaction->isFinishing()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionFinishedErrorMessage); return nullptr; } if (!m_transaction->isActive()) { exceptionState.throwDOMException(TransactionInactiveError, IDBDatabase::transactionInactiveErrorMessage); return nullptr; } if (m_transaction->isReadOnly()) { exceptionState.throwDOMException(ReadOnlyError, "The record may not be updated inside a read-only transaction."); return nullptr; } RefPtrWillBeRawPtr<IDBObjectStore> objectStore = effectiveObjectStore(); const IDBKeyPath& keyPath = objectStore->metadata().keyPath; const bool usesInLineKeys = !keyPath.isNull(); if (usesInLineKeys) { RefPtrWillBeRawPtr<IDBKey> keyPathKey = createIDBKeyFromScriptValueAndKeyPath(toIsolate(executionContext), value, keyPath); if (!keyPathKey || !keyPathKey->isEqual(m_primaryKey.get())) { exceptionState.throwDOMException(DataError, "The effective object store of this cursor uses in-line keys and evaluating the key path of the value parameter results in a different value than the cursor's effective key."); return nullptr; } } return objectStore->put(executionContext, WebIDBDatabase::CursorUpdate, IDBAny::create(this), value, m_primaryKey, exceptionState); }
void SourceBuffer::setAppendWindowStart(double start, ExceptionState& exceptionState) { // Section 3.1 appendWindowStart attribute setter steps. // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#widl-SourceBuffer-appendWindowStart // 1. If this object has been removed from the sourceBuffers attribute of the parent media source then throw an // InvalidStateError exception and abort these steps. // 2. If the updating attribute equals true, then throw an InvalidStateError exception and abort these steps. if (throwExceptionIfRemovedOrUpdating(isRemoved(), m_updating, exceptionState)) return; // 3. If the new value is less than 0 or greater than or equal to appendWindowEnd then throw an InvalidAccessError // exception and abort these steps. if (start < 0 || start >= m_appendWindowEnd) { exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::indexOutsideRange("value", start, 0.0, ExceptionMessages::ExclusiveBound, m_appendWindowEnd, ExceptionMessages::InclusiveBound)); return; } m_webSourceBuffer->setAppendWindowStart(start); // 4. Update the attribute to the new value. m_appendWindowStart = start; }
float SVGLengthContext::convertValueToUserUnits(float value, SVGLengthMode mode, SVGLengthType fromUnit, ExceptionState& es) const { // If the SVGLengthContext carries a custom viewport, force resolving against it. if (!m_overridenViewport.isEmpty()) { // 100% = 100.0 instead of 1.0 for historical reasons, this could eventually be changed if (fromUnit == LengthTypePercentage) value /= 100; return convertValueFromPercentageToUserUnits(value, mode, es); } switch (fromUnit) { case LengthTypeUnknown: es.throwDOMException(NotSupportedError); return 0; case LengthTypeNumber: return value; case LengthTypePX: return value; case LengthTypePercentage: return convertValueFromPercentageToUserUnits(value / 100, mode, es); case LengthTypeEMS: return convertValueFromEMSToUserUnits(value, es); case LengthTypeEXS: return convertValueFromEXSToUserUnits(value, es); case LengthTypeCM: return value * cssPixelsPerInch / 2.54f; case LengthTypeMM: return value * cssPixelsPerInch / 25.4f; case LengthTypeIN: return value * cssPixelsPerInch; case LengthTypePT: return value * cssPixelsPerInch / 72; case LengthTypePC: return value * cssPixelsPerInch / 6; } ASSERT_NOT_REACHED(); return 0; }