void nsXULTreeAccessible::TreeViewInvalidated(PRInt32 aStartRow, PRInt32 aEndRow, PRInt32 aStartCol, PRInt32 aEndCol) { if (IsDefunct()) return; PRInt32 endRow = aEndRow; nsresult rv; if (endRow == -1) { PRInt32 rowCount = 0; rv = mTreeView->GetRowCount(&rowCount); if (NS_FAILED(rv)) return; endRow = rowCount - 1; } nsCOMPtr<nsITreeColumns> treeColumns; mTree->GetColumns(getter_AddRefs(treeColumns)); if (!treeColumns) return; PRInt32 endCol = aEndCol; if (endCol == -1) { PRInt32 colCount = 0; rv = treeColumns->GetCount(&colCount); if (NS_FAILED(rv)) return; endCol = colCount - 1; } for (PRInt32 rowIdx = aStartRow; rowIdx <= endRow; ++rowIdx) { void *key = reinterpret_cast<void*>(rowIdx); nsAccessible *accessible = mAccessibleCache.GetWeak(key); if (accessible) { nsRefPtr<nsXULTreeItemAccessibleBase> treeitemAcc = do_QueryObject(accessible); NS_ASSERTION(treeitemAcc, "Wrong accessible at the given key!"); treeitemAcc->RowInvalidated(aStartCol, endCol); } } }
NS_IMETHODIMP nsXULListCellAccessible::GetColumnHeaderCells(nsIArray **aHeaderCells) { NS_ENSURE_ARG_POINTER(aHeaderCells); *aHeaderCells = nsnull; if (IsDefunct()) return NS_ERROR_FAILURE; nsCOMPtr<nsIAccessibleTable> table; GetTable(getter_AddRefs(table)); NS_ENSURE_STATE(table); // we expect to be in a listbox (table) // Get column header cell from XUL listhead. nsAccessible *list = nsnull; nsRefPtr<nsAccessible> tableAcc(do_QueryObject(table)); PRInt32 tableChildCount = tableAcc->GetChildCount(); for (PRInt32 childIdx = 0; childIdx < tableChildCount; childIdx++) { nsAccessible *child = tableAcc->GetChildAt(childIdx); if (nsAccUtils::Role(child) == nsIAccessibleRole::ROLE_LIST) { list = child; break; } } if (list) { PRInt32 colIdx = -1; GetColumnIndex(&colIdx); nsIAccessible *headerCell = list->GetChildAt(colIdx); if (headerCell) { nsresult rv = NS_OK; nsCOMPtr<nsIMutableArray> headerCells = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); headerCells->AppendElement(headerCell, PR_FALSE); NS_ADDREF(*aHeaderCells = headerCells); return NS_OK; } } // No column header cell from XUL markup, try to get it from ARIA markup. return nsAccUtils::GetHeaderCellsFor(table, this, nsAccUtils::eColumnHeaderCells, aHeaderCells); }
STDMETHODIMP ia2AccessibleEditableText::QueryInterface(REFIID iid, void** ppv) { *ppv = NULL; if (IID_IAccessibleEditableText == iid) { nsCOMPtr<nsIAccessibleEditableText> editTextAcc(do_QueryObject(this)); if (!editTextAcc) return E_NOINTERFACE; *ppv = static_cast<IAccessibleEditableText*>(this); (reinterpret_cast<IUnknown*>(*ppv))->AddRef(); return S_OK; } return E_NOINTERFACE; }
RefPtr<mozilla::dom::ServiceWorkerRegistration> WorkerGlobalScope::GetServiceWorkerRegistration( const ServiceWorkerRegistrationDescriptor& aDescriptor) const { mWorkerPrivate->AssertIsOnWorkerThread(); RefPtr<ServiceWorkerRegistration> ref; ForEachEventTargetObject([&](DOMEventTargetHelper* aTarget, bool* aDoneOut) { RefPtr<ServiceWorkerRegistration> swr = do_QueryObject(aTarget); if (!swr || !swr->MatchesDescriptor(aDescriptor)) { return; } ref = swr.forget(); *aDoneOut = true; }); return ref.forget(); }
/* static */ void nsDOMCSSDeclaration::GetCSSParsingEnvironmentForRule(css::Rule* aRule, CSSParsingEnvironment& aCSSParseEnv) { nsIStyleSheet* sheet = aRule ? aRule->GetStyleSheet() : nsnull; nsRefPtr<nsCSSStyleSheet> cssSheet(do_QueryObject(sheet)); if (!cssSheet) { aCSSParseEnv.mPrincipal = nsnull; return; } nsIDocument* document = sheet->GetOwningDocument(); aCSSParseEnv.mSheetURI = sheet->GetSheetURI(); aCSSParseEnv.mBaseURI = sheet->GetBaseURI(); aCSSParseEnv.mPrincipal = cssSheet->Principal(); aCSSParseEnv.mCSSLoader = document ? document->CSSLoader() : nsnull; }
STDMETHODIMP CAccessibleValue::QueryInterface(REFIID iid, void** ppv) { *ppv = NULL; if (IID_IAccessibleValue == iid) { nsCOMPtr<nsIAccessibleValue> valueAcc(do_QueryObject(this)); if (!valueAcc) return E_NOINTERFACE; *ppv = static_cast<IAccessibleValue*>(this); (reinterpret_cast<IUnknown*>(*ppv))->AddRef(); return S_OK; } return E_NOINTERFACE; }
nsresult nsXBLProtoImpl::CompilePrototypeMembers(nsXBLPrototypeBinding* aBinding) { // We want to pre-compile our implementation's members against a "prototype context". Then when we actually // bind the prototype to a real xbl instance, we'll clone the pre-compiled JS into the real instance's // context. nsCOMPtr<nsIScriptGlobalObjectOwner> globalOwner( do_QueryObject(aBinding->XBLDocumentInfo())); nsIScriptGlobalObject* globalObject = globalOwner->GetScriptGlobalObject(); NS_ENSURE_TRUE(globalObject, NS_ERROR_UNEXPECTED); nsIScriptContext *context = globalObject->GetContext(); NS_ENSURE_TRUE(context, NS_ERROR_OUT_OF_MEMORY); JSContext *cx = context->GetNativeContext(); JSObject *global = globalObject->GetGlobalJSObject(); void* classObject; nsresult rv = aBinding->InitClass(mClassName, cx, global, global, &classObject); if (NS_FAILED(rv)) return rv; mClassObject = (JSObject*) classObject; if (!mClassObject) return NS_ERROR_FAILURE; AutoVersionChecker avc(cx); // Now that we have a class object installed, we walk our member list and compile each of our // properties and methods in turn. for (nsXBLProtoImplMember* curr = mMembers; curr; curr = curr->GetNext()) { nsresult rv = curr->CompileMember(context, mClassName, mClassObject); if (NS_FAILED(rv)) { DestroyMembers(); return rv; } } return NS_OK; }
NS_IMETHODIMP inDOMUtils::GetCSSStyleRules(nsIDOMElement *aElement, const nsAString& aPseudo, nsISupportsArray **_retval) { NS_ENSURE_ARG_POINTER(aElement); *_retval = nullptr; nsCOMPtr<nsIAtom> pseudoElt; if (!aPseudo.IsEmpty()) { pseudoElt = do_GetAtom(aPseudo); } nsRuleNode* ruleNode = nullptr; nsCOMPtr<nsIContent> content = do_QueryInterface(aElement); NS_ENSURE_STATE(content); nsRefPtr<nsStyleContext> styleContext; GetRuleNodeForContent(content, pseudoElt, getter_AddRefs(styleContext), &ruleNode); if (!ruleNode) { // This can fail for content nodes that are not in the document or // if the document they're in doesn't have a presshell. Bail out. return NS_OK; } nsCOMPtr<nsISupportsArray> rules; NS_NewISupportsArray(getter_AddRefs(rules)); if (!rules) return NS_ERROR_OUT_OF_MEMORY; nsRefPtr<mozilla::css::StyleRule> cssRule; for ( ; !ruleNode->IsRoot(); ruleNode = ruleNode->GetParent()) { cssRule = do_QueryObject(ruleNode->GetRule()); if (cssRule) { nsCOMPtr<nsIDOMCSSRule> domRule = cssRule->GetDOMRule(); if (domRule) rules->InsertElementAt(domRule, 0); } } *_retval = rules; NS_ADDREF(*_retval); return NS_OK; }
nsresult nsXULTreeAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY, PRBool aDeepestChild, nsIAccessible **aChild) { nsIFrame *frame = GetFrame(); if (!frame) return NS_ERROR_FAILURE; nsPresContext *presContext = frame->PresContext(); nsCOMPtr<nsIPresShell> presShell = presContext->PresShell(); nsIFrame *rootFrame = presShell->GetRootFrame(); NS_ENSURE_STATE(rootFrame); nsIntRect rootRect = rootFrame->GetScreenRectExternal(); PRInt32 clientX = presContext->DevPixelsToIntCSSPixels(aX - rootRect.x); PRInt32 clientY = presContext->DevPixelsToIntCSSPixels(aY - rootRect.y); PRInt32 row = -1; nsCOMPtr<nsITreeColumn> column; nsCAutoString childEltUnused; mTree->GetCellAt(clientX, clientY, &row, getter_AddRefs(column), childEltUnused); // If we failed to find tree cell for the given point then it might be // tree columns. if (row == -1 || !column) return nsAccessibleWrap::GetChildAtPoint(aX, aY, aDeepestChild, aChild); nsAccessible *child = GetTreeItemAccessible(row); if (aDeepestChild && child) { // Look for accessible cell for the found item accessible. nsRefPtr<nsXULTreeItemAccessibleBase> treeitem = do_QueryObject(child); nsAccessible *cell = treeitem->GetCellAccessible(column); if (cell) child = cell; } NS_IF_ADDREF(*aChild = child); return NS_OK; }
void nsXULTreeGridRowAccessible::RowInvalidated(PRInt32 aStartColIdx, PRInt32 aEndColIdx) { nsCOMPtr<nsITreeColumns> treeColumns; mTree->GetColumns(getter_AddRefs(treeColumns)); if (!treeColumns) return; for (PRInt32 colIdx = aStartColIdx; colIdx <= aEndColIdx; ++colIdx) { nsCOMPtr<nsITreeColumn> column; treeColumns->GetColumnAt(colIdx, getter_AddRefs(column)); if (column && !nsCoreUtils::IsColumnHidden(column)) { nsAccessible *cellAccessible = GetCellAccessible(column); if (cellAccessible) { nsRefPtr<nsXULTreeGridCellAccessible> cellAcc = do_QueryObject(cellAccessible); cellAcc->CellInvalidated(); } } } }
NS_IMETHODIMP InsertTextTransaction::Merge(nsITransaction* aTransaction, bool* aDidMerge) { if (!aTransaction || !aDidMerge) { return NS_OK; } // Set out param default value *aDidMerge = false; // If aTransaction is a InsertTextTransaction, and if the selection hasn't // changed, then absorb it. RefPtr<InsertTextTransaction> otherTransaction = do_QueryObject(aTransaction); if (otherTransaction && IsSequentialInsert(*otherTransaction)) { nsAutoString otherData; otherTransaction->GetData(otherData); mStringToInsert += otherData; *aDidMerge = true; } return NS_OK; }
NS_IMETHODIMP SpeechRecognition::GetUserMediaErrorCallback::OnError(nsISupports* aError) { nsRefPtr<MediaStreamError> error = do_QueryObject(aError); if (!error) { return NS_OK; } SpeechRecognitionErrorCode errorCode; nsAutoString name; error->GetName(name); if (name.EqualsLiteral("PERMISSION_DENIED")) { errorCode = SpeechRecognitionErrorCode::Not_allowed; } else { errorCode = SpeechRecognitionErrorCode::Audio_capture; } nsAutoString message; error->GetMessage(message); mRecognition->DispatchError(SpeechRecognition::EVENT_AUDIO_ERROR, errorCode, message); return NS_OK; }
NS_IMETHODIMP CompositionTransaction::Merge(nsITransaction* aTransaction, bool* aDidMerge) { NS_ENSURE_ARG_POINTER(aTransaction && aDidMerge); // Check to make sure we aren't fixed, if we are then nothing gets absorbed if (mFixed) { *aDidMerge = false; return NS_OK; } // If aTransaction is another CompositionTransaction then absorb it RefPtr<CompositionTransaction> otherTransaction = do_QueryObject(aTransaction); if (otherTransaction) { // We absorb the next IME transaction by adopting its insert string mStringToInsert = otherTransaction->mStringToInsert; mRanges = otherTransaction->mRanges; *aDidMerge = true; return NS_OK; } *aDidMerge = false; return NS_OK; }
NS_IMETHODIMP nsXULTreeGridAccessible::GetCellAt(PRInt32 aRowIndex, PRInt32 aColumnIndex, nsIAccessible **aCell) { NS_ENSURE_ARG_POINTER(aCell); *aCell = nsnull; if (IsDefunct()) return NS_ERROR_FAILURE; nsAccessible *rowAccessible = GetTreeItemAccessible(aRowIndex); if (!rowAccessible) return NS_ERROR_INVALID_ARG; nsCOMPtr<nsITreeColumn> column = nsCoreUtils::GetSensibleColumnAt(mTree, aColumnIndex); if (!column) return NS_ERROR_INVALID_ARG; nsRefPtr<nsXULTreeItemAccessibleBase> rowAcc = do_QueryObject(rowAccessible); NS_IF_ADDREF(*aCell = rowAcc->GetCellAccessible(column)); return NS_OK; }
nsresult ResourceReader::OnWalkSubframe(nsINode* aNode) { RefPtr<nsFrameLoaderOwner> loaderOwner = do_QueryObject(aNode); NS_ENSURE_STATE(loaderOwner); RefPtr<nsFrameLoader> loader = loaderOwner->GetFrameLoader(); NS_ENSURE_STATE(loader); ++mOutstandingDocuments; // Pass in 0 as the outer window ID so that we start // persisting the root of this subframe, and not some other // subframe child of this subframe. ErrorResult err; loader->StartPersistence(0, this, err); nsresult rv = err.StealNSResult(); if (NS_FAILED(rv)) { if (rv == NS_ERROR_NO_CONTENT) { // Just ignore frames with no content document. rv = NS_OK; } // StartPersistence won't eventually call this if it failed, // so this does so (to keep mOutstandingDocuments correct). DocumentDone(rv); } return rv; }
// XXXbsmedberg: move this to windowmediator nsresult nsChromeRegistry::RefreshWindow(nsIDOMWindowInternal* aWindow) { // Deal with our subframes first. nsCOMPtr<nsIDOMWindowCollection> frames; aWindow->GetFrames(getter_AddRefs(frames)); PRUint32 length; frames->GetLength(&length); PRUint32 j; for (j = 0; j < length; j++) { nsCOMPtr<nsIDOMWindow> childWin; frames->Item(j, getter_AddRefs(childWin)); nsCOMPtr<nsIDOMWindowInternal> childInt(do_QueryInterface(childWin)); RefreshWindow(childInt); } nsresult rv; // Get the DOM document. nsCOMPtr<nsIDOMDocument> domDocument; aWindow->GetDocument(getter_AddRefs(domDocument)); if (!domDocument) return NS_OK; nsCOMPtr<nsIDocument> document = do_QueryInterface(domDocument); if (!document) return NS_OK; // Deal with the agent sheets first. Have to do all the style sets by hand. nsCOMPtr<nsIPresShell> shell = document->GetShell(); if (shell) { // Reload only the chrome URL agent style sheets. nsCOMArray<nsIStyleSheet> agentSheets; rv = shell->GetAgentStyleSheets(agentSheets); NS_ENSURE_SUCCESS(rv, rv); nsCOMArray<nsIStyleSheet> newAgentSheets; for (PRInt32 l = 0; l < agentSheets.Count(); ++l) { nsIStyleSheet *sheet = agentSheets[l]; nsIURI* uri = sheet->GetSheetURI(); if (IsChromeURI(uri)) { // Reload the sheet. nsRefPtr<nsCSSStyleSheet> newSheet; rv = document->LoadChromeSheetSync(uri, PR_TRUE, getter_AddRefs(newSheet)); if (NS_FAILED(rv)) return rv; if (newSheet) { rv = newAgentSheets.AppendObject(newSheet) ? NS_OK : NS_ERROR_FAILURE; if (NS_FAILED(rv)) return rv; } } else { // Just use the same sheet. rv = newAgentSheets.AppendObject(sheet) ? NS_OK : NS_ERROR_FAILURE; if (NS_FAILED(rv)) return rv; } } rv = shell->SetAgentStyleSheets(newAgentSheets); NS_ENSURE_SUCCESS(rv, rv); } // Build an array of nsIURIs of style sheets we need to load. nsCOMArray<nsIStyleSheet> oldSheets; nsCOMArray<nsIStyleSheet> newSheets; PRInt32 count = document->GetNumberOfStyleSheets(); // Iterate over the style sheets. PRInt32 i; for (i = 0; i < count; i++) { // Get the style sheet nsIStyleSheet *styleSheet = document->GetStyleSheetAt(i); if (!oldSheets.AppendObject(styleSheet)) { return NS_ERROR_OUT_OF_MEMORY; } } // Iterate over our old sheets and kick off a sync load of the new // sheet if and only if it's a chrome URL. for (i = 0; i < count; i++) { nsRefPtr<nsCSSStyleSheet> sheet = do_QueryObject(oldSheets[i]); nsIURI* uri = sheet ? sheet->GetOriginalURI() : nsnull; if (uri && IsChromeURI(uri)) { // Reload the sheet. nsRefPtr<nsCSSStyleSheet> newSheet; // XXX what about chrome sheets that have a title or are disabled? This // only works by sheer dumb luck. document->LoadChromeSheetSync(uri, PR_FALSE, getter_AddRefs(newSheet)); // Even if it's null, we put in in there. newSheets.AppendObject(newSheet); } else { // Just use the same sheet. newSheets.AppendObject(sheet); } } // Now notify the document that multiple sheets have been added and removed. document->UpdateStyleSheets(oldSheets, newSheets); return NS_OK; }
bool nsTreeSanitizer::SanitizeStyleSheet(const nsAString& aOriginal, nsAString& aSanitized, nsIDocument* aDocument, nsIURI* aBaseURI) { nsresult rv; aSanitized.Truncate(); // aSanitized will hold the permitted CSS text. // -moz-binding is blacklisted. bool didSanitize = false; // Create a sheet to hold the parsed CSS nsRefPtr<nsCSSStyleSheet> sheet; rv = NS_NewCSSStyleSheet(getter_AddRefs(sheet)); NS_ENSURE_SUCCESS(rv, PR_TRUE); sheet->SetURIs(aDocument->GetDocumentURI(), nsnull, aBaseURI); sheet->SetPrincipal(aDocument->NodePrincipal()); // Create the CSS parser, and parse the CSS text. nsCSSParser parser(nsnull, sheet); rv = parser.ParseSheet(aOriginal, aDocument->GetDocumentURI(), aBaseURI, aDocument->NodePrincipal(), 0, PR_FALSE); NS_ENSURE_SUCCESS(rv, PR_TRUE); // Mark the sheet as complete. NS_ABORT_IF_FALSE(!sheet->IsModified(), "should not get marked modified during parsing"); sheet->SetComplete(); // Loop through all the rules found in the CSS text PRInt32 ruleCount = sheet->StyleRuleCount(); for (PRInt32 i = 0; i < ruleCount; ++i) { nsRefPtr<mozilla::css::Rule> rule; rv = sheet->GetStyleRuleAt(i, *getter_AddRefs(rule)); if (NS_FAILED(rv)) continue; NS_ASSERTION(rule, "We should have a rule by now"); switch (rule->GetType()) { default: didSanitize = PR_TRUE; // Ignore these rule types. break; case mozilla::css::Rule::NAMESPACE_RULE: case mozilla::css::Rule::FONT_FACE_RULE: { // Append @namespace and @font-face rules verbatim. nsAutoString cssText; nsCOMPtr<nsIDOMCSSRule> styleRule = do_QueryInterface(rule); if (styleRule) { rv = styleRule->GetCssText(cssText); if (NS_SUCCEEDED(rv)) { aSanitized.Append(cssText); } } break; } case mozilla::css::Rule::STYLE_RULE: { // For style rules, we will just look for and remove the // -moz-binding properties. nsRefPtr<mozilla::css::StyleRule> styleRule = do_QueryObject(rule); NS_ASSERTION(styleRule, "Must be a style rule"); nsAutoString decl; bool sanitized = SanitizeStyleRule(styleRule, decl); didSanitize = sanitized || didSanitize; if (!sanitized) { styleRule->GetCssText(decl); } aSanitized.Append(decl); } } } return didSanitize; }
// Check if X-Frame-Options permits this document to be loaded as a subdocument. bool nsDSURIContentListener::CheckFrameOptions(nsIRequest* request) { nsCAutoString xfoHeaderValue; nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(request); if (!httpChannel) { return true; } httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("X-Frame-Options"), xfoHeaderValue); // return early if header does not have one of the two values with meaning if (!xfoHeaderValue.LowerCaseEqualsLiteral("deny") && !xfoHeaderValue.LowerCaseEqualsLiteral("sameorigin")) return true; if (mDocShell) { // We need to check the location of this window and the location of the top // window, if we're not the top. X-F-O: SAMEORIGIN requires that the // document must be same-origin with top window. X-F-O: DENY requires that // the document must never be framed. nsCOMPtr<nsIDOMWindow> thisWindow = do_GetInterface(static_cast<nsIDocShell*>(mDocShell)); // If we don't have DOMWindow there is no risk of clickjacking if (!thisWindow) return true; nsCOMPtr<nsIDOMWindow> topWindow; thisWindow->GetTop(getter_AddRefs(topWindow)); // if the document is in the top window, it's not in a frame. if (thisWindow == topWindow) return true; // Find the top docshell in our parent chain that doesn't have the system // principal and use it for the principal comparison. Finding the top // content-type docshell doesn't work because some chrome documents are // loaded in content docshells (see bug 593387). nsCOMPtr<nsIDocShellTreeItem> thisDocShellItem(do_QueryInterface( static_cast<nsIDocShell*> (mDocShell))); nsCOMPtr<nsIDocShellTreeItem> parentDocShellItem, curDocShellItem = thisDocShellItem; nsCOMPtr<nsIDocument> topDoc; nsresult rv; nsCOMPtr<nsIScriptSecurityManager> ssm = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); if (!ssm) return false; // Traverse up the parent chain to the top docshell that doesn't have // a system principal while (NS_SUCCEEDED(curDocShellItem->GetParent(getter_AddRefs(parentDocShellItem))) && parentDocShellItem) { bool system = false; topDoc = do_GetInterface(parentDocShellItem); if (topDoc) { if (NS_SUCCEEDED(ssm->IsSystemPrincipal(topDoc->NodePrincipal(), &system)) && system) { break; } } else { return false; } curDocShellItem = parentDocShellItem; } // If this document has the top non-SystemPrincipal docshell it is not being // framed or it is being framed by a chrome document, which we allow. if (curDocShellItem == thisDocShellItem) return true; // If the X-Frame-Options value is SAMEORIGIN, then the top frame in the // parent chain must be from the same origin as this document. if (xfoHeaderValue.LowerCaseEqualsLiteral("sameorigin")) { nsCOMPtr<nsIURI> uri; httpChannel->GetURI(getter_AddRefs(uri)); topDoc = do_GetInterface(curDocShellItem); nsCOMPtr<nsIURI> topUri; topDoc->NodePrincipal()->GetURI(getter_AddRefs(topUri)); rv = ssm->CheckSameOriginURI(uri, topUri, PR_TRUE); if (NS_SUCCEEDED(rv)) return true; } else { // If the value of the header is DENY, then the document // should never be permitted to load as a subdocument. NS_ASSERTION(xfoHeaderValue.LowerCaseEqualsLiteral("deny"), "How did we get here with some random header value?"); } // cancel the load and display about:blank httpChannel->Cancel(NS_BINDING_ABORTED); nsCOMPtr<nsIWebNavigation> webNav(do_QueryObject(mDocShell)); if (webNav) { webNav->LoadURI(NS_LITERAL_STRING("about:blank").get(), 0, nsnull, nsnull, nsnull); } return false; } return true; }
NS_IMETHODIMP PlaceholderTransaction::Merge(nsITransaction* aTransaction, bool* aDidMerge) { NS_ENSURE_TRUE(aDidMerge && aTransaction, NS_ERROR_NULL_POINTER); // set out param default value *aDidMerge=false; if (mForwarding) { NS_NOTREACHED("tried to merge into a placeholder that was in forwarding mode!"); return NS_ERROR_FAILURE; } // check to see if aTransaction is one of the editor's // private transactions. If not, we want to avoid merging // the foreign transaction into our placeholder since we // don't know what it does. nsCOMPtr<nsPIEditorTransaction> pTxn = do_QueryInterface(aTransaction); NS_ENSURE_TRUE(pTxn, NS_OK); // it's foreign so just bail! // XXX: hack, not safe! need nsIEditTransaction! EditTransactionBase* editTransactionBase = (EditTransactionBase*)aTransaction; // determine if this incoming txn is a placeholder txn nsCOMPtr<nsIAbsorbingTransaction> absorbingTransaction = do_QueryObject(editTransactionBase); // We are absorbing all transactions if mAbsorb is lit. if (mAbsorb) { RefPtr<CompositionTransaction> otherTransaction = do_QueryObject(aTransaction); if (otherTransaction) { // special handling for CompositionTransaction's: they need to merge with // any previous CompositionTransaction in this placeholder, if possible. if (!mCompositionTransaction) { // this is the first IME txn in the placeholder mCompositionTransaction = otherTransaction; AppendChild(editTransactionBase); } else { bool didMerge; mCompositionTransaction->Merge(otherTransaction, &didMerge); if (!didMerge) { // it wouldn't merge. Earlier IME txn is already committed and will // not absorb further IME txns. So just stack this one after it // and remember it as a candidate for further merges. mCompositionTransaction = otherTransaction; AppendChild(editTransactionBase); } } } else if (!absorbingTransaction) { // See bug 171243: just drop incoming placeholders on the floor. // Their children will be swallowed by this preexisting one. AppendChild(editTransactionBase); } *aDidMerge = true; // RememberEndingSelection(); // efficiency hack: no need to remember selection here, as we haven't yet // finished the initial batch and we know we will be told when the batch ends. // we can remeber the selection then. } else { // merge typing or IME or deletion transactions if the selection matches if ((mName.get() == nsGkAtoms::TypingTxnName || mName.get() == nsGkAtoms::IMETxnName || mName.get() == nsGkAtoms::DeleteTxnName) && !mCommitted) { if (absorbingTransaction) { nsCOMPtr<nsIAtom> atom; absorbingTransaction->GetTxnName(getter_AddRefs(atom)); if (atom && atom == mName) { // check if start selection of next placeholder matches // end selection of this placeholder bool isSame; absorbingTransaction->StartSelectionEquals(&mEndSel, &isSame); if (isSame) { mAbsorb = true; // we need to start absorbing again absorbingTransaction->ForwardEndBatchTo(this); // AppendChild(editTransactionBase); // see bug 171243: we don't need to merge placeholders // into placeholders. We just reactivate merging in the pre-existing // placeholder and drop the new one on the floor. The EndPlaceHolderBatch() // call on the new placeholder will be forwarded to this older one. RememberEndingSelection(); *aDidMerge = true; } } } } } return NS_OK; }
void DataTransferItem::FillInExternalData() { if (mData) { return; } NS_ConvertUTF16toUTF8 utf8format(mType); const char* format = utf8format.get(); if (strcmp(format, "text/plain") == 0) { format = kUnicodeMime; } else if (strcmp(format, "text/uri-list") == 0) { format = kURLDataMime; } nsCOMPtr<nsITransferable> trans = do_CreateInstance("@mozilla.org/widget/transferable;1"); if (NS_WARN_IF(!trans)) { return; } trans->Init(nullptr); trans->AddDataFlavor(format); if (mDataTransfer->GetEventMessage() == ePaste) { MOZ_ASSERT(mIndex == 0, "index in clipboard must be 0"); nsCOMPtr<nsIClipboard> clipboard = do_GetService("@mozilla.org/widget/clipboard;1"); if (!clipboard || mDataTransfer->ClipboardType() < 0) { return; } nsresult rv = clipboard->GetData(trans, mDataTransfer->ClipboardType()); if (NS_WARN_IF(NS_FAILED(rv))) { return; } } else { nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession(); if (!dragSession) { return; } nsresult rv = dragSession->GetData(trans, mIndex); if (NS_WARN_IF(NS_FAILED(rv))) { return; } } uint32_t length = 0; nsCOMPtr<nsISupports> data; nsresult rv = trans->GetTransferData(format, getter_AddRefs(data), &length); if (NS_WARN_IF(NS_FAILED(rv) || !data)) { return; } // Fill the variant RefPtr<nsVariantCC> variant = new nsVariantCC(); eKind oldKind = Kind(); if (oldKind == KIND_FILE) { // Because this is an external piece of data, mType is one of kFileMime, // kPNGImageMime, kJPEGImageMime, or kGIFImageMime. Some of these types // are passed in as a nsIInputStream which must be converted to a // dom::File before storing. if (nsCOMPtr<nsIInputStream> istream = do_QueryInterface(data)) { RefPtr<File> file = CreateFileFromInputStream(istream); if (NS_WARN_IF(!file)) { return; } data = do_QueryObject(file); } variant->SetAsISupports(data); } else { // We have an external piece of string data. Extract it and store it in the variant MOZ_ASSERT(oldKind == KIND_STRING); nsCOMPtr<nsISupportsString> supportsstr = do_QueryInterface(data); if (supportsstr) { nsAutoString str; supportsstr->GetData(str); variant->SetAsAString(str); } else { nsCOMPtr<nsISupportsCString> supportscstr = do_QueryInterface(data); if (supportscstr) { nsAutoCString str; supportscstr->GetData(str); variant->SetAsACString(str); } } } SetData(variant); #ifdef DEBUG if (oldKind != Kind()) { NS_WARNING("Clipboard data provided by the OS does not match predicted kind"); } #endif }
Variant_base * convertVariantToStorageVariant(nsIVariant* aVariant) { RefPtr<Variant_base> variant = do_QueryObject(aVariant); if (variant) { // JS helpers already convert the JS representation to a Storage Variant, // in such a case there's nothing left to do here, so just pass-through. return variant; } if (!aVariant) return new NullVariant(); uint16_t dataType; nsresult rv = aVariant->GetDataType(&dataType); NS_ENSURE_SUCCESS(rv, nullptr); switch (dataType) { case nsIDataType::VTYPE_BOOL: case nsIDataType::VTYPE_INT8: case nsIDataType::VTYPE_INT16: case nsIDataType::VTYPE_INT32: case nsIDataType::VTYPE_UINT8: case nsIDataType::VTYPE_UINT16: case nsIDataType::VTYPE_UINT32: case nsIDataType::VTYPE_INT64: case nsIDataType::VTYPE_UINT64: { int64_t v; rv = aVariant->GetAsInt64(&v); NS_ENSURE_SUCCESS(rv, nullptr); return new IntegerVariant(v); } case nsIDataType::VTYPE_FLOAT: case nsIDataType::VTYPE_DOUBLE: { double v; rv = aVariant->GetAsDouble(&v); NS_ENSURE_SUCCESS(rv, nullptr); return new FloatVariant(v); } case nsIDataType::VTYPE_CHAR: case nsIDataType::VTYPE_CHAR_STR: case nsIDataType::VTYPE_STRING_SIZE_IS: case nsIDataType::VTYPE_UTF8STRING: case nsIDataType::VTYPE_CSTRING: { nsCString v; rv = aVariant->GetAsAUTF8String(v); NS_ENSURE_SUCCESS(rv, nullptr); return new UTF8TextVariant(v); } case nsIDataType::VTYPE_WCHAR: case nsIDataType::VTYPE_DOMSTRING: case nsIDataType::VTYPE_WCHAR_STR: case nsIDataType::VTYPE_WSTRING_SIZE_IS: case nsIDataType::VTYPE_ASTRING: { nsString v; rv = aVariant->GetAsAString(v); NS_ENSURE_SUCCESS(rv, nullptr); return new TextVariant(v); } case nsIDataType::VTYPE_ARRAY: { uint16_t type; nsIID iid; uint32_t len; void *rawArray; // Note this copies the array data. rv = aVariant->GetAsArray(&type, &iid, &len, &rawArray); NS_ENSURE_SUCCESS(rv, nullptr); if (type == nsIDataType::VTYPE_UINT8) { std::pair<uint8_t *, int> v(static_cast<uint8_t *>(rawArray), len); // Take ownership of the data avoiding a further copy. return new AdoptedBlobVariant(v); } MOZ_FALLTHROUGH; } case nsIDataType::VTYPE_EMPTY: case nsIDataType::VTYPE_EMPTY_ARRAY: case nsIDataType::VTYPE_VOID: return new NullVariant(); case nsIDataType::VTYPE_ID: case nsIDataType::VTYPE_INTERFACE: case nsIDataType::VTYPE_INTERFACE_IS: default: NS_WARNING("Unsupported variant type"); return nullptr; } return nullptr; }
nsresult nsProfileLock::Lock(nsIFile* aProfileDir, nsIProfileUnlocker* *aUnlocker) { #if defined (XP_MACOSX) NS_NAMED_LITERAL_STRING(LOCKFILE_NAME, ".parentlock"); NS_NAMED_LITERAL_STRING(OLD_LOCKFILE_NAME, "parent.lock"); #elif defined (XP_UNIX) NS_NAMED_LITERAL_STRING(OLD_LOCKFILE_NAME, "lock"); NS_NAMED_LITERAL_STRING(LOCKFILE_NAME, ".parentlock"); #else NS_NAMED_LITERAL_STRING(LOCKFILE_NAME, "parent.lock"); #endif nsresult rv; if (aUnlocker) *aUnlocker = nullptr; NS_ENSURE_STATE(!mHaveLock); bool isDir; rv = aProfileDir->IsDirectory(&isDir); if (NS_FAILED(rv)) return rv; if (!isDir) return NS_ERROR_FILE_NOT_DIRECTORY; nsCOMPtr<nsIFile> lockFile; rv = aProfileDir->Clone(getter_AddRefs(lockFile)); if (NS_FAILED(rv)) return rv; rv = lockFile->Append(LOCKFILE_NAME); if (NS_FAILED(rv)) return rv; #if defined(XP_MACOSX) // First, try locking using fcntl. It is more reliable on // a local machine, but may not be supported by an NFS server. rv = LockWithFcntl(lockFile); if (NS_FAILED(rv) && (rv != NS_ERROR_FILE_ACCESS_DENIED)) { // If that failed for any reason other than NS_ERROR_FILE_ACCESS_DENIED, // assume we tried an NFS that does not support it. Now, try with symlink. rv = LockWithSymlink(lockFile, false); } if (NS_SUCCEEDED(rv)) { // Check for the old-style lock used by pre-mozilla 1.3 builds. // Those builds used an earlier check to prevent the application // from launching if another instance was already running. Because // of that, we don't need to create an old-style lock as well. struct LockProcessInfo { ProcessSerialNumber psn; unsigned long launchDate; }; PRFileDesc *fd = nullptr; int32_t ioBytes; ProcessInfoRec processInfo; LockProcessInfo lockProcessInfo; rv = lockFile->SetLeafName(OLD_LOCKFILE_NAME); if (NS_FAILED(rv)) return rv; rv = lockFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fd); if (NS_SUCCEEDED(rv)) { ioBytes = PR_Read(fd, &lockProcessInfo, sizeof(LockProcessInfo)); PR_Close(fd); if (ioBytes == sizeof(LockProcessInfo)) { #ifdef __LP64__ processInfo.processAppRef = nullptr; #else processInfo.processAppSpec = nullptr; #endif processInfo.processName = nullptr; processInfo.processInfoLength = sizeof(ProcessInfoRec); if (::GetProcessInformation(&lockProcessInfo.psn, &processInfo) == noErr && processInfo.processLaunchDate == lockProcessInfo.launchDate) { return NS_ERROR_FILE_ACCESS_DENIED; } } else { NS_WARNING("Could not read lock file - ignoring lock"); } } rv = NS_OK; // Don't propagate error from OpenNSPRFileDesc. } #elif defined(XP_UNIX) // Get the old lockfile name nsCOMPtr<nsIFile> oldLockFile; rv = aProfileDir->Clone(getter_AddRefs(oldLockFile)); if (NS_FAILED(rv)) return rv; rv = oldLockFile->Append(OLD_LOCKFILE_NAME); if (NS_FAILED(rv)) return rv; // First, try locking using fcntl. It is more reliable on // a local machine, but may not be supported by an NFS server. rv = LockWithFcntl(lockFile); if (NS_SUCCEEDED(rv)) { // Check to see whether there is a symlink lock held by an older // Firefox build, and also place our own symlink lock --- but // mark it "obsolete" so that other newer builds can break the lock // if they obtain the fcntl lock rv = LockWithSymlink(oldLockFile, true); // If the symlink failed for some reason other than it already // exists, then something went wrong e.g. the file system // doesn't support symlinks, or we don't have permission to // create a symlink there. In such cases we should just // continue because it's unlikely there is an old build // running with a symlink there and we've already successfully // placed a fcntl lock. if (rv != NS_ERROR_FILE_ACCESS_DENIED) rv = NS_OK; } else if (rv != NS_ERROR_FILE_ACCESS_DENIED) { // If that failed for any reason other than NS_ERROR_FILE_ACCESS_DENIED, // assume we tried an NFS that does not support it. Now, try with symlink // using the old symlink path rv = LockWithSymlink(oldLockFile, false); } #elif defined(XP_WIN) nsAutoString filePath; rv = lockFile->GetPath(filePath); if (NS_FAILED(rv)) return rv; lockFile->GetLastModifiedTime(&mReplacedLockTime); // always create the profile lock and never delete it so we can use its // modification timestamp to detect startup crashes mLockFileHandle = CreateFileW(filePath.get(), GENERIC_READ | GENERIC_WRITE, 0, // no sharing - of course nullptr, CREATE_ALWAYS, 0, nullptr); if (mLockFileHandle == INVALID_HANDLE_VALUE) { if (aUnlocker) { RefPtr<mozilla::ProfileUnlockerWin> unlocker( new mozilla::ProfileUnlockerWin(filePath)); if (NS_SUCCEEDED(unlocker->Init())) { nsCOMPtr<nsIProfileUnlocker> unlockerInterface( do_QueryObject(unlocker)); unlockerInterface.forget(aUnlocker); } } return NS_ERROR_FILE_ACCESS_DENIED; } #elif defined(XP_OS2) nsAutoCString filePath; rv = lockFile->GetNativePath(filePath); if (NS_FAILED(rv)) return rv; lockFile->GetLastModifiedTime(&mReplacedLockTime); ULONG ulAction = 0; APIRET rc; rc = DosOpen(filePath.get(), &mLockFileHandle, &ulAction, 0, FILE_NORMAL, OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYREADWRITE | OPEN_FLAGS_NOINHERIT, 0 ); if (rc != NO_ERROR) { mLockFileHandle = -1; return NS_ERROR_FILE_ACCESS_DENIED; } #elif defined(VMS) nsAutoCString filePath; rv = lockFile->GetNativePath(filePath); if (NS_FAILED(rv)) return rv; lockFile->GetLastModifiedTime(&mReplacedLockTime); mLockFileDesc = open_noshr(filePath.get(), O_CREAT, 0666); if (mLockFileDesc == -1) { if ((errno == EVMSERR) && (vaxc$errno == RMS$_FLK)) { return NS_ERROR_FILE_ACCESS_DENIED; } else { NS_ERROR("Failed to open lock file."); return NS_ERROR_FAILURE; } } #endif mHaveLock = true; return rv; }
nsresult nsAccessibleWrap::FirePlatformEvent(AccEvent* aEvent) { nsAccessible *accessible = aEvent->GetAccessible(); NS_ENSURE_TRUE(accessible, NS_ERROR_FAILURE); PRUint32 type = aEvent->GetEventType(); AtkObject *atkObj = nsAccessibleWrap::GetAtkObject(accessible); // We don't create ATK objects for nsIAccessible plain text leaves, // just return NS_OK in such case if (!atkObj) { NS_ASSERTION(type == nsIAccessibleEvent::EVENT_SHOW || type == nsIAccessibleEvent::EVENT_HIDE, "Event other than SHOW and HIDE fired for plain text leaves"); return NS_OK; } nsAccessibleWrap *accWrap = GetAccessibleWrap(atkObj); if (!accWrap) { return NS_OK; // Node is shut down } switch (type) { case nsIAccessibleEvent::EVENT_STATE_CHANGE: return FireAtkStateChangeEvent(aEvent, atkObj); case nsIAccessibleEvent::EVENT_TEXT_REMOVED: case nsIAccessibleEvent::EVENT_TEXT_INSERTED: return FireAtkTextChangedEvent(aEvent, atkObj); case nsIAccessibleEvent::EVENT_FOCUS: { MAI_LOG_DEBUG(("\n\nReceived: EVENT_FOCUS\n")); nsRefPtr<nsRootAccessible> rootAccWrap = accWrap->GetRootAccessible(); if (rootAccWrap && rootAccWrap->mActivated) { atk_focus_tracker_notify(atkObj); // Fire state change event for focus nsRefPtr<AccEvent> stateChangeEvent = new AccStateChangeEvent(accessible, nsIAccessibleStates::STATE_FOCUSED, PR_FALSE, PR_TRUE); return FireAtkStateChangeEvent(stateChangeEvent, atkObj); } } break; case nsIAccessibleEvent::EVENT_VALUE_CHANGE: { MAI_LOG_DEBUG(("\n\nReceived: EVENT_VALUE_CHANGE\n")); nsCOMPtr<nsIAccessibleValue> value(do_QueryObject(accessible)); if (value) { // Make sure this is a numeric value // Don't fire for MSAA string value changes (e.g. text editing) // ATK values are always numeric g_object_notify( (GObject*)atkObj, "accessible-value" ); } } break; case nsIAccessibleEvent::EVENT_SELECTION_CHANGED: MAI_LOG_DEBUG(("\n\nReceived: EVENT_SELECTION_CHANGED\n")); g_signal_emit_by_name(atkObj, "selection_changed"); break; case nsIAccessibleEvent::EVENT_TEXT_SELECTION_CHANGED: MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_SELECTION_CHANGED\n")); g_signal_emit_by_name(atkObj, "text_selection_changed"); break; case nsIAccessibleEvent::EVENT_TEXT_CARET_MOVED: { MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_CARET_MOVED\n")); AccCaretMoveEvent* caretMoveEvent = downcast_accEvent(aEvent); NS_ASSERTION(caretMoveEvent, "Event needs event data"); if (!caretMoveEvent) break; PRInt32 caretOffset = caretMoveEvent->GetCaretOffset(); MAI_LOG_DEBUG(("\n\nCaret postion: %d", caretOffset)); g_signal_emit_by_name(atkObj, "text_caret_moved", // Curent caret position caretOffset); } break; case nsIAccessibleEvent::EVENT_TEXT_ATTRIBUTE_CHANGED: MAI_LOG_DEBUG(("\n\nReceived: EVENT_TEXT_ATTRIBUTE_CHANGED\n")); g_signal_emit_by_name(atkObj, "text-attributes-changed"); break; case nsIAccessibleEvent::EVENT_TABLE_MODEL_CHANGED: MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_MODEL_CHANGED\n")); g_signal_emit_by_name(atkObj, "model_changed"); break; case nsIAccessibleEvent::EVENT_TABLE_ROW_INSERT: { MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_INSERT\n")); AccTableChangeEvent* tableEvent = downcast_accEvent(aEvent); NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE); PRInt32 rowIndex = tableEvent->GetIndex(); PRInt32 numRows = tableEvent->GetCount(); g_signal_emit_by_name(atkObj, "row_inserted", // After which the rows are inserted rowIndex, // The number of the inserted numRows); } break; case nsIAccessibleEvent::EVENT_TABLE_ROW_DELETE: { MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_DELETE\n")); AccTableChangeEvent* tableEvent = downcast_accEvent(aEvent); NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE); PRInt32 rowIndex = tableEvent->GetIndex(); PRInt32 numRows = tableEvent->GetCount(); g_signal_emit_by_name(atkObj, "row_deleted", // After which the rows are deleted rowIndex, // The number of the deleted numRows); } break; case nsIAccessibleEvent::EVENT_TABLE_ROW_REORDER: { MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_ROW_REORDER\n")); g_signal_emit_by_name(atkObj, "row_reordered"); break; } case nsIAccessibleEvent::EVENT_TABLE_COLUMN_INSERT: { MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_INSERT\n")); AccTableChangeEvent* tableEvent = downcast_accEvent(aEvent); NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE); PRInt32 colIndex = tableEvent->GetIndex(); PRInt32 numCols = tableEvent->GetCount(); g_signal_emit_by_name(atkObj, "column_inserted", // After which the columns are inserted colIndex, // The number of the inserted numCols); } break; case nsIAccessibleEvent::EVENT_TABLE_COLUMN_DELETE: { MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_DELETE\n")); AccTableChangeEvent* tableEvent = downcast_accEvent(aEvent); NS_ENSURE_TRUE(tableEvent, NS_ERROR_FAILURE); PRInt32 colIndex = tableEvent->GetIndex(); PRInt32 numCols = tableEvent->GetCount(); g_signal_emit_by_name(atkObj, "column_deleted", // After which the columns are deleted colIndex, // The number of the deleted numCols); } break; case nsIAccessibleEvent::EVENT_TABLE_COLUMN_REORDER: MAI_LOG_DEBUG(("\n\nReceived: EVENT_TABLE_COLUMN_REORDER\n")); g_signal_emit_by_name(atkObj, "column_reordered"); break; case nsIAccessibleEvent::EVENT_SECTION_CHANGED: MAI_LOG_DEBUG(("\n\nReceived: EVENT_SECTION_CHANGED\n")); g_signal_emit_by_name(atkObj, "visible_data_changed"); break; case nsIAccessibleEvent::EVENT_SHOW: return FireAtkShowHideEvent(aEvent, atkObj, PR_TRUE); case nsIAccessibleEvent::EVENT_HIDE: return FireAtkShowHideEvent(aEvent, atkObj, PR_FALSE); /* * Because dealing with menu is very different between nsIAccessible * and ATK, and the menu activity is important, specially transfer the * following two event. * Need more verification by AT test. */ case nsIAccessibleEvent::EVENT_MENU_START: MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENU_START\n")); break; case nsIAccessibleEvent::EVENT_MENU_END: MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENU_END\n")); break; case nsIAccessibleEvent::EVENT_WINDOW_ACTIVATE: { MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_ACTIVATED\n")); nsRootAccessible *rootAcc = static_cast<nsRootAccessible *>(accessible); rootAcc->mActivated = PR_TRUE; guint id = g_signal_lookup ("activate", MAI_TYPE_ATK_OBJECT); g_signal_emit(atkObj, id, 0); // Always fire a current focus event after activation. rootAcc->FireCurrentFocusEvent(); } break; case nsIAccessibleEvent::EVENT_WINDOW_DEACTIVATE: { MAI_LOG_DEBUG(("\n\nReceived: EVENT_WINDOW_DEACTIVATED\n")); nsRootAccessible *rootAcc = static_cast<nsRootAccessible *>(accessible); rootAcc->mActivated = PR_FALSE; guint id = g_signal_lookup ("deactivate", MAI_TYPE_ATK_OBJECT); g_signal_emit(atkObj, id, 0); } break; case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE: { MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_LOAD_COMPLETE\n")); g_signal_emit_by_name (atkObj, "load_complete"); } break; case nsIAccessibleEvent::EVENT_DOCUMENT_RELOAD: { MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_RELOAD\n")); g_signal_emit_by_name (atkObj, "reload"); } break; case nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED: { MAI_LOG_DEBUG(("\n\nReceived: EVENT_DOCUMENT_LOAD_STOPPED\n")); g_signal_emit_by_name (atkObj, "load_stopped"); } break; case nsIAccessibleEvent::EVENT_MENUPOPUP_START: MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUPOPUP_START\n")); atk_focus_tracker_notify(atkObj); // fire extra focus event atk_object_notify_state_change(atkObj, ATK_STATE_VISIBLE, PR_TRUE); atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, PR_TRUE); break; case nsIAccessibleEvent::EVENT_MENUPOPUP_END: MAI_LOG_DEBUG(("\n\nReceived: EVENT_MENUPOPUP_END\n")); atk_object_notify_state_change(atkObj, ATK_STATE_VISIBLE, PR_FALSE); atk_object_notify_state_change(atkObj, ATK_STATE_SHOWING, PR_FALSE); break; } return NS_OK; }
NS_IMETHODIMP PostMessageEvent::Run() { MOZ_ASSERT(mTargetWindow->IsOuterWindow(), "should have been passed an outer window!"); MOZ_ASSERT(!mSource || mSource->IsOuterWindow(), "should have been passed an outer window!"); AutoJSAPI jsapi; jsapi.Init(); JSContext* cx = jsapi.cx(); // The document is just used for the principal mismatch error message below. // Use a stack variable so mSourceDocument is not held onto after this method // finishes, regardless of the method outcome. nsCOMPtr<nsIDocument> sourceDocument; sourceDocument.swap(mSourceDocument); // If we bailed before this point we're going to leak mMessage, but // that's probably better than crashing. RefPtr<nsGlobalWindow> targetWindow; if (mTargetWindow->IsClosedOrClosing() || !(targetWindow = mTargetWindow->GetCurrentInnerWindowInternal()) || targetWindow->IsClosedOrClosing()) return NS_OK; MOZ_ASSERT(targetWindow->IsInnerWindow(), "we ordered an inner window!"); JSAutoCompartment ac(cx, targetWindow->GetWrapperPreserveColor()); // Ensure that any origin which might have been provided is the origin of this // window's document. Note that we do this *now* instead of when postMessage // is called because the target window might have been navigated to a // different location between then and now. If this check happened when // postMessage was called, it would be fairly easy for a malicious webpage to // intercept messages intended for another site by carefully timing navigation // of the target window so it changed location after postMessage but before // now. if (mProvidedPrincipal) { // Get the target's origin either from its principal or, in the case the // principal doesn't carry a URI (e.g. the system principal), the target's // document. nsIPrincipal* targetPrin = targetWindow->GetPrincipal(); if (NS_WARN_IF(!targetPrin)) return NS_OK; // Note: This is contrary to the spec with respect to file: URLs, which // the spec groups into a single origin, but given we intentionally // don't do that in other places it seems better to hold the line for // now. Long-term, we want HTML5 to address this so that we can // be compliant while being safer. if (!targetPrin->Equals(mProvidedPrincipal)) { nsAutoString providedOrigin, targetOrigin; nsresult rv = nsContentUtils::GetUTFOrigin(targetPrin, targetOrigin); NS_ENSURE_SUCCESS(rv, rv); rv = nsContentUtils::GetUTFOrigin(mProvidedPrincipal, providedOrigin); NS_ENSURE_SUCCESS(rv, rv); const char16_t* params[] = { providedOrigin.get(), targetOrigin.get() }; nsContentUtils::ReportToConsole(nsIScriptError::errorFlag, NS_LITERAL_CSTRING("DOM Window"), sourceDocument, nsContentUtils::eDOM_PROPERTIES, "TargetPrincipalDoesNotMatch", params, ArrayLength(params)); return NS_OK; } } ErrorResult rv; JS::Rooted<JS::Value> messageData(cx); nsCOMPtr<nsPIDOMWindowInner> window = targetWindow->AsInner(); Read(window, cx, &messageData, rv); if (NS_WARN_IF(rv.Failed())) { return rv.StealNSResult(); } // Create the event nsCOMPtr<mozilla::dom::EventTarget> eventTarget = do_QueryObject(targetWindow); RefPtr<MessageEvent> event = new MessageEvent(eventTarget, nullptr, nullptr); Nullable<WindowProxyOrMessagePort> source; source.SetValue().SetAsWindowProxy() = mSource ? mSource->AsOuter() : nullptr; event->InitMessageEvent(nullptr, NS_LITERAL_STRING("message"), false /*non-bubbling */, false /*cancelable */, messageData, mCallerOrigin, EmptyString(), source, nullptr); nsTArray<RefPtr<MessagePort>> ports = TakeTransferredPorts(); event->SetPorts(new MessagePortList(static_cast<dom::Event*>(event.get()), ports)); // We can't simply call dispatchEvent on the window because doing so ends // up flipping the trusted bit on the event, and we don't want that to // happen because then untrusted content can call postMessage on a chrome // window if it can get a reference to it. nsIPresShell *shell = targetWindow->GetExtantDoc()->GetShell(); RefPtr<nsPresContext> presContext; if (shell) presContext = shell->GetPresContext(); event->SetTrusted(mTrustedCaller); WidgetEvent* internalEvent = event->GetInternalNSEvent(); nsEventStatus status = nsEventStatus_eIgnore; EventDispatcher::Dispatch(window, presContext, internalEvent, static_cast<dom::Event*>(event.get()), &status); return NS_OK; }
NS_IMETHODIMP nsChannelClassifier::OnClassifyComplete(nsresult aErrorCode) { // Should only be called in the parent process. MOZ_ASSERT(XRE_IsParentProcess()); if (aErrorCode == NS_ERROR_TRACKING_URI && NS_SUCCEEDED(IsTrackerWhitelisted())) { LOG(("nsChannelClassifier[%p]:OnClassifyComplete tracker found " "in whitelist so we won't block it", this)); aErrorCode = NS_OK; } if (mSuspendedChannel) { nsAutoCString errorName; if (LOG_ENABLED()) { GetErrorName(aErrorCode, errorName); LOG(("nsChannelClassifier[%p]:OnClassifyComplete %s (suspended channel)", this, errorName.get())); } MarkEntryClassified(aErrorCode); // The value of |mTrackingProtectionEnabled| should be assigned at // |ShouldEnableTrackingProtection| before. MOZ_ASSERT(mTrackingProtectionEnabled, "Should contain a value."); if (aErrorCode == NS_ERROR_TRACKING_URI && !mTrackingProtectionEnabled.valueOr(false)) { if (sAnnotateChannelEnabled) { nsCOMPtr<nsIParentChannel> parentChannel; NS_QueryNotificationCallbacks(mChannel, parentChannel); if (parentChannel) { // This channel is a parent-process proxy for a child process // request. We should notify the child process as well. parentChannel->NotifyTrackingResource(); } RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(mChannel); if (httpChannel) { httpChannel->SetIsTrackingResource(); } } if (sLowerNetworkPriority) { if (LOG_ENABLED()) { nsCOMPtr<nsIURI> uri; mChannel->GetURI(getter_AddRefs(uri)); LOG(("nsChannelClassifier[%p]: lower the priority of channel %p" ", since %s is a tracker", this, mChannel.get(), uri->GetSpecOrDefault().get())); } nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(mChannel); if (p) { p->SetPriority(nsISupportsPriority::PRIORITY_LOWEST); } } aErrorCode = NS_OK; } if (NS_FAILED(aErrorCode)) { if (LOG_ENABLED()) { nsCOMPtr<nsIURI> uri; mChannel->GetURI(getter_AddRefs(uri)); LOG(("nsChannelClassifier[%p]: cancelling channel %p for %s " "with error code %s", this, mChannel.get(), uri->GetSpecOrDefault().get(), errorName.get())); } // Channel will be cancelled (page element blocked) due to tracking. // Do update the security state of the document and fire a security // change event. if (aErrorCode == NS_ERROR_TRACKING_URI) { SetBlockedTrackingContent(mChannel); } mChannel->Cancel(aErrorCode); } LOG(("nsChannelClassifier[%p]: resuming channel %p from " "OnClassifyComplete", this, mChannel.get())); mChannel->Resume(); } mChannel = nullptr; return NS_OK; }