An observer for page loads in a custom xul:browser - firefox-addon

In my firefox extension I'm creating a xul:browser element. I want to have an observer that intercepts any url changes within the embedded browser and opens the url in a new browser tab (in the main browser). I'd also like new windows spawned by the xul:browser window to open in a tab instead of a new browser window.
I've created an observer which works, but I don't yet know how to apply that observer only to the xul:browser element.
function myFunction(){
var container = jQuery("#container")[0];
var new_browser_element = document.createElement('browser');
container.appendChild(new_browser_element);
var observerService = Components.classes["#mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
observerService.addObserver(myObserver, "http-on-modify-request", false);
}
var myObserver = {
observe: function(aSubject, aTopic, aData){
if (aTopic != 'http-on-modify-request'){
aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
// alert(aSubject.URI.spec);
// Now open url in new tab
}
},
QueryInterface: function(iid){
if (!iid.equals(Components.interfaces.nsISupports) &&
!iid.equals(Components.interfaces.nsIObserver))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
};

You could try:
var myObserver = {
observe: function(aSubject, aTopic, aData){
if (aTopic == 'http-on-modify-request')
{
aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
var url = aSubject.URI.spec;
var postData ;
if (aSubject.requestMethod.toLowerCase() == "post")
{
var postText = this.readPostTextFromRequest(request);
if (postText)
{
var dataString = parseQuery(postText);
postData = postDataFromString(dataString);
}
}
var oHttp = aSubject.QueryInterface(Components.interfaces.nsIHttpChannel);
var interfaceRequestor = oHttp.notificationCallbacks.QueryInterface(Components.interfaces.nsIInterfaceRequestor);
var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow);
//check if it is one of your mini browser windows
if (jQuery(DOMWindow).hasClass('mini_browser'))
{
openInTab(url, postData);
var request = aSubject.QueryInterface(Components.interfaces.nsIRequest);
request.cancel(Components.results.NS_BINDING_ABORTED);
}
}
},
QueryInterface: function(iid){
if (!iid.equals(Components.interfaces.nsISupports) &&
!iid.equals(Components.interfaces.nsIObserver))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
},
readPostTextFromRequest : function(request) {
var is = request.QueryInterface(Components.interfaces.nsIUploadChannel).uploadStream;
if (is)
{
var ss = is.QueryInterface(Components.interfaces.nsISeekableStream);
var prevOffset;
if (ss)
{
prevOffset = ss.tell();
ss.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, 0);
}
// Read data from the stream..
var charset = "UTF-8";
var text = this.readFromStream(is, charset, true);
// Seek locks the file so, seek to the beginning only if necko hasn't read it yet,
// since necko doesn't seek to 0 before reading (at lest not till 459384 is fixed).
if (ss && prevOffset == 0)
ss.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, 0);
return text;
}
else {
dump("Failed to Query Interface for upload stream.\n");
}
}
return null;
},
readFromStream : function(stream, charset, noClose)
{
var sis = Components.classes["#mozilla.org/binaryinputstream;1"]
.getService(Components.interfaces.nsIBinaryInputStream);
sis.setInputStream(stream);
var segments = [];
for (var count = stream.available(); count; count = stream.available())
segments.push(sis.readBytes(count));
if (!noClose)
sis.close();
var text = segments.join("");
return text;
}
};
function openInTab(url, postData)
{
var wm = Components.classes["#mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var recentWindow = wm.getMostRecentWindow("navigator:browser");
if (recentWindow)
{
// Use an existing browser window, open tab and "select" it
recentWindow.gBrowser.selectedTab = recentWindow.gBrowser.addTab(url, null, null, postData);
}
}
function parseQuery() {
var qry = this;
var rex = /[?&]?([^=]+)(?:=([^&#]*))?/g;
var qmatch, key;
var paramValues = {};
// parse querystring storing key/values in the ParamValues associative array
while (qmatch = rex.exec(qry)) {
key = decodeURIComponent(qmatch[1]);// get decoded key
val = decodeURIComponent(qmatch[2]);// get decoded value
paramValues[key] = val;
}
return paramValues;
}
function postDataFromString(dataString)
{
// POST method requests must wrap the encoded text in a MIME
// stream
var stringStream = Components.classes["#mozilla.org/io/string-input-stream;1"]
.createInstance(Components.interfaces.nsIStringInputStream);
if ("data" in stringStream) // Gecko 1.9 or newer
stringStream.data = dataString;
else // 1.8 or older
stringStream.setData(dataString, dataString.length);
var postData = Components.classes["#mozilla.org/network/mime-input-stream;1"].
createInstance(Components.interfaces.nsIMIMEInputStream);
postData.addHeader("Content-Type", "application/x-www-form-urlencoded");
postData.addContentLength = true;
postData.setData(stringStream);
return postData;
}
I'll update this to fill in the blanks in a bit.
edit: see http://forums.mozillazine.org/viewtopic.php?p=2772951#p2772951 for how to get the source window of a request.
Request cancellation code from http://zenit.senecac.on.ca/wiki/index.php/Support_For_OpenID.
see http://mxr.mozilla.org/mozilla-central/source/netwerk/base/public/nsIRequest.idl for details on nsIRequest.
See http://forums.mozillazine.org/viewtopic.php?p=2404533#p2404533 and https://developer.mozilla.org/en/XUL/Method/addTab for the definition of addTab.
parseQuery comes from http://blog.strictly-software.com/2008/10/using-javascript-to-parse-querystring.html.
See https://developer.mozilla.org/en/Code_snippets/Post_data_to_window#Preprocessing_POST_data for how to process post data in a form suitable for addTab.
ReadPostFromText and ReadTextFromStream both come from firebug (though slightly modified)

Related

Google Sheets - A pull data function doesn't want to play nice with a history storing function

I found a couple of functions that met my needs, but they don't want to play nice together. The goal is to pull data once a day, then add it to a new column. The history function is fine, and I've got a trigger setup to run it once a day, but it's erroring when attempting to run automatically, and sending me an email with the following.
6/18/18 5:29 PM loadRegionAggregates TypeError: Cannot find function
forEach in object [object Object]. (line 19, file
"Code") time-based 6/18/18 5:29 PM
here's the full code.gs (I bolded the section with line 19, first line of the function)
// Requires a list of typeids, so something like Types!A:A
// https://docs.google.com/spreadsheets/d/1IixV0eNqg19FE6cLzb83G1Ucb0Otl-Jnvm6csAlPKwo/edit?usp=sharing for an example
function loadRegionAggregates(priceIDs,regionID){
if (typeof regionID == 'undefined'){
regionID=10000002;
}
if (typeof priceIDs == 'undefined'){
throw 'Need a list of typeids';
}
var prices = new Array();
var dirtyTypeIds = new Array();
var cleanTypeIds = new Array();
var url="https://market.fuzzwork.co.uk/aggregates/?station=60003760&types=34,35,36,37,38,39,40"
**priceIDs.forEach(function (row) {
row.forEach(function (cell) {
if (typeof(cell) === 'number' ) {
dirtyTypeIds.push(cell);
}**
});
});
cleanTypeIds = dirtyTypeIds.filter(function(v,i,a) {
return a.indexOf(v)===i;
});
prices.push(['TypeID','Buy volume','Buy Weighted Average','Max Buy','Min Buy','Buy Std Dev','Median Buy','Percentile Buy Price','Sell volume','Sell Weighted Average','Max sell','Min Sell','Sell Std Dev','Median Sell','Percentile Sell Price'])
var parameters = {method : "get", payload : ""};
var o,j,temparray,chunk = 100;
for (o=0,j=cleanTypeIds.length; o < j; o+=chunk) {
temparray = cleanTypeIds.slice(o,o+chunk);
Utilities.sleep(100);
var types=temparray.join(",").replace(/,$/,'')
var jsonFeed = UrlFetchApp.fetch(url+types, parameters).getContentText();
var json = JSON.parse(jsonFeed);
if(json) {
for(i in json) {
var price=[parseInt(i),
parseInt(json[i].buy.volume),
parseInt(json[i].buy.weightedAverage),
parseFloat(json[i].buy.max),
parseFloat(json[i].buy.min),
parseFloat(json[i].buy.stddev),
parseFloat(json[i].buy.median),
parseFloat(json[i].buy.percentile),
parseInt(json[i].sell.volume),
parseFloat(json[i].sell.weightedAverage),
parseFloat(json[i].sell.max),
parseFloat(json[i].sell.min),
parseFloat(json[i].sell.stddev),
parseFloat(json[i].sell.median),
parseFloat(json[i].sell.percentile)];
prices.push(price);
}
}
}
return prices;
}
function storeData() {
var sheet = SpreadsheetApp.getActiveSheet();
var datarange = sheet.getDataRange();
var numRows = datarange.getNumRows();
var numColumns = datarange.getNumColumns();
sheet.getRange(1,numColumns + 1).setValue(new Date());
for (var i=2; i <= numRows; i++) {
var prices = sheet.getRange(i, 8).getValue();
sheet.getRange(i, numColumns + 1).setValue(prices);
}
}
I found this link:
TypeError: Cannot find function forEach in object
Which explains some of it, but when the code runs in debug mode, I don't have a range defined, and then the live sheet bugs with:
ReferenceError: "row" is not defined (line 21).
Note: My original code works fine when I run the script locally, just not when the daily timer goes off. I'm assuming the issues listed on the linked query regarding no forEach class on the nested object are applying to whatever runs the triggered .gs
Edit: Ok so i've been working on this all day. I've learned how to set an array var (since I didn't need to change the array, static works) and i've been trying to get the rest of the code adjusted ever since. Here's where I am so far:
// Requires a list of typeids, so something like Types!A:A
// https://docs.google.com/spreadsheets/d/1IixV0eNqg19FE6cLzb83G1Ucb0Otl-Jnvm6csAlPKwo/edit?usp=sharing for an example
function loadRegionAggregates(priceIDs,regionID){
if (typeof regionID == 'undefined'){
regionID=10000002;
}
if (typeof priceIDs == 'undefined'){
priceIDs = [34,35,36,37,38,39,40,11399];
}
var prices = new Array();
var dirtyTypeIds = new Array();
var cleanTypeIds = new Array();
var url="https://market.fuzzwork.co.uk/aggregates/?station=60003760&types=34,35,36,37,38,39,40"
// for (var priceIDs) {
// if (row.hasOwnProperty(column)) {
// var cell = row[column];
// if (typeof cell == "number") {
priceIDs.push(priceIDs);
// }
// }
// }
cleanTypeIds = dirtyTypeIds.filter(function(v,i,a) {
return a.indexOf(v)===i;
});
prices.push(['TypeID','Buy volume','Buy Weighted Average','Max Buy','Min Buy','Buy Std Dev','Median Buy','Percentile Buy Price','Sell volume','Sell Weighted Average','Max sell','Min Sell','Sell Std Dev','Median Sell','Percentile Sell Price'])
var parameters = {method : "get", payload : ""};
var o,j,temparray,chunk = 100;
for (o=0,j=cleanTypeIds.length; o < j; o+=chunk) {
temparray = cleanTypeIds.slice(o,o+chunk);
Utilities.sleep(100);
var types=temparray.join(",").replace(/,$/,'')
var jsonFeed = UrlFetchApp.fetch(url+types, parameters).getContentText();
var json = JSON.parse(jsonFeed);
if(json) {
for(i in json) {
var price=[parseInt(i),
parseInt(json[i].buy.volume),
parseInt(json[i].buy.weightedAverage),
parseFloat(json[i].buy.max),
parseFloat(json[i].buy.min),
parseFloat(json[i].buy.stddev),
parseFloat(json[i].buy.median),
parseFloat(json[i].buy.percentile),
parseInt(json[i].sell.volume),
parseFloat(json[i].sell.weightedAverage),
parseFloat(json[i].sell.max),
parseFloat(json[i].sell.min),
parseFloat(json[i].sell.stddev),
parseFloat(json[i].sell.median),
parseFloat(json[i].sell.percentile)];
prices.push(price);
}
}
}
return prices;
}
function storeData() {
var sheet = SpreadsheetApp.getActiveSheet();
var datarange = sheet.getDataRange();
var numRows = datarange.getNumRows();
var numColumns = datarange.getNumColumns();
sheet.getRange(1,numColumns + 1).setValue(new Date());
for (var i=2; i <= numRows; i++) {
var prices = sheet.getRange(i, 8).getValue();
sheet.getRange(i, numColumns + 1).setValue(prices);
}
}
So far, so good. It's not throwing any more errors on debug, and the column headers are coming in, but it's not bringing in the data anymore from the push.
Help!

Google docs spreadsheet script error OAuthConfig when fetching data from Fitbit

I have got following script in Google docs spreadsheet which is fetching data from Fitbit. Script worked fine so far but recently on 6th July Google stopped using OAuthConfig so script is not working since:-(
I am not programmer, I am just advanced user. So I would like to kindly ask some programmer to help tune script below in order to make it work again.
// Key of ScriptProperty for Firtbit consumer key.
var CONSUMER_KEY_PROPERTY_NAME = "fitbitConsumerKey";
// Key of ScriptProperty for Fitbit consumer secret.
var CONSUMER_SECRET_PROPERTY_NAME = "fitbitConsumerSecret";
// Default loggable resources (from Fitbit API docs).
var LOGGABLES = ["activities/log/steps", "activities/log/distance",
"activities/log/activeScore", "activities/log/activityCalories",
"activities/log/calories", "foods/log/caloriesIn",
"activities/log/minutesSedentary",
"activities/log/minutesLightlyActive",
"activities/log/minutesFairlyActive",
"activities/log/minutesVeryActive", "sleep/timeInBed",
"sleep/minutesAsleep", "sleep/minutesAwake", "sleep/awakeningsCount",
"body/weight", "body/bmi", "body/fat",];
// function authorize() makes a call to the Fitbit API to fetch the user profile
function authorize() {
var oAuthConfig = UrlFetchApp.addOAuthService("fitbit");
oAuthConfig.setAccessTokenUrl("https://api.fitbit.com/oauth/access_token");
oAuthConfig.setRequestTokenUrl("https://api.fitbit.com/oauth/request_token");
oAuthConfig.setAuthorizationUrl("https://api.fitbit.com/oauth/authorize");
oAuthConfig.setConsumerKey(getConsumerKey());
oAuthConfig.setConsumerSecret(getConsumerSecret());
var options = {
"oAuthServiceName": "fitbit",
"oAuthUseToken": "always",
};
// get the profile to force authentication
Logger.log("Function authorize() is attempting a fetch...");
try {
var result = UrlFetchApp.fetch("https://api.fitbit.com/1/user/-/profile.json", options);
var o = Utilities.jsonParse(result.getContentText());
return o.user;
}
catch (exception) {
Logger.log(exception);
Browser.msgBox("Error attempting authorization");
return null;
}
}
// function setup accepts and stores the Consumer Key, Consumer Secret, firstDate, and list of Data Elements
function setup() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
var app = UiApp.createApplication().setTitle("Setup Fitbit Download");
app.setStyleAttribute("padding", "10px");
var consumerKeyLabel = app.createLabel("Fitbit OAuth Consumer Key:*");
var consumerKey = app.createTextBox();
consumerKey.setName("consumerKey");
consumerKey.setWidth("100%");
consumerKey.setText(getConsumerKey());
var consumerSecretLabel = app.createLabel("Fitbit OAuth Consumer Secret:*");
var consumerSecret = app.createTextBox();
consumerSecret.setName("consumerSecret");
consumerSecret.setWidth("100%");
consumerSecret.setText(getConsumerSecret());
var firstDate = app.createTextBox().setId("firstDate").setName("firstDate");
firstDate.setName("firstDate");
firstDate.setWidth("100%");
firstDate.setText(getFirstDate());
// add listbox to select data elements
var loggables = app.createListBox(true).setId("loggables").setName(
"loggables");
loggables.setVisibleItemCount(4);
// add all possible elements (in array LOGGABLES)
var logIndex = 0;
for (var resource in LOGGABLES) {
loggables.addItem(LOGGABLES[resource]);
// check if this resource is in the getLoggables list
if (getLoggables().indexOf(LOGGABLES[resource]) > -1) {
// if so, pre-select it
loggables.setItemSelected(logIndex, true);
}
logIndex++;
}
// create the save handler and button
var saveHandler = app.createServerClickHandler("saveSetup");
var saveButton = app.createButton("Save Setup", saveHandler);
// put the controls in a grid
var listPanel = app.createGrid(6, 3);
listPanel.setWidget(1, 0, consumerKeyLabel);
listPanel.setWidget(1, 1, consumerKey);
listPanel.setWidget(2, 0, consumerSecretLabel);
listPanel.setWidget(2, 1, consumerSecret);
listPanel.setWidget(3, 0, app.createLabel(" * (obtain these at dev.fitbit.com)"));
listPanel.setWidget(4, 0, app.createLabel("Start Date for download (yyyy-mm-dd)"));
listPanel.setWidget(4, 1, firstDate);
listPanel.setWidget(5, 0, app.createLabel("Data Elements to download:"));
listPanel.setWidget(5, 1, loggables);
// Ensure that all controls in the grid are handled
saveHandler.addCallbackElement(listPanel);
// Build a FlowPanel, adding the grid and the save button
var dialogPanel = app.createFlowPanel();
dialogPanel.add(listPanel);
dialogPanel.add(saveButton);
app.add(dialogPanel);
doc.show(app);
}
// function sync() is called to download all desired data from Fitbit API to the spreadsheet
function sync() {
// if the user has never performed setup, do it now
if (!isConfigured()) {
setup();
return;
}
var user = authorize();
// Spatny kod, oprava nize - var doc = SpreadsheetApp.getActiveSpreadsheet();
var doc = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Pavel');
doc.setFrozenRows(1);
var options = {
"oAuthServiceName": "fitbit",
"oAuthUseToken": "always",
"method": "GET"
};
// prepare and format today's date, and a list of desired data elements
var dateString = formatToday();
var activities = getLoggables();
// for each data element, fetch a list beginning from the firstDate, ending with today
for (var activity in activities) {
var currentActivity = activities[activity];
try {
var result = UrlFetchApp.fetch("https://api.fitbit.com/1/user/-/"
+ currentActivity + "/date/" + getFirstDate() + "/"
+ dateString + ".json", options);
} catch (exception) {
Logger.log(exception);
Browser.msgBox("Error downloading " + currentActivity);
}
var o = Utilities.jsonParse(result.getContentText());
// set title
var titleCell = doc.getRange("a1");
titleCell.setValue("date");
var cell = doc.getRange('a2');
// fill the spreadsheet with the data
var index = 0;
for (var i in o) {
// set title for this column
var title = i.substring(i.lastIndexOf('-') + 1);
titleCell.offset(0, 1 + activity * 1.0).setValue(title);
var row = o[i];
for (var j in row) {
var val = row[j];
cell.offset(index, 0).setValue(val["dateTime"]);
// set the date index
cell.offset(index, 1 + activity * 1.0).setValue(val["value"]);
// set the value index index
index++;
}
}
}
}
function isConfigured() {
return getConsumerKey() != "" && getConsumerSecret() != "";
}
function setConsumerKey(key) {
ScriptProperties.setProperty(CONSUMER_KEY_PROPERTY_NAME, key);
}
function getConsumerKey() {
var key = ScriptProperties.getProperty(CONSUMER_KEY_PROPERTY_NAME);
if (key == null) {
key = "";
}
return key;
}
function setLoggables(loggable) {
ScriptProperties.setProperty("loggables", loggable);
}
function getLoggables() {
var loggable = ScriptProperties.getProperty("loggables");
if (loggable == null) {
loggable = LOGGABLES;
} else {
loggable = loggable.split(',');
}
return loggable;
}
function setFirstDate(firstDate) {
ScriptProperties.setProperty("firstDate", firstDate);
}
function getFirstDate() {
var firstDate = ScriptProperties.getProperty("firstDate");
if (firstDate == null) {
firstDate = "2012-01-01";
}
return firstDate;
}
function formatToday() {
var todayDate = new Date;
return todayDate.getFullYear()
+ '-'
+ ("00" + (todayDate.getMonth() + 1)).slice(-2)
+ '-'
+ ("00" + todayDate.getDate()).slice(-2);
}
function setConsumerSecret(secret) {
ScriptProperties.setProperty(CONSUMER_SECRET_PROPERTY_NAME, secret);
}
function getConsumerSecret() {
var secret = ScriptProperties.getProperty(CONSUMER_SECRET_PROPERTY_NAME);
if (secret == null) {
secret = "";
}
return secret;
}
// function saveSetup saves the setup params from the UI
function saveSetup(e) {
setConsumerKey(e.parameter.consumerKey);
setConsumerSecret(e.parameter.consumerSecret);
setLoggables(e.parameter.loggables);
setFirstDate(e.parameter.firstDate);
var app = UiApp.getActiveApplication();
app.close();
return app;
}
// function onOpen is called when the spreadsheet is opened; adds the Fitbit menu
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var menuEntries = [{
name: "Sync",
functionName: "sync"
}, {
name: "Setup",
functionName: "setup"
}, {
name: "Authorize",
functionName: "authorize"
}];
ss.addMenu("Fitbit", menuEntries);
}
// function onInstall is called when the script is installed (obsolete?)
function onInstall() {
onOpen();
}
Problem solved with updated code at https://github.com/loghound/Fitbit-for-Google-App-Script

Memory Leak with Phonegap Cordova Web Audio

I've seen this question asked here already : Web Audio API Memory Leaks on Mobile Platforms but there doesn't seem to be any response to it. I've tried lots of different variations - setting variables to null once I'm finished with them, or declaring the variables within scope, but it appears that the AudioContext (or OfflineAudioContext ) is not being Garbage collected after each operation. I'm using this with Phonegap, on an IOS, so the browser is safari. Any ideas how to solve this memory leak?
Here is my code:
function readVocalsToBuffer(file){
console.log('readVocalsToBuffer');
var reader = new FileReader();
reader.onloadend = function(evt){
var x = audioContext.decodeAudioData(evt.target._result, function(buffer){
if(!buffer){
console.log('error decoding file to Audio Buffer');
return;
}
window.voiceBuffer = buffer;
loadBuffers();
});
}
reader.readAsArrayBuffer(file);
}
function loadBuffers(){
console.log('loadBuffers');
try{
var bufferLoader = new BufferLoader(
audioContext,
[
"."+window.srcSong
],
createOffLineContext
);
bufferLoader.load()
}
catch(e){
console.log(e.message);
}
}
function createOffLineContext(bufferList){
console.log('createOfflineContext');
offline = new webkitOfflineAudioContext(2, window.voiceBuffer.length, 44100);
var vocalSource = offline.createBufferSource();
vocalSource.buffer = window.voiceBuffer;
vocalSource.connect(offline.destination);
var backing = offline.createBufferSource();
backing.buffer = bufferList[0];
backing.connect(offline.destination);
vocalSource.start(0);
backing.start(0);
offline.oncomplete = function(ev){
vocalSource.stop(0);
backing.stop(0);
vocalSource.disconnect(0);
backing.disconnect(0);
delete vocalSource;
delete backing;
delete window.voiceBuffer;
window.renderedFile = ev.renderedBuffer;
var bufferR = ev.renderedBuffer.getChannelData(0);
var bufferL = ev.renderedBuffer.getChannelData(1);
var interleaved = interleave(bufferL, bufferR);
var dataview = encodeWAV(interleaved);
window.audioBlob = new Blob([dataview], {type: 'Wav'});
saveFile();
}
offline.startRendering();
}
function interleave(inputL, inputR){
console.log('interleave');
var length = inputL.length + inputR.length;
var result = new Float32Array(length);
var index = 0,
inputIndex = 0;
while (index < length){
result[index++] = inputL[inputIndex];
result[index++] = inputR[inputIndex];
inputIndex++;
}
return result;
}
function saveFile(){
offline = null;
console.log('saveFile');
delete window.renderedFile;
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFSSuccess, fail);
}

BreezeJS - issues with export and import

I am trying to work as The "Sandbox Editor"
function getClonedWorkItem(entityType, entityId) {
var clonedManager = entityManager.createEmptyCopy();
var oentity = entityManager.getEntityByKey(_mapEntityTypeToSingleType(entityType), entityId);
//export it to the new manager
var exportData = entityManager.exportEntities([oentity], true);
clonedManager.importEntities(exportData);
var cloned = clonedManager.getEntityByKey(_mapEntityTypeToSingleType(entityType), entityId);
return {
entity: cloned,
__context: clonedManager
};
}
the problem is that the cloned item dont have the extrametadata under the aspect, so i cannot sent it to the server to update - as it fails on
function updateDeleteMergeRequest(request, aspect, prefix) {
var extraMetadata = aspect.extraMetadata;
var uri = extraMetadata.uri || extraMetadata.id;
if (__stringStartsWith(uri, prefix)) {
uri = uri.substring(prefix.length);
}
request.requestUri = uri;
if (extraMetadata.etag) {
request.headers["If-Match"] = extraMetadata.etag;
}
}

The document.body.innerHTML.replace() replaces the url in the address bar

I am trying to make an extension as part of which i want certain words in the web pages to be highlighted. The document.body.innerHTML.replace() replaces the url in the address bar as well. So the moment this code gets exwecuted the page doesnt get loaded properly..
Is there a way around this problem?
onPageLoad: function(aEvent) {
var doc = aEvent.originalTarget;
var str="the";
var regex;
var regex = new RegExp(str, "g");
doc.body.innerHTML = doc.body.innerHTML.replace(regex,'<b>'+str+'</b>');
}
The listener is registered as follows in a browser.xul overlay:
window.addEventListener("load", function() {
myExtension.init();
}, false);
var myExtension = {
init: function() {
var appcontent = document.getElementById("appcontent"); // browser
if(appcontent)
appcontent.addEventListener("DOMContentLoaded", myExtension.onPageLoad, false);
},
onPageLoad: function(aEvent) {
if(aEvent.originalTarget.nodeName=="#document"){
var doc = aEvent.originalTarget;
var str="the";
var regex;
var regex = new RegExp(str, "g");
doc.body.innerHTML = doc.body.innerHTML.replace(regex,'<b>'+str+'</b>');
}
}
The if condition in the function happens to do the trick..
:)

Resources