How to access the DOM of a Contentful page with a bookmarklet? - javascript

After a page like this is fully loaded
https://app.contentful.com/spaces/.../entries/...
(an internal customized company page for editing a page on a site), I easily can access elements and text like this from the console:
document.querySelectorAll("p[data-test-id='cf-ui-paragraph']")[8].textContent;
But using the same query in a bookmarklet fails on the very first line -- even after the page is fully loaded.
javascript:(function() {
var path = document.querySelectorAll("p[data-test-id='cf-ui-paragraph']")[8].textContent;
//
//
})();
Uncaught TypeError: Cannot read properties of undefined (reading 'textContent')
This seems to be a common issue but all I've seen here is the fact that it's 'not the same DOM'.
Any wisdom on how to get this (or any query at all) working on a Contentful backend editor page?

Related

Meteor - Error when loading/refreshing page: Exception from Tracker afterFlush function: undefined

As described above, I am getting an error and an empty page (but the layout including the navbar is there) is shown. This error always occurs, when I refresh the link via the browser or in case I access the link directly through the browser. Everything is fine, when I use my navigation bar to navigate through the templates. So, I canĀ“t see any data after a real "load" of the page.
I am using Meteor Blaze on Windows.
Here is a screenshot:
Neither the picture, nor other data is shown.
I am not sure, if this is 100% the reason for that behavior, but always if this behavior occurs, I get this error message in the client console:
Exception from Tracker afterFlush function: undefined
and
TypeError: Cannot read property 'username' of undefined
at Blaze.TemplateInstance. (http://localhost:3000/app/client/templates/common/navigation.js?hash=142e989d312ba94a4b875a71e5e557bdd5255272:3:40)
at http://localhost:3000/packages/blaze.js?hash=f33d3dfed63a491d24e3aa07ad66c24b5fe8c761:3398:22
at Function.Template._withTemplateInstanceFunc (http://localhost:3000/packages/blaze.js?hash=f33d3dfed63a491d24e3aa07ad66c24b5fe8c761:3744:12)
at fireCallbacks (http://localhost:3000/packages/blaze.js?hash=f33d3dfed63a491d24e3aa07ad66c24b5fe8c761:3394:12)
at Blaze.View. (http://localhost:3000/packages/blaze.js?hash=f33d3dfed63a491d24e3aa07ad66c24b5fe8c761:3487:5)
at http://localhost:3000/packages/blaze.js?hash=f33d3dfed63a491d24e3aa07ad66c24b5fe8c761:1845:14
at Object.Blaze._withCurrentView (http://localhost:3000/packages/blaze.js?hash=f33d3dfed63a491d24e3aa07ad66c24b5fe8c761:2271:12)
at http://localhost:3000/packages/blaze.js?hash=f33d3dfed63a491d24e3aa07ad66c24b5fe8c761:1844:15
at Object.Tracker._runFlush (http://localhost:3000/packages/tracker.js?hash=997515fa2d5b0530ba07741da556c4b36963ef3b:548:11)
at onGlobalMessage (http://localhost:3000/packages/meteor.js?hash=6d285d84547b3dad9717a7c89c664b61b45ea3d8:398:23)
undefined
I searched for tracker, afterFlush etc., but I am not sure what I have to change in my code?
When you load this route "fresh" (using a refresh or pasting the url into the browser) Meteor reloads the entire application including the Meteor.user() object. At line 40 of client/templates/common/navigation.js you are probably trying to access Meteor.user().username but Meteor.user() hasn't yet loaded so you get the error. You need to defend against this in your code and/or show a loading template until your subscriptions and the user object are all ready.
The first line of the error dump points to the error:
TypeError: Cannot read property 'username' of undefined at Blaze.TemplateInstance.
(http://localhost:3000/app/client/templates/common/navigation.js?hash=142e989d312ba94a4b875a71e5e557bdd5255272:3:40)
The :40 at the end there is the line number the error occurred on.

Firefox extension: Access to main document from sidebar

I'm brand new to writing Firefox extensions and I'm trying to create a sidebar which searches for certain elements in the main document and shows info about them in the sidebar. I followed the instructions here to create the sidebar with no problems.
Problem I'm having now is accessing the main window or document in my sidebar.js file.
The docs here say to use
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow);
But that gives me this error:
TypeError: window.QueryInterface is not a function
I'm getting the warning:
The Components object is deprecated. It will soon be removed.
Which makes me think even if the code above worked for me it's not the best method.
The error messages indicate that your code is running in an unprivileged javascript context. .QueryInterface() is XPCOM code, i.e. accessing internal browser components which is only available to privileged code.
It is generally not advisable to for "leaf content" (windows/sidebars spawned by addons) to have direct control. Instead your addon main code should coordinate the individual views. Your sidebar should be dumb, just pass messages to addon code and the addon then modifies the content of the tab.
Due e10s various parts of the browser may end up running in separate processes in the future and will not have direct access to each other.
If you're not developing with the addon-sdk - which is designed with message-passing as its primary way of gluing components together - you will have to use the message manager to wire your addon, sidebar and content scripts together.
Use tabs.create() | MDN as in:
browser.tabs.create({url:"https://www.google.com"});
I also used that documentation and I also got that error. The documentation is too old.
browser.tabs.create({url:"https://www.google.com"})
will work fine

Dynamics 2013 Accessing Page entities is hard to access with iframe based views

I am building an angular application which is running as a web resource on Dynamics 2013.
The application runs using a button which is added to the commandContainer using Ribbon workbench which then that button calls a Xrm.Internal.openDialog
All this works fine until I want to start using the Entities exposed by Xrm.Page.Data
Basically my button runs in the context of the main page of dynamics however the Entities are inside an iframe which based on the page I am in has a different Id and name.
So using a simple selector I can not get its contentWindow and start using the Entities.
The #crmContentPanel always has few iframes in it starting from #contentIFrame0 to #contentIFrame(n) and I can never know which iframe is the one with Entities in it.
What is the best practice, associated work flow with developing applications in this environment? How can I easily and reliably access the correct frame which holds the main page entities and work with them.
Perhaps the script is in the wrong location and needs to injected into the main content area so it has direct access to the correct Xrm? How can I achieve that?
Furthermore once I eventually manage to access this data, how can I easily pass this data to my angular application which runs in the dialog as from the documentation I read that the dialog is only allowed 1 query string param and it has to be called data. That would not be enough for my application to start using $routeParams. And I don't think using local or session storage is nice practice. What is the correct approach in this situation.
Sample code of my button script:
function runSendSender() {
// Content Iframe Entity data:
var contentFrameXrm = $('#crmContentPanel')
.find("iframe#contentIFrame0...n")[0]
.contentWindow['Xrm'];
// even if above selector was consistent across pages
// I need to send over much more than this one Id :(
var data = contentFrameXrm.Page.data.entity.getId();
var src = "/WebResources/concep_/ConcepDynamicsApp/ConcepDynamicsApp.html?data=" + data;
var DialogOptions = new Xrm.DialogOptions();
DialogOptions.width = 800;
DialogOptions.height = 500;
Xrm.Internal.openDialog(src, DialogOptions, null, null, CallbackFunction);
function CallbackFunction(returnValue) { }
}
Little more detail
When I type the following in the console I can sometimes (randomly) read the title of the form:
$('#crmContentPanel').find("iframe#contentIFrame0")[0].contentWindow['Xrm'].Page.ui.get_formTitle();
But the same code from the associated web resource function can not access the iframe and errors:
Can not Cannot read property 'contentWindow' of undefined.
Why is the iframe not accessible via the resource script and how can I access the correct context and form title/id.
I'm usually including following JavaScript file to the header of the custom WebResource that need to have an access to the CRM specific actions / information:
<script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>
This gives access to some none-entity specific information, such as Xrm.Page.context.getServerUrl() or Xrm.Page.context.getUserId() for example.
But if you added layer with your own iFrame on top of the standard entity page, you definitely can access to information underneath your current context by using following construction:
window.parent.Xrm.Page.data.entity.attributes.get("name").getValue();
Note the window.parent prefix.
The record Id can be sent to runSendSender as parameter by the ribbon itself. Just add the appropriate CrmParameter (MSDN) to the function call.
In your case, the parameter value would be FirstPrimaryItemId ("Provides one GUID identifier as a string for the record being viewed.")
After that, you'll have your function changed like this
function runSendSender(recordId) { ... }
Also, stay out from internals: to open a web resource in a dialog, you should use the supported way (link provides info about passing parameters other than data to the resource).
Xrm.Utility.openWebResource(webResourceName,webResourceData,width, height)

creating custom web interface app using node-webkit and manipulating DOM with Javascript

I want to create a custom web interface/app to a web site. Basically a streamline/custom view of important summary data. The data can be cached locally in the app and updated weekly if there are changes to the source site. I am using two windows. One window I load the html from remote site, the second window I manipulate the DOM/tables of the first window using Javascript to only display information that is important. If there is a better way or tool to do this as I have not found it yet. I am having problems with Javascript not being able to manipulate the DOM of the first window.
Im trying to edit/format the DOM (hide/delete table rows change colors) in the 2nd window from javascript running in the first window (startup node-webkit).
Docs say that I should have universal access to the other windows? How do I make sure this is true?
var gui = require('nw.gui');
var new_win = gui.Window.get( window.open('http://example.com/index.html'));
var my_elem = new_win.document.getElementById('myelement');
my_elem.style.display='none';
Type Error: Cannot read property of 'getElementById' of undefined
Any ideas?
In order to access the document property of the new window you have to access it in the window key.
Basically change your line 3 to this:
var my_elem = new_win.window.document.getElementById('myelement');

SharePoint 2013 App: 'Object' not defined (IFrame / IE9)

When developing an (SharePoint hosted) App Part for SharePoint 2013 I continiously get the error message 'Object' not defined. On other occassions (depending on which external .js file I'm loading) I might get an 'Function' not defined error. To be more specific: I only get this error, when I'm adding the App Part to a (wiki) page. The page is loaded in IE9 in Standards mode (but the error also happens in Compat View).
I found the following Information at Microsoft: APIs Are Not Available if iFrame Is Removed from DOM Tree => http://msdn.microsoft.com/en-us/library/gg622929(v=VS.85).aspx?ppud=4
I've added a simple alert to the head of the HTML page I'm trying to load as the source of the App Part (which is in fact a simple IFrame object) and indeed the page is loaded multiple times when adding the App Part. Once the App Part is added, the alert is only triggered once and I don't experience any 'Object' not defined errors. So I suspect that my App Part is first created and then manipulated several times (being attached and detached from the DOM).
It seems that my App Part, because it's temporarily removed from the DOM removes the JavaScript API! If that is the case, then how can I develop App Parts that rely on JavaScript (and shouldn't they not rely on JavaScript in the first place?!) ...
I can "surpress" this behaviour if I reload the page untill the JavaScript API is available again (this seems to be after the last time the IFrame was detached and attached again). I therefore simply put the following script as the first statement in the page's head:
<script type="text/javascript">
// Work-around for IE9 (http://msdn.microsoft.com/en-us/library/gg622929(v=VS.85).aspx?ppud=4)
if (typeof Object == 'undefined' || typeof Function == 'undefined') {
window.location.reload();
}
</script>
Still, this "pre-emptive" collection of garbage to me seems a bug rather than a feature!

Categories

Resources