QDomElement QgsWcsCapabilities::domElement( const QDomElement &element, const QString &path ) { QStringList names = path.split( '.' ); if ( names.isEmpty() ) return QDomElement(); QDomElement el = firstChild( element, names.value( 0 ) ); if ( names.size() == 1 || el.isNull() ) { return el; } names.removeFirst(); return domElement( el, names.join( QStringLiteral( "." ) ) ); }
already_AddRefed<nsIDOMCSSStyleDeclaration> nsCoreUtils::GetComputedStyleDeclaration(const nsAString& aPseudoElt, nsIContent *aContent) { nsIContent* content = GetDOMElementFor(aContent); if (!content) return nsnull; // Returns number of items in style declaration nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(content->OwnerDoc()->GetWindow()); if (!window) return nsnull; nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl; nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(content)); window->GetComputedStyle(domElement, aPseudoElt, getter_AddRefs(cssDecl)); return cssDecl.forget(); }
already_AddRefed<nsIDOMCSSStyleDeclaration> nsCoreUtils::GetComputedStyleDeclaration(const nsAString& aPseudoElt, nsIContent *aContent) { nsIContent* content = GetDOMElementFor(aContent); if (!content) return nsnull; // Returns number of items in style declaration nsIDocument* document = content->GetOwnerDoc(); if (!document) return nsnull; nsCOMPtr<nsIDOMViewCSS> viewCSS(do_QueryInterface(document->GetWindow())); if (!viewCSS) return nsnull; nsIDOMCSSStyleDeclaration* cssDecl = nsnull; nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(content)); viewCSS->GetComputedStyle(domElement, aPseudoElt, &cssDecl); return cssDecl; }
nsresult nsContextMenuInfo::GetBackgroundImageRequestInternal(nsIDOMNode *aDOMNode, imgIRequest **aRequest) { NS_ENSURE_ARG_POINTER(aDOMNode); nsCOMPtr<nsIDOMNode> domNode = aDOMNode; nsCOMPtr<nsIDOMNode> parentNode; nsCOMPtr<nsIDOMDocument> document; domNode->GetOwnerDocument(getter_AddRefs(document)); NS_ENSURE_TRUE(document, NS_ERROR_FAILURE); nsCOMPtr<nsIDOMWindow> window; document->GetDefaultView(getter_AddRefs(window)); NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); nsCOMPtr<nsIDOMCSSPrimitiveValue> primitiveValue; nsAutoString bgStringValue; // get Content Security Policy to pass to LoadImage nsCOMPtr<nsIDocument> doc(do_QueryInterface(document)); nsCOMPtr<nsIPrincipal> principal; nsCOMPtr<nsIChannelPolicy> channelPolicy; nsCOMPtr<nsIContentSecurityPolicy> csp; if (doc) { principal = doc->NodePrincipal(); nsresult rv = principal->GetCsp(getter_AddRefs(csp)); NS_ENSURE_SUCCESS(rv, rv); if (csp) { channelPolicy = do_CreateInstance("@mozilla.org/nschannelpolicy;1"); channelPolicy->SetContentSecurityPolicy(csp); channelPolicy->SetLoadType(nsIContentPolicy::TYPE_IMAGE); } } while (true) { nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(domNode)); // bail for the parent node of the root element or null argument if (!domElement) break; nsCOMPtr<nsIDOMCSSStyleDeclaration> computedStyle; window->GetComputedStyle(domElement, EmptyString(), getter_AddRefs(computedStyle)); if (computedStyle) { nsCOMPtr<nsIDOMCSSValue> cssValue; computedStyle->GetPropertyCSSValue(NS_LITERAL_STRING("background-image"), getter_AddRefs(cssValue)); primitiveValue = do_QueryInterface(cssValue); if (primitiveValue) { primitiveValue->GetStringValue(bgStringValue); if (!bgStringValue.EqualsLiteral("none")) { nsCOMPtr<nsIURI> bgUri; NS_NewURI(getter_AddRefs(bgUri), bgStringValue); NS_ENSURE_TRUE(bgUri, NS_ERROR_FAILURE); nsCOMPtr<imgILoader> il(do_GetService( "@mozilla.org/image/loader;1")); NS_ENSURE_TRUE(il, NS_ERROR_FAILURE); return il->LoadImage(bgUri, nullptr, nullptr, principal, nullptr, nullptr, nullptr, nsIRequest::LOAD_NORMAL, nullptr, nullptr, channelPolicy, aRequest); } } // bail if we encounter non-transparent background-color computedStyle->GetPropertyCSSValue(NS_LITERAL_STRING("background-color"), getter_AddRefs(cssValue)); primitiveValue = do_QueryInterface(cssValue); if (primitiveValue) { primitiveValue->GetStringValue(bgStringValue); if (!bgStringValue.EqualsLiteral("transparent")) return NS_ERROR_FAILURE; } } domNode->GetParentNode(getter_AddRefs(parentNode)); domNode = parentNode; } return NS_ERROR_FAILURE; }
bool QgsWcsCapabilities::parseCapabilitiesDom( QByteArray const &xml, QgsWcsCapabilitiesProperty &capabilities ) { QgsDebugMsg( "Entered." ); #ifdef QGISDEBUG QFile file( QDir::tempPath() + "/qgis-wcs-capabilities.xml" ); if ( file.open( QIODevice::WriteOnly ) ) { file.write( xml ); file.close(); } #endif if ( ! convertToDom( xml ) ) return false; QDomElement docElem = mCapabilitiesDom.documentElement(); // Assert that the DTD is what we expected (i.e. a WCS Capabilities document) QgsDebugMsg( "testing tagName " + docElem.tagName() ); QString tagName = stripNS( docElem.tagName() ); if ( // We don't support 1.0, but try WCS_Capabilities tag to get version tagName != "WCS_Capabilities" && // 1.0 tagName != "Capabilities" // 1.1, tags seen: Capabilities, wcs:Capabilities ) { if ( tagName == "ExceptionReport" ) { mErrorTitle = tr( "Exception" ); mErrorFormat = "text/plain"; mError = tr( "Could not get WCS capabilities: %1" ).arg( domElementText( docElem, "Exception.ExceptionText" ) ); } else { mErrorTitle = tr( "Dom Exception" ); mErrorFormat = "text/plain"; mError = tr( "Could not get WCS capabilities in the expected format (DTD): no %1 found.\nThis might be due to an incorrect WCS Server URL.\nTag:%3\nResponse was:\n%4" ) .arg( "Capabilities" ) .arg( docElem.tagName() ) .arg( QString( xml ) ); } QgsLogger::debug( "Dom Exception: " + mError ); return false; } capabilities.version = docElem.attribute( "version" ); mVersion = capabilities.version; if ( !mVersion.startsWith( "1.0" ) && !mVersion.startsWith( "1.1" ) ) { mErrorTitle = tr( "Version not supported" ); mErrorFormat = "text/plain"; mError = tr( "WCS server version %1 is not supported by QGIS (supported versions: 1.0.0, 1.1.0, 1.1.2)" ) .arg( mVersion ); QgsLogger::debug( "WCS version: " + mError ); return false; } if ( mVersion.startsWith( "1.0" ) ) { capabilities.title = domElementText( docElem, "Service.name" ); capabilities.abstract = domElementText( docElem, "Service.description" ); // There is also "label" in 1.0 capabilities.getCoverageGetUrl = domElement( docElem, "Capability.Request.GetCoverage.DCPType.HTTP.Get.OnlineResource" ).attribute( "xlink:href" ); parseContentMetadata( domElement( docElem, "ContentMetadata" ), capabilities.contents ); } else if ( mVersion.startsWith( "1.1" ) ) { capabilities.title = domElementText( docElem, "ServiceIdentification.Title" ); capabilities.abstract = domElementText( docElem, "ServiceIdentification.Abstract" ); QList<QDomElement> operationElements = domElements( docElem, "OperationsMetadata.Operation" ); foreach ( QDomElement el, operationElements ) { if ( el.attribute( "name" ) == "GetCoverage" ) { capabilities.getCoverageGetUrl = domElement( el, "DCP.HTTP.Get" ).attribute( "xlink:href" ); } } parseCoverageSummary( domElement( docElem, "Contents" ), capabilities.contents ); }
nsresult nsXULPopupListener::FireFocusOnTargetContent(nsIDOMNode* aTargetNode) { nsresult rv; nsCOMPtr<nsIDOMDocument> domDoc; rv = aTargetNode->GetOwnerDocument(getter_AddRefs(domDoc)); if(NS_SUCCEEDED(rv) && domDoc) { nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc); // Get nsIDOMElement for targetNode nsIPresShell *shell = doc->GetShell(); if (!shell) return NS_ERROR_FAILURE; // strong reference to keep this from going away between events // XXXbz between what events? We don't use this local at all! nsRefPtr<nsPresContext> context = shell->GetPresContext(); nsCOMPtr<nsIContent> content = do_QueryInterface(aTargetNode); nsIFrame* targetFrame = content->GetPrimaryFrame(); if (!targetFrame) return NS_ERROR_FAILURE; const nsStyleUserInterface* ui = targetFrame->GetStyleUserInterface(); PRBool suppressBlur = (ui->mUserFocus == NS_STYLE_USER_FOCUS_IGNORE); nsCOMPtr<nsIDOMElement> element; nsCOMPtr<nsIContent> newFocus = do_QueryInterface(content); nsIFrame* currFrame = targetFrame; // Look for the nearest enclosing focusable frame. while (currFrame) { PRInt32 tabIndexUnused; if (currFrame->IsFocusable(&tabIndexUnused, PR_TRUE)) { newFocus = currFrame->GetContent(); nsCOMPtr<nsIDOMElement> domElement(do_QueryInterface(newFocus)); if (domElement) { element = domElement; break; } } currFrame = currFrame->GetParent(); } nsIFocusManager* fm = nsFocusManager::GetFocusManager(); if (fm) { if (element) { fm->SetFocus(element, nsIFocusManager::FLAG_BYMOUSE | nsIFocusManager::FLAG_NOSCROLL); } else if (!suppressBlur) { nsPIDOMWindow *window = doc->GetWindow(); fm->ClearFocus(window); } } nsIEventStateManager *esm = context->EventStateManager(); nsCOMPtr<nsIContent> focusableContent = do_QueryInterface(element); esm->SetContentState(focusableContent, NS_EVENT_STATE_ACTIVE); } return rv; }
// ------------------------ 1.1 ---------------------------------------------- bool QgsWcsCapabilities::parseDescribeCoverageDom11( QByteArray const &xml, QgsWcsCoverageSummary *coverage ) { QgsDebugMsg( "coverage->identifier = " + coverage->identifier ); if ( ! convertToDom( xml ) ) return false; QDomElement docElem = mCapabilitiesDom.documentElement(); QgsDebugMsg( "testing tagName " + docElem.tagName() ); QString tagName = stripNS( docElem.tagName() ); if ( tagName != QLatin1String( "CoverageDescriptions" ) ) { mErrorTitle = tr( "Dom Exception" ); mErrorFormat = QStringLiteral( "text/plain" ); mError = tr( "Could not get WCS capabilities in the expected format (DTD): no %1 found.\nThis might be due to an incorrect WCS Server URL.\nTag: %3\nResponse was:\n%4" ) .arg( QStringLiteral( "CoverageDescriptions" ), docElem.tagName(), QString( xml ) ); QgsLogger::debug( "Dom Exception: " + mError ); return false; } // Get image size, we can get it from BoundingBox with crs=urn:ogc:def:crs:OGC::imageCRS // but while at least one BoundingBox is mandatory, it does not have to be urn:ogc:def:crs:OGC::imageCRS // TODO: if BoundingBox with crs=urn:ogc:def:crs:OGC::imageCRS is not found, // we could calculate image size from GridCRS.GridOffsets (if available) QList<QDomElement> boundingBoxElements = domElements( docElem, QStringLiteral( "CoverageDescription.Domain.SpatialDomain.BoundingBox" ) ); QgsDebugMsg( QStringLiteral( "%1 BoundingBox found" ).arg( boundingBoxElements.size() ) ); const auto constBoundingBoxElements = boundingBoxElements; for ( const QDomElement &el : constBoundingBoxElements ) { QString authid = crsUrnToAuthId( el.attribute( QStringLiteral( "crs" ) ) ); QList<double> low = parseDoubles( domElementText( el, QStringLiteral( "LowerCorner" ) ) ); QList<double> high = parseDoubles( domElementText( el, QStringLiteral( "UpperCorner" ) ) ); if ( low.size() != 2 && high.size() != 2 ) continue; if ( el.attribute( QStringLiteral( "crs" ) ) == QLatin1String( "urn:ogc:def:crs:OGC::imageCRS" ) ) { coverage->width = ( int )( high[0] - low[0] + 1 ); coverage->height = ( int )( high[1] - low[1] + 1 ); coverage->hasSize = true; } else { QgsRectangle box; QgsCoordinateReferenceSystem crs = QgsCoordinateReferenceSystem::fromOgcWmsCrs( authid ); if ( crs.isValid() && crs.hasAxisInverted() ) { box = QgsRectangle( low[1], low[0], high[1], high[0] ); } else { box = QgsRectangle( low[0], low[1], high[0], high[1] ); } coverage->boundingBoxes.insert( authid, box ); QgsDebugMsg( "crs: " + crs.authid() + ' ' + crs.description() + QString( " axisInverted = %1" ).arg( crs.hasAxisInverted() ) ); QgsDebugMsg( "BoundingBox: " + authid + " : " + box.toString() ); } } QgsDebugMsg( QStringLiteral( "width = %1 height = %2" ).arg( coverage->width ).arg( coverage->height ) ); // Each georectified coverage should have GridCRS QDomElement gridCRSElement = domElement( docElem, QStringLiteral( "CoverageDescription.Domain.SpatialDomain.GridCRS" ) ); if ( !gridCRSElement.isNull() ) { QString crsUrn = firstChildText( gridCRSElement, QStringLiteral( "GridBaseCRS" ) ); coverage->nativeCrs = crsUrnToAuthId( crsUrn ); QgsDebugMsg( "nativeCrs = " + coverage->nativeCrs ); // TODO: consider getting coverage size from GridOffsets (resolution) // if urn:ogc:def:crs:OGC::imageCRS BoundingBox was not found } coverage->times = domElementsTexts( docElem, QStringLiteral( "CoverageDescription.Domain.TemporalDomain.timePosition" ) ); QList<QDomElement> timePeriodElements = domElements( docElem, QStringLiteral( "CoverageDescription.Domain.TemporalDomain.timePeriod" ) ); QgsDebugMsg( QStringLiteral( "%1 timePeriod found" ).arg( timePeriodElements.size() ) ); const auto constTimePeriodElements = timePeriodElements; for ( const QDomElement &el : constTimePeriodElements ) { QString beginPosition = domElementText( el, QStringLiteral( "beginTime" ) ); QString endPosition = domElementText( el, QStringLiteral( "endTime" ) ); QString timeResolution = domElementText( el, QStringLiteral( "timeResolution" ) ); // Format used in request QString time = beginPosition + '/' + endPosition; if ( !timeResolution.isEmpty() ) { time += '/' + timeResolution; } coverage->times << time; } // NULL / no data values // TODO: handle multiple fields / ranges (?) Q_FOREACH ( const QString &text, domElementsTexts( docElem, "CoverageDescription.Range.Field.NullValue" ) ) { bool ok; double val = text.toDouble( &ok ); if ( ok ) { coverage->nullValues.append( val ); } } QStringList formats = domElementsTexts( docElem, QStringLiteral( "CoverageDescription.SupportedFormat" ) ); // There could be formats from GetCapabilities if ( !formats.isEmpty() ) { coverage->supportedFormat = formats; } QStringList crss = domElementsTexts( docElem, QStringLiteral( "CoverageDescription.SupportedCRS" ) ); QSet<QString> authids; // Set, in case one CRS is in more formats (URN, non URN) const auto constCrss = crss; for ( const QString &crs : constCrss ) { authids.insert( crsUrnToAuthId( crs ) ); } if ( !authids.isEmpty() ) { coverage->supportedCrs = authids.toList(); } coverage->described = true; return true; }
bool QgsWcsCapabilities::parseDescribeCoverageDom10( QByteArray const &xml, QgsWcsCoverageSummary *coverage ) { QgsDebugMsg( "coverage->identifier = " + coverage->identifier ); if ( ! convertToDom( xml ) ) return false; QDomElement docElem = mCapabilitiesDom.documentElement(); QgsDebugMsg( "testing tagName " + docElem.tagName() ); QString tagName = stripNS( docElem.tagName() ); if ( tagName != QLatin1String( "CoverageDescription" ) ) { mErrorTitle = tr( "Dom Exception" ); mErrorFormat = QStringLiteral( "text/plain" ); mError = tr( "Could not get WCS capabilities in the expected format (DTD): no %1 found.\nThis might be due to an incorrect WCS Server URL.\nTag: %3\nResponse was:\n%4" ) .arg( QStringLiteral( "CoverageDescription" ), docElem.tagName(), QString( xml ) ); QgsLogger::debug( "Dom Exception: " + mError ); return false; } QDomElement coverageOfferingElement = firstChild( docElem, QStringLiteral( "CoverageOffering" ) ); if ( coverageOfferingElement.isNull() ) return false; QDomElement supportedCRSsElement = firstChild( coverageOfferingElement, QStringLiteral( "supportedCRSs" ) ); // requestResponseCRSs and requestCRSs + responseCRSs are alternatives // we try to parse one or the other QStringList crsList; crsList = domElementsTexts( coverageOfferingElement, QStringLiteral( "supportedCRSs.requestResponseCRSs" ) ); if ( crsList.isEmpty() ) { crsList = domElementsTexts( coverageOfferingElement, QStringLiteral( "supportedCRSs.requestCRSs" ) ); crsList << domElementsTexts( coverageOfferingElement, QStringLiteral( "supportedCRSs.responseCRSs" ) ); } // exclude invalid CRSs from the lists for ( const QString &crsid : qgis::as_const( crsList ) ) { if ( QgsCoordinateReferenceSystem::fromOgcWmsCrs( crsid ).isValid() ) { coverage->supportedCrs << crsid; } } // TODO: requestCRSs, responseCRSs - must be then implemented also in provider //QgsDebugMsg( "supportedCrs = " + coverage->supportedCrs.join( "," ) ); coverage->nativeCrs = domElementText( coverageOfferingElement, QStringLiteral( "supportedCRSs.nativeCRSs" ) ); // may be GTiff, GeoTIFF, TIFF, GIF, .... coverage->supportedFormat = domElementsTexts( coverageOfferingElement, QStringLiteral( "supportedFormats.formats" ) ); QgsDebugMsg( "supportedFormat = " + coverage->supportedFormat.join( "," ) ); // spatialDomain and Grid/RectifiedGrid are optional according to specificationi. // If missing, we cannot get native resolution and size. QDomElement gridElement = domElement( coverageOfferingElement, QStringLiteral( "domainSet.spatialDomain.RectifiedGrid" ) ); if ( gridElement.isNull() ) { // Grid has also GridEnvelope from which we can get coverage size but it does not gridElement = domElement( coverageOfferingElement, QStringLiteral( "domainSet.spatialDomain.Grid" ) ); } // If supportedCRSs.nativeCRSs is not defined we try to get it from RectifiedGrid if ( coverage->nativeCrs.isEmpty() ) { QString crs = gridElement.attribute( QStringLiteral( "srsName" ) ); if ( QgsCoordinateReferenceSystem::fromOgcWmsCrs( crs ).isValid() ) { coverage->nativeCrs = crs; } } if ( !gridElement.isNull() ) { QList<int> low = parseInts( domElementText( gridElement, QStringLiteral( "limits.GridEnvelope.low" ) ) ); QList<int> high = parseInts( domElementText( gridElement, QStringLiteral( "limits.GridEnvelope.high" ) ) ); if ( low.size() == 2 && high.size() == 2 ) { // low/high are indexes in grid -> size is height - low + 1 double width = high[0] - low[0] + 1; double height = high[1] - low[1] + 1; if ( width > 0 && height > 0 ) { coverage->width = width; coverage->height = height; coverage->hasSize = true; } } // RectifiedGrid has also gml:origin which we don't need I think (attention however // it should contain gml:Point but mapserver 6.0.3 / WCS 1.0.0 is using gml:pos instead) // RectifiedGrid also contains 2 gml:offsetVector which could be used to get resolution // but it should be sufficient to calc resolution from size // TODO: check if coverage is rotated, in that case probably treat as without size // or recalc resolution from rotated grid to base CRS } QList<QDomElement> envelopeElements = domElements( coverageOfferingElement, QStringLiteral( "domainSet.spatialDomain.Envelope" ) ); QgsDebugMsg( QStringLiteral( "%1 envelopeElements found" ).arg( envelopeElements.size() ) ); const auto constEnvelopeElements = envelopeElements; for ( const QDomElement &el : constEnvelopeElements ) { QString srsName = el.attribute( QStringLiteral( "srsName" ) ); QList<QDomElement> posElements = domElements( el, QStringLiteral( "pos" ) ); if ( posElements.size() != 2 ) { QgsDebugMsg( QStringLiteral( "Wrong number of pos elements" ) ); continue; } QList<double> low = parseDoubles( posElements.value( 0 ).text() ); QList<double> high = parseDoubles( posElements.value( 1 ).text() ); if ( low.size() == 2 && high.size() == 2 ) { QgsRectangle box( low[0], low[1], high[0], high[1] ); coverage->boundingBoxes.insert( srsName, box ); QgsDebugMsg( "Envelope: " + srsName + " : " + box.toString() ); } } coverage->times = domElementsTexts( coverageOfferingElement, QStringLiteral( "domainSet.temporalDomain.timePosition" ) ); QList<QDomElement> timePeriodElements = domElements( coverageOfferingElement, QStringLiteral( "domainSet.temporalDomain.timePeriod" ) ); QgsDebugMsg( QStringLiteral( "%1 timePeriod found" ).arg( timePeriodElements.size() ) ); const auto constTimePeriodElements = timePeriodElements; for ( const QDomElement &el : constTimePeriodElements ) { QString beginPosition = domElementText( el, QStringLiteral( "beginPosition" ) ); QString endPosition = domElementText( el, QStringLiteral( "endPosition" ) ); QString timeResolution = domElementText( el, QStringLiteral( "timeResolution" ) ); // Format used in request QString time = beginPosition + '/' + endPosition; if ( !timeResolution.isEmpty() ) { time += '/' + timeResolution; } coverage->times << time; } // Find native bounding box if ( !coverage->nativeCrs.isEmpty() ) { const auto boundingBoxes = coverage->boundingBoxes; for ( auto it = boundingBoxes.constBegin(); it != boundingBoxes.constEnd(); ++it ) { if ( it.key() == coverage->nativeCrs ) { coverage->nativeBoundingBox = it.value(); } } } // NULL / no data values // TODO: handle multiple range sets Q_FOREACH ( const QString &text, domElementsTexts( coverageOfferingElement, "rangeSet.RangeSet.nullValue.singleValue" ) ) { bool ok; double val = text.toDouble( &ok ); if ( ok ) { coverage->nullValues.append( val ); } } coverage->described = true; return true; }
QString QgsWcsCapabilities::domElementText( const QDomElement &element, const QString &path ) { QDomElement el = domElement( element, path ); return el.text(); }