Compare commits
2 Commits
RJCTEST_BA
...
regalloc_c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c43d4984f | ||
|
|
cfe021ff88 |
134
mozilla/ef/Compiler/RegisterAllocator/BitSet.cpp
Normal file
134
mozilla/ef/Compiler/RegisterAllocator/BitSet.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
// Return the next bit after index set to true or -1 if none.
|
||||
//
|
||||
Int32 BitSet::nextOne(Int32 pos) const
|
||||
{
|
||||
++pos;
|
||||
|
||||
if (pos < 0 || Uint32(pos) >= universeSize)
|
||||
return -1;
|
||||
|
||||
Uint32 offset = getWordOffset(pos);
|
||||
Uint8 index = getBitOffset(pos);
|
||||
Word* ptr = &word[offset];
|
||||
Word currentWord = *ptr++ >> index;
|
||||
|
||||
if (currentWord != Word(0)) {
|
||||
while ((currentWord & Word(1)) == 0) {
|
||||
++index;
|
||||
currentWord >>= 1;
|
||||
}
|
||||
return (offset << nBitsInWordLog2) + index;
|
||||
}
|
||||
|
||||
Word* limit = &word[getSizeInWords(universeSize)];
|
||||
while (ptr < limit) {
|
||||
++offset;
|
||||
currentWord = *ptr++;
|
||||
if (currentWord != Word(0)) {
|
||||
index = 0;
|
||||
while ((currentWord & Word(1)) == 0) {
|
||||
++index;
|
||||
currentWord >>= 1;
|
||||
}
|
||||
return (offset << nBitsInWordLog2) + index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Return the next bit after index set to false or -1 if none.
|
||||
//
|
||||
Int32 BitSet::nextZero(Int32 pos) const
|
||||
{
|
||||
++pos;
|
||||
|
||||
if (pos < 0 || Uint32(pos) >= universeSize)
|
||||
return -1;
|
||||
|
||||
Uint32 offset = getWordOffset(pos);
|
||||
Uint8 index = getBitOffset(pos);
|
||||
Word* ptr = &word[offset];
|
||||
Word currentWord = *ptr++ >> index;
|
||||
|
||||
if (currentWord != Word(~0)) {
|
||||
for (; index < nBitsInWord; ++index) {
|
||||
if ((currentWord & Word(1)) == 0) {
|
||||
Int32 ret = (offset << nBitsInWordLog2) + index;
|
||||
return (Uint32(ret) < universeSize) ? ret : -1;
|
||||
}
|
||||
currentWord >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
Word* limit = &word[getSizeInWords(universeSize)];
|
||||
while (ptr < limit) {
|
||||
++offset;
|
||||
currentWord = *ptr++;
|
||||
if (currentWord != Word(~0)) {
|
||||
for (index = 0; index < nBitsInWord; ++index) {
|
||||
if ((currentWord & Word(1)) == 0) {
|
||||
Int32 ret = (offset << nBitsInWordLog2) + index;
|
||||
return (Uint32(ret) < universeSize) ? ret : -1;
|
||||
}
|
||||
currentWord >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
|
||||
// Print the set.
|
||||
//
|
||||
void BitSet::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("[ "));
|
||||
|
||||
for (Int32 i = firstOne(); i != -1; i = nextOne(i)) {
|
||||
Int32 currentBit = i;
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", currentBit));
|
||||
|
||||
Int32 nextBit = nextOne(currentBit);
|
||||
if (nextBit != currentBit + 1) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" "));
|
||||
continue;
|
||||
}
|
||||
|
||||
while ((nextBit != -1) && (nextBit == (currentBit + 1))) {
|
||||
currentBit = nextBit;
|
||||
nextBit = nextOne(nextBit);
|
||||
}
|
||||
|
||||
if (currentBit > (i+1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("-%d ", currentBit));
|
||||
else
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" %d ", currentBit));
|
||||
|
||||
i = currentBit;
|
||||
}
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("]\n"));
|
||||
}
|
||||
|
||||
#endif // DEBUG_LOG
|
||||
195
mozilla/ef/Compiler/RegisterAllocator/BitSet.h
Normal file
195
mozilla/ef/Compiler/RegisterAllocator/BitSet.h
Normal file
@@ -0,0 +1,195 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _BITSET_H_
|
||||
#define _BITSET_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "LogModule.h"
|
||||
#include "Pool.h"
|
||||
#include <string.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// BitSet -
|
||||
|
||||
class BitSet
|
||||
{
|
||||
private:
|
||||
|
||||
#if (PR_BITS_PER_WORD == 64)
|
||||
typedef Uint64 Word;
|
||||
#elif (PR_BITS_PER_WORD == 32)
|
||||
typedef Uint32 Word;
|
||||
#endif
|
||||
|
||||
static const nBitsInWord = PR_BITS_PER_WORD;
|
||||
static const nBytesInWord = PR_BYTES_PER_WORD;
|
||||
static const nBitsInWordLog2 = PR_BITS_PER_WORD_LOG2;
|
||||
static const nBytesInWordLog2 = PR_BYTES_PER_WORD_LOG2;
|
||||
|
||||
// Return the number of Word need to store the universe.
|
||||
static Uint32 getSizeInWords(Uint32 sizeOfUniverse) {return (sizeOfUniverse + (nBitsInWord - 1)) >> nBitsInWordLog2;}
|
||||
// Return the given element offset in its containing Word.
|
||||
static Uint32 getBitOffset(Uint32 element) {return element & (nBitsInWord - 1);}
|
||||
// Return the Word offset for the given element int the universe.
|
||||
static Uint32 getWordOffset(Uint32 element) {return element >> nBitsInWordLog2;}
|
||||
// Return the mask for the given bit index.
|
||||
static Word getMask(Uint8 index) {return Word(1) << index;}
|
||||
|
||||
private:
|
||||
|
||||
Uint32 universeSize; // Size of the universe
|
||||
Word* word; // universe memory.
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
BitSet(const BitSet&);
|
||||
|
||||
// Check if the given set's universe is of the same size than this universe.
|
||||
void checkUniverseCompatibility(const BitSet& set) const {assert(set.universeSize == universeSize);}
|
||||
// Check if pos is valid for this set's universe.
|
||||
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
|
||||
|
||||
public:
|
||||
|
||||
// Create a bitset of universeSize bits.
|
||||
BitSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {word = new(pool) Word[getSizeInWords(universeSize)]; clear();}
|
||||
|
||||
// Return the size of this bitset.
|
||||
Uint32 getSize() const {return universeSize;}
|
||||
|
||||
// Clear the bitset.
|
||||
void clear() {memset(word, 0x00, getSizeInWords(universeSize) << nBytesInWordLog2);}
|
||||
// Clear the bit at index.
|
||||
void clear(Uint32 index) {checkMember(index); word[getWordOffset(index)] &= ~getMask(index);}
|
||||
// Set the bitset.
|
||||
void set() {memset(word, 0xFF, getSizeInWords(universeSize) << nBytesInWordLog2);}
|
||||
// Set the bit at index.
|
||||
void set(Uint32 index) {checkMember(index); word[getWordOffset(index)] |= getMask(index);}
|
||||
// Return true if the bit at index is set.
|
||||
bool test(Uint32 index) const {checkMember(index); return (word[getWordOffset(index)] & getMask(index)) != 0;}
|
||||
// Union with the given bitset.
|
||||
inline void or(const BitSet& set);
|
||||
// Intersection with the given bitset.
|
||||
inline void and(const BitSet& set);
|
||||
// Difference with the given bitset.
|
||||
inline void difference(const BitSet& set);
|
||||
// Copy set.
|
||||
inline BitSet& operator = (const BitSet& set);
|
||||
// Return true if the bitset are identical.
|
||||
friend bool operator == (const BitSet& set1, const BitSet& set2);
|
||||
// Return true if the bitset are different.
|
||||
friend bool operator != (const BitSet& set1, const BitSet& set2);
|
||||
|
||||
// Logical operators.
|
||||
BitSet& operator |= (const BitSet& set) {or(set); return *this;}
|
||||
BitSet& operator &= (const BitSet& set) {and(set); return *this;}
|
||||
BitSet& operator -= (const BitSet& set) {difference(set); return *this;}
|
||||
|
||||
// Return the first bit at set to true or -1 if none.
|
||||
Int32 firstOne() const {return nextOne(-1);}
|
||||
// Return the next bit after index set to true or -1 if none.
|
||||
Int32 nextOne(Int32 pos) const;
|
||||
// Return the first bit at set to false or -1 if none.
|
||||
Int32 firstZero() const {return nextZero(-1);}
|
||||
// Return the next bit after index set to false or -1 if none.
|
||||
Int32 nextZero(Int32 pos) const;
|
||||
|
||||
// Iterator to conform with the set API.
|
||||
typedef Int32 iterator;
|
||||
// Return true if the walk is ordered.
|
||||
static bool isOrdered() {return true;}
|
||||
// Return the iterator for the first element of this set.
|
||||
iterator begin() const {return firstOne();}
|
||||
// Return the next iterator.
|
||||
iterator advance(iterator pos) const {return nextOne(pos);}
|
||||
// Return true if the iterator is at the end of the set.
|
||||
bool done(iterator pos) const {return pos == -1;}
|
||||
// Return the element corresponding to the given iterator.
|
||||
Uint32 get(iterator pos) const {return pos;}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the set.
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
// Union with the given bitset.
|
||||
//
|
||||
inline void BitSet::or(const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Word* src = set.word;
|
||||
Word* dst = word;
|
||||
Word* limit = &src[getSizeInWords(universeSize)];
|
||||
|
||||
while (src < limit)
|
||||
*dst++ |= *src++;
|
||||
}
|
||||
|
||||
// Intersection with the given bitset.
|
||||
//
|
||||
inline void BitSet::and(const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Word* src = set.word;
|
||||
Word* dst = word;
|
||||
Word* limit = &src[getSizeInWords(universeSize)];
|
||||
|
||||
while (src < limit)
|
||||
*dst++ &= *src++;
|
||||
}
|
||||
|
||||
// Difference with the given bitset.
|
||||
//
|
||||
inline void BitSet::difference(const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Word* src = set.word;
|
||||
Word* dst = word;
|
||||
Word* limit = &src[getSizeInWords(universeSize)];
|
||||
|
||||
while (src < limit)
|
||||
*dst++ &= ~*src++;
|
||||
}
|
||||
|
||||
// Copy the given set into this set.
|
||||
//
|
||||
inline BitSet& BitSet::operator = (const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
if (this != &set)
|
||||
memcpy(word, set.word, getSizeInWords(universeSize) << nBytesInWordLog2);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Return true if the given set is identical to this set.
|
||||
inline bool operator == (const BitSet& set1, const BitSet& set2)
|
||||
{
|
||||
set1.checkUniverseCompatibility(set2);
|
||||
|
||||
if (&set1 == &set2)
|
||||
return true;
|
||||
|
||||
return memcmp(set1.word, set2.word, BitSet::getSizeInWords(set1.universeSize) << BitSet::nBytesInWordLog2) == 0;
|
||||
}
|
||||
|
||||
inline bool operator != (const BitSet& set1, const BitSet& set2) {return !(set1 == set2);}
|
||||
|
||||
#endif // _BITSET_H
|
||||
159
mozilla/ef/Compiler/RegisterAllocator/Coalescing.h
Normal file
159
mozilla/ef/Compiler/RegisterAllocator/Coalescing.h
Normal file
@@ -0,0 +1,159 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _COALESCING_H_
|
||||
#define _COALESCING_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "InterferenceGraph.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "SparseSet.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
|
||||
#if 1
|
||||
// Performing an ultra conservative coalescing meens that when we look at
|
||||
// candidates (source,destination) for coalescing we need to make sure
|
||||
// that the combined interference of the source and destination register
|
||||
// will not exceed the total number of register available for the register
|
||||
// class.
|
||||
#define ULTRA_CONSERVATIVE_COALESCING
|
||||
#else
|
||||
// If we are not doing an ultra conservative coalescing we have to make sure
|
||||
// that the total number of neighbor whose degree is greater than the total
|
||||
// number of register is not greater than the total number of register.
|
||||
#undef ULTRA_CONSERVATIVE_COALESCING
|
||||
#endif
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct Coalescing
|
||||
{
|
||||
static bool coalesce(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Coalescing<RegisterPressure>::coalesce(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
|
||||
// Initialize the lookup table
|
||||
//
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* newRange = new RegisterName[2 * rangeCount];
|
||||
RegisterName* coalescedRange = &newRange[rangeCount];
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
init(coalescedRange, rangeCount);
|
||||
|
||||
SparseSet interferences(pool, rangeCount);
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
bool removedInstructions = false;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.lndList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
|
||||
// Walk the nodes in the loop nesting depth list.
|
||||
for (Int32 n = nNodes - 1; n >= 0; n--) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
|
||||
InstructionList::iterator it = instructions.begin();
|
||||
while (!instructions.done(it)) {
|
||||
Instruction& instruction = instructions.get(it);
|
||||
it = instructions.advance(it);
|
||||
|
||||
if ((instruction.getFlags() & ifCopy) != 0) {
|
||||
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
|
||||
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
|
||||
|
||||
RegisterName source = findRoot(name2range[instruction.getInstructionUseBegin()[0].getRegisterName()], coalescedRange);
|
||||
RegisterName destination = findRoot(name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()], coalescedRange);
|
||||
|
||||
if (source == destination) {
|
||||
instruction.remove();
|
||||
} else if (!iGraph.interfere(source, destination)) {
|
||||
InterferenceVector* sourceVector = iGraph.getInterferenceVector(source);
|
||||
InterferenceVector* destinationVector = iGraph.getInterferenceVector(destination);
|
||||
|
||||
#ifdef ULTRA_CONSERVATIVE_COALESCING
|
||||
interferences.clear();
|
||||
|
||||
InterferenceVector* vector;
|
||||
for (vector = sourceVector; vector != NULL; vector = vector->next) {
|
||||
RegisterName* neighbors = vector->neighbors;
|
||||
for (Uint32 i = 0; i < vector->count; i++)
|
||||
interferences.set(findRoot(neighbors[i], coalescedRange));
|
||||
}
|
||||
for (vector = destinationVector; vector != NULL; vector = vector->next) {
|
||||
RegisterName* neighbors = vector->neighbors;
|
||||
for (Uint32 i = 0; i < vector->count; i++)
|
||||
interferences.set(findRoot(neighbors[i], coalescedRange));
|
||||
}
|
||||
|
||||
Uint32 count = interferences.getSize();
|
||||
#else // ULTRA_CONSERVATIVE_COALESCING
|
||||
trespass("not implemented");
|
||||
Uint32 count = 0;
|
||||
#endif // ULTRA_CONSERVATIVE_COALESCING
|
||||
|
||||
if (count < 6 /* FIX: should get the number from the class */) {
|
||||
// Update the interferences vector.
|
||||
if (sourceVector == NULL) {
|
||||
iGraph.setInterferenceVector(source, destinationVector);
|
||||
sourceVector = destinationVector;
|
||||
} else if (destinationVector == NULL)
|
||||
iGraph.setInterferenceVector(destination, sourceVector);
|
||||
else {
|
||||
InterferenceVector* last = NULL;
|
||||
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next)
|
||||
last = v;
|
||||
assert(last);
|
||||
last->next = destinationVector;
|
||||
iGraph.setInterferenceVector(destination, sourceVector);
|
||||
}
|
||||
// Update the interference matrix.
|
||||
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next) {
|
||||
RegisterName* neighbors = v->neighbors;
|
||||
for (Uint32 i = 0; i < v->count; i++) {
|
||||
RegisterName neighbor = findRoot(neighbors[i], coalescedRange);
|
||||
iGraph.setInterference(neighbor, source);
|
||||
iGraph.setInterference(neighbor, destination);
|
||||
}
|
||||
}
|
||||
|
||||
instruction.remove();
|
||||
coalescedRange[source] = destination;
|
||||
removedInstructions = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerAllocator.rangeCount = compress(registerAllocator.name2range, coalescedRange, registerAllocator.nameCount, rangeCount);
|
||||
delete newRange;
|
||||
|
||||
return removedInstructions;
|
||||
}
|
||||
|
||||
#endif // _COALESCING_H_
|
||||
283
mozilla/ef/Compiler/RegisterAllocator/Coloring.cpp
Normal file
283
mozilla/ef/Compiler/RegisterAllocator/Coloring.cpp
Normal file
@@ -0,0 +1,283 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef NEW_LAURENTM_CODE
|
||||
|
||||
#include "Coloring.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "FastBitSet.h"
|
||||
#include "FastBitMatrix.h"
|
||||
#include "CpuInfo.h"
|
||||
|
||||
bool Coloring::
|
||||
assignRegisters(FastBitMatrix& interferenceMatrix)
|
||||
{
|
||||
PRUint32 *stackPtr = new(pool) PRUint32[vRegManager.count()];
|
||||
|
||||
return select(interferenceMatrix, stackPtr, simplify(interferenceMatrix, stackPtr));
|
||||
}
|
||||
|
||||
PRInt32 Coloring::
|
||||
getLowestSpillCostRegister(FastBitSet& bitset)
|
||||
{
|
||||
PRInt32 lowest = bitset.firstOne();
|
||||
if (lowest != -1)
|
||||
{
|
||||
Flt32 cost = vRegManager.getVirtualRegister(lowest).spillInfo.spillCost;
|
||||
for (PRInt32 r = bitset.nextOne(lowest); r != -1; r = bitset.nextOne(r))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
|
||||
if (!vReg.spillInfo.infiniteSpillCost && (vReg.spillInfo.spillCost < cost))
|
||||
{
|
||||
cost = vReg.spillInfo.spillCost;
|
||||
lowest = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
return lowest;
|
||||
}
|
||||
|
||||
PRUint32* Coloring::
|
||||
simplify(FastBitMatrix interferenceMatrix, PRUint32* stackPtr)
|
||||
{
|
||||
// first we construct the sets low and high. low contains all nodes of degree
|
||||
// inferior to the number of register available on the processor. All the
|
||||
// nodes with an high degree and a finite spill cost are placed in high.
|
||||
// Nodes of high degree and infinite spill cost are not included in either sets.
|
||||
|
||||
PRUint32 nRegisters = vRegManager.count();
|
||||
FastBitSet low(pool, nRegisters);
|
||||
FastBitSet high(pool, nRegisters);
|
||||
FastBitSet stack(pool, nRegisters);
|
||||
|
||||
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
|
||||
|
||||
if (vReg.getClass() == vrcStackSlot)
|
||||
{
|
||||
stack.set(i);
|
||||
vReg.colorRegister(nRegisters);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vReg.colorInfo.interferenceDegree < NUMBER_OF_REGISTERS)
|
||||
low.set(i);
|
||||
else // if (!vReg.spillInfo.infiniteSpillCost)
|
||||
high.set(i);
|
||||
|
||||
// Set coloring info.
|
||||
vReg.spillInfo.willSpill = false;
|
||||
|
||||
switch(vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
vReg.colorRegister(LAST_GREGISTER + 1);
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
vReg.colorRegister(LAST_FPREGISTER + 1);
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(false); // Cannot happen.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// push the stack registers
|
||||
PRInt32 j;
|
||||
for (j = stack.firstOne(); j != -1; j = stack.nextOne(j))
|
||||
*stackPtr++ = j;
|
||||
|
||||
// simplify
|
||||
while (true)
|
||||
{
|
||||
PRInt32 r;
|
||||
while ((r = getLowestSpillCostRegister(low)) != -1)
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
|
||||
|
||||
/* update low and high */
|
||||
FastBitSet inter(interferenceMatrix.getRow(r), nRegisters);
|
||||
for (j = inter.firstOne(); j != -1; j = inter.nextOne(j))
|
||||
{
|
||||
VirtualRegister& neighbor = vRegManager.getVirtualRegister(j);
|
||||
// if the new interference degree of one of his neighbor becomes
|
||||
// NUMBER_OF_REGISTERS - 1 then it is added to the set 'low'.
|
||||
|
||||
PRUint32 maxInterference = 0;
|
||||
switch (neighbor.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
maxInterference = NUMBER_OF_GREGISTERS;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
maxInterference = NUMBER_OF_FPREGISTERS;
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(false);
|
||||
}
|
||||
if ((vRegManager.getVirtualRegister(j).colorInfo.interferenceDegree-- == maxInterference))
|
||||
{
|
||||
high.clear(j);
|
||||
low.set(j);
|
||||
}
|
||||
vReg.colorInfo.interferenceDegree--;
|
||||
interferenceMatrix.clear(r, j);
|
||||
interferenceMatrix.clear(j, r);
|
||||
}
|
||||
low.clear(r);
|
||||
|
||||
// Push this register.
|
||||
*stackPtr++ = r;
|
||||
}
|
||||
if ((r = getLowestSpillCostRegister(high)) != -1)
|
||||
{
|
||||
high.clear(r);
|
||||
low.set(r);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return stackPtr;
|
||||
}
|
||||
|
||||
bool Coloring::
|
||||
select(FastBitMatrix& interferenceMatrix, PRUint32* stackBase, PRUint32* stackPtr)
|
||||
{
|
||||
PRUint32 nRegisters = vRegManager.count();
|
||||
FastBitSet usedRegisters(NUMBER_OF_REGISTERS + 1); // usedRegisters if used for both GR & FPR.
|
||||
FastBitSet preColoredRegisters(NUMBER_OF_REGISTERS + 1);
|
||||
FastBitSet usedStack(nRegisters + 1);
|
||||
bool success = true;
|
||||
Int32 lastUsedSSR = -1;
|
||||
|
||||
// select
|
||||
while (stackPtr != stackBase)
|
||||
{
|
||||
// Pop one register.
|
||||
PRUint32 r = *--stackPtr;
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
|
||||
|
||||
FastBitSet neighbors(interferenceMatrix.getRow(r), nRegisters);
|
||||
|
||||
if (vReg.getClass() == vrcStackSlot)
|
||||
// Stack slots coloring.
|
||||
{
|
||||
usedStack.clear();
|
||||
|
||||
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
|
||||
usedStack.set(vRegManager.getVirtualRegister(i).getColor());
|
||||
|
||||
Int32 color = usedStack.firstZero();
|
||||
vReg.colorRegister(color);
|
||||
if (color > lastUsedSSR)
|
||||
lastUsedSSR = color;
|
||||
}
|
||||
else
|
||||
// Integer & Floating point register coloring.
|
||||
{
|
||||
usedRegisters.clear();
|
||||
preColoredRegisters.clear();
|
||||
|
||||
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
|
||||
{
|
||||
VirtualRegister& nvReg = vRegManager.getVirtualRegister(i);
|
||||
usedRegisters.set(nvReg.getColor());
|
||||
if (nvReg.isPreColored())
|
||||
preColoredRegisters.set(nvReg.getPreColor());
|
||||
}
|
||||
if (vReg.hasSpecialInterference)
|
||||
usedRegisters |= vReg.specialInterference;
|
||||
|
||||
PRInt8 c = -1;
|
||||
PRInt8 maxColor = 0;
|
||||
PRInt8 firstColor = 0;
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
firstColor = FIRST_GREGISTER;
|
||||
maxColor = LAST_GREGISTER;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
firstColor = FIRST_FPREGISTER;
|
||||
maxColor = LAST_FPREGISTER;
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(false);
|
||||
}
|
||||
|
||||
if (vReg.isPreColored())
|
||||
{
|
||||
c = vReg.getPreColor();
|
||||
if (usedRegisters.test(c))
|
||||
c = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c = usedRegisters.nextZero(firstColor - 1); (c >= 0) && (c <= maxColor) && (preColoredRegisters.test(c));
|
||||
c = usedRegisters.nextZero(c)) {}
|
||||
}
|
||||
|
||||
if ((c >= 0) && (c <= maxColor))
|
||||
{
|
||||
vReg.colorRegister(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
VirtualRegister& stackRegister = vRegManager.newVirtualRegister(vrcStackSlot);
|
||||
vReg.equivalentRegister[vrcStackSlot] = &stackRegister;
|
||||
vReg.spillInfo.willSpill = true;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (success)
|
||||
{
|
||||
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
if (vReg.getColor() > LAST_GREGISTER)
|
||||
PR_ASSERT(false);
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
#if NUMBER_OF_FPREGISTERS != 0
|
||||
if (vReg.getColor() > LAST_FPREGISTER)
|
||||
PR_ASSERT(false);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vRegManager.nUsedStackSlots = lastUsedSSR + 1;
|
||||
return success;
|
||||
}
|
||||
#endif // NEW_LAURENTM_CODE
|
||||
284
mozilla/ef/Compiler/RegisterAllocator/Coloring.h
Normal file
284
mozilla/ef/Compiler/RegisterAllocator/Coloring.h
Normal file
@@ -0,0 +1,284 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "InterferenceGraph.h"
|
||||
#include "SparseSet.h"
|
||||
#include "Spilling.h"
|
||||
#include "Splits.h"
|
||||
|
||||
UT_EXTERN_LOG_MODULE(RegAlloc);
|
||||
|
||||
template <class RegisterPressure>
|
||||
class Coloring
|
||||
{
|
||||
private:
|
||||
static RegisterName* simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack);
|
||||
static bool select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr);
|
||||
|
||||
public:
|
||||
static bool color(RegisterAllocator& registerAllocator);
|
||||
static void finalColoring(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Coloring<RegisterPressure>::finalColoring(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
RegisterName* color = registerAllocator.color;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
usePtr->setRegisterName(color[name2range[usePtr->getRegisterName()]]);
|
||||
#ifdef DEBUG
|
||||
RegisterID rid = usePtr->getRegisterID();
|
||||
setColoredRegister(rid);
|
||||
usePtr->setRegisterID(rid);
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
definePtr->setRegisterName(color[name2range[definePtr->getRegisterName()]]);
|
||||
#ifdef DEBUG
|
||||
RegisterID rid = definePtr->getRegisterID();
|
||||
setColoredRegister(rid);
|
||||
definePtr->setRegisterID(rid);
|
||||
#endif // DEBUG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Coloring<RegisterPressure>::select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr)
|
||||
{
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* color = new RegisterName[rangeCount];
|
||||
registerAllocator.color = color;
|
||||
|
||||
for (Uint32 r = 1; r < rangeCount; r++)
|
||||
color[r] = RegisterName(6); // FIX;
|
||||
|
||||
// Color the preColored registers.
|
||||
//
|
||||
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
|
||||
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
|
||||
if (machinePtr->id != invalidID) {
|
||||
color[name2range[getName(machinePtr->id)]] = machinePtr->color;
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill preColor range %d as %d\n", name2range[getName(machinePtr->id)], machinePtr->color));
|
||||
}
|
||||
|
||||
SpillCost* cost = registerAllocator.spillCost;
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet& spill = *new(pool) SparseSet(pool, rangeCount);
|
||||
registerAllocator.willSpill = &spill;
|
||||
SparseSet neighborColors(pool, 6); // FIX
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
|
||||
bool coloringFailed = false;
|
||||
while (coloringStackPtr > coloringStack) {
|
||||
RegisterName range = *--coloringStackPtr;
|
||||
|
||||
if (!cost[range].infinite && cost[range].cost < 0) {
|
||||
coloringFailed = true;
|
||||
spill.set(range);
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, will spill.\n", range));
|
||||
} else {
|
||||
neighborColors.clear();
|
||||
|
||||
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
|
||||
for (Int32 i = vector->count - 1; i >= 0; --i) {
|
||||
RegisterName neighborColor = color[vector->neighbors[i]];
|
||||
if (neighborColor < 6) // FIX
|
||||
neighborColors.set(neighborColor);
|
||||
}
|
||||
|
||||
if (neighborColors.getSize() == 6) { // FIX
|
||||
coloringFailed = true;
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, ", range));
|
||||
|
||||
if (!Splits<RegisterPressure>::findSplit(registerAllocator, color, range)) {
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will spill.\n"));
|
||||
spill.set(range);
|
||||
} else
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will split.\n"));
|
||||
} else {
|
||||
for (Uint32 i = 0; i < 6; i++) // FIX
|
||||
if (!neighborColors.test(i)) {
|
||||
fprintf(stdout, "\twill color %d as %d\n", range, i);
|
||||
color[range] = RegisterName(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
if (coloringFailed) {
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring failed:\n"));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill spill: "));
|
||||
spill.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
} else {
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring succeeded:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++)
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\trange %d colored as %d\n", i, color[i]));
|
||||
}
|
||||
#endif
|
||||
|
||||
return !coloringFailed;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
RegisterName* Coloring<RegisterPressure>::simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack)
|
||||
{
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
SpillCost* spillCost = registerAllocator.spillCost;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
|
||||
Uint32* degree = new Uint32[rangeCount];
|
||||
for (RegisterName i = RegisterName(1); i < rangeCount; i = RegisterName(i + 1)) {
|
||||
InterferenceVector* vector = iGraph.getInterferenceVector(i);
|
||||
degree[i] = (vector != NULL) ? vector->count : 0;
|
||||
}
|
||||
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet low(pool, rangeCount);
|
||||
SparseSet high(pool, rangeCount);
|
||||
SparseSet highInfinite(pool, rangeCount);
|
||||
SparseSet preColored(pool, rangeCount);
|
||||
|
||||
// Get the precolored registers.
|
||||
//
|
||||
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
|
||||
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
|
||||
if (machinePtr->id != invalidID)
|
||||
preColored.set(name2range[getName(machinePtr->id)]);
|
||||
|
||||
// Insert the live ranges in the sets.
|
||||
//
|
||||
for (Uint32 range = 1; range < rangeCount; range++)
|
||||
if (!preColored.test(range))
|
||||
if (degree[range] < 6) // FIX
|
||||
low.set(range);
|
||||
else if (!spillCost[range].infinite)
|
||||
high.set(range);
|
||||
else
|
||||
highInfinite.set(range);
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring sets:\n\tlow = "));
|
||||
low.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thigh = "));
|
||||
high.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thighInfinite = "));
|
||||
highInfinite.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tpreColored = "));
|
||||
preColored.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
RegisterName* coloringStackPtr = coloringStack;
|
||||
|
||||
while (low.getSize() != 0 || high.getSize() != 0) {
|
||||
while (low.getSize() != 0) {
|
||||
RegisterName range = RegisterName(low.getOne());
|
||||
low.clear(range);
|
||||
*coloringStackPtr++ = range;
|
||||
|
||||
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
|
||||
for (Int32 i = (vector->count - 1); i >= 0; --i) {
|
||||
RegisterName neighbor = vector->neighbors[i];
|
||||
degree[neighbor]--;
|
||||
|
||||
if (degree[neighbor] < 6) // FIX
|
||||
if (high.test(neighbor)) {
|
||||
high.clear(neighbor);
|
||||
low.set(neighbor);
|
||||
} else if (highInfinite.test(neighbor)) {
|
||||
highInfinite.clear(neighbor);
|
||||
low.set(neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (high.getSize() != 0) {
|
||||
RegisterName best = RegisterName(high.getOne());
|
||||
double bestCost = spillCost[best].cost;
|
||||
double bestDegree = degree[best];
|
||||
|
||||
// Choose the next best candidate.
|
||||
//
|
||||
for (SparseSet::iterator i = high.begin(); !high.done(i); i = high.advance(i)) {
|
||||
RegisterName range = RegisterName(high.get(i));
|
||||
double thisCost = spillCost[range].cost;
|
||||
double thisDegree = degree[range];
|
||||
|
||||
if (thisCost * bestDegree < bestCost * thisDegree) {
|
||||
best = range;
|
||||
bestCost = thisCost;
|
||||
bestDegree = thisDegree;
|
||||
}
|
||||
}
|
||||
|
||||
high.clear(best);
|
||||
low.set(best);
|
||||
}
|
||||
}
|
||||
assert(highInfinite.getSize() == 0);
|
||||
|
||||
delete degree;
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring stack:\n\t"));
|
||||
for (RegisterName* sp = coloringStack; sp < coloringStackPtr; ++sp)
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("%d ", *sp));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\n"));
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
return coloringStackPtr;
|
||||
}
|
||||
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Coloring<RegisterPressure>::color(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
RegisterName* coloringStack = new RegisterName[registerAllocator.rangeCount];
|
||||
return select(registerAllocator, coloringStack, simplify(registerAllocator, coloringStack));
|
||||
}
|
||||
212
mozilla/ef/Compiler/RegisterAllocator/DominatorGraph.cpp
Normal file
212
mozilla/ef/Compiler/RegisterAllocator/DominatorGraph.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
|
||||
#include "DominatorGraph.h"
|
||||
|
||||
DominatorGraph::DominatorGraph(ControlGraph& controlGraph) : controlGraph(controlGraph)
|
||||
{
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
GtoV = new Uint32[nNodes + 1];
|
||||
VtoG = new Uint32[nNodes + 1];
|
||||
|
||||
Uint32 v = 1;
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
VtoG[v] = n;
|
||||
GtoV[n] = v++;
|
||||
}
|
||||
|
||||
// Initialize all the 1-based arrays.
|
||||
//
|
||||
parent = new Uint32[v];
|
||||
semi = new Uint32[v];
|
||||
vertex = new Uint32[v];
|
||||
label = new Uint32[v];
|
||||
size = new Uint32[v];
|
||||
ancestor = new Uint32[v];
|
||||
child = new Uint32[v];
|
||||
dom = new Uint32[v];
|
||||
bucket = new DGLinkedList*[v];
|
||||
|
||||
memset(semi, '\0', v * sizeof(Uint32));
|
||||
memset(bucket, '\0', v * sizeof(DGLinkedList*));
|
||||
|
||||
vCount = v;
|
||||
|
||||
build();
|
||||
|
||||
delete parent;
|
||||
delete semi;
|
||||
delete vertex;
|
||||
delete label;
|
||||
delete size;
|
||||
delete ancestor;
|
||||
delete child;
|
||||
delete dom;
|
||||
delete bucket;
|
||||
}
|
||||
|
||||
Uint32 DominatorGraph::DFS(Uint32 vx, Uint32 n)
|
||||
{
|
||||
semi[vx] = ++n;
|
||||
vertex[n] = label[vx] = vx;
|
||||
ancestor[vx] = child[vx] = 0;
|
||||
size[vx] = 1;
|
||||
|
||||
|
||||
ControlNode& node = *controlGraph.dfsList[VtoG[vx]];
|
||||
ControlEdge* successorEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorPtr = node.getSuccessorsBegin(); successorPtr < successorEnd; successorPtr++) {
|
||||
Uint32 w = GtoV[successorPtr->getTarget().dfsNum];
|
||||
if (semi[w] == 0) {
|
||||
parent[w] = vx;
|
||||
n = DFS(w, n);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void DominatorGraph::LINK(Uint32 vx, Uint32 w)
|
||||
{
|
||||
Uint32 s = w;
|
||||
|
||||
while (semi[label[w]] < semi[label[child[s]]]) {
|
||||
if (size[s] + size[child[child[s]]] >= (size[child[s]] << 1)) {
|
||||
ancestor[child[s]] = s;
|
||||
child[s] = child[child[s]];
|
||||
} else {
|
||||
size[child[s]] = size[s];
|
||||
s = ancestor[s] = child[s];
|
||||
}
|
||||
}
|
||||
label[s] = label[w];
|
||||
size[vx] += size[w];
|
||||
if(size[vx] < (size[w] << 1)) {
|
||||
Uint32 t = s;
|
||||
s = child[vx];
|
||||
child[vx] = t;
|
||||
}
|
||||
while( s != 0 ) {
|
||||
ancestor[s] = vx;
|
||||
s = child[s];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DominatorGraph::COMPRESS(Uint32 vx)
|
||||
{
|
||||
if(ancestor[ancestor[vx]] != 0) {
|
||||
COMPRESS(ancestor[vx]);
|
||||
if(semi[label[ancestor[vx]]] < semi[label[vx]])
|
||||
label[vx] = label[ancestor[vx]];
|
||||
ancestor[vx] = ancestor[ancestor[vx]];
|
||||
}
|
||||
}
|
||||
|
||||
Uint32 DominatorGraph::EVAL(Uint32 vx)
|
||||
{
|
||||
if(ancestor[vx] == 0)
|
||||
return label[vx];
|
||||
COMPRESS(vx);
|
||||
return (semi[label[ancestor[vx]]] >= semi[label[vx]]) ? label[vx] : label[ancestor[vx]];
|
||||
}
|
||||
|
||||
void DominatorGraph::build()
|
||||
{
|
||||
Uint32 n = DFS(GtoV[0], 0);
|
||||
size[0] = label[0] = semi[0];
|
||||
|
||||
for (Uint32 i = n; i >= 2; i--) {
|
||||
Uint32 w = vertex[i];
|
||||
|
||||
ControlNode& node = *controlGraph.dfsList[VtoG[w]];
|
||||
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
|
||||
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p)) {
|
||||
Uint32 vx = GtoV[predecessors.get(p).getSource().dfsNum];
|
||||
Uint32 u = EVAL(vx);
|
||||
|
||||
if(semi[u] < semi[w])
|
||||
semi[w] = semi[u];
|
||||
}
|
||||
|
||||
DGLinkedList* elem = new DGLinkedList();
|
||||
elem->next = bucket[vertex[semi[w]]];
|
||||
elem->index = w;
|
||||
bucket[vertex[semi[w]]] = elem;
|
||||
|
||||
LINK(parent[w], w);
|
||||
|
||||
elem = bucket[parent[w]];
|
||||
while(elem != NULL) {
|
||||
Uint32 vx = elem->index;
|
||||
Uint32 u = EVAL(vx);
|
||||
dom[vx] = (semi[u] < semi[vx]) ? u : parent[w];
|
||||
elem = elem->next;
|
||||
}
|
||||
}
|
||||
|
||||
memset(size, '\0', n * sizeof(Uint32));
|
||||
Pool& pool = controlGraph.pool;
|
||||
nodes = new(pool) DGNode[n];
|
||||
|
||||
for(Uint32 j = 2; j <= n; j++) {
|
||||
Uint32 w = vertex[j];
|
||||
Uint32 d = dom[w];
|
||||
if(d != vertex[semi[w]]) {
|
||||
d = dom[d];
|
||||
dom[w] = d;
|
||||
}
|
||||
size[d]++;
|
||||
}
|
||||
dom[GtoV[0]] = 0;
|
||||
|
||||
for (Uint32 k = 1; k <= n; k++) {
|
||||
DGNode& node = nodes[VtoG[k]];
|
||||
Uint32 count = size[k];
|
||||
node.successorsEnd = node.successorsBegin = (count) ? new(pool) Uint32[count] : (Uint32*) 0;
|
||||
}
|
||||
|
||||
for (Uint32 l = 2; l <= n; l++)
|
||||
*(nodes[VtoG[dom[l]]].successorsEnd)++ = VtoG[l];
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
void DominatorGraph::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Dominator Graph:\n"));
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
for (Uint32 i = 0; i < nNodes; i++) {
|
||||
DGNode& node = nodes[i];
|
||||
if (node.successorsBegin != node.successorsEnd) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tN%d dominates ", i));
|
||||
for (Uint32* successorsPtr = node.successorsBegin; successorsPtr < node.successorsEnd; successorsPtr++)
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d ", *successorsPtr));
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
|
||||
|
||||
80
mozilla/ef/Compiler/RegisterAllocator/DominatorGraph.h
Normal file
80
mozilla/ef/Compiler/RegisterAllocator/DominatorGraph.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DOMINATOR_GRAPH_H_
|
||||
#define _DOMINATOR_GRAPH_H_
|
||||
|
||||
#include "LogModule.h"
|
||||
|
||||
class ControlGraph;
|
||||
|
||||
struct DGNode
|
||||
{
|
||||
Uint32* successorsBegin;
|
||||
Uint32* successorsEnd;
|
||||
};
|
||||
|
||||
struct DGLinkedList
|
||||
{
|
||||
DGLinkedList* next;
|
||||
Uint32 index;
|
||||
};
|
||||
|
||||
class DominatorGraph
|
||||
{
|
||||
private:
|
||||
|
||||
ControlGraph& controlGraph;
|
||||
|
||||
Uint32 vCount;
|
||||
|
||||
Uint32* VtoG;
|
||||
Uint32* GtoV;
|
||||
Uint32* parent;
|
||||
Uint32* semi;
|
||||
Uint32* vertex;
|
||||
Uint32* label;
|
||||
Uint32* size;
|
||||
Uint32* ancestor;
|
||||
Uint32* child;
|
||||
Uint32* dom;
|
||||
DGLinkedList** bucket;
|
||||
DGNode* nodes;
|
||||
|
||||
private:
|
||||
|
||||
void build();
|
||||
|
||||
Uint32 DFS(Uint32 vx, Uint32 n);
|
||||
void LINK(Uint32 vx, Uint32 w);
|
||||
void COMPRESS(Uint32 vx);
|
||||
Uint32 EVAL(Uint32 vx);
|
||||
|
||||
public:
|
||||
|
||||
DominatorGraph(ControlGraph& controlGraph);
|
||||
|
||||
Uint32* getSuccessorsBegin(Uint32 n) const {return nodes[n].successorsBegin;}
|
||||
Uint32* getSuccessorsEnd(Uint32 n) const {return nodes[n].successorsEnd;}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
#endif // _DOMINATOR_GRAPH_H_
|
||||
20
mozilla/ef/Compiler/RegisterAllocator/HashSet.cpp
Normal file
20
mozilla/ef/Compiler/RegisterAllocator/HashSet.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashSet.h"
|
||||
97
mozilla/ef/Compiler/RegisterAllocator/HashSet.h
Normal file
97
mozilla/ef/Compiler/RegisterAllocator/HashSet.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _HASH_SET_H_
|
||||
#define _HASH_SET_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include <string.h>
|
||||
|
||||
struct HashSetElement
|
||||
{
|
||||
Uint32 index;
|
||||
HashSetElement* next;
|
||||
};
|
||||
|
||||
class HashSet
|
||||
{
|
||||
private:
|
||||
|
||||
static const hashSize = 64;
|
||||
|
||||
// Return the hash code for the given element index.
|
||||
static Uint32 getHashCode(Uint32 index) {return index & (hashSize - 1);} // Could be better !
|
||||
|
||||
private:
|
||||
|
||||
Pool& allocationPool;
|
||||
HashSetElement** bucket;
|
||||
HashSetElement* free;
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
HashSet(const HashSet&);
|
||||
// No copy operator.
|
||||
void operator = (const HashSet&);
|
||||
|
||||
public:
|
||||
|
||||
// Create a new HashSet.
|
||||
inline HashSet(Pool& pool, Uint32 universeSize);
|
||||
|
||||
// Clear the hashset.
|
||||
void clear();
|
||||
// Clear the element for the given index.
|
||||
void clear(Uint32 index);
|
||||
// Set the element for the given index.
|
||||
void set(Uint32 index);
|
||||
// Return true if the element at index is a member.
|
||||
bool test(Uint32 index) const;
|
||||
// Union with the given hashset.
|
||||
inline void or(const HashSet& set);
|
||||
// Intersection with the given hashset.
|
||||
inline void and(const HashSet& set);
|
||||
// Difference with the given hashset.
|
||||
inline void difference(const HashSet& set);
|
||||
|
||||
// Logical operators.
|
||||
HashSet& operator |= (const HashSet& set) {or(set); return *this;}
|
||||
HashSet& operator &= (const HashSet& set) {and(set); return *this;}
|
||||
HashSet& operator -= (const HashSet& set) {difference(set); return *this;}
|
||||
|
||||
// Iterator to conform with the set API.
|
||||
typedef HashSetElement* iterator;
|
||||
// Return the iterator for the first element of this set.
|
||||
iterator begin() const;
|
||||
// Return the next iterator.
|
||||
iterator advance(iterator pos) const;
|
||||
// Return true if the iterator is at the end of the set.
|
||||
bool done(iterator pos) const {return pos == NULL;}
|
||||
};
|
||||
|
||||
|
||||
inline HashSet::HashSet(Pool& pool, Uint32 /*universeSize*/)
|
||||
: allocationPool(pool), free(NULL)
|
||||
{
|
||||
bucket = new(pool) HashSetElement*[hashSize];
|
||||
memset(bucket, '\0', sizeof(HashSetElement*));
|
||||
}
|
||||
|
||||
#endif // _HASH_SET_H_
|
||||
213
mozilla/ef/Compiler/RegisterAllocator/IndexedPool.h
Normal file
213
mozilla/ef/Compiler/RegisterAllocator/IndexedPool.h
Normal file
@@ -0,0 +1,213 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _INDEXED_POOL_H_
|
||||
#define _INDEXED_POOL_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// IndexedPool<IndexedObjectSubclass> is an indexed pool of objects. The
|
||||
// template parameter 'IndexedObjectSubclass' must be a subclass of the struct
|
||||
// IndexedObject.
|
||||
//
|
||||
// When the indexed pool is ask to allocate and initialize a new object (using
|
||||
// the operator new(anIndexedPool) it will zero the memory used to store the
|
||||
// object and initialize the field 'index' of this object to its position in
|
||||
// the pool.
|
||||
//
|
||||
// An object allocated by the indexed pool can be freed by calling the method
|
||||
// IndexedPool::release(IndexedElement& objectIndex).
|
||||
//
|
||||
// example:
|
||||
//
|
||||
// IndexedPool<IndexedElement> elementPool;
|
||||
//
|
||||
// IndexedElement& element1 = *new(elementPool) IndexedElement();
|
||||
// IndexedElement& element2 = *new(elementPool) IndexedElement();
|
||||
//
|
||||
// indexedPool.release(element1);
|
||||
// IndexedElement& element3 = *new(elementPool) IndexedElement();
|
||||
//
|
||||
// At this point element1 is no longer a valid object, element2 is at
|
||||
// index 2 and element3 is at index 1.
|
||||
//
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// IndexedObject -
|
||||
//
|
||||
|
||||
template<class Object>
|
||||
struct IndexedObject
|
||||
{
|
||||
Uint32 index; // Index in the pool.
|
||||
Object* next; // Used to link IndexedObject together.
|
||||
|
||||
Uint32 getIndex() {return index;}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// IndexedPool<IndexedObject> -
|
||||
//
|
||||
|
||||
template <class IndexedObject>
|
||||
class IndexedPool
|
||||
{
|
||||
private:
|
||||
|
||||
static const blockSize = 4; // Size of one block.
|
||||
|
||||
Uint32 nBlocks; // Number of blocks in the pool.
|
||||
IndexedObject** block; // Array of block pointers.
|
||||
IndexedObject* freeObjects; // Chained list of free IndexedObjects.
|
||||
Uint32 nextIndex; // Index of the next free object in the last block.
|
||||
|
||||
private:
|
||||
|
||||
void allocateAnotherBlock();
|
||||
IndexedObject& newObject();
|
||||
|
||||
public:
|
||||
|
||||
IndexedPool() : nBlocks(0), block(NULL), freeObjects(NULL), nextIndex(1) {}
|
||||
~IndexedPool();
|
||||
|
||||
IndexedObject& get(Uint32 index) const;
|
||||
void release(IndexedObject& object);
|
||||
|
||||
void setSize(Uint32 size) {assert(size < nextIndex); nextIndex = size;}
|
||||
|
||||
// Return the universe size.
|
||||
Uint32 getSize() {return nextIndex;}
|
||||
|
||||
friend void* operator new(size_t, IndexedPool<IndexedObject>& pool); // Needs to call newObject().
|
||||
};
|
||||
|
||||
// Free all the memory allocated for this object.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
IndexedPool<IndexedObject>::~IndexedPool()
|
||||
{
|
||||
for (Uint32 n = 0; n < nBlocks; n++)
|
||||
free(&((IndexedObject **) &block[n][n*blockSize])[-(n + 1)]);
|
||||
}
|
||||
|
||||
// Release the given. This object will be iserted in the chained
|
||||
// list of free IndexedObjects. To minimize the fragmentation the chained list
|
||||
// is ordered by ascending indexes.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
void IndexedPool<IndexedObject>::release(IndexedObject& object)
|
||||
{
|
||||
Uint32 index = object.index;
|
||||
IndexedObject* list = freeObjects;
|
||||
|
||||
assert(&object == &get(index)); // Make sure that object is owned by this pool.
|
||||
|
||||
if (list == NULL) { // The list is empty.
|
||||
freeObjects = &object;
|
||||
object.next = NULL;
|
||||
} else { // The list contains at least 1 element.
|
||||
if (index < list->index) { // insert as first element.
|
||||
freeObjects = &object;
|
||||
object.next = list;
|
||||
} else { // Find this object's place.
|
||||
while ((list->next) != NULL && (list->next->index < index))
|
||||
list = list->next;
|
||||
|
||||
object.next = list->next;
|
||||
list->next = &object;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Sanity check to be sure that the list is correctly ordered.
|
||||
for (IndexedObject* obj = freeObjects; obj != NULL; obj = obj->next)
|
||||
if (obj->next != NULL)
|
||||
assert(obj->index < obj->next->index);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create a new block of IndexedObjects. We will allocate the memory to
|
||||
// store IndexedPool::blockSize IndexedObject and the new Array of block
|
||||
// pointers.
|
||||
// The newly created IndexedObjects will not be initialized.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
void IndexedPool<IndexedObject>::allocateAnotherBlock()
|
||||
{
|
||||
void* memory = (void *) malloc((nBlocks + 1) * sizeof(Uint32) + blockSize * sizeof(IndexedObject));
|
||||
|
||||
memcpy(memory, block, nBlocks * sizeof(Uint32));
|
||||
|
||||
block = (IndexedObject **) memory;
|
||||
IndexedObject* objects = (IndexedObject *) &block[nBlocks + 1];
|
||||
|
||||
block[nBlocks] = &objects[-(nBlocks * blockSize)];
|
||||
nBlocks++;
|
||||
}
|
||||
|
||||
// Return the IndexedObject at the position 'index' in the pool.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
IndexedObject& IndexedPool<IndexedObject>::get(Uint32 index) const
|
||||
{
|
||||
Uint32 blockIndex = index / blockSize;
|
||||
assert(blockIndex < nBlocks);
|
||||
|
||||
return block[blockIndex][index];
|
||||
}
|
||||
|
||||
// Return the reference of an unused object in the pool.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
IndexedObject& IndexedPool<IndexedObject>::newObject()
|
||||
{
|
||||
if (freeObjects != NULL) {
|
||||
IndexedObject& newObject = *freeObjects;
|
||||
freeObjects = newObject.next;
|
||||
return newObject;
|
||||
}
|
||||
|
||||
Uint32 nextIndex = this->nextIndex++;
|
||||
Uint32 blockIndex = nextIndex / blockSize;
|
||||
|
||||
while (blockIndex >= nBlocks)
|
||||
allocateAnotherBlock();
|
||||
|
||||
IndexedObject& newObject = block[blockIndex][nextIndex];
|
||||
newObject.index = nextIndex;
|
||||
|
||||
return newObject;
|
||||
}
|
||||
|
||||
// Return the address of the next unsused object in the given
|
||||
// indexed pool. The field index of the newly allocated object
|
||||
// will be initialized to the corresponding index of this object
|
||||
// in the pool.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
void* operator new(size_t size, IndexedPool<IndexedObject>& pool)
|
||||
{
|
||||
assert(size == sizeof(IndexedObject));
|
||||
return (void *) &pool.newObject();
|
||||
}
|
||||
|
||||
#endif // _INDEXED_POOL_H_
|
||||
258
mozilla/ef/Compiler/RegisterAllocator/InterferenceGraph.h
Normal file
258
mozilla/ef/Compiler/RegisterAllocator/InterferenceGraph.h
Normal file
@@ -0,0 +1,258 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _INTERFERENCE_GRAPH_H_
|
||||
#define _INTERFERENCE_GRAPH_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "Primitives.h"
|
||||
#include "Instruction.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "SparseSet.h"
|
||||
#include <string.h>
|
||||
|
||||
struct InterferenceVector
|
||||
{
|
||||
Uint32 count;
|
||||
InterferenceVector* next;
|
||||
RegisterName* neighbors;
|
||||
|
||||
InterferenceVector() : count(0), next(NULL) {}
|
||||
};
|
||||
|
||||
class RegisterAllocator;
|
||||
|
||||
template <class RegisterPressure>
|
||||
class InterferenceGraph
|
||||
{
|
||||
private:
|
||||
|
||||
RegisterAllocator& registerAllocator;
|
||||
|
||||
RegisterPressure::Set* interferences;
|
||||
InterferenceVector** vector;
|
||||
Uint32* offset;
|
||||
Uint32 rangeCount;
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
InterferenceGraph(const InterferenceGraph&);
|
||||
// No copy operator.
|
||||
void operator = (const InterferenceGraph&);
|
||||
|
||||
// Check if reg is a member of the universe.
|
||||
void checkMember(RegisterName name) {assert(name < rangeCount);}
|
||||
// Return the edge index for the interference between name1 and name2.
|
||||
Uint32 getEdgeIndex(RegisterName name1, RegisterName name2);
|
||||
|
||||
public:
|
||||
InterferenceGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
|
||||
|
||||
// Calculate the interferences.
|
||||
void build();
|
||||
// Return true if reg1 and reg2 interfere.
|
||||
bool interfere(RegisterName name1, RegisterName name2);
|
||||
// Return the interference vector for the given register or NULL if there is none.
|
||||
InterferenceVector* getInterferenceVector(RegisterName name) {return vector[name];}
|
||||
// Set the interference between name1 and name2.
|
||||
void setInterference(RegisterName name1, RegisterName name2);
|
||||
// Set the interference vector for the given register.
|
||||
void setInterferenceVector(RegisterName name, InterferenceVector* v) {vector[name] = v;}
|
||||
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the interferences.
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void InterferenceGraph<RegisterPressure>::build()
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
this->rangeCount = rangeCount;
|
||||
|
||||
// Initialize the structures.
|
||||
//
|
||||
offset = new(pool) Uint32[rangeCount + 1];
|
||||
vector = new(pool) InterferenceVector*[rangeCount];
|
||||
memset(vector, '\0', sizeof(InterferenceVector*) * rangeCount);
|
||||
|
||||
Uint32 o = 0;
|
||||
offset[0] = 0;
|
||||
for (Uint32 i = 1; i <= rangeCount; ++i) {
|
||||
offset[i] = o;
|
||||
o += i;
|
||||
}
|
||||
|
||||
interferences = new(pool) RegisterPressure::Set(pool, (rangeCount * rangeCount) / 2);
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
LivenessInfo<RegisterPressure> liveness = Liveness<RegisterPressure>::analysis(controlGraph, rangeCount, name2range);
|
||||
registerAllocator.liveness = liveness;
|
||||
SparseSet currentLive(pool, rangeCount);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
currentLive = liveness.liveOut[n];
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
// Handle the copy instruction to avoid unnecessary interference between the 2 registers.
|
||||
if ((instruction.getFlags() & ifCopy) != 0) {
|
||||
assert(useBegin != useEnd && useBegin[0].isRegister());
|
||||
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
|
||||
}
|
||||
|
||||
// Create the interferences.
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName define = name2range[definePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator e = currentLive.begin(); !currentLive.done(e); e = currentLive.advance(e)) {
|
||||
RegisterName live = RegisterName(currentLive.get(e));
|
||||
|
||||
if ((live != define) && !interfere(live, define) && registerAllocator.canInterfere(live, define)) {
|
||||
|
||||
if (vector[define] == NULL)
|
||||
vector[define] = new(pool) InterferenceVector();
|
||||
vector[define]->count++;
|
||||
|
||||
if (vector[live] == NULL)
|
||||
vector[live] = new(pool) InterferenceVector();
|
||||
vector[live]->count++;
|
||||
|
||||
setInterference(live, define);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now update the liveness.
|
||||
//
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentLive.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
currentLive.set(name2range[usePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate the memory to store the interferences.
|
||||
//
|
||||
for (Uint32 e = 0; e < rangeCount; e++)
|
||||
if (vector[e] != NULL) {
|
||||
InterferenceVector& v = *vector[e];
|
||||
v.neighbors = new(pool) RegisterName[v.count];
|
||||
v.count = 0;
|
||||
}
|
||||
|
||||
// Initialize the edges.
|
||||
//
|
||||
if (RegisterPressure::Set::isOrdered()) {
|
||||
RegisterName name1 = RegisterName(0);
|
||||
|
||||
for (RegisterPressure::Set::iterator i = interferences->begin(); !interferences->done(i); i = interferences->advance(i)) {
|
||||
Uint32 interferenceIndex = interferences->get(i);
|
||||
|
||||
while(interferenceIndex >= offset[name1 + 1])
|
||||
name1 = RegisterName(name1 + 1);
|
||||
|
||||
assert((interferenceIndex >= offset[name1]) && (interferenceIndex < offset[name1 + 1]));
|
||||
|
||||
RegisterName name2 = RegisterName(interferenceIndex - offset[name1]);
|
||||
|
||||
assert(interfere(name1, name2));
|
||||
|
||||
InterferenceVector& vector1 = *vector[name1];
|
||||
vector1.neighbors[vector1.count++] = name2;
|
||||
|
||||
InterferenceVector& vector2 = *vector[name2];
|
||||
vector2.neighbors[vector2.count++] = name1;
|
||||
}
|
||||
} else {
|
||||
trespass("not Implemented"); // FIX: need one more pass to initialize the vectors.
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
Uint32 InterferenceGraph<RegisterPressure>::getEdgeIndex(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
checkMember(name1); checkMember(name2);
|
||||
assert(name1 != name2); // This is not possible.
|
||||
return (name1 < name2) ? offset[name2] + name1 : offset[name1] + name2;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void InterferenceGraph<RegisterPressure>::setInterference(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
interferences->set(getEdgeIndex(name1, name2));
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool InterferenceGraph<RegisterPressure>::interfere(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
return interferences->test(getEdgeIndex(name1, name2));
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
template <class RegisterPressure>
|
||||
void InterferenceGraph<RegisterPressure>::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Vectors:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++) {
|
||||
if (vector[i] != NULL) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tvr%d: (", i));
|
||||
for (InterferenceVector* v = vector[i]; v != NULL; v = v->next)
|
||||
for (Uint32 j = 0; j < v->count; j++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", v->neighbors[j]));
|
||||
if (v->next != NULL || j != (v->count - 1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (","));
|
||||
}
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (")\n"));
|
||||
}
|
||||
}
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Matrix:\n"));
|
||||
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
|
||||
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && interfere(name1, name2)) ? '1' : '0'));
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
#endif // _INTERFERENCE_GRAPH_H_
|
||||
87
mozilla/ef/Compiler/RegisterAllocator/LiveRange.h
Normal file
87
mozilla/ef/Compiler/RegisterAllocator/LiveRange.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIVE_RANGE_H_
|
||||
#define _LIVE_RANGE_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Primitives.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct LiveRange
|
||||
{
|
||||
static void build(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRange<RegisterPressure>::build(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
// Intialize the lookup table.
|
||||
//
|
||||
Uint32 nameCount = registerAllocator.nameCount;
|
||||
RegisterName* nameTable = new(registerAllocator.pool) RegisterName[2*nameCount];
|
||||
RegisterName* rangeName = &nameTable[nameCount];
|
||||
|
||||
init(rangeName, nameCount);
|
||||
|
||||
// Walk the graph.
|
||||
//
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
SparseSet destination(registerAllocator.pool, nameCount);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
|
||||
destination.clear();
|
||||
for (InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
|
||||
Instruction& phiNode = phiNodes.get(i);
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
|
||||
destination.set(findRoot(phiNode.getInstructionDefineBegin()[0].getRegisterName(), rangeName));
|
||||
}
|
||||
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
|
||||
RegisterName destinationName = phiNode.getInstructionDefineBegin()[0].getRegisterName();
|
||||
RegisterName destinationRoot = findRoot(destinationName, rangeName);
|
||||
|
||||
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
|
||||
assert(usePtr->isRegister());
|
||||
RegisterName sourceName = usePtr->getRegisterName();
|
||||
RegisterName sourceRoot = findRoot(sourceName, rangeName);
|
||||
|
||||
if (sourceRoot != destinationRoot && !destination.test(sourceRoot))
|
||||
rangeName[sourceRoot] = destinationRoot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerAllocator.rangeCount = compress(registerAllocator.name2range, rangeName, nameCount, nameCount);
|
||||
}
|
||||
|
||||
#endif // _LIVE_RANGE_H_
|
||||
163
mozilla/ef/Compiler/RegisterAllocator/LiveRangeGraph.h
Normal file
163
mozilla/ef/Compiler/RegisterAllocator/LiveRangeGraph.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIVE_RANGE_GRAPH_
|
||||
#define _LIVE_RANGE_GRAPH_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
class RegisterAllocator;
|
||||
|
||||
template <class RegisterPressure>
|
||||
class LiveRangeGraph
|
||||
{
|
||||
private:
|
||||
|
||||
RegisterAllocator& registerAllocator;
|
||||
|
||||
RegisterPressure::Set* edges;
|
||||
Uint32 rangeCount;
|
||||
|
||||
public:
|
||||
//
|
||||
//
|
||||
LiveRangeGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
|
||||
|
||||
//
|
||||
//
|
||||
void build();
|
||||
|
||||
//
|
||||
//
|
||||
void addEdge(RegisterName name1, RegisterName name2);
|
||||
|
||||
//
|
||||
//
|
||||
bool haveEdge(RegisterName name1, RegisterName name2);
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
//
|
||||
//
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::build()
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
this->rangeCount = rangeCount;
|
||||
|
||||
edges = new(pool) RegisterPressure::Set(pool, rangeCount * rangeCount);
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
LivenessInfo<RegisterPressure>& liveness = registerAllocator.liveness;
|
||||
SparseSet currentLive(pool, rangeCount);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
currentLive = liveness.liveOut[n];
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
if ((instruction.getFlags() & ifCopy) != 0) {
|
||||
assert(useBegin != useEnd && useBegin[0].isRegister());
|
||||
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName define = name2range[definePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
|
||||
RegisterName live = RegisterName(currentLive.get(l));
|
||||
if (define != live && registerAllocator.canInterfere(define, live))
|
||||
addEdge(define, live);
|
||||
}
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentLive.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
currentLive.set(name2range[usePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName use = name2range[usePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
|
||||
RegisterName live = RegisterName(currentLive.get(l));
|
||||
if (use != live && registerAllocator.canInterfere(use, live))
|
||||
addEdge(use, live);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::addEdge(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
assert(name1 != name2);
|
||||
edges->set(name1 * rangeCount + name2);
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool LiveRangeGraph<RegisterPressure>::haveEdge(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
assert(name1 != name2);
|
||||
return edges->test(name1 * rangeCount + name2);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Live ranges graph:\n"));
|
||||
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
|
||||
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && haveEdge(name1, name2)) ? '1' : '0'));
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
#endif // _LIVE_RANGE_GRAPH_
|
||||
21
mozilla/ef/Compiler/RegisterAllocator/Liveness.cpp
Normal file
21
mozilla/ef/Compiler/RegisterAllocator/Liveness.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Liveness.h"
|
||||
|
||||
301
mozilla/ef/Compiler/RegisterAllocator/Liveness.h
Normal file
301
mozilla/ef/Compiler/RegisterAllocator/Liveness.h
Normal file
@@ -0,0 +1,301 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIVENESS_H_
|
||||
#define _LIVENESS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LivenessInfo -
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct LivenessInfo
|
||||
{
|
||||
RegisterPressure::Set* liveIn;
|
||||
RegisterPressure::Set* liveOut;
|
||||
DEBUG_LOG_ONLY(Uint32 size);
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Liveness
|
||||
//
|
||||
// The liveness is defined by the following data-flow equations:
|
||||
//
|
||||
// LiveIn(n) = LocalLive(n) U (LiveOut(n) - Killed(n)).
|
||||
// LiveOut(n) = U LiveIn(s) (s a successor of n).
|
||||
//
|
||||
// where LocalLive(n) is the set of used registers in the block n, Killed(n)
|
||||
// is the set of defined registers in the block n, LiveIn(n) is the set of
|
||||
// live registers at the begining of the block n and LiveOut(n) is the set
|
||||
// of live registers at the end of the block n.
|
||||
//
|
||||
//
|
||||
// We will compute the liveness analysis in two stages:
|
||||
//
|
||||
// 1- Build LocalLive(n) (wich is an approximation of LiveIn(n)) and Killed(n)
|
||||
// for each block n.
|
||||
// 2- Perform a backward data-flow analysis to propagate the liveness information
|
||||
// through the entire control-flow graph.
|
||||
//
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct Liveness
|
||||
{
|
||||
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range);
|
||||
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 nameCount);
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
// Allocate the temporary sets.
|
||||
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
|
||||
|
||||
// Allocate the globals sets.
|
||||
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
|
||||
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
|
||||
|
||||
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
|
||||
//
|
||||
for (Uint32 n = 0; n < (nNodes - 1); n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLocalLive = liveIn[n];
|
||||
RegisterPressure::Set& currentKilled = killed[n];
|
||||
|
||||
// Find the instructions contributions to the sets LocalLive and Killed.
|
||||
//
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
Uint32 index = name2range[usePtr->getRegisterName()];
|
||||
|
||||
if (!currentKilled.test(index))
|
||||
currentLocalLive.set(index);
|
||||
}
|
||||
|
||||
// If a Virtualregister is 'defined' then we add it to the set Killed.
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentKilled.set(name2range[definePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
|
||||
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
|
||||
// control-flow graph.
|
||||
//
|
||||
RegisterPressure::Set temp(pool, rangeCount);
|
||||
|
||||
bool changed;
|
||||
do {
|
||||
changed = false;
|
||||
|
||||
// For all nodes is this graph except the endNode.
|
||||
for (Int32 n = (nNodes - 2); n >= 0; n--) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLiveIn = liveIn[n];
|
||||
RegisterPressure::Set& currentLiveOut = liveOut[n];
|
||||
|
||||
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
|
||||
// temp will be the new LiveOut(n).
|
||||
Uint32 nSuccessors = node.nSuccessors();
|
||||
if (nSuccessors != 0) {
|
||||
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
|
||||
for (Uint32 s = 1; s < nSuccessors; s++)
|
||||
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
|
||||
} else
|
||||
temp.clear();
|
||||
|
||||
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
|
||||
// new LiveIn(n).
|
||||
if (currentLiveOut != temp) {
|
||||
currentLiveOut = temp;
|
||||
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
|
||||
temp |= currentLiveIn;
|
||||
|
||||
if (currentLiveIn != temp) {
|
||||
currentLiveIn = temp;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(changed);
|
||||
|
||||
LivenessInfo<RegisterPressure> liveness;
|
||||
liveness.liveIn = liveIn;
|
||||
liveness.liveOut = liveOut;
|
||||
DEBUG_LOG_ONLY(liveness.size = nNodes);
|
||||
return liveness;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 nameCount)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
// Allocate the temporary sets.
|
||||
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
RegisterPressure::Set* usedByPhiNodes = NULL;
|
||||
|
||||
// Allocate the globals sets.
|
||||
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
|
||||
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
|
||||
//
|
||||
for (Uint32 n = 0; n < (nNodes - 1); n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLocalLive = liveIn[n];
|
||||
RegisterPressure::Set& currentKilled = killed[n];
|
||||
|
||||
InstructionList& phiNodes = node.getPhiNodeInstructions();
|
||||
|
||||
if ((usedByPhiNodes == NULL) && !phiNodes.empty())
|
||||
usedByPhiNodes = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
InstructionDefine& define = phiNode.getInstructionDefineBegin()[0];
|
||||
currentKilled.set(define.getRegisterName());
|
||||
|
||||
typedef DoublyLinkedList<ControlEdge> ControlEdgeList;
|
||||
const ControlEdgeList& predecessors = node.getPredecessors();
|
||||
ControlEdgeList::iterator p = predecessors.begin();
|
||||
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++, p = predecessors.advance(p))
|
||||
if (usePtr->isRegister())
|
||||
usedByPhiNodes[predecessors.get(p).getSource().dfsNum].set(usePtr->getRegisterName());
|
||||
}
|
||||
|
||||
// Find the instructions contributions to the sets LocalLive and Killed.
|
||||
//
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
Uint32 index = usePtr->getRegisterName();
|
||||
|
||||
if (!currentKilled.test(index))
|
||||
currentLocalLive.set(index);
|
||||
}
|
||||
|
||||
// If a Virtualregister is 'defined' then we add it to the set Killed.
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentKilled.set(definePtr->getRegisterName());
|
||||
}
|
||||
}
|
||||
|
||||
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
|
||||
// control-flow graph.
|
||||
//
|
||||
RegisterPressure::Set temp(pool, nameCount);
|
||||
|
||||
bool changed;
|
||||
do {
|
||||
changed = false;
|
||||
|
||||
// For all nodes is this graph except the endNode.
|
||||
for (Int32 n = (nNodes - 2); n >= 0; n--) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLiveIn = liveIn[n];
|
||||
RegisterPressure::Set& currentLiveOut = liveOut[n];
|
||||
|
||||
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
|
||||
// temp will be the new LiveOut(n).
|
||||
Uint32 nSuccessors = node.nSuccessors();
|
||||
if (nSuccessors != 0) {
|
||||
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
|
||||
for (Uint32 s = 1; s < nSuccessors; s++)
|
||||
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
|
||||
} else
|
||||
temp.clear();
|
||||
|
||||
// Insert the phiNodes contribution.
|
||||
if (usedByPhiNodes != NULL)
|
||||
temp |= usedByPhiNodes[n];
|
||||
|
||||
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
|
||||
// new LiveIn(n).
|
||||
if (currentLiveOut != temp) {
|
||||
currentLiveOut = temp;
|
||||
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
|
||||
temp |= currentLiveIn;
|
||||
|
||||
if (currentLiveIn != temp) {
|
||||
currentLiveIn = temp;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(changed);
|
||||
|
||||
LivenessInfo<RegisterPressure> liveness;
|
||||
liveness.liveIn = liveIn;
|
||||
liveness.liveOut = liveOut;
|
||||
DEBUG_LOG_ONLY(liveness.size = nNodes);
|
||||
return liveness;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
template <class RegisterPressure>
|
||||
void LivenessInfo<RegisterPressure>::printPretty(LogModuleObject log)
|
||||
{
|
||||
for (Uint32 n = 0; n < size; n++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Node N%d:\n\tliveIn = ", n));
|
||||
liveIn[n].printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tliveOut = "));
|
||||
liveOut[n].printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
#endif // _LIVENESS_H_
|
||||
40
mozilla/ef/Compiler/RegisterAllocator/Makefile
Normal file
40
mozilla/ef/Compiler/RegisterAllocator/Makefile
Normal file
@@ -0,0 +1,40 @@
|
||||
#! gmake
|
||||
|
||||
DEPTH = ../..
|
||||
|
||||
MODULE_NAME = RegisterAllocator
|
||||
|
||||
include $(DEPTH)/config/config.mk
|
||||
|
||||
INCLUDES += \
|
||||
-I$(DEPTH)/Utilities/General \
|
||||
-I$(DEPTH)/Utilities/zlib \
|
||||
-I$(DEPTH)/Runtime/ClassReader \
|
||||
-I$(DEPTH)/Runtime/NativeMethods \
|
||||
-I$(DEPTH)/Runtime/System \
|
||||
-I$(DEPTH)/Runtime/ClassInfo \
|
||||
-I$(DEPTH)/Runtime/FileReader \
|
||||
-I$(DEPTH)/Compiler/PrimitiveGraph \
|
||||
-I$(DEPTH)/Compiler/FrontEnd \
|
||||
-I$(DEPTH)/Compiler/Optimizer \
|
||||
-I$(DEPTH)/Compiler/CodeGenerator \
|
||||
-I$(DEPTH)/Compiler/CodeGenerator/md \
|
||||
-I$(DEPTH)/Compiler/CodeGenerator/md/$(CPU_ARCH) \
|
||||
-I$(DEPTH)/Compiler/RegisterAllocator \
|
||||
-I$(DEPTH)/Driver/StandAloneJava \
|
||||
-I$(DEPTH)/Debugger \
|
||||
$(NULL)
|
||||
|
||||
CXXSRCS = \
|
||||
RegisterAllocator.cpp \
|
||||
RegisterAllocatorTools.cpp \
|
||||
DominatorGraph.cpp \
|
||||
VirtualRegister.cpp \
|
||||
BitSet.cpp \
|
||||
SparseSet.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
|
||||
libs:: $(MODULE)
|
||||
392
mozilla/ef/Compiler/RegisterAllocator/PhiNodeRemover.h
Normal file
392
mozilla/ef/Compiler/RegisterAllocator/PhiNodeRemover.h
Normal file
@@ -0,0 +1,392 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _PHI_NODE_REMOVER_H_
|
||||
#define _PHI_NODE_REMOVER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "DominatorGraph.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "Liveness.h"
|
||||
#include "Instruction.h"
|
||||
#include "InstructionEmitter.h"
|
||||
#include "SparseSet.h"
|
||||
#include <string.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterNameNode -
|
||||
|
||||
struct RegisterNameNode
|
||||
{
|
||||
RegisterNameNode* next;
|
||||
RegisterName newName;
|
||||
Uint32 nextPushed;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CopyData -
|
||||
|
||||
struct CopyData
|
||||
{
|
||||
RegisterName source;
|
||||
RegisterClassKind classKind;
|
||||
Uint32 useCount;
|
||||
bool isLiveOut;
|
||||
RegisterName sourceNameToUse;
|
||||
RegisterName temporaryName;
|
||||
RegisterNameNode* newName;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// PhiNodeRemover<RegisterPressure> -
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct PhiNodeRemover
|
||||
{
|
||||
// Replace the phi nodes by copy instructions.
|
||||
static void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
|
||||
};
|
||||
|
||||
// Split some of the critical edges and return true if there are still some
|
||||
// in the graph after that.
|
||||
//
|
||||
static bool splitCriticalEdges(ControlGraph& /*cg*/)
|
||||
{
|
||||
// FIX: not implemented.
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void pushName(Pool& pool, RegisterNameNode** stack, SparseSet& pushed, Uint32* nodeListPointer, RegisterName oldName, RegisterName newName)
|
||||
{
|
||||
RegisterNameNode& newNode = *new(pool) RegisterNameNode();
|
||||
|
||||
if (pushed.test(oldName))
|
||||
(*stack)->newName = newName;
|
||||
else {
|
||||
newNode.newName = newName;
|
||||
newNode.nextPushed = *nodeListPointer;
|
||||
*nodeListPointer = oldName;
|
||||
newNode.next = *stack;
|
||||
*stack = &newNode;
|
||||
pushed.set(oldName);
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void PhiNodeRemover<RegisterPressure>::replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
// Initialize the local variables.
|
||||
//
|
||||
|
||||
// When we insert the copies we will also need to create new VirtualRegisters for
|
||||
// the insertion of temporaries. The maximum number of temporary register will not
|
||||
// exceed the number of phiNodes in the primitive graph.
|
||||
Uint32 nameCount = vrManager.getSize();
|
||||
Uint32 maxNameCount = nameCount;
|
||||
for (Uint32 n = 0; n < nNodes; n++)
|
||||
maxNameCount += nodes[n]->getPhiNodes().length();
|
||||
|
||||
// If the CFG contains some critical edges (backward edge which source has more than one
|
||||
// outgoing edge and destination has more than one incomimg edge) then we need the liveness
|
||||
// information to be able to insert temporary copies.
|
||||
RegisterPressure::Set* liveOut = NULL;
|
||||
if (splitCriticalEdges(controlGraph))
|
||||
liveOut = Liveness<LowRegisterPressure>::analysis(controlGraph, nameCount).liveOut;
|
||||
|
||||
DominatorGraph dGraph(controlGraph);
|
||||
|
||||
SparseSet pushed(pool, maxNameCount);
|
||||
SparseSet destinationList(pool, maxNameCount);
|
||||
SparseSet workList(pool, maxNameCount);
|
||||
|
||||
CopyData* copyStats = new(pool) CopyData[maxNameCount];
|
||||
memset(copyStats, '\0', maxNameCount*sizeof(CopyData));
|
||||
|
||||
struct NodeStack {
|
||||
Uint32* next;
|
||||
Uint32* limit;
|
||||
Uint32 pushedList;
|
||||
};
|
||||
|
||||
// Allocate the node stack and initialize the node stack pointer.
|
||||
NodeStack* nodeStack = new(pool) NodeStack[nNodes + 1];
|
||||
NodeStack* nodeStackPtr = nodeStack;
|
||||
|
||||
// We start by the begin node.
|
||||
Uint32 startNode = 0;
|
||||
Uint32* next = &startNode;
|
||||
Uint32* limit = &startNode + 1;
|
||||
|
||||
while (true) {
|
||||
|
||||
if (next == limit) {
|
||||
// If there are no more node in the sibling, we have to pop the current
|
||||
// frame from the stack and update the copyStats of the pushed nodes.
|
||||
//
|
||||
if (nodeStackPtr == nodeStack)
|
||||
// We are at the bottom of the stack and there are no more nodes
|
||||
// to look at. We are done !
|
||||
break;
|
||||
|
||||
--nodeStackPtr;
|
||||
// We are done with all the children of this node in the dominator tree.
|
||||
// We need to update the copy information of all the new names pushed
|
||||
// during the walk over this node.
|
||||
Uint32 pushedList = nodeStackPtr->pushedList;
|
||||
while (pushedList != 0) {
|
||||
Uint32 nextName = copyStats[pushedList].newName->nextPushed;
|
||||
copyStats[pushedList].newName = copyStats[pushedList].newName->next;
|
||||
pushedList = nextName;
|
||||
}
|
||||
|
||||
// restore the previous frame.
|
||||
next = nodeStackPtr->next;
|
||||
limit = nodeStackPtr->limit;
|
||||
} else {
|
||||
Uint32 currentNode = *next++;
|
||||
Uint32 pushedList = 0;
|
||||
|
||||
|
||||
// Initialize the sets.
|
||||
pushed.clear();
|
||||
destinationList.clear();
|
||||
|
||||
// STEP1:
|
||||
// Walk the instruction list and to replace all the instruction uses with their new name.
|
||||
// If the instruction is a phi node and its defined register is alive at the end of this
|
||||
// block then we push the defined register into the stack.
|
||||
//
|
||||
ControlNode& node = *nodes[currentNode];
|
||||
RegisterPressure::Set* currentLiveOut = (liveOut != NULL) ? &liveOut[currentNode] : (RegisterPressure::Set*) 0;
|
||||
|
||||
InstructionList& phiNodes = node.getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
|
||||
assert(usePtr->isRegister());
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
|
||||
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
|
||||
usePtr->setRegisterName(copyStats[name].newName->newName);
|
||||
}
|
||||
|
||||
if (currentLiveOut != NULL) {
|
||||
// This is a phi node and we have to push its defined name if it is live
|
||||
// at the end of the node. We only need to do this if the CFG has critical edges.
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
|
||||
RegisterName name = phiNode.getInstructionDefineBegin()[0].getRegisterName();
|
||||
|
||||
if (currentLiveOut->test(name))
|
||||
pushName(pool, &(copyStats[name].newName), pushed, &pushedList, name, name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
|
||||
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
|
||||
usePtr->setRegisterName(copyStats[name].newName->newName);
|
||||
}
|
||||
}
|
||||
|
||||
// STEP2:
|
||||
// Look at this node's successors' phiNodes. We keep track of the number of time
|
||||
// a VR will be used by another copy instruction and insert each definition into the
|
||||
// destinationList. This is the only pass over this node's successors as we will
|
||||
// get all the information we need in the CopyData structures.
|
||||
//
|
||||
ControlEdge* successorEdgeEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorEdgePtr = node.getSuccessorsBegin(); successorEdgePtr < successorEdgeEnd; successorEdgePtr++) {
|
||||
Uint32 useIndex = successorEdgePtr->getIndex();
|
||||
ControlNode& successor = successorEdgePtr->getTarget();
|
||||
|
||||
// Look at its phi nodes. The phi nodes are at the top of the instruction list. We exit
|
||||
// as soon as we find an instruction which is not a phi node
|
||||
InstructionList& phiNodes = successor.getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
assert((phiNode.getInstructionUseBegin() + useIndex) < phiNode.getInstructionUseEnd());
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd());
|
||||
|
||||
InstructionUse& source = phiNode.getInstructionUseBegin()[useIndex];
|
||||
InstructionDefine& destination = phiNode.getInstructionDefineBegin()[0];
|
||||
|
||||
assert(source.isRegister() && destination.isRegister());
|
||||
|
||||
RegisterName sourceName = source.getRegisterName();
|
||||
RegisterName destinationName = destination.getRegisterName();
|
||||
|
||||
// Get the correct name for the source.
|
||||
if (copyStats[sourceName].newName != NULL)
|
||||
sourceName = copyStats[sourceName].newName->newName;
|
||||
|
||||
// Update the CopyData structures.
|
||||
if ((sourceName != rnInvalid) && (sourceName != destinationName)) {
|
||||
copyStats[destinationName].source = sourceName;
|
||||
copyStats[destinationName].classKind = destination.getRegisterClass();
|
||||
copyStats[destinationName].isLiveOut = (currentLiveOut != NULL) ? currentLiveOut->test(destinationName) : false;
|
||||
copyStats[destinationName].sourceNameToUse = destinationName;
|
||||
copyStats[sourceName].sourceNameToUse = sourceName;
|
||||
copyStats[sourceName].useCount++;
|
||||
destinationList.set(destinationName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// STEP3:
|
||||
// Insert into the worklist only the destination registers that will be not used in
|
||||
// another copy instruction in this block.
|
||||
//
|
||||
assert(workList.getSize() == 0);
|
||||
for (SparseSet::iterator d = destinationList.begin(); !destinationList.done(d); d = destinationList.advance(d)) {
|
||||
Uint32 dest = destinationList.get(d);
|
||||
if (copyStats[dest].useCount == 0)
|
||||
workList.set(dest);
|
||||
}
|
||||
|
||||
// STEP4:
|
||||
// Insert the copy instructions.
|
||||
//
|
||||
Uint32 destinationListSize = destinationList.getSize();
|
||||
InstructionList::iterator endOfTheNode = instructions.end();
|
||||
|
||||
// Find the right place to insert the copy instructions.
|
||||
if (destinationListSize != 0)
|
||||
while (instructions.get(endOfTheNode).getFlags() & ifControl)
|
||||
endOfTheNode = instructions.retreat(endOfTheNode);
|
||||
|
||||
while (destinationListSize != 0) {
|
||||
while(workList.getSize()) {
|
||||
RegisterName destinationName = RegisterName(workList.getOne());
|
||||
RegisterName sourceName = copyStats[destinationName].source;
|
||||
|
||||
workList.clear(destinationName);
|
||||
if (copyStats[destinationName].isLiveOut && !copyStats[destinationName].temporaryName) {
|
||||
// Lost copy problem.
|
||||
copyStats[destinationName].isLiveOut = false;
|
||||
|
||||
RegisterName sourceName = destinationName;
|
||||
RegisterClassKind classKind = copyStats[sourceName].classKind;
|
||||
RegisterName destinationName = getName(vrManager.newVirtualRegister(classKind));
|
||||
assert(destinationName < maxNameCount);
|
||||
|
||||
copyStats[destinationName].classKind = classKind;
|
||||
copyStats[sourceName].useCount = 0;
|
||||
|
||||
// We need to insert a copy to a temporary register to keep the
|
||||
// source register valid at the end of the node defining it.
|
||||
// This copy will be inserted right after the phi node defining it.
|
||||
RegisterName from = copyStats[sourceName].sourceNameToUse;
|
||||
Instruction* definingPhiNode = vrManager.getVirtualRegister(from).getDefiningInstruction();
|
||||
assert(definingPhiNode && (definingPhiNode->getFlags() & ifPhiNode) != 0);
|
||||
|
||||
RegisterID fromID = buildRegisterID(from, classKind);
|
||||
RegisterID toID = buildRegisterID(destinationName, classKind);
|
||||
Instruction& copy = emitter.newCopy(*definingPhiNode->getPrimitive(), fromID, toID);
|
||||
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
|
||||
definingPhiNode->getPrimitive()->getContainer()->getInstructions().addFirst(copy);
|
||||
|
||||
copyStats[sourceName].temporaryName = destinationName;
|
||||
copyStats[sourceName].sourceNameToUse = destinationName;
|
||||
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
|
||||
}
|
||||
|
||||
// Insert the copy instruction at the end of the current node.
|
||||
RegisterName from = copyStats[sourceName].sourceNameToUse;
|
||||
|
||||
RegisterClassKind classKind = copyStats[destinationName].classKind;
|
||||
RegisterID fromID = buildRegisterID(from, classKind);
|
||||
RegisterID toID = buildRegisterID(destinationName, classKind);
|
||||
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
|
||||
instructions.insertAfter(copy, endOfTheNode);
|
||||
endOfTheNode = instructions.advance(endOfTheNode);
|
||||
|
||||
copyStats[sourceName].useCount = 0;
|
||||
if (destinationList.test(sourceName) && copyStats[sourceName].isLiveOut)
|
||||
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
|
||||
copyStats[sourceName].isLiveOut = false;
|
||||
copyStats[sourceName].sourceNameToUse = destinationName;
|
||||
|
||||
if (destinationList.test(sourceName))
|
||||
workList.set(sourceName);
|
||||
destinationList.clear(destinationName);
|
||||
}
|
||||
|
||||
destinationListSize = destinationList.getSize();
|
||||
if (destinationListSize != 0) {
|
||||
RegisterName sourceName = RegisterName(destinationList.getOne());
|
||||
RegisterName destinationName;
|
||||
|
||||
if (!copyStats[sourceName].temporaryName) {
|
||||
// Cycle problem.
|
||||
RegisterClassKind classKind = copyStats[sourceName].classKind;
|
||||
destinationName = getName(vrManager.newVirtualRegister(classKind));
|
||||
assert(destinationName < maxNameCount);
|
||||
|
||||
copyStats[destinationName].classKind = classKind;
|
||||
copyStats[sourceName].temporaryName = destinationName;
|
||||
|
||||
// Insert the copy instruction at the end of the current node.
|
||||
RegisterName from = copyStats[sourceName].sourceNameToUse;
|
||||
|
||||
RegisterID fromID = buildRegisterID(from, classKind);
|
||||
RegisterID toID = buildRegisterID(destinationName, classKind);
|
||||
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
|
||||
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
|
||||
instructions.insertAfter(copy, endOfTheNode);
|
||||
endOfTheNode = instructions.advance(endOfTheNode);
|
||||
} else
|
||||
destinationName = copyStats[sourceName].temporaryName;
|
||||
|
||||
copyStats[sourceName].useCount = 0;
|
||||
copyStats[sourceName].isLiveOut = false;
|
||||
copyStats[sourceName].sourceNameToUse = destinationName;
|
||||
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
|
||||
|
||||
workList.set(sourceName);
|
||||
}
|
||||
}
|
||||
|
||||
nodeStackPtr->pushedList = pushedList;
|
||||
nodeStackPtr->next = next;
|
||||
nodeStackPtr->limit = limit;
|
||||
++nodeStackPtr;
|
||||
next = dGraph.getSuccessorsBegin(currentNode);
|
||||
limit = dGraph.getSuccessorsEnd(currentNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _PHI_NODE_REMOVER_H_
|
||||
155
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocator.cpp
Normal file
155
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocator.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "LogModule.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
#include "PhiNodeRemover.h"
|
||||
#include "LiveRange.h"
|
||||
#include "Liveness.h"
|
||||
#include "InterferenceGraph.h"
|
||||
#include "LiveRangeGraph.h"
|
||||
#include "Coalescing.h"
|
||||
#include "Spilling.h"
|
||||
#include "Coloring.h"
|
||||
#include "Splits.h"
|
||||
|
||||
class Pool;
|
||||
class ControlGraph;
|
||||
class VirtualRegisterManager;
|
||||
class InstructionEmitter;
|
||||
|
||||
UT_DEFINE_LOG_MODULE(RegAlloc);
|
||||
|
||||
void RegisterAllocator::allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
|
||||
{
|
||||
// Insert the phi node instructions. We want to do this to have a single defined register per instruction.
|
||||
// If we keep the PhiNode (as a DataNode) and a PhiNode is of DoubleWordKind then we have to execute
|
||||
// some special code for the high word annotation.
|
||||
//
|
||||
RegisterAllocatorTools::insertPhiNodeInstructions(controlGraph, emitter);
|
||||
|
||||
// Perform some tests on the instruction graph.
|
||||
//
|
||||
DEBUG_ONLY(RegisterAllocatorTools::testTheInstructionGraph(controlGraph, vrManager));
|
||||
|
||||
// Replace the phi node instructions by their equivalent copy instructions.
|
||||
//
|
||||
PhiNodeRemover<LowRegisterPressure>::replacePhiNodes(controlGraph, vrManager, emitter);
|
||||
|
||||
// Do the register allocation.
|
||||
//
|
||||
RegisterAllocator registerAllocator(pool, controlGraph, vrManager, emitter);
|
||||
registerAllocator.doGraphColoring();
|
||||
}
|
||||
|
||||
void RegisterAllocator::doGraphColoring()
|
||||
{
|
||||
// Initialize the liverange map.
|
||||
//
|
||||
initLiveRanges();
|
||||
|
||||
// Build the live ranges. We do this to compress the number of RegisterNames
|
||||
// used in the insterference graph.
|
||||
//
|
||||
LiveRange<LowRegisterPressure>::build(*this);
|
||||
|
||||
// Remove unnecessary copies.
|
||||
//
|
||||
RegisterAllocatorTools::removeUnnecessaryCopies(*this);
|
||||
|
||||
for (Uint8 loop = 0; loop < 10; loop++) {
|
||||
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********* RegisterAllocator loop %d *********\n", loop));
|
||||
|
||||
while(true) {
|
||||
// Build the interference graph.
|
||||
//
|
||||
iGraph.build();
|
||||
|
||||
// Coalesce the copy instructions.
|
||||
//
|
||||
if (!Coalescing<LowRegisterPressure>::coalesce(*this))
|
||||
break;
|
||||
}
|
||||
|
||||
// Print the interference graph.
|
||||
//
|
||||
DEBUG_LOG_ONLY(iGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
|
||||
|
||||
// Calculate the spill costs.
|
||||
//
|
||||
Spilling<LowRegisterPressure>::calculateSpillCosts(*this);
|
||||
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSpillCosts(*this));
|
||||
|
||||
// Calculate the split costs.
|
||||
//
|
||||
Splits<LowRegisterPressure>::calculateSplitCosts(*this);
|
||||
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSplitCosts(*this));
|
||||
|
||||
// Build the live range graph.
|
||||
//
|
||||
lGraph.build();
|
||||
DEBUG_LOG_ONLY(lGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
|
||||
|
||||
// Color the graph. If it succeeds then we're done with the
|
||||
// register allocation.
|
||||
//
|
||||
if (Coloring<LowRegisterPressure>::color(*this)) {
|
||||
// Write the final colors in the instruction graph.
|
||||
//
|
||||
Coloring<LowRegisterPressure>::finalColoring(*this);
|
||||
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********** RegisterAllocator done **********\n"));
|
||||
DEBUG_LOG_ONLY(RegisterAllocatorTools::printInstructions(*this));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to spill some registers.
|
||||
//
|
||||
Spilling<LowRegisterPressure>::insertSpillCode(*this);
|
||||
|
||||
// Insert the split instructions.
|
||||
//
|
||||
Splits<LowRegisterPressure>::insertSplitCode(*this);
|
||||
|
||||
// Update the live ranges.
|
||||
//
|
||||
// FIX
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
RegisterAllocatorTools::updateInstructionGraph(*this);
|
||||
RegisterAllocatorTools::printInstructions(*this);
|
||||
#endif
|
||||
fprintf(stderr, "!!! Coloring failed after 10 loops !!!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
void RegisterAllocator::initLiveRanges()
|
||||
{
|
||||
Uint32 count = this->nameCount;
|
||||
RegisterName* name2range = new(pool) RegisterName[nameCount];
|
||||
for (RegisterName r = RegisterName(1); r < count; r = RegisterName(r + 1))
|
||||
name2range[r] = r;
|
||||
this->name2range = name2range;
|
||||
rangeCount = count;
|
||||
}
|
||||
88
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocator.h
Normal file
88
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocator.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_ALLOCATOR_H_
|
||||
#define _REGISTER_ALLOCATOR_H_
|
||||
|
||||
class Pool;
|
||||
class ControlGraph;
|
||||
class InstructionEmitter;
|
||||
struct SpillCost;
|
||||
struct SplitCost;
|
||||
|
||||
#include "Liveness.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "RegisterPressure.h" // This should included by Backend.cpp
|
||||
#include "InterferenceGraph.h"
|
||||
#include "LiveRangeGraph.h"
|
||||
|
||||
//template <class RegisterPressure>
|
||||
class RegisterAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
Pool& pool; //
|
||||
ControlGraph& controlGraph; //
|
||||
VirtualRegisterManager& vrManager; //
|
||||
InstructionEmitter& emitter; //
|
||||
|
||||
RegisterName* name2range; //
|
||||
RegisterName* color; //
|
||||
SpillCost* spillCost; //
|
||||
SparseSet* willSpill; //
|
||||
SplitCost* splitCost; //
|
||||
NameLinkedList** splitAround; //
|
||||
InterferenceGraph<LowRegisterPressure> iGraph; //
|
||||
LiveRangeGraph<LowRegisterPressure> lGraph; //
|
||||
LivenessInfo<LowRegisterPressure> liveness; //
|
||||
Uint32 nameCount; //
|
||||
Uint32 rangeCount; //
|
||||
bool splitFound; //
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
//
|
||||
void doGraphColoring();
|
||||
|
||||
public:
|
||||
|
||||
//
|
||||
//
|
||||
inline RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
|
||||
|
||||
//
|
||||
//
|
||||
bool canInterfere(RegisterName /*name1*/, RegisterName /*name2*/) const {return true;}
|
||||
|
||||
//
|
||||
//
|
||||
void initLiveRanges();
|
||||
|
||||
//
|
||||
//
|
||||
static void allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
|
||||
};
|
||||
|
||||
//
|
||||
//
|
||||
inline RegisterAllocator::RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
|
||||
: pool(pool), controlGraph(controlGraph), vrManager(vrManager), emitter(emitter), iGraph(*this), lGraph(*this), nameCount(vrManager.getSize()) {}
|
||||
|
||||
#endif // _REGISTER_ALLOCATOR_H_
|
||||
|
||||
355
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocatorTools.cpp
Normal file
355
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocatorTools.cpp
Normal file
@@ -0,0 +1,355 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "LogModule.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Primitives.h"
|
||||
#include "InstructionEmitter.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "Spilling.h"
|
||||
#include "Splits.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
UT_EXTERN_LOG_MODULE(RegAlloc);
|
||||
|
||||
#ifdef DEBUG
|
||||
void RegisterAllocatorTools::testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
|
||||
{
|
||||
// Test the declared VirtualRegisters. The register allocator tries to condense the register universe.
|
||||
// Any gap in the VirtualRegister names will be a loss of efficiency !!!!
|
||||
|
||||
Uint32 nameCount = vrManager.getSize();
|
||||
BitSet registerSeen(controlGraph.pool, nameCount);
|
||||
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
registerSeen.set(usePtr->getRegisterName());
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
registerSeen.set(definePtr->getRegisterName());
|
||||
}
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& instruction = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
registerSeen.set(usePtr->getRegisterName());
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
registerSeen.set(definePtr->getRegisterName());
|
||||
}
|
||||
}
|
||||
|
||||
bool renameRegisters = false;
|
||||
for (BitSet::iterator i = registerSeen.nextZero(0); !registerSeen.done(i); i = registerSeen.nextZero(i)) {
|
||||
renameRegisters = true;
|
||||
fprintf(stderr,
|
||||
"WARNING: The VirtualRegister vr%d has been allocated during CodeGeneration but\n"
|
||||
" is never used nor defined by any instruction in the instruction graph\n"
|
||||
" PLEASE FIX \n",
|
||||
i);
|
||||
}
|
||||
if (renameRegisters) {
|
||||
Instruction** definingInstruction = new Instruction*[nameCount];
|
||||
memset(definingInstruction, '\0', nameCount * sizeof(Instruction*));
|
||||
RegisterName* newName = new RegisterName[nameCount];
|
||||
memset(newName, '\0', nameCount * sizeof(RegisterName));
|
||||
RegisterName nextName = RegisterName(1);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
usePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName name = definePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
definePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
}
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& instruction = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
usePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName name = definePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
definePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vrManager.setSize(nextName);
|
||||
|
||||
for (RegisterName r = RegisterName(1); r < nextName; r = RegisterName(r + 1))
|
||||
vrManager.getVirtualRegister(r).definingInstruction = definingInstruction[r];
|
||||
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("RegisterMap:\n"));
|
||||
for (Uint32 i = 1; i < nameCount; i++)
|
||||
if (newName[i] != 0)
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d becomes vr%d.\n", i, newName[i]));
|
||||
else
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d is dead.\n", i));
|
||||
|
||||
|
||||
delete newName;
|
||||
delete definingInstruction;
|
||||
}
|
||||
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
void RegisterAllocatorTools::removeUnnecessaryCopies(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i);) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
i = instructions.advance(i);
|
||||
|
||||
if (instruction.getFlags() & ifCopy) {
|
||||
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
|
||||
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
|
||||
|
||||
RegisterName source = name2range[instruction.getInstructionUseBegin()[0].getRegisterName()];
|
||||
RegisterName destination = name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()];
|
||||
|
||||
if (source == destination)
|
||||
instruction.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RegisterAllocatorTools::updateInstructionGraph(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
|
||||
}
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& instruction = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RegisterAllocatorTools::insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
DoublyLinkedList<PhiNode>& phiNodes = node.getPhiNodes();
|
||||
|
||||
if (!phiNodes.empty()) {
|
||||
|
||||
// Set the index of the incoming edges.
|
||||
Uint32 index = 0;
|
||||
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
|
||||
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p))
|
||||
predecessors.get(p).setIndex(index++);
|
||||
|
||||
// Insert the phi node instruction in the instruction list.
|
||||
for (DoublyLinkedList<PhiNode>::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
|
||||
PhiNode& phiNode = phiNodes.get(i);
|
||||
ValueKind kind = phiNode.getKind();
|
||||
|
||||
if (!isStorableKind(kind))
|
||||
continue;
|
||||
|
||||
RegisterClassKind classKind = rckGeneral; // FIX: get class kind from phi node kind.
|
||||
Uint32 nInputs = phiNode.nInputs();
|
||||
|
||||
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
|
||||
|
||||
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drLow);
|
||||
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
|
||||
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drLow);
|
||||
|
||||
node.addPhiNodeInstruction(phiNodeInstruction);
|
||||
|
||||
if (isDoublewordKind(kind)) {
|
||||
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
|
||||
|
||||
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drHigh);
|
||||
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
|
||||
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drHigh);
|
||||
|
||||
node.addPhiNodeInstruction(phiNodeInstruction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
|
||||
void RegisterAllocatorTools::printSpillCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
SpillCost* cost = registerAllocator.spillCost;
|
||||
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Spill costs:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : ", i));
|
||||
if (cost[i].infinite)
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("infinite\n"));
|
||||
else
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%f\n", cost[i].cost));
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterAllocatorTools::printSplitCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
SplitCost* cost = registerAllocator.splitCost;
|
||||
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Split costs:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : loads = %f stores = %f\n", i, cost[i].loads, cost[i].stores));
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterAllocatorTools::printInstructions(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
|
||||
ControlNode** nodes = registerAllocator.controlGraph.dfsList;
|
||||
Uint32 nNodes = registerAllocator.controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d:\n", n));
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
|
||||
if (!phiNodes.empty()) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" PhiNodes:\n", n));
|
||||
for(InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
|
||||
phiNodes.get(i).printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
if (!instructions.empty())
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" Instructions:\n", n));
|
||||
}
|
||||
|
||||
for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
instructions.get(i).printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
117
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocatorTools.h
Normal file
117
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocatorTools.h
Normal file
@@ -0,0 +1,117 @@
|
||||
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
|
||||
//
|
||||
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
|
||||
// NETSCAPE COMMUNICATIONS CORPORATION
|
||||
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
|
||||
// Reserved. Use of this Source Code is subject to the terms of the
|
||||
// applicable license agreement from Netscape Communications Corporation.
|
||||
// The copyright notice(s) in this Source Code does not indicate actual or
|
||||
// intended publication of this Source Code.
|
||||
//
|
||||
// $Id: RegisterAllocatorTools.h,v 1.1.2.1 1999-03-02 16:12:05 fur%netscape.com Exp $
|
||||
//
|
||||
|
||||
#ifndef _REGISTER_ALLOCATOR_TOOLS_H_
|
||||
#define _REGISTER_ALLOCATOR_TOOLS_H_
|
||||
|
||||
#include "LogModule.h"
|
||||
#include "RegisterTypes.h"
|
||||
#include <string.h>
|
||||
|
||||
class RegisterAllocator;
|
||||
class ControlGraph;
|
||||
class InstructionEmitter;
|
||||
class VirtualRegisterManager;
|
||||
|
||||
struct RegisterAllocatorTools
|
||||
{
|
||||
//
|
||||
//
|
||||
static void insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter);
|
||||
|
||||
//
|
||||
//
|
||||
static void updateInstructionGraph(RegisterAllocator& registerAllocator);
|
||||
|
||||
//
|
||||
//
|
||||
static void removeUnnecessaryCopies(RegisterAllocator& registerAllocator);
|
||||
|
||||
#ifdef DEBUG
|
||||
//
|
||||
//
|
||||
static void testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
|
||||
#endif // DEBUG
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
//
|
||||
//
|
||||
static void printInstructions(RegisterAllocator& registerAllocator);
|
||||
|
||||
//
|
||||
//
|
||||
static void printSpillCosts(RegisterAllocator& registerAllocator);
|
||||
|
||||
//
|
||||
//
|
||||
static void printSplitCosts(RegisterAllocator& registerAllocator);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
//
|
||||
// FIX: this should go in a class (LookupTable ?)
|
||||
//
|
||||
|
||||
inline RegisterName findRoot(RegisterName name, RegisterName* table)
|
||||
{
|
||||
RegisterName* stack = table;
|
||||
RegisterName* stackPtr = stack;
|
||||
|
||||
RegisterName newName;
|
||||
while((newName = table[name]) != name) {
|
||||
*--stackPtr = name;
|
||||
name = newName;
|
||||
}
|
||||
|
||||
while (stackPtr != stack)
|
||||
table[*stackPtr++] = name;
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
inline void init(RegisterName* table, Uint32 nameCount)
|
||||
{
|
||||
for (RegisterName r = RegisterName(0); r < nameCount; r = RegisterName(r + 1))
|
||||
table[r] = r;
|
||||
}
|
||||
|
||||
inline Uint32 compress(RegisterName* name2range, RegisterName* table, Uint32 nameCount, Uint32 tableSize)
|
||||
{
|
||||
RegisterName* liveRange = new RegisterName[tableSize];
|
||||
memset(liveRange, '\0', tableSize * sizeof(RegisterName));
|
||||
|
||||
// Update the lookup table.
|
||||
for (RegisterName r = RegisterName(1); r < tableSize; r = RegisterName(r + 1))
|
||||
findRoot(r, table);
|
||||
|
||||
// Count the liveranges.
|
||||
Uint32 liveRangeCount = 1;
|
||||
for (RegisterName s = RegisterName(1); s < tableSize; s = RegisterName(s + 1))
|
||||
if (table[s] == s)
|
||||
liveRange[s] = RegisterName(liveRangeCount++);
|
||||
|
||||
for (RegisterName t = RegisterName(1); t < nameCount; t = RegisterName(t + 1))
|
||||
name2range[t] = liveRange[table[name2range[t]]];
|
||||
|
||||
return liveRangeCount;
|
||||
}
|
||||
|
||||
inline double doLog10(Uint32 power)
|
||||
{
|
||||
double log = 1.0;
|
||||
while (power--)
|
||||
log *= 10.0;
|
||||
return log;
|
||||
}
|
||||
|
||||
#endif // _REGISTER_ALLOCATOR_TOOLS_H_
|
||||
38
mozilla/ef/Compiler/RegisterAllocator/RegisterAssigner.h
Normal file
38
mozilla/ef/Compiler/RegisterAllocator/RegisterAssigner.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_ASSIGNER_H_
|
||||
#define _REGISTER_ASSIGNER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "VirtualRegister.h"
|
||||
|
||||
class FastBitMatrix;
|
||||
|
||||
class RegisterAssigner
|
||||
{
|
||||
protected:
|
||||
VirtualRegisterManager& vRegManager;
|
||||
|
||||
public:
|
||||
RegisterAssigner(VirtualRegisterManager& vrMan) : vRegManager(vrMan) {}
|
||||
|
||||
virtual bool assignRegisters(FastBitMatrix& interferenceMatrix) = 0;
|
||||
};
|
||||
|
||||
#endif /* _REGISTER_ASSIGNER_H_ */
|
||||
25
mozilla/ef/Compiler/RegisterAllocator/RegisterClass.h
Normal file
25
mozilla/ef/Compiler/RegisterAllocator/RegisterClass.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_CLASS_H_
|
||||
#define _REGISTER_CLASS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
#endif // _REGISTER_CLASS_H_
|
||||
37
mozilla/ef/Compiler/RegisterAllocator/RegisterPressure.h
Normal file
37
mozilla/ef/Compiler/RegisterAllocator/RegisterPressure.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_PRESSURE_H_
|
||||
#define _REGISTER_PRESSURE_H_
|
||||
|
||||
#include "BitSet.h"
|
||||
#include "HashSet.h"
|
||||
|
||||
struct LowRegisterPressure
|
||||
{
|
||||
typedef BitSet Set;
|
||||
static const bool setIsOrdered = true;
|
||||
};
|
||||
|
||||
struct HighRegisterPressure
|
||||
{
|
||||
typedef HashSet Set;
|
||||
static const bool setIsOrdered = false;
|
||||
};
|
||||
|
||||
#endif // _REGISTER_PRESSURE_H_
|
||||
104
mozilla/ef/Compiler/RegisterAllocator/RegisterTypes.h
Normal file
104
mozilla/ef/Compiler/RegisterAllocator/RegisterTypes.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_TYPES_H_
|
||||
#define _REGISTER_TYPES_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterName -
|
||||
//
|
||||
|
||||
enum RegisterName {
|
||||
rnInvalid = 0,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterClassKind -
|
||||
//
|
||||
|
||||
enum RegisterClassKind {
|
||||
rckInvalid = 0,
|
||||
rckGeneral,
|
||||
rckStackSlot,
|
||||
|
||||
nRegisterClassKind
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterID -
|
||||
//
|
||||
|
||||
enum RegisterID {
|
||||
invalidID = 0
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterKind -
|
||||
//
|
||||
|
||||
enum RegisterKind {
|
||||
rkCallerSave = 0,
|
||||
rkCalleeSave,
|
||||
};
|
||||
|
||||
struct NameLinkedList {
|
||||
RegisterName name;
|
||||
NameLinkedList* next;
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
const registerNameMask = 0x03ffffff;
|
||||
const coloredRegisterMask = 0x04000000;
|
||||
const machineRegisterMask = 0x08000000;
|
||||
const registerClassMask = 0xf0000000;
|
||||
|
||||
const registerNameShift = 0;
|
||||
const coloredRegisterShift = 26;
|
||||
const machineRegisterShift = 27;
|
||||
const registerClassShift = 28;
|
||||
|
||||
#else // DEBUG
|
||||
|
||||
const registerNameMask = 0x0fffffff;
|
||||
const registerClassMask = 0xf0000000;
|
||||
|
||||
const registerNameShift = 0;
|
||||
const registerClassShift = 28;
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
inline RegisterClassKind getClass(RegisterID registerID) {return RegisterClassKind((registerID & registerClassMask) >> registerClassShift);}
|
||||
inline RegisterName getName(RegisterID registerID) {return RegisterName((registerID & registerNameMask) >> registerNameShift);}
|
||||
inline void setClass(RegisterID& registerID, RegisterClassKind classKind) {registerID = RegisterID((registerID & ~registerClassMask) | ((classKind << registerClassShift) & registerClassMask));}
|
||||
inline void setName(RegisterID& registerID, RegisterName name) {assert((name & ~registerNameMask) == 0); registerID = RegisterID((registerID & ~registerNameMask) | ((name << registerNameShift) & registerNameMask));}
|
||||
inline RegisterID buildRegisterID(RegisterName name, RegisterClassKind classKind) {return RegisterID(((classKind << registerClassShift) & registerClassMask) | ((name << registerNameShift) & registerNameMask));}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
inline bool isMachineRegister(RegisterID rid) {return (rid & machineRegisterMask) != 0;}
|
||||
inline void setMachineRegister(RegisterID& rid) {rid = RegisterID(rid | machineRegisterMask);}
|
||||
inline bool isColoredRegister(RegisterID rid) {return (rid & coloredRegisterMask) != 0;}
|
||||
inline void setColoredRegister(RegisterID& rid) {rid = RegisterID(rid | coloredRegisterMask);}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
#endif // _REGISTER_TYPES_H_
|
||||
32
mozilla/ef/Compiler/RegisterAllocator/SSATools.cpp
Normal file
32
mozilla/ef/Compiler/RegisterAllocator/SSATools.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "SSATools.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "Liveness.h"
|
||||
|
||||
void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
|
||||
{
|
||||
if (!controlGraph.hasBackEdges)
|
||||
return;
|
||||
|
||||
Liveness liveness(controlGraph.pool);
|
||||
liveness.buildLivenessAnalysis(controlGraph, vrManager);
|
||||
}
|
||||
29
mozilla/ef/Compiler/RegisterAllocator/SSATools.h
Normal file
29
mozilla/ef/Compiler/RegisterAllocator/SSATools.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SSA_TOOLS_H_
|
||||
#define _SSA_TOOLS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
|
||||
class ControlGraph;
|
||||
class VirtualRegisterManager;
|
||||
|
||||
extern void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
|
||||
|
||||
#endif // _SSA_TOOLS_H_
|
||||
37
mozilla/ef/Compiler/RegisterAllocator/SparseSet.cpp
Normal file
37
mozilla/ef/Compiler/RegisterAllocator/SparseSet.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "SparseSet.h"
|
||||
#include "BitSet.h"
|
||||
#include "Pool.h"
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the set.
|
||||
//
|
||||
void SparseSet::printPretty(LogModuleObject log)
|
||||
{
|
||||
Pool pool;
|
||||
BitSet set(pool, universeSize);
|
||||
|
||||
for (Uint32 i = 0; i < count; i++)
|
||||
set.set(node[i].element);
|
||||
|
||||
set.printPretty(log);
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
168
mozilla/ef/Compiler/RegisterAllocator/SparseSet.h
Normal file
168
mozilla/ef/Compiler/RegisterAllocator/SparseSet.h
Normal file
@@ -0,0 +1,168 @@
|
||||
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
|
||||
//
|
||||
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
|
||||
// NETSCAPE COMMUNICATIONS CORPORATION
|
||||
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
|
||||
// Reserved. Use of this Source Code is subject to the terms of the
|
||||
// applicable license agreement from Netscape Communications Corporation.
|
||||
// The copyright notice(s) in this Source Code does not indicate actual or
|
||||
// intended publication of this Source Code.
|
||||
//
|
||||
// $Id: SparseSet.h,v 1.1.2.1 1999-03-02 16:12:07 fur%netscape.com Exp $
|
||||
//
|
||||
|
||||
#ifndef _SPARSE_SET_H_
|
||||
#define _SPARSE_SET_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "LogModule.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
class SparseSet
|
||||
{
|
||||
private:
|
||||
|
||||
struct Node {
|
||||
Uint32 element;
|
||||
Uint32 stackIndex;
|
||||
};
|
||||
|
||||
Node* node;
|
||||
Uint32 count;
|
||||
Uint32 universeSize;
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
SparseSet(const SparseSet&);
|
||||
|
||||
// Check if the given set's universe is of the same size than this universe.
|
||||
void checkUniverseCompatibility(const SparseSet& set) const {assert(set.universeSize == universeSize);}
|
||||
// Check if pos is valid for this set's universe.
|
||||
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
|
||||
|
||||
public:
|
||||
|
||||
SparseSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {node = new(pool) Node[universeSize]; clear();}
|
||||
|
||||
// Clear the sparse set.
|
||||
void clear() {count = 0;}
|
||||
// Clear the element at index.
|
||||
inline void clear(Uint32 index);
|
||||
// Set the element at index.
|
||||
inline void set(Uint32 index);
|
||||
// Return true if the element at index is set.
|
||||
inline bool test(Uint32 index) const;
|
||||
// Union with the given sparse set.
|
||||
inline void or(const SparseSet& set);
|
||||
// Intersection with the given sparse set.
|
||||
inline void and(const SparseSet& set);
|
||||
// Difference with the given sparse set.
|
||||
inline void difference(const SparseSet& set);
|
||||
// Copy set.
|
||||
inline SparseSet& operator = (const SparseSet& set);
|
||||
inline SparseSet& operator = (const BitSet& set);
|
||||
// Return true if the sparse sets are identical.
|
||||
friend bool operator == (const SparseSet& set1, const SparseSet& set2);
|
||||
// Return true if the sparse sets are different.
|
||||
friend bool operator != (const SparseSet& set1, const SparseSet& set2);
|
||||
|
||||
// Logical operators.
|
||||
SparseSet& operator |= (const SparseSet& set) {or(set); return *this;}
|
||||
SparseSet& operator &= (const SparseSet& set) {and(set); return *this;}
|
||||
SparseSet& operator -= (const SparseSet& set) {difference(set); return *this;}
|
||||
|
||||
// Iterator to conform with the set API.
|
||||
typedef Int32 iterator;
|
||||
// Return the iterator for the first element of this set.
|
||||
iterator begin() const {return count - 1;}
|
||||
// Return the next iterator.
|
||||
iterator advance(iterator pos) const {return --pos;}
|
||||
// Return true if the iterator is at the end of the set.
|
||||
bool done(iterator pos) const {return pos < 0;}
|
||||
// Return the element for the given iterator;
|
||||
Uint32 get(iterator pos) const {return node[pos].element;}
|
||||
// Return one element of this set.
|
||||
Uint32 getOne() const {assert(count > 0); return node[0].element;}
|
||||
// Return the size of this set.
|
||||
Uint32 getSize() const {return count;}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the set.
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
inline void SparseSet::clear(Uint32 element)
|
||||
{
|
||||
checkMember(element);
|
||||
Uint32 count = this->count;
|
||||
Node* node = this->node;
|
||||
|
||||
Uint32 stackIndex = node[element].stackIndex;
|
||||
|
||||
if ((stackIndex < count) && (node[stackIndex].element == element)) {
|
||||
Uint32 stackTop = node[count - 1].element;
|
||||
|
||||
node[stackIndex].element = stackTop;
|
||||
node[stackTop].stackIndex = stackIndex;
|
||||
this->count = count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline void SparseSet::set(Uint32 element)
|
||||
{
|
||||
checkMember(element);
|
||||
Uint32 count = this->count;
|
||||
Node* node = this->node;
|
||||
|
||||
Uint32 stackIndex = node[element].stackIndex;
|
||||
|
||||
if ((stackIndex >= count) || (node[stackIndex].element != element)) {
|
||||
node[count].element = element;
|
||||
node[element].stackIndex = count;
|
||||
this->count = count + 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool SparseSet::test(Uint32 element) const
|
||||
{
|
||||
checkMember(element);
|
||||
Node* node = this->node;
|
||||
|
||||
Uint32 stackIndex = node[element].stackIndex;
|
||||
return ((stackIndex < count) && (node[stackIndex].element == element));
|
||||
}
|
||||
|
||||
inline SparseSet& SparseSet::operator = (const SparseSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Uint32 sourceCount = set.getSize();
|
||||
Node* node = this->node;
|
||||
|
||||
memcpy(node, set.node, sourceCount * sizeof(Node));
|
||||
|
||||
for (Uint32 i = 0; i < sourceCount; i++) {
|
||||
Uint32 element = node[i].element;
|
||||
node[element].stackIndex = i;
|
||||
}
|
||||
|
||||
count = sourceCount;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline SparseSet& SparseSet::operator = (const BitSet& set)
|
||||
{
|
||||
// FIX: there's room for optimization here.
|
||||
assert(universeSize == set.getSize());
|
||||
|
||||
clear();
|
||||
for (Int32 i = set.firstOne(); i != -1; i = set.nextOne(i))
|
||||
this->set(i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif // _SPARSE_SET_H_
|
||||
270
mozilla/ef/Compiler/RegisterAllocator/Spilling.cpp
Normal file
270
mozilla/ef/Compiler/RegisterAllocator/Spilling.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef NEW_LAURENTM_CODE
|
||||
#define INCLUDE_EMITTER
|
||||
#include "CpuInfo.h"
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "InstructionEmitter.h"
|
||||
#include "Spilling.h"
|
||||
|
||||
|
||||
void Spilling::
|
||||
insertSpillCode(ControlNode** dfsList, Uint32 nNodes)
|
||||
{
|
||||
PRUint32 nVirtualRegisters = vRegManager.count();
|
||||
FastBitSet currentLive(vRegManager.pool, nVirtualRegisters);
|
||||
FastBitSet usedInThisInstruction(vRegManager.pool, nVirtualRegisters);
|
||||
RegisterFifo grNeedLoad(nVirtualRegisters);
|
||||
RegisterFifo fpNeedLoad(nVirtualRegisters);
|
||||
|
||||
for (PRInt32 n = nNodes - 1; n >= 0; n--)
|
||||
{
|
||||
PR_ASSERT(grNeedLoad.empty() & fpNeedLoad.empty());
|
||||
ControlNode& node = *dfsList[n];
|
||||
|
||||
currentLive = node.liveAtEnd;
|
||||
|
||||
PRUint32 nGeneralAlive = 0;
|
||||
PRUint32 nFloatingPointAlive = 0;
|
||||
|
||||
// Get the number of registers alive at the end of this node.
|
||||
for (PRInt32 j = currentLive.firstOne(); j != -1; j = currentLive.nextOne(j))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(j);
|
||||
if (vReg.spillInfo.willSpill)
|
||||
{
|
||||
currentLive.clear(j);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
nGeneralAlive++;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
nFloatingPointAlive++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if(node.dfsNum == 8) printf("\n________Begin Node %d________\n", node.dfsNum);
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i))
|
||||
{
|
||||
Instruction& instruction = instructions.get(i);
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* defPtr;
|
||||
|
||||
// if(node.dfsNum == 8) { printf("\n");
|
||||
// instruction.printPretty(stdout);
|
||||
// printf("\n"); }
|
||||
|
||||
// Handle definitions
|
||||
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
|
||||
if (defPtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = defPtr->getVirtualRegister();
|
||||
currentLive.clear(vReg.getRegisterIndex());
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
nGeneralAlive--;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
nFloatingPointAlive--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for deaths
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = usePtr->getVirtualRegister();
|
||||
if (!currentLive.test(vReg.getRegisterIndex()))
|
||||
// This is the last use of this register.
|
||||
{
|
||||
currentLive.set(vReg.getRegisterIndex());
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
nGeneralAlive++;
|
||||
while (/*(nGeneralAlive > NUMBER_OF_GREGISTERS) &&*/ !grNeedLoad.empty())
|
||||
{
|
||||
PRUint32 toLoad = grNeedLoad.get();
|
||||
currentLive.clear(toLoad);
|
||||
nGeneralAlive--;
|
||||
|
||||
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
|
||||
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
|
||||
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
|
||||
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
|
||||
nReg.releaseSelf();
|
||||
}
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
nFloatingPointAlive++;
|
||||
while (/*(nFloatingPointAlive > NUMBER_OF_FPREGISTERS) &&*/ !fpNeedLoad.empty())
|
||||
{
|
||||
PRUint32 toLoad = fpNeedLoad.get();
|
||||
currentLive.clear(toLoad);
|
||||
nFloatingPointAlive--;
|
||||
|
||||
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
|
||||
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
|
||||
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
|
||||
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
|
||||
nReg.releaseSelf();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle uses
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = usePtr->getVirtualRegister();
|
||||
PRUint32 registerIndex = vReg.getRegisterIndex();
|
||||
|
||||
if (vReg.spillInfo.willSpill) {
|
||||
#if defined(GENERATE_FOR_X86)
|
||||
if (!instruction.switchUseToSpill((usePtr - useBegin), *vReg.equivalentRegister[vrcStackSlot]))
|
||||
#endif
|
||||
{
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
if (!grNeedLoad.test(registerIndex))
|
||||
{
|
||||
grNeedLoad.put(registerIndex);
|
||||
VirtualRegister& alias = vRegManager.newVirtualRegister(vrcInteger);
|
||||
if (vReg.isPreColored())
|
||||
alias.preColorRegister(vReg.getPreColor());
|
||||
/* if (vReg.hasSpecialInterference) {
|
||||
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
|
||||
alias.specialInterference = vReg.specialInterference;
|
||||
alias.hasSpecialInterference = true;
|
||||
} */
|
||||
vReg.setAlias(alias);
|
||||
vReg.retainSelf();
|
||||
}
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
if (!fpNeedLoad.test(registerIndex))
|
||||
{
|
||||
fpNeedLoad.put(registerIndex);
|
||||
VirtualRegister& alias = vRegManager.newVirtualRegister(vReg.getClass());
|
||||
if (vReg.isPreColored())
|
||||
alias.preColorRegister(vReg.getPreColor());
|
||||
/*if (vReg.hasSpecialInterference) {
|
||||
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
|
||||
alias.specialInterference = vReg.specialInterference;
|
||||
alias.hasSpecialInterference = true;
|
||||
} */
|
||||
vReg.setAlias(alias);
|
||||
vReg.retainSelf();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
usePtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
|
||||
usedInThisInstruction.set(registerIndex);
|
||||
vReg.spillInfo.lastUsingInstruction = &instruction;
|
||||
}
|
||||
currentLive.clear(registerIndex);
|
||||
} else { // will not spill
|
||||
currentLive.set(registerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle definitions
|
||||
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
|
||||
if (defPtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = defPtr->getVirtualRegister();
|
||||
|
||||
if (vReg.spillInfo.willSpill)
|
||||
#if defined(GENERATE_FOR_X86)
|
||||
if (!instruction.switchDefineToSpill((defPtr - defBegin), *vReg.equivalentRegister[vrcStackSlot]))
|
||||
#endif
|
||||
{
|
||||
if (usedInThisInstruction.test(vReg.getRegisterIndex()))
|
||||
// this virtualRegister was used in this instruction and is also defined. We need to move
|
||||
// this virtual register to its alias first and then save it to memory.
|
||||
{
|
||||
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
|
||||
vReg.getAlias(), *vReg.equivalentRegister[vrcStackSlot]);
|
||||
defPtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
|
||||
}
|
||||
else
|
||||
{
|
||||
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
|
||||
vReg, *vReg.equivalentRegister[vrcStackSlot]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!grNeedLoad.empty())
|
||||
{
|
||||
PRUint32 nl = grNeedLoad.get();
|
||||
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
|
||||
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
|
||||
|
||||
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
|
||||
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
|
||||
nlReg.releaseSelf();
|
||||
}
|
||||
while (!fpNeedLoad.empty())
|
||||
{
|
||||
PRUint32 nl = fpNeedLoad.get();
|
||||
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
|
||||
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
|
||||
|
||||
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
|
||||
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
|
||||
nlReg.releaseSelf();
|
||||
}
|
||||
|
||||
// if(node.dfsNum == 8) printf("\n________End Node %d________\n", node.dfsNum);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
269
mozilla/ef/Compiler/RegisterAllocator/Spilling.h
Normal file
269
mozilla/ef/Compiler/RegisterAllocator/Spilling.h
Normal file
@@ -0,0 +1,269 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SPILLING_H_
|
||||
#define _SPILLING_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "SparseSet.h"
|
||||
|
||||
template <class RegisterPressure>
|
||||
class Spilling
|
||||
{
|
||||
private:
|
||||
static void insertStoreAfter(Instruction& instruction, RegisterName name);
|
||||
static void insertLoadBefore(Instruction& instruction, RegisterName name);
|
||||
|
||||
public:
|
||||
static void calculateSpillCosts(RegisterAllocator& registerAllocator);
|
||||
static void insertSpillCode(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
struct SpillCost
|
||||
{
|
||||
double loads;
|
||||
double stores;
|
||||
double copies;
|
||||
double cost;
|
||||
bool infinite;
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::insertSpillCode(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet currentLive(pool, rangeCount);
|
||||
SparseSet needLoad(pool, rangeCount);
|
||||
SparseSet mustSpill(pool, rangeCount);
|
||||
SparseSet& willSpill = *registerAllocator.willSpill;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
|
||||
needLoad.clear();
|
||||
currentLive = liveOut[n];
|
||||
mustSpill = currentLive;
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i);) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
i = instructions.retreat(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
bool foundLiveDefine = false;
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
if (currentLive.test(name2range[definePtr->getRegisterName()])) {
|
||||
foundLiveDefine = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
foundLiveDefine = true;
|
||||
break;
|
||||
}
|
||||
if (defineBegin != defineEnd && !foundLiveDefine) {
|
||||
fprintf(stderr, "!!! Removed instruction because it was only defining unused registers !!!\n");
|
||||
instruction.remove();
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName range = name2range[definePtr->getRegisterName()];
|
||||
#ifdef DEBUG
|
||||
if (needLoad.test(range))
|
||||
if (!mustSpill.test(range) && registerAllocator.spillCost[range].infinite && willSpill.test(range)) {
|
||||
fprintf(stderr, "Tried to spill a register with infinite spill cost\n");
|
||||
abort();
|
||||
}
|
||||
#endif // DEBUG
|
||||
if (willSpill.test(range))
|
||||
insertStoreAfter(instruction, range);
|
||||
|
||||
needLoad.clear(range);
|
||||
}
|
||||
|
||||
if (instruction.getFlags() & ifCopy)
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
if (!currentLive.test(range))
|
||||
for (SparseSet::iterator r = needLoad.begin(); !needLoad.done(r); r = needLoad.advance(r)) {
|
||||
RegisterName load = RegisterName(needLoad.get(r));
|
||||
if (willSpill.test(load))
|
||||
insertLoadBefore(instruction, load);
|
||||
mustSpill.set(load);
|
||||
}
|
||||
needLoad.clear();
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentLive.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
currentLive.set(range);
|
||||
needLoad.set(range);
|
||||
}
|
||||
}
|
||||
|
||||
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
|
||||
RegisterName load = RegisterName(needLoad.get(l));
|
||||
if (willSpill.test(load))
|
||||
insertLoadBefore(instructions.first(), load);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::insertLoadBefore(Instruction& /*instruction*/, RegisterName name)
|
||||
{
|
||||
fprintf(stdout, "will insert load for range %d\n", name);
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::insertStoreAfter(Instruction& /*instruction*/, RegisterName name)
|
||||
{
|
||||
fprintf(stdout, "will insert store for range %d\n", name);
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::calculateSpillCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet live(pool, rangeCount);
|
||||
SparseSet needLoad(pool, rangeCount);
|
||||
SparseSet mustSpill(pool, rangeCount);
|
||||
|
||||
SparseSet alreadyStored(pool, rangeCount); // FIX: should get this from previous spilling.
|
||||
|
||||
SpillCost* cost = new SpillCost[rangeCount];
|
||||
memset(cost, '\0', rangeCount * sizeof(SpillCost));
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
double weight = doLog10(node.loopDepth);
|
||||
|
||||
needLoad.clear();
|
||||
live = liveOut[n];
|
||||
mustSpill = live;
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName range = name2range[definePtr->getRegisterName()];
|
||||
|
||||
if (needLoad.test(range))
|
||||
if (!mustSpill.test(range))
|
||||
cost[range].infinite = true;
|
||||
|
||||
if ((false /* !rematerializable(range) */ || !needLoad.test(range)) && !alreadyStored.test(range))
|
||||
cost[range].stores += weight;
|
||||
|
||||
needLoad.clear(range);
|
||||
}
|
||||
|
||||
if (instruction.getFlags() & ifCopy)
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
if (!live.test(name2range[usePtr->getRegisterName()])) {
|
||||
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
|
||||
Uint32 range = needLoad.get(l);
|
||||
cost[range].loads += weight;
|
||||
mustSpill.set(range);
|
||||
}
|
||||
needLoad.clear();
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
live.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
|
||||
live.set(range);
|
||||
needLoad.set(range);
|
||||
}
|
||||
|
||||
if (instruction.getFlags() & ifCopy) {
|
||||
assert(useBegin != useEnd && useBegin[0].isRegister());
|
||||
assert(defineBegin != defineEnd && defineBegin[0].isRegister());
|
||||
|
||||
RegisterName source = name2range[useBegin[0].getRegisterName()];
|
||||
RegisterName destination = name2range[defineBegin[0].getRegisterName()];
|
||||
|
||||
cost[source].copies += weight;
|
||||
cost[destination].copies += weight;
|
||||
}
|
||||
}
|
||||
|
||||
for (SparseSet::iterator s = needLoad.begin(); !needLoad.done(s); s = needLoad.advance(s))
|
||||
cost[needLoad.get(s)].loads += weight;
|
||||
}
|
||||
|
||||
for (Uint32 r = 0; r < rangeCount; r++) {
|
||||
SpillCost& c = cost[r];
|
||||
c.cost = 2 * (c.loads + c.stores) - c.copies;
|
||||
}
|
||||
|
||||
registerAllocator.spillCost = cost;
|
||||
}
|
||||
|
||||
#endif // _SPILLING_H_
|
||||
239
mozilla/ef/Compiler/RegisterAllocator/Splits.h
Normal file
239
mozilla/ef/Compiler/RegisterAllocator/Splits.h
Normal file
@@ -0,0 +1,239 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SPLITS_H_
|
||||
#define _SPLITS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
|
||||
UT_EXTERN_LOG_MODULE(RegAlloc);
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct Splits
|
||||
{
|
||||
static void calculateSplitCosts(RegisterAllocator& registerAllocator);
|
||||
static bool findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range);
|
||||
static void insertSplitCode(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
struct SplitCost
|
||||
{
|
||||
double loads;
|
||||
double stores;
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Splits<RegisterPressure>::insertSplitCode(RegisterAllocator& /*registerAllocator*/)
|
||||
{
|
||||
// FIX
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Splits<RegisterPressure>::findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range)
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
NameLinkedList** neighborsWithColor = new(pool) NameLinkedList*[6]; // FIX
|
||||
memset(neighborsWithColor, '\0', 6 * sizeof(NameLinkedList*));
|
||||
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
|
||||
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
|
||||
for (Int32 i = vector->count - 1; i >=0; --i) {
|
||||
RegisterName neighbor = vector->neighbors[i];
|
||||
RegisterName c = color[neighbor];
|
||||
|
||||
if (c < 6) { // FIX
|
||||
NameLinkedList* node = new(pool) NameLinkedList();
|
||||
node->name = neighbor;
|
||||
node->next = neighborsWithColor[c];
|
||||
neighborsWithColor[c] = node;
|
||||
}
|
||||
}
|
||||
|
||||
bool splitAroundName = true;
|
||||
|
||||
LiveRangeGraph<RegisterPressure>& lGraph = registerAllocator.lGraph;
|
||||
RegisterName bestColor = RegisterName(6); // FIX
|
||||
double bestCost = registerAllocator.spillCost[range].cost;
|
||||
SplitCost* splitCost = registerAllocator.splitCost;
|
||||
|
||||
for (RegisterName i = RegisterName(0); i < 6; i = RegisterName(i + 1)) { // FIX
|
||||
|
||||
double splitAroundNameCost = 0.0;
|
||||
bool canSplitAroundName = true;
|
||||
|
||||
SplitCost& sCost = splitCost[range];
|
||||
double addedCost = 2.0 * (sCost.stores + sCost.loads);
|
||||
|
||||
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
|
||||
RegisterName neighbor = node->name;
|
||||
if (lGraph.haveEdge(neighbor, range)) {
|
||||
canSplitAroundName = false;
|
||||
break;
|
||||
} else
|
||||
splitAroundNameCost += addedCost;
|
||||
}
|
||||
if (canSplitAroundName && splitAroundNameCost < bestCost) {
|
||||
bestCost = splitAroundNameCost;
|
||||
bestColor = i;
|
||||
splitAroundName = true;
|
||||
}
|
||||
|
||||
double splitAroundColorCost = 0.0;
|
||||
bool canSplitAroundColor = true;
|
||||
|
||||
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
|
||||
RegisterName neighbor = node->name;
|
||||
if (lGraph.haveEdge(range, neighbor)) {
|
||||
canSplitAroundColor = false;
|
||||
break;
|
||||
} else {
|
||||
SplitCost& sCost = splitCost[neighbor];
|
||||
double addedCost = 2.0 * (sCost.stores + sCost.loads);
|
||||
splitAroundColorCost += addedCost;
|
||||
}
|
||||
}
|
||||
if (canSplitAroundColor && splitAroundColorCost < bestCost) {
|
||||
bestCost = splitAroundColorCost;
|
||||
bestColor = i;
|
||||
splitAroundName = false;
|
||||
}
|
||||
}
|
||||
if (bestColor < RegisterName(6)) {
|
||||
color[range] = bestColor;
|
||||
registerAllocator.splitFound = true;
|
||||
|
||||
NameLinkedList** splitAround = registerAllocator.splitAround;
|
||||
|
||||
if (splitAroundName)
|
||||
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
|
||||
NameLinkedList* newNode = new(pool) NameLinkedList();
|
||||
newNode->name = node->name;
|
||||
newNode->next = splitAround[range];
|
||||
splitAround[range] = newNode;
|
||||
}
|
||||
else
|
||||
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
|
||||
NameLinkedList* newNode = new(pool) NameLinkedList();
|
||||
RegisterName neighbor = node->name;
|
||||
newNode->name = range;
|
||||
newNode->next = splitAround[neighbor];
|
||||
splitAround[neighbor] = newNode;
|
||||
}
|
||||
|
||||
trespass("Found a split");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Splits<RegisterPressure>::calculateSplitCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
SplitCost* splitCost = new(pool) SplitCost[rangeCount];
|
||||
memset(splitCost, '\0', rangeCount * sizeof(SplitCost));
|
||||
|
||||
SparseSet live(pool, rangeCount);
|
||||
RegisterPressure::Set* liveIn = registerAllocator.liveness.liveIn;
|
||||
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
double weight = doLog10(node.loopDepth);
|
||||
|
||||
live = liveOut[n];
|
||||
|
||||
ControlEdge* successorsEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++) {
|
||||
ControlNode& successor = successorsPtr->getTarget();
|
||||
|
||||
if (successor.getControlKind() != ckEnd) {
|
||||
RegisterPressure::Set& successorLiveIn = liveIn[successor.dfsNum];
|
||||
|
||||
for (SparseSet::iterator i = live.begin(); !live.done(i); i = live.advance(i)) {
|
||||
RegisterName name = RegisterName(live.get(i));
|
||||
if (!successorLiveIn.test(name))
|
||||
splitCost[name].loads += doLog10(successor.loopDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
splitCost[name2range[definePtr->getRegisterName()]].stores += weight;
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
if (!live.test(range)) {
|
||||
if (&instruction != &instructions.last())
|
||||
splitCost[range].loads += weight;
|
||||
else {
|
||||
ControlEdge* successorsEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++)
|
||||
splitCost[range].loads += doLog10(successorsPtr->getTarget().loopDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
live.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
live.set(name2range[usePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
|
||||
NameLinkedList** splitAround = new(pool) NameLinkedList*[rangeCount];
|
||||
memset(splitAround, '\0', rangeCount * sizeof(NameLinkedList*));
|
||||
registerAllocator.splitAround = splitAround;
|
||||
|
||||
registerAllocator.splitCost = splitCost;
|
||||
registerAllocator.splitFound = false;
|
||||
}
|
||||
|
||||
#endif // _SPLITS_H_
|
||||
186
mozilla/ef/Compiler/RegisterAllocator/Timer.cpp
Normal file
186
mozilla/ef/Compiler/RegisterAllocator/Timer.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashTable.h"
|
||||
#include "Timer.h"
|
||||
#include "Pool.h"
|
||||
|
||||
static Pool pool; // Pool for the Timer class.
|
||||
static HashTable<TimerEntry*> timerEntries(pool); // Timers hashtable.
|
||||
|
||||
const nTimersInABlock = 128; // Number of timers in a block.
|
||||
static PRTime *timers = new(pool) PRTime[nTimersInABlock]; // A block of timers.
|
||||
static Uint8 nextTimer = 0; // nextAvailableTimer.
|
||||
|
||||
//
|
||||
// Calibrate the call to PR_Now().
|
||||
//
|
||||
static PRTime calibrate()
|
||||
{
|
||||
PRTime t = PR_Now();
|
||||
PRTime& a = *new(pool) PRTime();
|
||||
|
||||
// Call 10 times the PR_Now() function.
|
||||
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
|
||||
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
|
||||
t = (PR_Now() - t + 9) / 10;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static PRTime adjust = calibrate();
|
||||
|
||||
//
|
||||
// Return the named timer..
|
||||
//
|
||||
TimerEntry& Timer::getTimerEntry(const char* name)
|
||||
{
|
||||
if (!timerEntries.exists(name)) {
|
||||
TimerEntry* newEntry = new(pool) TimerEntry();
|
||||
newEntry->accumulator = 0;
|
||||
newEntry->running = false;
|
||||
timerEntries.add(name, newEntry);
|
||||
}
|
||||
|
||||
return *timerEntries[name];
|
||||
}
|
||||
|
||||
//
|
||||
// Return a reference to a new timer.
|
||||
//
|
||||
PRTime& Timer::getNewTimer()
|
||||
{
|
||||
if (nextTimer >= nTimersInABlock) {
|
||||
timers = new(pool) PRTime[nTimersInABlock];
|
||||
nextTimer = 0;
|
||||
}
|
||||
return timers[nextTimer++];
|
||||
}
|
||||
|
||||
static Uint32 timersAreFrozen = 0;
|
||||
|
||||
//
|
||||
// Start the named timer.
|
||||
//
|
||||
void Timer::start(const char* name)
|
||||
{
|
||||
if (timersAreFrozen)
|
||||
return;
|
||||
|
||||
freezeTimers();
|
||||
|
||||
TimerEntry& timer = getTimerEntry(name);
|
||||
PR_ASSERT(!timer.running);
|
||||
|
||||
timer.accumulator = 0;
|
||||
timer.running = true;
|
||||
timer.done = false;
|
||||
|
||||
unfreezeTimers();
|
||||
}
|
||||
|
||||
//
|
||||
// Stop the named timer.
|
||||
//
|
||||
void Timer::stop(const char* name)
|
||||
{
|
||||
if (timersAreFrozen)
|
||||
return;
|
||||
|
||||
freezeTimers();
|
||||
|
||||
TimerEntry& timer = getTimerEntry(name);
|
||||
PR_ASSERT(timer.running);
|
||||
timer.running = false;
|
||||
timer.done = true;
|
||||
|
||||
unfreezeTimers();
|
||||
}
|
||||
|
||||
//
|
||||
// Freeze all the running timers.
|
||||
//
|
||||
void Timer::freezeTimers()
|
||||
{
|
||||
PRTime when = PR_Now() - adjust;
|
||||
|
||||
if (timersAreFrozen == 0) {
|
||||
Vector<TimerEntry*> entries = timerEntries;
|
||||
Uint32 count = entries.size();
|
||||
|
||||
for (Uint32 i = 0; i < count; i++) {
|
||||
TimerEntry& entry = *entries[i];
|
||||
if (entry.running) {
|
||||
entry.accumulator += (when - *entry.startTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
timersAreFrozen++;
|
||||
}
|
||||
|
||||
//
|
||||
// Unfreeze all the running timers.
|
||||
//
|
||||
void Timer::unfreezeTimers()
|
||||
{
|
||||
PR_ASSERT(timersAreFrozen != 0);
|
||||
timersAreFrozen--;
|
||||
|
||||
if (timersAreFrozen == 0) {
|
||||
Vector<TimerEntry *> entries = timerEntries;
|
||||
Uint32 count = entries.size();
|
||||
|
||||
PRTime& newStart = getNewTimer();
|
||||
|
||||
for (Uint32 i = 0; i < count; i++) {
|
||||
TimerEntry& entry = *entries[i];
|
||||
if (entry.running) {
|
||||
entry.startTime = &newStart;
|
||||
}
|
||||
}
|
||||
|
||||
newStart = PR_Now();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Print the named timer in the file f.
|
||||
//
|
||||
void Timer::print(FILE* f, const char *name)
|
||||
{
|
||||
if (timersAreFrozen)
|
||||
return;
|
||||
|
||||
freezeTimers();
|
||||
|
||||
TimerEntry& timer = getTimerEntry(name);
|
||||
|
||||
PR_ASSERT(timer.done);
|
||||
PRTime elapsed = timer.accumulator;
|
||||
|
||||
if (elapsed >> 32) {
|
||||
fprintf(f, "[timer %s out of range]\n", name);
|
||||
} else {
|
||||
fprintf(f, "[%dus in %s]\n", Uint32(elapsed), name);
|
||||
}
|
||||
fflush(f);
|
||||
|
||||
unfreezeTimers();
|
||||
}
|
||||
|
||||
80
mozilla/ef/Compiler/RegisterAllocator/Timer.h
Normal file
80
mozilla/ef/Compiler/RegisterAllocator/Timer.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashTable.h"
|
||||
#include "prtime.h"
|
||||
|
||||
//
|
||||
// Naming convention:
|
||||
// As the class Timer contains only static methods, the timer's name should start with the
|
||||
// module name. Otherwise starting 2 timers with the same name will assert.
|
||||
//
|
||||
|
||||
#ifndef NO_TIMER
|
||||
|
||||
struct TimerEntry
|
||||
{
|
||||
PRTime *startTime; // Current time when we start the timer.
|
||||
PRTime accumulator; // Time spent in this timer.
|
||||
bool running; // True if the timer is running.
|
||||
bool done; // True if the timer was running and was stopped.
|
||||
};
|
||||
|
||||
class Timer
|
||||
{
|
||||
private:
|
||||
|
||||
// Return the named timer.
|
||||
static TimerEntry& getTimerEntry(const char* name);
|
||||
// Return a reference to a new Timer.
|
||||
static PRTime& getNewTimer();
|
||||
|
||||
public:
|
||||
|
||||
// Start the timer.
|
||||
static void start(const char* name);
|
||||
// Stop the timer.
|
||||
static void stop(const char* name);
|
||||
// Freeze all the running timers.
|
||||
static void freezeTimers();
|
||||
// Unfreeze all the running timers.
|
||||
static void unfreezeTimers();
|
||||
// Print the timer.
|
||||
static void print(FILE* f, const char *name);
|
||||
};
|
||||
|
||||
inline void startTimer(const char* name) {Timer::start(name);}
|
||||
inline void stopTimer(const char* name) {Timer::stop(name); Timer::print(stdout, name);}
|
||||
#define START_TIMER_SAFE Timer::freezeTimers();
|
||||
#define END_TIMER_SAFE Timer::unfreezeTimers();
|
||||
#define TIMER_SAFE(x) START_TIMER_SAFE x; END_TIMER_SAFE
|
||||
|
||||
#else /* NO_TIMER */
|
||||
|
||||
inline void startTimer(const char* /*name*/) {}
|
||||
inline void stopTimer(const char* /*name*/) {}
|
||||
#define START_TIMER_SAFE
|
||||
#define END_TIMER_SAFE
|
||||
#define TIMER_SAFE(x) x;
|
||||
|
||||
#endif /* NO_TIMER */
|
||||
#endif /* _TIMER_H_ */
|
||||
40
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.cpp
Normal file
40
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "Instruction.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VirtualRegister -
|
||||
|
||||
#ifdef MANUAL_TEMPLATES
|
||||
template class IndexedPool<VirtualRegister>;
|
||||
#endif
|
||||
|
||||
// Set the defining instruction.
|
||||
//
|
||||
void VirtualRegister::setDefiningInstruction(Instruction& instruction)
|
||||
{
|
||||
if (definingInstruction != NULL) {
|
||||
if ((instruction.getFlags() & ifCopy) && (definingInstruction->getFlags() & ifPhiNode))
|
||||
return;
|
||||
}
|
||||
definingInstruction = &instruction;
|
||||
}
|
||||
|
||||
116
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.h
Normal file
116
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _VIRTUAL_REGISTER_H_
|
||||
#define _VIRTUAL_REGISTER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "IndexedPool.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "RegisterTypes.h"
|
||||
#include "RegisterClass.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VirtualRegister - 24b
|
||||
|
||||
class Instruction;
|
||||
|
||||
class VirtualRegister : public IndexedObject<VirtualRegister>
|
||||
{
|
||||
public:
|
||||
|
||||
Instruction* definingInstruction; // Instruction defining this VR.
|
||||
|
||||
// Initialize a VR of the given classKind.
|
||||
VirtualRegister(RegisterClassKind /*classKind*/) : definingInstruction(NULL) {}
|
||||
|
||||
// Return the defining instruction for this VR.
|
||||
Instruction* getDefiningInstruction() const {return definingInstruction;}
|
||||
// Set the defining instruction.
|
||||
void setDefiningInstruction(Instruction& insn);
|
||||
};
|
||||
|
||||
// Return true if the VirtualRegisters are equals. The only way 2 VRs can be equal is if
|
||||
// they have the same index. If they have the same index then they are at the same
|
||||
// address in the indexed pool.
|
||||
//
|
||||
inline bool operator == (const VirtualRegister& regA, const VirtualRegister& regB) {return ®A == ®B;}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VirtualRegisterManager -
|
||||
|
||||
struct PreColoredRegister
|
||||
{
|
||||
RegisterID id;
|
||||
RegisterName color;
|
||||
};
|
||||
|
||||
class VirtualRegisterManager
|
||||
{
|
||||
private:
|
||||
|
||||
IndexedPool<VirtualRegister> registerPool;
|
||||
PreColoredRegister machineRegister[6];
|
||||
|
||||
public:
|
||||
VirtualRegisterManager()
|
||||
{
|
||||
for (Uint32 i = 0; i < 6; i++)
|
||||
machineRegister[i].id = invalidID;
|
||||
}
|
||||
|
||||
// Return the VirtualRegister at the given index.
|
||||
VirtualRegister& getVirtualRegister(RegisterName name) const {return registerPool.get(name);}
|
||||
|
||||
// Return a new VirtualRegister.
|
||||
RegisterID newVirtualRegister(RegisterClassKind classKind)
|
||||
{
|
||||
VirtualRegister& vReg = *new(registerPool) VirtualRegister(classKind);
|
||||
RegisterID rid;
|
||||
|
||||
setName(rid, RegisterName(vReg.getIndex()));
|
||||
setClass(rid, classKind);
|
||||
return rid;
|
||||
}
|
||||
|
||||
RegisterID newMachineRegister(RegisterName name, RegisterClassKind classKind)
|
||||
{
|
||||
RegisterID rid = machineRegister[name].id;
|
||||
|
||||
if (rid == invalidID) {
|
||||
rid = newVirtualRegister(classKind);
|
||||
DEBUG_ONLY(setMachineRegister(rid));
|
||||
machineRegister[name].id = rid;
|
||||
machineRegister[name].color = name;
|
||||
}
|
||||
|
||||
return rid;
|
||||
}
|
||||
|
||||
PreColoredRegister* getMachineRegistersBegin() const {return (PreColoredRegister*) machineRegister;} // FIX
|
||||
PreColoredRegister* getMachineRegistersEnd() const {return (PreColoredRegister*) &machineRegister[6];} // FIX
|
||||
|
||||
// Return the VirtualRegister universe size.
|
||||
Uint32 getSize() {return registerPool.getSize();}
|
||||
|
||||
void setSize(Uint32 size) {registerPool.setSize(size);}
|
||||
};
|
||||
|
||||
#endif // _VIRTUAL_REGISTER_H_
|
||||
@@ -1,32 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = public src resources
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,26 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* Defining the following causes NS_APPSHELL to be defined as NS_EXPORT. */
|
||||
#define _IMPL_NS_APPSHELL
|
||||
|
||||
#include "MacSharedPrefix.h"
|
||||
@@ -1,26 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/* Defining the following causes NS_APPSHELL to be defined as NS_EXPORT. */
|
||||
#define _IMPL_NS_APPSHELL
|
||||
|
||||
#include "MacSharedPrefix_debug.h"
|
||||
@@ -1,26 +0,0 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
DIRS=public src resources
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
@@ -1 +0,0 @@
|
||||
nsIBookmarksService.idl
|
||||
@@ -1,35 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = appcomps
|
||||
XPIDL_MODULE = bookmarks
|
||||
|
||||
XPIDLSRCS = nsIBookmarksService.idl
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
|
||||
MODULE=bookmarks
|
||||
|
||||
XPIDLSRCS = \
|
||||
.\nsIBookmarksService.idl \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* The Browser Bookmarks service
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIRDFResource;
|
||||
|
||||
[scriptable, uuid(a82e9300-e4af-11d2-8fdf-0008c70adc7b)]
|
||||
interface nsIBookmarksService : nsISupports
|
||||
{
|
||||
const unsigned long BOOKMARK_DEFAULT_TYPE = 0;
|
||||
const unsigned long BOOKMARK_SEARCH_TYPE = 1;
|
||||
const unsigned long BOOKMARK_FIND_TYPE = 2;
|
||||
|
||||
boolean ReadBookmarks();
|
||||
boolean IsBookmarked(in string aURI);
|
||||
|
||||
void addBookmarkImmediately(in string aURI, in wstring aTitle, in long bmType, in wstring docCharset);
|
||||
|
||||
nsIRDFResource createFolder(in wstring aName, in nsIRDFResource aParentFolder);
|
||||
nsIRDFResource createFolderWithDetails(in wstring aName, in nsIRDFResource aParentFolder,
|
||||
in long aIndex);
|
||||
|
||||
nsIRDFResource createGroup(in wstring aName, in nsIRDFResource aParentFolder);
|
||||
nsIRDFResource createGroupWithDetails(in wstring aName, in nsIRDFResource aParentFolder,
|
||||
in long aIndex);
|
||||
|
||||
nsIRDFResource createBookmark(in wstring aName, in string aURL, in nsIRDFResource aParentFolder);
|
||||
nsIRDFResource createBookmarkWithDetails(in wstring aName, in string aURI, in wstring docCharSet,
|
||||
in nsIRDFResource aFolder, in long aIndex);
|
||||
|
||||
void updateBookmarkIcon(in string aURL, in wstring iconURL);
|
||||
void removeBookmarkIcon(in string aURL, in wstring iconURL);
|
||||
|
||||
void updateLastVisitedDate(in string aURL, in wstring docCharset);
|
||||
|
||||
string resolveKeyword(in wstring aName);
|
||||
|
||||
wstring getLastCharset(in string aURI);
|
||||
|
||||
void importSystemBookmarks(in nsIRDFResource aParentFolder);
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
||||
// {E638D760-8687-11d2-B530-000000000000}
|
||||
#define NS_BOOKMARKS_SERVICE_CID \
|
||||
{ 0xe638d760, 0x8687, 0x11d2, { 0xb5, 0x30, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }
|
||||
|
||||
#define NS_BOOKMARKS_SERVICE_CONTRACTID \
|
||||
"@mozilla.org/browser/bookmarks-service;1"
|
||||
|
||||
#define NS_BOOKMARKS_DATASOURCE_CONTRACTID \
|
||||
"@mozilla.org/rdf/datasource;1?name=bookmarks"
|
||||
|
||||
%}
|
||||
@@ -1,9 +0,0 @@
|
||||
bm-find.js
|
||||
bm-find.xul
|
||||
bm-panel.js
|
||||
bm-panel.xul
|
||||
bm-props.js
|
||||
bm-props.xul
|
||||
bookmarks.js
|
||||
bookmarksDD.js
|
||||
bookmarks.xul
|
||||
@@ -1,30 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
@@ -1,348 +0,0 @@
|
||||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@netscape.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Add Bookmark Dialog.
|
||||
* ====================
|
||||
*
|
||||
* This is a generic bookmark dialog that allows for bookmark addition
|
||||
* and folder selection. It can be opened with various parameters that
|
||||
* result in appearance/purpose differences and initial state.
|
||||
*
|
||||
* Use: Open with 'openDialog', with the flags
|
||||
* 'centerscreen,chrome,dialog=no,resizable=yes'
|
||||
*
|
||||
* Parameters:
|
||||
* Apart from the standard openDialog parameters, this dialog can
|
||||
* be passed additional information, which gets mapped to the
|
||||
* window.arguments array:
|
||||
*
|
||||
* window.arguments[0]: Bookmark Name. The value to be prefilled
|
||||
* into the "Name: " field (if visible).
|
||||
* window.arguments[1]: Bookmark URL: The location of the bookmark.
|
||||
* The value to be filled in the "Location: "
|
||||
* field (if visible).
|
||||
* window.arguments[2]: Bookmark Folder. The RDF Resource URI of the
|
||||
* folder that this bookmark should be created in.
|
||||
* window.arguments[3]: Bookmark Charset. The charset that should be
|
||||
* used when adding a bookmark to the specified
|
||||
* URL. (Usually the charset of the current
|
||||
* document when launching this window).
|
||||
* window.arguments[4]: The mode of operation. See notes for details.
|
||||
* window.arguments[5]: If the mode is "addGroup", this is an array
|
||||
* of objects with name, URL and charset
|
||||
* properties, one for each group member.
|
||||
*
|
||||
* Mode of Operation Notes:
|
||||
* ------------------------
|
||||
* This dialog can be opened in four different ways by using a parameter
|
||||
* passed through the call to openDialog. The 'mode' of operation
|
||||
* of the window is expressed in window.arguments[4]. The valid modes are:
|
||||
*
|
||||
* 1) <default> (no fifth open parameter).
|
||||
* Opens this dialog with the bookmark Name, URL and folder selection
|
||||
* components visible.
|
||||
* 2) "newBookmark" (fifth open parameter = String("newBookmark"))
|
||||
* Opens the dialog as in (1) above except the folder selection tree
|
||||
* is hidden. This type of mode is useful when the creation folder
|
||||
* is pre-determined.
|
||||
* 3) "selectFolder" (fifth open parameter = String("selectFolder"))
|
||||
* Opens the dialog as in (1) above except the Name/Location section
|
||||
* is hidden, and the dialog takes on the utility of a Folder chooser.
|
||||
* Used when the user must select a Folder for some purpose.
|
||||
* 4) "addGroup" (fifth open parameter = String("addGroup"))
|
||||
* Opens the dialog like <default>, with a checkbox to select between
|
||||
* filing a single bookmark or a group. For the single bookmark the
|
||||
* values are taken from the name, URL and charset arguments.
|
||||
* For the group, the values are taken from the sixth argument.
|
||||
* This parameter can also be String("addGroup,group") where "group"
|
||||
* specifies that the dialog starts in filing as a group.
|
||||
*/
|
||||
|
||||
var gFld_Name = null;
|
||||
var gFld_URL = null;
|
||||
var gFolderTree = null;
|
||||
var gCB_AddGroup = null;
|
||||
|
||||
var gBookmarkCharset = null;
|
||||
|
||||
const kRDFSContractID = "@mozilla.org/rdf/rdf-service;1";
|
||||
const kRDFSIID = Components.interfaces.nsIRDFService;
|
||||
const kRDF = Components.classes[kRDFSContractID].getService(kRDFSIID);
|
||||
|
||||
var gSelectItemObserver = null;
|
||||
|
||||
var gCreateInFolder = "NC:NewBookmarkFolder";
|
||||
|
||||
function Startup()
|
||||
{
|
||||
gFld_Name = document.getElementById("name");
|
||||
gFld_URL = document.getElementById("url");
|
||||
gCB_AddGroup = document.getElementById("addgroup");
|
||||
var bookmarkView = document.getElementById("bookmarks-view");
|
||||
|
||||
var shouldSetOKButton = true;
|
||||
var dialogElement = document.documentElement;
|
||||
if ("arguments" in window) {
|
||||
var ind;
|
||||
var folderItem = null;
|
||||
var arg;
|
||||
if (window.arguments.length < 5)
|
||||
arg = null;
|
||||
else
|
||||
arg = window.arguments[4];
|
||||
switch (arg) {
|
||||
case "selectFolder":
|
||||
// If we're being opened as a folder selection window
|
||||
document.getElementById("bookmarknamegrid").setAttribute("hidden", "true");
|
||||
document.getElementById("createinseparator").setAttribute("hidden", "true");
|
||||
document.getElementById("nameseparator").setAttribute("hidden", "true");
|
||||
sizeToContent();
|
||||
dialogElement.setAttribute("title", dialogElement.getAttribute("title-selectFolder"));
|
||||
shouldSetOKButton = false;
|
||||
if (window.arguments[2])
|
||||
folderItem = bookmarkView.rdf.GetResource(window.arguments[2]);
|
||||
if (folderItem) {
|
||||
ind = bookmarkView.treeBuilder.getIndexOfResource(folderItem);
|
||||
bookmarkView.treeBoxObject.selection.select(ind);
|
||||
}
|
||||
break;
|
||||
case "newBookmark":
|
||||
setupFields();
|
||||
if (window.arguments[2])
|
||||
gCreateInFolder = window.arguments[2];
|
||||
document.getElementById("folderbox").setAttribute("hidden", "true");
|
||||
sizeToFit();
|
||||
break;
|
||||
case "addGroup":
|
||||
document.getElementById("showaddgroup").setAttribute("hidden", "false");
|
||||
setupFields();
|
||||
sizeToFit();
|
||||
break;
|
||||
case "addGroup,group":
|
||||
document.getElementById("showaddgroup").setAttribute("hidden", "false");
|
||||
gCB_AddGroup.setAttribute("checked", "true");
|
||||
setupFields();
|
||||
toggleGroup();
|
||||
sizeToFit();
|
||||
break;
|
||||
default:
|
||||
// Regular Add Bookmark
|
||||
setupFields();
|
||||
if (window.arguments[2]) {
|
||||
gCreateInFolder = window.arguments[2];
|
||||
folderItem = bookmarkView.rdf.GetResource(gCreateInFolder);
|
||||
if (folderItem) {
|
||||
ind = bookmarkView.treeBuilder.getIndexOfResource(folderItem);
|
||||
bookmarkView.treeBoxObject.selection.select(ind);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldSetOKButton)
|
||||
onFieldInput();
|
||||
if (document.getElementById("bookmarknamegrid").hasAttribute("hidden")) {
|
||||
bookmarkView.tree.focus();
|
||||
if (bookmarkView.currentIndex == -1)
|
||||
bookmarkView.treeBoxObject.selection.select(0);
|
||||
}
|
||||
else {
|
||||
gFld_Name.select();
|
||||
gFld_Name.focus();
|
||||
}
|
||||
}
|
||||
|
||||
function sizeToFit()
|
||||
{
|
||||
var dialogElement = document.documentElement;
|
||||
dialogElement.removeAttribute("persist");
|
||||
dialogElement.removeAttribute("height");
|
||||
dialogElement.removeAttribute("width");
|
||||
dialogElement.setAttribute("style", dialogElement.getAttribute("style"));
|
||||
sizeToContent();
|
||||
}
|
||||
|
||||
function setupFields()
|
||||
{
|
||||
// New bookmark in predetermined folder.
|
||||
gFld_Name.value = window.arguments[0] || "";
|
||||
gFld_URL.value = window.arguments[1] || "";
|
||||
onFieldInput();
|
||||
gFld_Name.select();
|
||||
gFld_Name.focus();
|
||||
gBookmarkCharset = window.arguments[3] || null;
|
||||
}
|
||||
|
||||
function onFieldInput()
|
||||
{
|
||||
const ok = document.documentElement.getButton("accept");
|
||||
ok.disabled = gFld_URL.value == "" && !addingGroup() ||
|
||||
gFld_Name.value == "";
|
||||
}
|
||||
|
||||
function onOK()
|
||||
{
|
||||
if (!document.getElementById("folderbox").hasAttribute("hidden")) {
|
||||
var bookmarkView = document.getElementById("bookmarks-view");
|
||||
var currentIndex = bookmarkView.currentIndex;
|
||||
if (currentIndex != -1)
|
||||
gCreateInFolder = bookmarkView.treeBuilder.getResourceAtIndex(currentIndex).Value;
|
||||
}
|
||||
// In Select Folder Mode, do nothing but tell our caller what
|
||||
// folder was selected.
|
||||
if (window.arguments.length > 4 && window.arguments[4] == "selectFolder")
|
||||
window.arguments[5].selectedFolder = gCreateInFolder;
|
||||
else {
|
||||
// Otherwise add a bookmark to the selected folder.
|
||||
|
||||
const kBMDS = kRDF.GetDataSource("rdf:bookmarks");
|
||||
const kBMSContractID = "@mozilla.org/browser/bookmarks-service;1";
|
||||
const kBMSIID = Components.interfaces.nsIBookmarksService;
|
||||
const kBMS = Components.classes[kBMSContractID].getService(kBMSIID);
|
||||
var rFolder = kRDF.GetResource(gCreateInFolder, true);
|
||||
const kRDFCContractID = "@mozilla.org/rdf/container;1";
|
||||
const kRDFIID = Components.interfaces.nsIRDFContainer;
|
||||
const kRDFC = Components.classes[kRDFCContractID].getService(kRDFIID);
|
||||
try {
|
||||
kRDFC.Init(kBMDS, rFolder);
|
||||
}
|
||||
catch (e) {
|
||||
// No "NC:NewBookmarkFolder" exists, just append to the root.
|
||||
rFolder = kRDF.GetResource("NC:BookmarksRoot", true);
|
||||
kRDFC.Init(kBMDS, rFolder);
|
||||
}
|
||||
|
||||
// if no URL was provided and we're not filing as a group, do nothing
|
||||
if (!gFld_URL.value && !addingGroup())
|
||||
return;
|
||||
|
||||
var url;
|
||||
if (addingGroup()) {
|
||||
const group = kBMS.createGroup(gFld_Name.value, rFolder);
|
||||
const groups = window.arguments[5];
|
||||
for (var i = 0; i < groups.length; ++i) {
|
||||
url = getNormalizedURL(groups[i].url);
|
||||
kBMS.createBookmarkWithDetails(groups[i].name, url,
|
||||
groups[i].charset, group, -1);
|
||||
}
|
||||
} else {
|
||||
url = getNormalizedURL(gFld_URL.value);
|
||||
var newBookmark = kBMS.createBookmarkWithDetails(gFld_Name.value, url, gBookmarkCharset, rFolder, -1);
|
||||
if (window.arguments.length > 4 && window.arguments[4] == "newBookmark") {
|
||||
window.arguments[5].newBookmark = newBookmark;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getNormalizedURL(url)
|
||||
{
|
||||
// Check to see if the item is a local directory path, and if so, convert
|
||||
// to a file URL so that aggregation with rdf:files works
|
||||
try {
|
||||
const kLF = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
kLF.initWithPath(url);
|
||||
if (kLF.exists()) {
|
||||
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.classes.nsIIOService);
|
||||
|
||||
url = ioService.getURLSpecFromFile(kLF);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
var gBookmarksShell = null;
|
||||
function createNewFolder ()
|
||||
{
|
||||
var bookmarksView = document.getElementById("bookmarks-view");
|
||||
bookmarksView.createNewFolder();
|
||||
}
|
||||
|
||||
function useDefaultFolder ()
|
||||
{
|
||||
const kBMDS = kRDF.GetDataSource("rdf:bookmarks");
|
||||
var bookmarkView = document.getElementById("bookmarks-view");
|
||||
var sources = kBMDS.GetSources(bookmarkView.rdf.GetResource(NC_NS + "FolderType"), bookmarkView.rdf.GetResource("NC:NewBookmarkFolder"), true);
|
||||
var folder = null;
|
||||
if (sources.hasMoreElements()) {
|
||||
folder = sources.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
}
|
||||
var ind = bookmarkView.treeBuilder.getIndexOfResource(folder);
|
||||
if (ind != -1) {
|
||||
bookmarkView.tree.focus();
|
||||
bookmarkView.treeBoxObject.selection.select(ind);
|
||||
gCreateInFolder = folder.Value;
|
||||
}
|
||||
else {
|
||||
bookmarkView.treeBoxObject.selection.clearSelection();
|
||||
gCreateInFolder = "NC:BookmarksRoot";
|
||||
}
|
||||
}
|
||||
|
||||
var gOldNameValue = "";
|
||||
var gOldURLValue = "";
|
||||
|
||||
function toggleGroup()
|
||||
{
|
||||
// swap between single bookmark and group name
|
||||
var temp = gOldNameValue;
|
||||
gOldNameValue = gFld_Name.value;
|
||||
gFld_Name.value = temp;
|
||||
|
||||
// swap between single bookmark and group url
|
||||
temp = gOldURLValue;
|
||||
gOldURLValue = gFld_URL.value;
|
||||
gFld_URL.value = temp;
|
||||
gFld_URL.disabled = gCB_AddGroup.getAttribute("checked") == "true";
|
||||
|
||||
gFld_Name.select();
|
||||
gFld_Name.focus();
|
||||
onFieldInput();
|
||||
}
|
||||
|
||||
function addingGroup()
|
||||
{
|
||||
const showAddGroup = document.getElementById("showaddgroup");
|
||||
return showAddGroup.getAttribute("hidden") != "true" && gCB_AddGroup.getAttribute("checked") == "true";
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- -*- Mode: HTML; indent-tabs-mode: nil; -*- -->
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the Netscape Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/NPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The Original Code is mozilla.org code.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
Ben Goodger <ben@netscape.com> (Original Author)
|
||||
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://communicator/skin/"?>
|
||||
<?xml-stylesheet href="chrome://communicator/skin/bookmarks/bookmarks.css"?>
|
||||
<?xml-stylesheet href="chrome://communicator/content/bookmarks/bookmarks.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd" >
|
||||
%brandDTD;
|
||||
<!ENTITY % addBookmarkDTD SYSTEM "chrome://communicator/locale/bookmarks/addBookmark.dtd">
|
||||
%addBookmarkDTD;
|
||||
]>
|
||||
|
||||
<dialog id="newBookmarkDialog" style="width: 36em;"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
ondialogaccept="return onOK(event)"
|
||||
title="&newBookmark.title;" title-selectFolder="&selectFolder.label;"
|
||||
onload="Startup();"
|
||||
persist="screenX screenY width height"
|
||||
screenX="24" screenY="24">
|
||||
|
||||
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksOverlay.js"/>
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksTree.js"/>
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/addBookmark.js"/>
|
||||
|
||||
<stringbundle id="bookmarksbundle"
|
||||
src="chrome://communicator/locale/bookmarks/bookmark.properties"/>
|
||||
|
||||
<broadcaster id="showaddgroup" hidden="true"/>
|
||||
|
||||
<separator id="nameseparator" class="thin"/>
|
||||
|
||||
<grid id="bookmarknamegrid">
|
||||
<columns>
|
||||
<column/>
|
||||
<column flex="5"/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row align="center">
|
||||
<label value="&name.label;" accesskey="&name.accesskey;" control="name"/>
|
||||
<textbox id="name" oninput="onFieldInput();"/>
|
||||
<spacer/>
|
||||
</row>
|
||||
<row>
|
||||
<separator class="thin"/>
|
||||
<separator class="thin"/>
|
||||
<spacer/>
|
||||
</row>
|
||||
<row align="center">
|
||||
<label value="&url.label;" accesskey="&url.accesskey;" control="url"/>
|
||||
<textbox id="url" oninput="onFieldInput();"/>
|
||||
<spacer/>
|
||||
</row>
|
||||
<row observes="showaddgroup">
|
||||
<separator class="thin"/>
|
||||
<separator class="thin"/>
|
||||
<spacer/>
|
||||
</row>
|
||||
<row observes="showaddgroup">
|
||||
<spacer/>
|
||||
<hbox pack="start">
|
||||
<checkbox id="addgroup" label="&addGroup.label;"
|
||||
accesskey="&addGroup.accesskey;" oncommand="toggleGroup();"/>
|
||||
</hbox>
|
||||
<spacer/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
|
||||
<separator id="createinseparator"/>
|
||||
|
||||
<vbox id="folderbox" flex="1">
|
||||
<separator/>
|
||||
<hbox flex="1">
|
||||
<label id="createinlabel" value="&createin.label;"/>
|
||||
<hbox flex="1">
|
||||
<bookmarks-tree id="bookmarks-view" flex="1" type="folders"/>
|
||||
<vbox>
|
||||
<button label="&button.newfolder.label;" accesskey="&button.newfolder.accesskey;"
|
||||
oncommand="createNewFolder();"/>
|
||||
<button label="&button.defaultfolder.label;"
|
||||
accesskey="&button.defaultfolder.accesskey;"
|
||||
oncommand="useDefaultFolder();"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
<separator/>
|
||||
|
||||
</dialog>
|
||||
@@ -1,87 +0,0 @@
|
||||
<?xml version="1.0"?> <!-- -*- Mode: SGML; indent-tabs-mode: nil; -*- -->
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the Netscape Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/NPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The Original Code is mozilla.org code.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
Ben Goodger <ben@netscape.com> (Original Author, v2.0)
|
||||
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://communicator/skin/sidebar/sidebarListView.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://communicator/skin/bookmarks/bookmarksWindow.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://communicator/content/bookmarks/bookmarks.css" type="text/css"?>
|
||||
|
||||
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://communicator/content/bookmarks/bookmarksOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://communicator/content/tasksOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://communicator/content/communicatorOverlay.xul"?>
|
||||
|
||||
<!DOCTYPE window SYSTEM "chrome://communicator/locale/bookmarks/bookmarks.dtd">
|
||||
|
||||
<page id="bookmarksPanel"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="Startup();" elementtofocus="bookmarks-view">
|
||||
|
||||
<!-- XXX - would like to cut this dependency out -->
|
||||
<script type="application/x-javascript" src="chrome://global/content/strres.js"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/globalOverlay.js"/>
|
||||
|
||||
<!-- Bookmarks Shell -->
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksOverlay.js"/>
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksPanel.js"/>
|
||||
|
||||
<!-- Drag and Drop -->
|
||||
<script type="application/x-javascript" src="chrome://global/content/nsDragAndDrop.js"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/nsTransferable.js"/>
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksDD.js"/>
|
||||
|
||||
|
||||
<!-- context menu, tooltips, etc -->
|
||||
<popupset id="bookmarksPopupset"/>
|
||||
|
||||
<!-- bookmarks string bundle -->
|
||||
<stringbundleset id="stringbundleset"/>
|
||||
|
||||
<!-- bookmarks & edit commands -->
|
||||
<commands id="commands">
|
||||
<commandset id="CommandUpdate_Bookmarks"
|
||||
commandupdater="true"
|
||||
events="click,focus"
|
||||
oncommandupdate="document.getElementById('bookmarks-view').onCommandUpdate();">
|
||||
</commandset>
|
||||
<commandset id="bookmarksItems"/>
|
||||
</commands>
|
||||
|
||||
<hbox id="panel-bar" class="toolbar">
|
||||
<toolbarbutton id="btnAddBookmark" label="&command.addBookmark.label;"
|
||||
oncommand="addBookmark();"/>
|
||||
<toolbarbutton id="btnManageBookmarks" label="&command.manageBookmarks.label;"
|
||||
oncommand="manageBookmarks();"/>
|
||||
<spacer flex="1"/>
|
||||
<toolbarseparator/>
|
||||
<toolbarbutton id="btnFindBookmarks" label="&command.findBookmarks.label;"
|
||||
oncommand="document.getElementById('bookmarks-view').openFindDialog();"/>
|
||||
</hbox>
|
||||
|
||||
<bookmarks-tree id="bookmarks-view" class="sidebar" type="single-column" flex="1"/>
|
||||
|
||||
</page>
|
||||
@@ -1,387 +0,0 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
var NC_NAMESPACE_URI = "http://home.netscape.com/NC-rdf#";
|
||||
|
||||
// XXX MAKE SURE that the "url" field is LAST!
|
||||
// This is important for what happens if/when the URL itself is changed.
|
||||
// Ask rjc@netscape.com if you want to know why exactly this is.
|
||||
|
||||
// This is the set of fields that are visible in the window.
|
||||
var gFields = ["name", "shortcut", "description", "url"];
|
||||
|
||||
// ...and this is a parallel array that contains the RDF properties
|
||||
// that they are associated with.
|
||||
var gProperties = [NC_NAMESPACE_URI + "Name",
|
||||
NC_NAMESPACE_URI + "ShortcutURL",
|
||||
NC_NAMESPACE_URI + "Description",
|
||||
NC_NAMESPACE_URI + "URL"];
|
||||
|
||||
var RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"]
|
||||
.getService(Components.interfaces.nsIRDFService);
|
||||
|
||||
var RDFC = Components.classes["@mozilla.org/rdf/container-utils;1"]
|
||||
.getService(Components.interfaces.nsIRDFContainerUtils);
|
||||
|
||||
var Bookmarks = RDF.GetDataSource("rdf:bookmarks");
|
||||
|
||||
var gBookmarkURL = "";
|
||||
|
||||
function Init()
|
||||
{
|
||||
var x;
|
||||
gBookmarkURL = window.arguments[0];
|
||||
|
||||
// Initialize the properties panel by copying the values from the
|
||||
// RDF graph into the fields on screen.
|
||||
|
||||
for (var i = 0; i < gFields.length; ++i) {
|
||||
var field = document.getElementById(gFields[i]);
|
||||
|
||||
var value = Bookmarks.GetTarget(RDF.GetResource(gBookmarkURL),
|
||||
RDF.GetResource(gProperties[i]),
|
||||
true);
|
||||
|
||||
if (value)
|
||||
value = value.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
||||
|
||||
if (value) //make sure were aren't stuffing null into any fields
|
||||
field.value = value;
|
||||
}
|
||||
|
||||
var propsWindow = document.getElementById("bmPropsWindow");
|
||||
var nameNode = document.getElementById("name");
|
||||
var title = propsWindow.getAttribute("title");
|
||||
title = title.replace(/\*\*bm_title\*\*/gi, nameNode.value);
|
||||
propsWindow.setAttribute("title", title);
|
||||
|
||||
// check bookmark schedule
|
||||
value = Bookmarks.GetTarget(RDF.GetResource(gBookmarkURL),
|
||||
RDF.GetResource("http://home.netscape.com/WEB-rdf#Schedule"),
|
||||
true);
|
||||
|
||||
if (value) {
|
||||
value = value.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
||||
|
||||
if (value) {
|
||||
var values = value.split("|");
|
||||
if (values.length == 4) {
|
||||
// get day range
|
||||
var days = values[0];
|
||||
var dayNode = document.getElementById("dayRange");
|
||||
var dayItems = dayNode.childNodes[0].childNodes;
|
||||
for (x=0; x < dayItems.length; ++x) {
|
||||
if (dayItems[x].getAttribute("value") == days) {
|
||||
dayNode.selectedItem = dayItems[x];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// get hour range
|
||||
var hours = values[1].split("-");
|
||||
var startHour = "";
|
||||
var endHour = "";
|
||||
|
||||
if (hours.length == 2) {
|
||||
startHour = hours[0];
|
||||
endHour = hours[1];
|
||||
}
|
||||
|
||||
// set start hour
|
||||
var startHourNode = document.getElementById("startHourRange");
|
||||
var startHourItems = startHourNode.childNodes[0].childNodes;
|
||||
for (x=0; x < startHourItems.length; ++x) {
|
||||
if (startHourItems[x].getAttribute("value") == startHour) {
|
||||
startHourNode.selectedItem = startHourItems[x];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// set end hour
|
||||
var endHourNode = document.getElementById("endHourRange");
|
||||
var endHourItems = endHourNode.childNodes[0].childNodes;
|
||||
for (x=0; x < endHourItems.length; ++x) {
|
||||
if (endHourItems[x].getAttribute("value") == endHour) {
|
||||
endHourNode.selectedItem = endHourItems[x];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// get duration
|
||||
var duration = values[2];
|
||||
var durationNode = document.getElementById("duration");
|
||||
durationNode.value = duration;
|
||||
|
||||
// get notification method
|
||||
var method = values[3];
|
||||
if (method.indexOf("icon") >= 0)
|
||||
document.getElementById("bookmarkIcon").checked = true;
|
||||
|
||||
if (method.indexOf("sound") >= 0)
|
||||
document.getElementById("playSound").checked = true;
|
||||
|
||||
if (method.indexOf("alert") >= 0)
|
||||
document.getElementById("showAlert").checked = true;
|
||||
|
||||
if (method.indexOf("open") >= 0)
|
||||
document.getElementById("openWindow").checked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if its a container, disable some things
|
||||
var isContainerFlag = RDFC.IsContainer(Bookmarks, RDF.GetResource(gBookmarkURL));
|
||||
if (!isContainerFlag) {
|
||||
// XXX To do: the "RDFC.IsContainer" call above only works for RDF sequences;
|
||||
// if its not a RDF sequence, we should to more checking to see if
|
||||
// the item in question is really a container of not. A good example
|
||||
// of this is the "File System" container.
|
||||
}
|
||||
|
||||
if (isContainerFlag) {
|
||||
// If it is a folder, it has no URL or Keyword
|
||||
document.getElementById("locationrow").setAttribute("hidden", "true");
|
||||
document.getElementById("shortcutrow").setAttribute("hidden", "true");
|
||||
}
|
||||
|
||||
if (gBookmarkURL.substr(0, 7).toLowerCase() != "http://" &&
|
||||
gBookmarkURL.substr(0, 8).toLowerCase() != "https://") {
|
||||
// only allow scheduling of http/https URLs
|
||||
document.getElementById("ScheduleTab").setAttribute("hidden", "true");
|
||||
document.getElementById("NotifyTab").setAttribute("hidden", "true");
|
||||
}
|
||||
|
||||
sizeToContent();
|
||||
|
||||
// Set up the enabled of controls on the scheduling panels
|
||||
dayRangeChange(document.getElementById("dayRange"));
|
||||
|
||||
// set initial focus
|
||||
var name = document.getElementById("name");
|
||||
name.focus();
|
||||
name.select();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function Commit()
|
||||
{
|
||||
var changed = false;
|
||||
|
||||
// Grovel through the fields to see if any of the values have
|
||||
// changed. If so, update the RDF graph and force them to be saved
|
||||
// to disk.
|
||||
for (var i = 0; i < gFields.length; ++i) {
|
||||
var field = document.getElementById(gFields[i]);
|
||||
|
||||
if (field) {
|
||||
// Get the new value as a literal, using 'null' if the value is empty.
|
||||
var newvalue = field.value;
|
||||
|
||||
var oldvalue = Bookmarks.GetTarget(RDF.GetResource(gBookmarkURL),
|
||||
RDF.GetResource(gProperties[i]),
|
||||
true);
|
||||
|
||||
if (oldvalue)
|
||||
oldvalue = oldvalue.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
||||
|
||||
if (newvalue && gProperties[i] == (NC_NAMESPACE_URI + "ShortcutURL")) {
|
||||
// shortcuts are always lowercased internally
|
||||
newvalue = newvalue.toLowerCase();
|
||||
}
|
||||
else if (newvalue && gProperties[i] == (NC_NAMESPACE_URI + "URL")) {
|
||||
// we're dealing with the URL attribute;
|
||||
// if a scheme isn't specified, use "http://"
|
||||
if (newvalue.indexOf(":") < 0)
|
||||
newvalue = "http://" + newvalue;
|
||||
}
|
||||
|
||||
if (newvalue)
|
||||
newvalue = RDF.GetLiteral(newvalue);
|
||||
|
||||
if (updateAttribute(gProperties[i], oldvalue, newvalue)) {
|
||||
// Update gBookmarkURL if the url changed
|
||||
if (newvalue && gProperties[i] == NC_NAMESPACE_URI + "URL")
|
||||
gBookmarkURL = newvalue.Value;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update bookmark schedule if necessary;
|
||||
// if the tab was removed, just skip it
|
||||
var scheduleTab = document.getElementById("ScheduleTab");
|
||||
if (scheduleTab) {
|
||||
var scheduleRes = "http://home.netscape.com/WEB-rdf#Schedule";
|
||||
oldvalue = Bookmarks.GetTarget(RDF.GetResource(gBookmarkURL),
|
||||
RDF.GetResource(scheduleRes), true);
|
||||
newvalue = "";
|
||||
var dayRangeNode = document.getElementById("dayRange");
|
||||
var dayRange = dayRangeNode.selectedItem.getAttribute("value");
|
||||
|
||||
if (dayRange) {
|
||||
var startHourRangeNode = document.getElementById("startHourRange");
|
||||
var startHourRange = startHourRangeNode.selectedItem.getAttribute("value");
|
||||
|
||||
var endHourRangeNode = document.getElementById("endHourRange");
|
||||
var endHourRange = endHourRangeNode.selectedItem.getAttribute("value");
|
||||
|
||||
if (parseInt(startHourRange) > parseInt(endHourRange)) {
|
||||
var temp = startHourRange;
|
||||
startHourRange = endHourRange;
|
||||
endHourRange = temp;
|
||||
}
|
||||
|
||||
var bookmarkBundle;
|
||||
var duration = document.getElementById("duration").value;
|
||||
if (!duration) {
|
||||
bookmarkBundle = document.getElementById("bundle_bookmark");
|
||||
alert (bookmarkBundle.getString("pleaseEnterADuration"));
|
||||
return false;
|
||||
}
|
||||
|
||||
var methods = [];
|
||||
if (document.getElementById("bookmarkIcon").checked)
|
||||
methods.push("icon");
|
||||
if (document.getElementById("playSound").checked)
|
||||
methods.push("sound");
|
||||
if (document.getElementById("showAlert").checked)
|
||||
methods.push("alert");
|
||||
if (document.getElementById("openWindow").checked)
|
||||
methods.push("open");
|
||||
|
||||
if (methods.length == 0) {
|
||||
bookmarkBundle = document.getElementById("bundle_bookmark");
|
||||
alert (bookmarkBundle.getString("pleaseSelectANotification"));
|
||||
return false;
|
||||
}
|
||||
|
||||
var method = methods.join(); // join string in array with ","
|
||||
|
||||
newvalue = dayRange + "|" + startHourRange + "-" + endHourRange + "|" + duration + "|" + method;
|
||||
}
|
||||
|
||||
if (newvalue)
|
||||
newvalue = RDF.GetLiteral(newvalue);
|
||||
|
||||
if (updateAttribute(scheduleRes, oldvalue, newvalue))
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
var remote = Bookmarks.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
|
||||
if (remote)
|
||||
remote.Flush();
|
||||
}
|
||||
|
||||
window.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
function updateAttribute(prop, oldvalue, newvalue)
|
||||
{
|
||||
var changed = false;
|
||||
|
||||
if (prop && (oldvalue || newvalue) && oldvalue != newvalue) {
|
||||
|
||||
if (oldvalue && !newvalue) {
|
||||
Bookmarks.Unassert(RDF.GetResource(gBookmarkURL),
|
||||
RDF.GetResource(prop),
|
||||
oldvalue);
|
||||
}
|
||||
else if (!oldvalue && newvalue) {
|
||||
Bookmarks.Assert(RDF.GetResource(gBookmarkURL),
|
||||
RDF.GetResource(prop),
|
||||
newvalue,
|
||||
true);
|
||||
}
|
||||
else /* if (oldvalue && newvalue) */ {
|
||||
Bookmarks.Change(RDF.GetResource(gBookmarkURL),
|
||||
RDF.GetResource(prop),
|
||||
oldvalue,
|
||||
newvalue);
|
||||
}
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
function setEndHourRange()
|
||||
{
|
||||
// Get the values of the start-time and end-time as ints
|
||||
var startHourRangeNode = document.getElementById("startHourRange");
|
||||
var startHourRange = startHourRangeNode.selectedItem.getAttribute("value");
|
||||
var startHourRangeInt = parseInt(startHourRange);
|
||||
|
||||
var endHourRangeNode = document.getElementById("endHourRange");
|
||||
var endHourRange = endHourRangeNode.selectedItem.getAttribute("value");
|
||||
var endHourRangeInt = parseInt(endHourRange);
|
||||
|
||||
var endHourItemNode = endHourRangeNode.firstChild.firstChild;
|
||||
|
||||
var index = 0;
|
||||
|
||||
// disable all those end-times before the start-time
|
||||
for (; index < startHourRangeInt; ++index) {
|
||||
endHourItemNode.setAttribute("disabled", "true");
|
||||
endHourItemNode = endHourItemNode.nextSibling;
|
||||
}
|
||||
|
||||
// update the selected value if it's out of the allowed range
|
||||
if (startHourRangeInt >= endHourRangeInt)
|
||||
endHourRangeNode.selectedItem = endHourItemNode;
|
||||
|
||||
// make sure all the end-times after the start-time are enabled
|
||||
for (; index < 24; ++index) {
|
||||
endHourItemNode.removeAttribute("disabled");
|
||||
endHourItemNode = endHourItemNode.nextSibling;
|
||||
}
|
||||
}
|
||||
|
||||
function dayRangeChange (aMenuList)
|
||||
{
|
||||
var controls = ["startHourRange", "endHourRange", "duration", "bookmarkIcon",
|
||||
"showAlert", "openWindow", "playSound", "durationSubLabel",
|
||||
"durationLabel", "startHourRangeLabel", "endHourRangeLabel"];
|
||||
for (var i = 0; i < controls.length; ++i)
|
||||
document.getElementById(controls[i]).disabled = !aMenuList.value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,235 +0,0 @@
|
||||
<?xml version="1.0"?> <!-- -*- Mode: SGML; indent-tabs-mode: nil; -*- -->
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the Netscape Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/NPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The Original Code is mozilla.org code.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://communicator/skin/bookmarks/bookmarks.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd" >
|
||||
%brandDTD;
|
||||
<!ENTITY % bmpropsDTD SYSTEM "chrome://communicator/locale/bookmarks/bm-props.dtd">
|
||||
%bmpropsDTD;
|
||||
]>
|
||||
|
||||
<dialog id="bmPropsWindow" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="&bookmarks.windowtitle.label;"
|
||||
onload="Init()" style="width: 30em;"
|
||||
ondialogaccept="return Commit();">
|
||||
|
||||
<stringbundle id="bundle_bookmark" src="chrome://communicator/locale/bookmarks/bookmark.properties"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/globalOverlay.js"/>
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bm-props.js"/>
|
||||
|
||||
<keyset id="keyset"/>
|
||||
|
||||
<tabbox>
|
||||
<tabs>
|
||||
<tab label="&generalInfo.label;" accesskey="&generalInfo.accesskey;"/>
|
||||
<tab id="ScheduleTab" label="&schedule.label;" accesskey="&schedule.accesskey;"/>
|
||||
<tab id="NotifyTab" label="¬ification.label;" accesskey="¬ification.accesskey;"/>
|
||||
</tabs>
|
||||
<tabpanels>
|
||||
<vbox>
|
||||
<separator class="thin"/>
|
||||
<hbox align="start">
|
||||
<image class="message-icon"/>
|
||||
<separator class="thin" orient="vertical"/>
|
||||
<description flex="1">&generaldesc.label;</description>
|
||||
</hbox>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
||||
<vbox class="box-padded">
|
||||
<grid>
|
||||
<columns>
|
||||
<column />
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row align="center">
|
||||
<label value="&bookmarks.name.label;" control="name"/>
|
||||
<textbox id="name"/>
|
||||
</row>
|
||||
<row id="locationrow" align="center">
|
||||
<label value="&bookmarks.location.label;" control="url"/>
|
||||
<textbox id="url" />
|
||||
</row>
|
||||
<row id="shortcutrow" align="center">
|
||||
<label value="&bookmarks.shortcut.label;" control="shortcut"/>
|
||||
<textbox id="shortcut" />
|
||||
</row>
|
||||
<row>
|
||||
<label value="&bookmarks.description.label;" control="description"/>
|
||||
<textbox multiline="true" wrap="virtual" id="description" flex="1"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<separator/>
|
||||
</vbox>
|
||||
</vbox>
|
||||
|
||||
<vbox>
|
||||
<separator class="thin"/>
|
||||
<hbox align="center">
|
||||
<image id="schedule-icon"/>
|
||||
<separator class="thin" orient="vertical"/>
|
||||
<description flex="1">&schedule.description;</description>
|
||||
</hbox>
|
||||
<separator class="thin"/>
|
||||
<hbox class="box-padded">
|
||||
<spacer flex="1"/>
|
||||
<groupbox>
|
||||
<caption label="&checkforupdates.legend.label;"/>
|
||||
<grid flex="1">
|
||||
<columns>
|
||||
<column/>
|
||||
<column flex="1"/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row align="center">
|
||||
<label value="&when.label;" control="dayRange"/>
|
||||
<hbox>
|
||||
<menulist id="dayRange" oncommand="dayRangeChange(this);">
|
||||
<menupopup>
|
||||
<menuitem value="" label="&checknever.label;"/>
|
||||
<menuseparator />
|
||||
<menuitem value="0123456" label="&checkeveryday.label;"/>
|
||||
<menuitem value="12345" label="&checkweekdays.label;"/>
|
||||
<menuitem value="06" label="&checkweekends.label;"/>
|
||||
<menuitem value="1" label="&checkmondays.label;"/>
|
||||
<menuitem value="2" label="&checktuesdays.label;"/>
|
||||
<menuitem value="3" label="&checkwednesdays.label;"/>
|
||||
<menuitem value="4" label="&checkthursdays.label;"/>
|
||||
<menuitem value="5" label="&checkfridays.label;"/>
|
||||
<menuitem value="6" label="&checksaturdays.label;"/>
|
||||
<menuitem value="0" label="&checksundays.label;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</hbox>
|
||||
</row>
|
||||
<row align="center">
|
||||
<label id="startHourRangeLabel"
|
||||
value="&from.label;" control="startHourRange"/>
|
||||
<hbox align="center">
|
||||
<menulist id="startHourRange" oncommand="setEndHourRange()">
|
||||
<menupopup>
|
||||
<menuitem value="0" label="&midnight.label;"/>
|
||||
<menuitem value="1" label="&AMone.label;"/>
|
||||
<menuitem value="2" label="&AMtwo.label;"/>
|
||||
<menuitem value="3" label="&AMthree.label;"/>
|
||||
<menuitem value="4" label="&AMfour.label;"/>
|
||||
<menuitem value="5" label="&AMfive.label;"/>
|
||||
<menuitem value="6" label="&AMsix.label;"/>
|
||||
<menuitem value="7" label="&AMseven.label;"/>
|
||||
<menuitem value="8" label="&AMeight.label;"/>
|
||||
<menuitem value="9" label="&AMnine.label;"/>
|
||||
<menuitem value="10" label="&AMten.label;"/>
|
||||
<menuitem value="11" label="&AMeleven.label;"/>
|
||||
<menuitem value="12" label="&noon.label;"/>
|
||||
<menuitem value="13" label="&PMone.label;"/>
|
||||
<menuitem value="14" label="&PMtwo.label;"/>
|
||||
<menuitem value="15" label="&PMthree.label;"/>
|
||||
<menuitem value="16" label="&PMfour.label;"/>
|
||||
<menuitem value="17" label="&PMfive.label;"/>
|
||||
<menuitem value="18" label="&PMsix.label;"/>
|
||||
<menuitem value="19" label="&PMseven.label;"/>
|
||||
<menuitem value="20" label="&PMeight.label;"/>
|
||||
<menuitem value="21" label="&PMnine.label;"/>
|
||||
<menuitem value="22" label="&PMten.label;"/>
|
||||
<menuitem value="23" label="&PMeleven.label;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<label id="endHourRangeLabel"
|
||||
value="&to.label;" control="endHourRange"/>
|
||||
<menulist id="endHourRange">
|
||||
<menupopup onpopupshowing="setEndHourRange()">
|
||||
<menuitem value="1" label="&AMone.label;"/>
|
||||
<menuitem value="2" label="&AMtwo.label;"/>
|
||||
<menuitem value="3" label="&AMthree.label;"/>
|
||||
<menuitem value="4" label="&AMfour.label;"/>
|
||||
<menuitem value="5" label="&AMfive.label;"/>
|
||||
<menuitem value="6" label="&AMsix.label;"/>
|
||||
<menuitem value="7" label="&AMseven.label;"/>
|
||||
<menuitem value="8" label="&AMeight.label;"/>
|
||||
<menuitem value="9" label="&AMnine.label;"/>
|
||||
<menuitem value="10" label="&AMten.label;"/>
|
||||
<menuitem value="11" label="&AMeleven.label;"/>
|
||||
<menuitem value="12" label="&noon.label;"/>
|
||||
<menuitem value="13" label="&PMone.label;"/>
|
||||
<menuitem value="14" label="&PMtwo.label;"/>
|
||||
<menuitem value="15" label="&PMthree.label;"/>
|
||||
<menuitem value="16" label="&PMfour.label;"/>
|
||||
<menuitem value="17" label="&PMfive.label;"/>
|
||||
<menuitem value="18" label="&PMsix.label;"/>
|
||||
<menuitem value="19" label="&PMseven.label;"/>
|
||||
<menuitem value="20" label="&PMeight.label;"/>
|
||||
<menuitem value="21" label="&PMnine.label;"/>
|
||||
<menuitem value="22" label="&PMten.label;"/>
|
||||
<menuitem value="23" label="&PMeleven.label;"/>
|
||||
<menuitem value="24" label="&midnight.label;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</hbox>
|
||||
</row>
|
||||
<row align="center">
|
||||
<label id="durationLabel"
|
||||
value="&every.label;" control="duration"/>
|
||||
<hbox align="center">
|
||||
<textbox id="duration" size="4" value="60" />
|
||||
<label id="durationSubLabel" value="&minutes.label;" />
|
||||
</hbox>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
<separator class="thin"/>
|
||||
</groupbox>
|
||||
<spacer flex="1"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
<vbox>
|
||||
<separator class="thin"/>
|
||||
<hbox align="start">
|
||||
<image id="notification-icon"/>
|
||||
<separator class="thin" orient="vertical"/>
|
||||
<description flex="1">¬ification.description;</description>
|
||||
</hbox>
|
||||
<separator class="thin"/>
|
||||
<hbox class="box-padded">
|
||||
<spacer flex="1"/>
|
||||
<groupbox>
|
||||
<caption label="¬ifications.legend.label;" />
|
||||
<vbox align="start">
|
||||
<checkbox id="bookmarkIcon" label="¬ification.icon.label;" />
|
||||
<checkbox id="showAlert" label="¬ification.alert.label;" />
|
||||
<checkbox id="openWindow" label="¬ification.window.label;" />
|
||||
<checkbox id="playSound" label="¬ification.sound.label;" />
|
||||
</vbox>
|
||||
</groupbox>
|
||||
<spacer flex="1"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
</dialog>
|
||||
@@ -1,854 +0,0 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
This is the old bookmarks code, included here for the sake of the bookmarks sidebar panel,
|
||||
which will be fixed to use my new code in .9. In the mean time, this file provides a
|
||||
life line to various functionality.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
var NC_NS = "http://home.netscape.com/NC-rdf#";
|
||||
var RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
|
||||
|
||||
function Init() {
|
||||
var tree = document.getElementById("bookmarksTree");
|
||||
tree.controllers.appendController(BookmarksController);
|
||||
var children = document.getElementById('treechildren-bookmarks');
|
||||
tree.selectItem(children.firstChild);
|
||||
tree.focus();
|
||||
|
||||
RefreshSort();
|
||||
}
|
||||
|
||||
var BookmarksController = {
|
||||
supportsCommand: function(command)
|
||||
{
|
||||
switch(command)
|
||||
{
|
||||
case "cmd_undo":
|
||||
case "cmd_redo":
|
||||
return false;
|
||||
case "cmd_cut":
|
||||
case "cmd_copy":
|
||||
case "cmd_paste":
|
||||
case "cmd_delete":
|
||||
case "cmd_selectAll":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
},
|
||||
isCommandEnabled: function(command)
|
||||
{
|
||||
switch(command)
|
||||
{
|
||||
case "cmd_undo":
|
||||
case "cmd_redo":
|
||||
return false;
|
||||
case "cmd_cut":
|
||||
case "cmd_copy":
|
||||
case "cmd_paste":
|
||||
case "cmd_delete":
|
||||
case "cmd_selectAll":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
},
|
||||
doCommand: function(command)
|
||||
{
|
||||
switch(command)
|
||||
{
|
||||
case "cmd_undo":
|
||||
case "cmd_redo":
|
||||
break;
|
||||
case "cmd_cut":
|
||||
doCut();
|
||||
break;
|
||||
case "cmd_copy":
|
||||
doCopy();
|
||||
break;
|
||||
case "cmd_paste":
|
||||
doPaste();
|
||||
break;
|
||||
case "cmd_delete":
|
||||
doDelete();
|
||||
break;
|
||||
case "cmd_selectAll":
|
||||
doSelectAll();
|
||||
break;
|
||||
}
|
||||
},
|
||||
onEvent: function(event)
|
||||
{
|
||||
// On blur events set the menu item texts back to the normal values
|
||||
/*if (event == 'blur' )
|
||||
{
|
||||
goSetMenuValue('cmd_undo', 'valueDefault');
|
||||
goSetMenuValue('cmd_redo', 'valueDefault');
|
||||
}*/
|
||||
}
|
||||
};
|
||||
|
||||
function CommandUpdate_Bookmarks()
|
||||
{
|
||||
//goUpdateCommand('button_delete');
|
||||
// get selection info from dir pane
|
||||
/*
|
||||
var oneAddressBookSelected = false;
|
||||
if ( dirTree && dirTree.selectedItems && (dirTree.selectedItems.length == 1) )
|
||||
oneAddressBookSelected = true;
|
||||
|
||||
// get selection info from results pane
|
||||
var selectedCards = GetSelectedAddresses();
|
||||
var oneOrMoreCardsSelected = false;
|
||||
if ( selectedCards )
|
||||
oneOrMoreCardsSelected = true;
|
||||
*/
|
||||
// set commands to enabled / disabled
|
||||
//goSetCommandEnabled('cmd_PrintCard', oneAddressBookSelected);
|
||||
goSetCommandEnabled('bm_cmd_find', true/*oneAddressBookSelected*/);
|
||||
}
|
||||
|
||||
function copySelectionToClipboard()
|
||||
{
|
||||
var treeNode = document.getElementById("bookmarksTree");
|
||||
if (!treeNode) return false;
|
||||
var select_list = treeNode.selectedItems;
|
||||
if (!select_list) return false;
|
||||
if (select_list.length < 1) return false;
|
||||
|
||||
var rdf_uri = "@mozilla.org/rdf/rdf-service;1"
|
||||
var RDF = Components.classes[rdf_uri].getService();
|
||||
RDF = RDF.QueryInterface(Components.interfaces.nsIRDFService);
|
||||
if (!RDF) return false;
|
||||
|
||||
var Bookmarks = RDF.GetDataSource("rdf:bookmarks");
|
||||
if (!Bookmarks) return false;
|
||||
|
||||
var nameRes = RDF.GetResource(NC_NS + "Name");
|
||||
if (!nameRes) return false;
|
||||
|
||||
// Build a url that encodes all the select nodes
|
||||
// as well as their parent nodes
|
||||
var url = "";
|
||||
var text = "";
|
||||
var html = "";
|
||||
|
||||
for (var nodeIndex = 0; nodeIndex < select_list.length; nodeIndex++)
|
||||
{
|
||||
var node = select_list[nodeIndex];
|
||||
if (!node) continue;
|
||||
|
||||
var ID = getAbsoluteID("bookmarksTree", node);
|
||||
if (!ID) continue;
|
||||
|
||||
var IDRes = RDF.GetResource(ID);
|
||||
if (!IDRes) continue;
|
||||
var nameNode = Bookmarks.GetTarget(IDRes, nameRes, true);
|
||||
var theName = "";
|
||||
if (nameNode)
|
||||
nameNode =
|
||||
nameNode.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
||||
if (nameNode) theName = nameNode.Value;
|
||||
|
||||
url += "ID:{" + ID + "};";
|
||||
url += "NAME:{" + theName + "};";
|
||||
|
||||
if (node.getAttribute("container") == "true")
|
||||
{
|
||||
var type = node.getAttribute("type");
|
||||
if (type == NC_NS + "BookmarkSeparator")
|
||||
{
|
||||
// Note: can't encode separators in text, just html
|
||||
html += "<hr><p>";
|
||||
}
|
||||
else
|
||||
{
|
||||
text += ID + "\r";
|
||||
|
||||
html += "<a href='" + ID + "'>";
|
||||
if (theName != "")
|
||||
{
|
||||
html += theName;
|
||||
}
|
||||
html += "</a><p>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (url == "") return false;
|
||||
|
||||
// get some useful components
|
||||
var trans_uri = "@mozilla.org/widget/transferable;1";
|
||||
var trans = Components.classes[trans_uri].createInstance();
|
||||
if (trans) trans = trans.QueryInterface(Components.interfaces.nsITransferable);
|
||||
if (!trans) return false;
|
||||
|
||||
var clip_uri = "@mozilla.org/widget/clipboard;1";
|
||||
var clip = Components.classes[clip_uri].getService();
|
||||
if (clip) clip = clip.QueryInterface(Components.interfaces.nsIClipboard);
|
||||
if (!clip) return false;
|
||||
clip.emptyClipboard(Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||
|
||||
// save bookmark's ID
|
||||
trans.addDataFlavor("moz/bookmarkclipboarditem");
|
||||
var data_uri = "@mozilla.org/supports-wstring;1";
|
||||
var data = Components.classes[data_uri].createInstance();
|
||||
if (data) {
|
||||
data = data.QueryInterface(Components.interfaces.nsISupportsWString);
|
||||
}
|
||||
if (!data) return false;
|
||||
data.data = url;
|
||||
// double byte data
|
||||
trans.setTransferData("moz/bookmarkclipboarditem", data, url.length*2);
|
||||
|
||||
if (text != "")
|
||||
{
|
||||
trans.addDataFlavor("text/unicode");
|
||||
|
||||
var textData_uri = "@mozilla.org/supports-wstring;1";
|
||||
var textData = Components.classes[textData_uri].createInstance();
|
||||
if (textData) textData = textData.QueryInterface(Components.interfaces.nsISupportsWString);
|
||||
if (!textData) return false;
|
||||
textData.data = text;
|
||||
// double byte data
|
||||
trans.setTransferData("text/unicode", textData, text.length*2);
|
||||
}
|
||||
if (html != "")
|
||||
{
|
||||
trans.addDataFlavor("text/html");
|
||||
|
||||
var wstring_uri = "@mozilla.org/supports-wstring;1";
|
||||
var htmlData = Components.classes[wstring_uri].createInstance();
|
||||
if (htmlData) {
|
||||
var wstring_interface = Components.interfaces.nsISupportsWString;
|
||||
htmlData = htmlData.QueryInterface(wstring_interface);
|
||||
}
|
||||
if (!htmlData) return false;
|
||||
htmlData.data = html;
|
||||
// double byte data
|
||||
trans.setTransferData("text/html", htmlData, html.length*2);
|
||||
}
|
||||
clip.setData(trans, null,
|
||||
Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||
return true;
|
||||
}
|
||||
|
||||
function doCut()
|
||||
{
|
||||
if (copySelectionToClipboard() == true) {
|
||||
doDelete(false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function doCopy()
|
||||
{
|
||||
copySelectionToClipboard();
|
||||
return true;
|
||||
}
|
||||
|
||||
function doPaste()
|
||||
{
|
||||
var treeNode = document.getElementById("bookmarksTree");
|
||||
if (!treeNode) return false;
|
||||
var select_list = treeNode.selectedItems;
|
||||
if (!select_list) return false;
|
||||
if (select_list.length != 1) return false;
|
||||
|
||||
var pasteNodeID = select_list[0].getAttribute("id");
|
||||
var isContainerFlag = (select_list[0].getAttribute("container") == "true");
|
||||
|
||||
var clip_uri = "@mozilla.org/widget/clipboard;1";
|
||||
var clip = Components.classes[clip_uri].getService();
|
||||
if (clip) clip = clip.QueryInterface(Components.interfaces.nsIClipboard);
|
||||
if (!clip) return false;
|
||||
|
||||
var trans_uri = "@mozilla.org/widget/transferable;1";
|
||||
var trans = Components.classes[trans_uri].createInstance();
|
||||
if (trans) {
|
||||
trans = trans.QueryInterface(Components.interfaces.nsITransferable);
|
||||
}
|
||||
if (!trans) return false;
|
||||
trans.addDataFlavor("moz/bookmarkclipboarditem");
|
||||
|
||||
clip.getData(trans, Components.interfaces.nsIClipboard.kGlobalClipboard);
|
||||
var data = new Object();
|
||||
var dataLen = new Object();
|
||||
trans.getTransferData("moz/bookmarkclipboarditem", data, dataLen);
|
||||
if (data) {
|
||||
var data_interface = Components.interfaces.nsISupportsWString
|
||||
data = data.value.QueryInterface(data_interface);
|
||||
}
|
||||
var url = null;
|
||||
// double byte data
|
||||
if (data) url = data.data.substring(0, dataLen.value / 2);
|
||||
if (!url) return false;
|
||||
|
||||
var strings = url.split(";");
|
||||
if (!strings) return false;
|
||||
|
||||
var rdf_uri = "@mozilla.org/rdf/rdf-service;1";
|
||||
var RDF = Components.classes[rdf_uri].getService();
|
||||
RDF = RDF.QueryInterface(Components.interfaces.nsIRDFService);
|
||||
if (!RDF) return false;
|
||||
var rdfc_uri = "@mozilla.org/rdf/container;1";
|
||||
var RDFC = Components.classes[rdfc_uri].getService();
|
||||
RDFC = RDFC.QueryInterface(Components.interfaces.nsIRDFContainer);
|
||||
if (!RDFC) return false;
|
||||
var Bookmarks = RDF.GetDataSource("rdf:bookmarks");
|
||||
if (!Bookmarks) return false;
|
||||
|
||||
var nameRes = RDF.GetResource(NC_NS + "Name");
|
||||
if (!nameRes) return false;
|
||||
|
||||
pasteNodeRes = RDF.GetResource(pasteNodeID);
|
||||
if (!pasteNodeRes) return false;
|
||||
var pasteContainerRes = null;
|
||||
var pasteNodeIndex = -1;
|
||||
if (isContainerFlag == true)
|
||||
{
|
||||
pasteContainerRes = pasteNodeRes;
|
||||
}
|
||||
else
|
||||
{
|
||||
var parID = select_list[0].parentNode.parentNode.getAttribute("ref");
|
||||
if (!parID) {
|
||||
parID = select_list[0].parentNode.parentNode.getAttribute("id");
|
||||
}
|
||||
if (!parID) return false;
|
||||
pasteContainerRes = RDF.GetResource(parID);
|
||||
if (!pasteContainerRes) return false;
|
||||
}
|
||||
RDFC.Init(Bookmarks, pasteContainerRes);
|
||||
|
||||
if (isContainerFlag == false)
|
||||
{
|
||||
pasteNodeIndex = RDFC.IndexOf(pasteNodeRes);
|
||||
if (pasteNodeIndex < 0) return false; // how did that happen?
|
||||
}
|
||||
|
||||
var typeRes = RDF.GetResource(RDF_NS + "type");
|
||||
if (!typeRes) return false;
|
||||
var bmTypeRes = RDF.GetResource(NC_NS + "Bookmark");
|
||||
if (!bmTypeRes) return false;
|
||||
|
||||
var dirty = false;
|
||||
for (var x=0; x<strings.length; x=x+2)
|
||||
{
|
||||
var theID = strings[x];
|
||||
var theName = strings[x+1];
|
||||
if ((theID.indexOf("ID:{") == 0) && (theName.indexOf("NAME:{") == 0))
|
||||
{
|
||||
theID = theID.substr(4, theID.length-5);
|
||||
theName = theName.substr(6, theName.length-7);
|
||||
|
||||
var IDRes = RDF.GetResource(theID);
|
||||
if (!IDRes) continue;
|
||||
|
||||
if (RDFC.IndexOf(IDRes) > 0)
|
||||
continue;
|
||||
|
||||
if (theName != "")
|
||||
{
|
||||
var NameLiteral = RDF.GetLiteral(theName);
|
||||
if (NameLiteral)
|
||||
{
|
||||
Bookmarks.Assert(IDRes, nameRes, NameLiteral, true);
|
||||
dirty = true;
|
||||
}
|
||||
}
|
||||
if (isContainerFlag == true)
|
||||
RDFC.AppendElement(IDRes);
|
||||
else
|
||||
RDFC.InsertElementAt(IDRes, pasteNodeIndex++, true);
|
||||
dirty = true;
|
||||
|
||||
// make sure appropriate bookmark type is set
|
||||
var bmTypeNode = Bookmarks.GetTarget( IDRes, typeRes, true );
|
||||
if (!bmTypeNode)
|
||||
{
|
||||
// set default bookmark type
|
||||
Bookmarks.Assert(IDRes, typeRes, bmTypeRes, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dirty == true)
|
||||
{
|
||||
var rdf_ds_interface = Components.interfaces.nsIRDFRemoteDataSource;
|
||||
var remote = Bookmarks.QueryInterface(rdf_ds_interface);
|
||||
if (remote)
|
||||
remote.Flush();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function doDelete(promptFlag)
|
||||
{
|
||||
var treeNode = document.getElementById("bookmarksTree");
|
||||
if (!treeNode) return false;
|
||||
var select_list = treeNode.selectedItems;
|
||||
if (!select_list) return false;
|
||||
if (select_list.length < 1) return false;
|
||||
|
||||
if (promptFlag == true)
|
||||
{
|
||||
var deleteStr = '';
|
||||
if (select_list.length == 1) {
|
||||
deleteStr = get_localized_string("DeleteItem");
|
||||
} else {
|
||||
deleteStr = get_localized_string("DeleteItems");
|
||||
}
|
||||
var ok = confirm(deleteStr);
|
||||
if (!ok) return false;
|
||||
}
|
||||
|
||||
var RDF_uri = "@mozilla.org/rdf/rdf-service;1";
|
||||
var RDF = Components.classes[RDF_uri].getService();
|
||||
RDF = RDF.QueryInterface(Components.interfaces.nsIRDFService);
|
||||
if (!RDF) return false;
|
||||
|
||||
var RDFC_uri = "@mozilla.org/rdf/container;1";
|
||||
var RDFC = Components.classes[RDFC_uri].getService();
|
||||
RDFC = RDFC.QueryInterface(Components.interfaces.nsIRDFContainer);
|
||||
if (!RDFC) return false;
|
||||
|
||||
var Bookmarks = RDF.GetDataSource("rdf:bookmarks");
|
||||
if (!Bookmarks) return false;
|
||||
|
||||
var dirty = false;
|
||||
|
||||
// note: backwards delete so that we handle odd deletion cases such as
|
||||
// deleting a child of a folder as well as the folder itself
|
||||
for (var nodeIndex=select_list.length-1; nodeIndex>=0; nodeIndex--)
|
||||
{
|
||||
var node = select_list[nodeIndex];
|
||||
if (!node) continue;
|
||||
var ID = node.getAttribute("id");
|
||||
if (!ID) continue;
|
||||
|
||||
// don't allow deletion of various "special" folders
|
||||
if ((ID == "NC:BookmarksRoot") || (ID == "NC:IEFavoritesRoot"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var parentID = node.parentNode.parentNode.getAttribute("ref");
|
||||
if (!parentID) parentID = node.parentNode.parentNode.getAttribute("id");
|
||||
if (!parentID) continue;
|
||||
|
||||
var IDRes = RDF.GetResource(ID);
|
||||
if (!IDRes) continue;
|
||||
var parentIDRes = RDF.GetResource(parentID);
|
||||
if (!parentIDRes) continue;
|
||||
|
||||
RDFC.Init(Bookmarks, parentIDRes);
|
||||
RDFC.RemoveElement(IDRes, true);
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if (dirty == true)
|
||||
{
|
||||
var remote = Bookmarks.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
|
||||
if (remote)
|
||||
remote.Flush();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function doSelectAll()
|
||||
{
|
||||
var treeNode = document.getElementById("bookmarksTree");
|
||||
if (!treeNode) return false;
|
||||
treeNode.selectAll();
|
||||
return true;
|
||||
}
|
||||
|
||||
function doUnload()
|
||||
{
|
||||
// Get the current window position/size.
|
||||
var x = window.screenX;
|
||||
var y = window.screenY;
|
||||
var h = window.outerHeight;
|
||||
var w = window.outerWidth;
|
||||
|
||||
// Store these into the window attributes (for persistence).
|
||||
var win = document.getElementById("bookmark-window");
|
||||
win.setAttribute("x", x);
|
||||
win.setAttribute("y", y);
|
||||
win.setAttribute("height", h);
|
||||
win.setAttribute("width", w);
|
||||
}
|
||||
|
||||
function BookmarkProperties()
|
||||
{
|
||||
var treeNode = document.getElementById('bookmarksTree');
|
||||
var select_list = treeNode.selectedItems;
|
||||
|
||||
if (select_list.length >= 1) {
|
||||
// don't bother showing properties on bookmark separators
|
||||
var type = select_list[0].getAttribute('type');
|
||||
if (type != NC_NS + "BookmarkSeparator") {
|
||||
window.openDialog("chrome://communicator/content/bookmarks/bm-props.xul",
|
||||
"_blank", "centerscreen,chrome,menubar",
|
||||
select_list[0].getAttribute("id"));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function OpenBookmarksFind()
|
||||
{
|
||||
window.openDialog("chrome://communicator/content/bookmarks/bm-find.xul",
|
||||
"FindBookmarksWindow",
|
||||
"dialog=no,close,chrome,resizable", "bookmarks");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function getAbsoluteID(root, node)
|
||||
{
|
||||
var url = node.getAttribute("ref");
|
||||
if ((url == null) || (url == ""))
|
||||
{
|
||||
url = node.getAttribute("id");
|
||||
}
|
||||
try
|
||||
{
|
||||
var rootNode = document.getElementById(root);
|
||||
var ds = null;
|
||||
if (rootNode)
|
||||
{
|
||||
ds = rootNode.database;
|
||||
}
|
||||
|
||||
// add support for anonymous resources such as Internet Search results,
|
||||
// IE favorites under Win32, and NetPositive URLs under BeOS
|
||||
var rdf_uri = "@mozilla.org/rdf/rdf-service;1";
|
||||
var rdf = Components.classes[rdf_uri].getService();
|
||||
if (rdf) rdf = rdf.QueryInterface(Components.interfaces.nsIRDFService);
|
||||
if (rdf && ds)
|
||||
{
|
||||
var src = rdf.GetResource(url, true);
|
||||
var prop = rdf.GetResource(NC_NS + "URL",
|
||||
true);
|
||||
var target = ds.GetTarget(src, prop, true);
|
||||
if (target) target = target.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
||||
if (target) target = target.Value;
|
||||
if (target) url = target;
|
||||
}
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
function OpenURL(event, node, root)
|
||||
{
|
||||
if ((event.button != 0) || (event.detail != 2)
|
||||
|| (node.nodeName != "treeitem"))
|
||||
return false;
|
||||
|
||||
if (node.getAttribute("container") == "true")
|
||||
return false;
|
||||
|
||||
var url = getAbsoluteID(root, node);
|
||||
|
||||
// Ignore "NC:" urls.
|
||||
if (url.substring(0, 3) == "NC:")
|
||||
return false;
|
||||
|
||||
if (event.altKey)
|
||||
{
|
||||
BookmarkProperties();
|
||||
}
|
||||
else
|
||||
{
|
||||
// get right sized window
|
||||
window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no", url);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
const nsIFilePicker = Components.interfaces.nsIFilePicker;
|
||||
|
||||
function doContextCmd(cmdName)
|
||||
{
|
||||
// Do some prompting/confirmation for various bookmark
|
||||
// commands that we know about.
|
||||
// If we have values to pass it, they are added to the arguments array
|
||||
|
||||
var nameVal = "";
|
||||
var urlVal = "";
|
||||
var promptStr;
|
||||
|
||||
var picker_uri;
|
||||
var filePicker;
|
||||
|
||||
if (cmdName == NC_NS + "command?cmd=newbookmark")
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
promptStr = get_localized_string("NewBookmarkURLPrompt");
|
||||
urlVal = prompt(promptStr, "");
|
||||
if (!urlVal || urlVal=="") return false;
|
||||
|
||||
// ensure we get a fully qualified URL (protocol colon address)
|
||||
var colonOffset = urlVal.indexOf(":");
|
||||
if (colonOffset > 0) break;
|
||||
alert(get_localized_string("NeedValidURL"));
|
||||
}
|
||||
|
||||
promptStr = get_localized_string("NewBookmarkNamePrompt");
|
||||
nameVal = prompt(promptStr, "");
|
||||
if (!nameVal || nameVal=="") return false;
|
||||
}
|
||||
else if (cmdName == NC_NS + "command?cmd=newfolder")
|
||||
{
|
||||
promptStr = get_localized_string("NewFolderNamePrompt");
|
||||
nameVal = prompt(promptStr, "");
|
||||
if (!nameVal || nameVal=="") return false;
|
||||
}
|
||||
else if ((cmdName == NC_NS + "command?cmd=deletebookmark") ||
|
||||
(cmdName == NC_NS + "command?cmd=deletebookmarkfolder") ||
|
||||
(cmdName == NC_NS + "command?cmd=deletebookmarkseparator"))
|
||||
{
|
||||
return doDelete(true);
|
||||
//var promptStr = get_localized_string("DeleteItems");
|
||||
//if (!confirm(promptStr)) return false;
|
||||
}
|
||||
else if (cmdName == NC_NS + "command?cmd=import")
|
||||
{
|
||||
try
|
||||
{
|
||||
picker_uri = "@mozilla.org/filepicker;1";
|
||||
filePicker = Components.classes[picker_uri].createInstance(nsIFilePicker);
|
||||
if (!filePicker) return false;
|
||||
|
||||
promptStr = get_localized_string("SelectImport");
|
||||
filePicker.init(window, promptStr, nsIFilePicker.modeOpen);
|
||||
filePicker.appendFilters(nsIFilePicker.filterHTML | nsIFilePicker.filterAll);
|
||||
if (filePicker.show() != nsIFilePicker.returnCancel)
|
||||
var filename = filePicker.fileURL.spec;
|
||||
if ((!filename) || (filename == "")) return false;
|
||||
|
||||
urlVal = filename;
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (cmdName == NC_NS + "command?cmd=export")
|
||||
{
|
||||
try
|
||||
{
|
||||
picker_uri = "@mozilla.org/filepicker;1";
|
||||
filePicker = Components.classes[picker_uri].createInstance(nsIFilePicker);
|
||||
if (!filePicker) return false;
|
||||
|
||||
promptStr = get_localized_string("EnterExport");
|
||||
filePicker.init(window, promptStr, nsIFilePicker.modeSave);
|
||||
filePicker.defaultString = "bookmarks.html";
|
||||
filePicker.appendFilters(nsIFilePicker.filterHTML | nsIFilePicker.filterAll);
|
||||
if (filePicker.show() != nsIFilePicker.returnCancel &&
|
||||
filePicker.fileURL.spec &&
|
||||
filePicker.fileURL.spec.length > 0) {
|
||||
urlVal = filePicker.fileURL.spec;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var treeNode = document.getElementById("bookmarksTree");
|
||||
if (!treeNode) return false;
|
||||
var db = treeNode.database;
|
||||
if (!db) return false;
|
||||
|
||||
var compositeDB = db.QueryInterface(Components.interfaces.nsIRDFDataSource);
|
||||
if (!compositeDB) return false;
|
||||
|
||||
var isupports_uri = "@mozilla.org/rdf/rdf-service;1";
|
||||
var isupports = Components.classes[isupports_uri].getService();
|
||||
if (!isupports) return false;
|
||||
var rdf = isupports.QueryInterface(Components.interfaces.nsIRDFService);
|
||||
if (!rdf) return false;
|
||||
|
||||
// need a resource for the command
|
||||
var cmdResource = rdf.GetResource(cmdName);
|
||||
if (!cmdResource) return false;
|
||||
cmdResource = cmdResource.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
if (!cmdResource) return false;
|
||||
|
||||
// set up selection nsISupportsArray
|
||||
var selection_uri = "@mozilla.org/supports-array;1";
|
||||
var selectionInstance = Components.classes[selection_uri].createInstance();
|
||||
var selectionArray = selectionInstance.QueryInterface(Components.interfaces.nsISupportsArray);
|
||||
|
||||
// set up arguments nsISupportsArray
|
||||
var arguments_uri = "@mozilla.org/supports-array;1";
|
||||
var argumentsInstance = Components.classes[arguments_uri].createInstance();
|
||||
var argumentsArray = argumentsInstance.QueryInterface(Components.interfaces.nsISupportsArray);
|
||||
|
||||
// get various arguments (parent, name)
|
||||
var parentArc = rdf.GetResource(NC_NS + "parent");
|
||||
if (!parentArc) return false;
|
||||
var nameArc = rdf.GetResource(NC_NS + "Name");
|
||||
if (!nameArc) return false;
|
||||
var urlArc = rdf.GetResource(NC_NS + "URL");
|
||||
if (!urlArc) return false;
|
||||
|
||||
var select_list = treeNode.selectedItems;
|
||||
|
||||
var uri;
|
||||
var rdfNode;
|
||||
|
||||
if (select_list.length < 1)
|
||||
{
|
||||
// if nothing is selected, default to using the "ref"
|
||||
// on the root of the tree
|
||||
uri = treeNode.getAttribute("ref");
|
||||
if (!uri || uri=="") return false;
|
||||
rdfNode = rdf.GetResource(uri);
|
||||
// add node into selection array
|
||||
if (rdfNode)
|
||||
{
|
||||
selectionArray.AppendElement(rdfNode);
|
||||
}
|
||||
|
||||
// add singular arguments into arguments array
|
||||
if ((nameVal) && (nameVal != ""))
|
||||
{
|
||||
var nameLiteral = rdf.GetLiteral(nameVal);
|
||||
if (!nameLiteral) return false;
|
||||
argumentsArray.AppendElement(nameArc);
|
||||
argumentsArray.AppendElement(nameLiteral);
|
||||
}
|
||||
if ((urlVal) && (urlVal != ""))
|
||||
{
|
||||
var urlLiteral = rdf.GetLiteral(urlVal);
|
||||
if (!urlLiteral) return false;
|
||||
argumentsArray.AppendElement(urlArc);
|
||||
argumentsArray.AppendElement(urlLiteral);
|
||||
}
|
||||
}
|
||||
else for (var nodeIndex=0; nodeIndex<select_list.length; nodeIndex++)
|
||||
{
|
||||
var node = select_list[nodeIndex];
|
||||
if (!node) break;
|
||||
uri = node.getAttribute("ref");
|
||||
if ((uri) || (uri == ""))
|
||||
{
|
||||
uri = node.getAttribute("id");
|
||||
}
|
||||
if (!uri) return false;
|
||||
|
||||
rdfNode = rdf.GetResource(uri);
|
||||
if (!rdfNode) break;
|
||||
|
||||
// add node into selection array
|
||||
selectionArray.AppendElement(rdfNode);
|
||||
|
||||
// get the parent's URI
|
||||
var parentURI = "";
|
||||
var theParent = node.parentNode.parentNode;
|
||||
parentURI = theParent.getAttribute("ref");
|
||||
if ((!parentURI) || (parentURI == ""))
|
||||
{
|
||||
parentURI = theParent.getAttribute("id");
|
||||
}
|
||||
if (parentURI == "") return false;
|
||||
|
||||
var parentNode = rdf.GetResource(parentURI, true);
|
||||
if (!parentNode) return false;
|
||||
|
||||
// add multiple arguments into arguments array
|
||||
argumentsArray.AppendElement(parentArc);
|
||||
argumentsArray.AppendElement(parentNode);
|
||||
|
||||
if ((nameVal) && (nameVal != ""))
|
||||
{
|
||||
var nameLiteral2 = rdf.GetLiteral(nameVal);
|
||||
if (!nameLiteral2) return false;
|
||||
argumentsArray.AppendElement(nameArc);
|
||||
argumentsArray.AppendElement(nameLiteral2);
|
||||
}
|
||||
if ((urlVal) && (urlVal != ""))
|
||||
{
|
||||
var urlLiteral2 = rdf.GetLiteral(urlVal);
|
||||
if (!urlLiteral2) return false;
|
||||
argumentsArray.AppendElement(urlArc);
|
||||
argumentsArray.AppendElement(urlLiteral2);
|
||||
}
|
||||
}
|
||||
|
||||
// do the command
|
||||
compositeDB.DoCommand(selectionArray, cmdResource, argumentsArray);
|
||||
return true;
|
||||
}
|
||||
|
||||
function bookmarkSelect()
|
||||
{
|
||||
var tree = document.getElementById("bookmarksTree");
|
||||
var status = document.getElementById("statusbar-text");
|
||||
var val = "";
|
||||
if (tree.selectedItems.length == 1)
|
||||
{
|
||||
val = getAbsoluteID("bookmarksTree", tree.selectedItems[0]);
|
||||
|
||||
// Ignore "NC:" urls.
|
||||
if (val.substring(0, 3) == "NC:")
|
||||
{
|
||||
val = "";
|
||||
}
|
||||
}
|
||||
status.label = val;
|
||||
return true;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
bookmarks-tree, bookmarks-tree[type="multi-column"]
|
||||
{
|
||||
-moz-binding : url("chrome://communicator/content/bookmarks/bookmarks.xml#bookmarks-tree-full");
|
||||
}
|
||||
|
||||
bookmarks-tree[type="single-column"]
|
||||
{
|
||||
-moz-binding : url("chrome://communicator/content/bookmarks/bookmarks.xml#bookmarks-tree-name");
|
||||
}
|
||||
|
||||
bookmarks-tree[type="folders"]
|
||||
{
|
||||
-moz-binding : url("chrome://communicator/content/bookmarks/bookmarks.xml#bookmarks-tree-folders");
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@netscape.com> (Original Author, v3.0)
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Initialize the command controllers, set focus, tree root,
|
||||
// window title state, etc.
|
||||
function Startup()
|
||||
{
|
||||
const windowNode = document.getElementById("bookmark-window");
|
||||
const bookmarksView = document.getElementById("bookmarks-view");
|
||||
var titleString;
|
||||
|
||||
// If we've been opened with a parameter, root the tree on it.
|
||||
if ("arguments" in window && window.arguments[0]) {
|
||||
var title;
|
||||
var uri = window.arguments[0];
|
||||
bookmarksView.tree.setAttribute("ref", uri);
|
||||
if (uri.substring(0,5) == "find:") {
|
||||
title = bookmarksView._bundle.GetStringFromName("search_results_title");
|
||||
// Update the windowtype so that future searches are directed
|
||||
// there and the window is not re-used for bookmarks.
|
||||
windowNode.setAttribute("windowtype", "bookmarks:searchresults");
|
||||
}
|
||||
else {
|
||||
const krNameArc = bookmarksView.rdf.GetResource(NC_NS + "Name");
|
||||
const krRoot = bookmarksView.rdf.GetResource(window.arguments[0]);
|
||||
var rName = bookmarksView.db.GetTarget(krRoot, krNameArc, true);
|
||||
title = rName.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
||||
}
|
||||
titleString = bookmarksView._bundle.GetStringFromName("window_title");
|
||||
titleString = titleString.replace(/%folder_name%/gi, title);
|
||||
windowNode.setAttribute("title", titleString);
|
||||
}
|
||||
else {
|
||||
const kProfileContractID = "@mozilla.org/profile/manager;1";
|
||||
const kProfileIID = Components.interfaces.nsIProfile;
|
||||
const kProfile = Components.classes[kProfileContractID].getService(kProfileIID);
|
||||
var length = {value:0};
|
||||
var profileList = kProfile.getProfileList(length);
|
||||
// unset the default BM title if the user has more than one profile
|
||||
// or if he/she has changed the name of the default one.
|
||||
// the profile "default" is not localizable.
|
||||
if (length.value > 1 || kProfile.currentProfile.toLowerCase() != "default") {
|
||||
titleString = bookmarksView._bundle.GetStringFromName("bookmarks_root");
|
||||
titleString = titleString.replace(/%user_name%/, kProfile.currentProfile);
|
||||
windowNode.setAttribute("title", titleString);
|
||||
}
|
||||
}
|
||||
|
||||
bookmarksView.treeBoxObject.selection.select(0);
|
||||
bookmarksView.tree.focus();
|
||||
}
|
||||
|
||||
function Shutdown ()
|
||||
{
|
||||
// Store current window position and size in window attributes (for persistence).
|
||||
var win = document.getElementById("bookmark-window");
|
||||
win.setAttribute("x", screenX);
|
||||
win.setAttribute("y", screenY);
|
||||
win.setAttribute("height", outerHeight);
|
||||
win.setAttribute("width", outerWidth);
|
||||
|
||||
var bookmarksView = document.getElementById("bookmarks-view");
|
||||
bookmarksView.flushBMDatasource();
|
||||
}
|
||||
|
||||
var gConstructedViewMenuSortItems = false;
|
||||
function fillViewMenu(aEvent)
|
||||
{
|
||||
var adjacentElement = document.getElementById("fill-before-this-node");
|
||||
var popupElement = aEvent.target;
|
||||
|
||||
var bookmarksView = document.getElementById("bookmarks-view");
|
||||
var columns = bookmarksView.columns;
|
||||
|
||||
if (!gConstructedViewMenuSortItems) {
|
||||
for (var i = 0; i < columns.length; ++i) {
|
||||
var name = columns[i].name;
|
||||
var accesskey = columns[i].accesskey;
|
||||
|
||||
var menuitem = document.createElement("menuitem");
|
||||
var nameTemplate = bookmarksView._bundle.GetStringFromName("SortMenuItem");
|
||||
name = nameTemplate.replace(/%NAME%/g, columns[i].label);
|
||||
menuitem.setAttribute("label", name);
|
||||
menuitem.setAttribute("accesskey", columns[i].accesskey);
|
||||
menuitem.setAttribute("resource", columns[i].resource);
|
||||
menuitem.setAttribute("id", "sortMenuItem:" + columns[i].resource);
|
||||
menuitem.setAttribute("checked", columns[i].sortActive);
|
||||
menuitem.setAttribute("name", "sortSet");
|
||||
menuitem.setAttribute("type", "radio");
|
||||
|
||||
popupElement.insertBefore(menuitem, adjacentElement);
|
||||
}
|
||||
|
||||
gConstructedViewMenuSortItems = true;
|
||||
}
|
||||
|
||||
const kPrefSvcContractID = "@mozilla.org/preferences;1";
|
||||
const kPrefSvcIID = Components.interfaces.nsIPrefService;
|
||||
var prefSvc = Components.classes[kPrefSvcContractID].getService(kPrefSvcIID);
|
||||
var bookmarksSortPrefs = prefSvc.getBranch("browser.bookmarks.sort.");
|
||||
|
||||
if (gConstructedViewMenuSortItems) {
|
||||
var resource = bookmarksSortPrefs.getCharPref("resource");
|
||||
var element = document.getElementById("sortMenuItem:" + resource);
|
||||
if (element)
|
||||
element.setAttribute("checked", "true");
|
||||
}
|
||||
|
||||
var sortAscendingMenu = document.getElementById("ascending");
|
||||
var sortDescendingMenu = document.getElementById("descending");
|
||||
var noSortMenu = document.getElementById("natural");
|
||||
|
||||
sortAscendingMenu.setAttribute("checked", "false");
|
||||
sortDescendingMenu.setAttribute("checked", "false");
|
||||
noSortMenu.setAttribute("checked", "false");
|
||||
var direction = bookmarksSortPrefs.getCharPref("direction");
|
||||
if (direction == "natural")
|
||||
sortAscendingMenu.setAttribute("checked", "true");
|
||||
else if (direction == "ascending")
|
||||
sortDescendingMenu.setAttribute("checked", "true");
|
||||
else
|
||||
noSortMenu.setAttribute("checked", "true");
|
||||
}
|
||||
|
||||
function onViewMenuSortItemSelected(aEvent)
|
||||
{
|
||||
var resource = aEvent.target.getAttribute("resource");
|
||||
|
||||
const kPrefSvcContractID = "@mozilla.org/preferences;1";
|
||||
const kPrefSvcIID = Components.interfaces.nsIPrefService;
|
||||
var prefSvc = Components.classes[kPrefSvcContractID].getService(kPrefSvcIID);
|
||||
var bookmarksSortPrefs = prefSvc.getBranch("browser.bookmarks.sort.");
|
||||
|
||||
switch (resource) {
|
||||
case "":
|
||||
break;
|
||||
case "direction":
|
||||
var dirn = bookmarksSortPrefs.getCharPref("direction");
|
||||
if (aEvent.target.id == "ascending")
|
||||
bookmarksSortPrefs.setCharPref("direction", "natural");
|
||||
else if (aEvent.target.id == "descending")
|
||||
bookmarksSortPrefs.setCharPref("direction", "ascending");
|
||||
else
|
||||
bookmarksSortPrefs.setCharPref("direction", "descending");
|
||||
break;
|
||||
default:
|
||||
bookmarksSortPrefs.setCharPref("resource", resource);
|
||||
var direction = bookmarksSortPrefs.getCharPref("direction");
|
||||
if (direction == "descending")
|
||||
bookmarksSortPrefs.setCharPref("direction", "natural");
|
||||
break;
|
||||
}
|
||||
|
||||
aEvent.preventCapture();
|
||||
}
|
||||
|
||||
var gConstructedColumnsMenuItems = false;
|
||||
function fillColumnsMenu(aEvent)
|
||||
{
|
||||
var bookmarksView = document.getElementById("bookmarks-view");
|
||||
var columns = bookmarksView.columns;
|
||||
var i;
|
||||
|
||||
if (!gConstructedColumnsMenuItems) {
|
||||
for (i = 0; i < columns.length; ++i) {
|
||||
var menuitem = document.createElement("menuitem");
|
||||
menuitem.setAttribute("label", columns[i].label);
|
||||
menuitem.setAttribute("resource", columns[i].resource);
|
||||
menuitem.setAttribute("id", "columnMenuItem:" + columns[i].resource);
|
||||
menuitem.setAttribute("type", "checkbox");
|
||||
menuitem.setAttribute("checked", columns[i].hidden != "true");
|
||||
aEvent.target.appendChild(menuitem);
|
||||
}
|
||||
|
||||
gConstructedColumnsMenuItems = true;
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < columns.length; ++i) {
|
||||
var element = document.getElementById("columnMenuItem:" + columns[i].resource);
|
||||
if (element && columns[i].hidden != "true")
|
||||
element.setAttribute("checked", "true");
|
||||
}
|
||||
}
|
||||
|
||||
aEvent.preventBubble();
|
||||
}
|
||||
|
||||
function onViewMenuColumnItemSelected(aEvent)
|
||||
{
|
||||
var resource = aEvent.target.getAttribute("resource");
|
||||
if (resource != "") {
|
||||
var bookmarksView = document.getElementById("bookmarks-view");
|
||||
bookmarksView.toggleColumnVisibility(resource);
|
||||
}
|
||||
|
||||
aEvent.preventBubble();
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,252 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- -*- Mode: HTML; indent-tabs-mode: nil; -*- -->
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the Netscape Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/NPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The Original Code is mozilla.org code.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
Ben Goodger <ben@netscape.com>
|
||||
Blake Ross <blakeross@telocity.com>
|
||||
Dean Tessman <dean_tessman@hotmail.com>
|
||||
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://communicator/skin/bookmarks/bookmarksWindow.css" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://communicator/content/bookmarks/bookmarks.css" type="text/css"?>
|
||||
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://communicator/content/bookmarks/bookmarksOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://communicator/content/tasksOverlay.xul"?>
|
||||
<?xul-overlay href="chrome://communicator/content/communicatorOverlay.xul"?>
|
||||
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % utilDTD SYSTEM "chrome://communicator/locale/utilityOverlay.dtd" >
|
||||
%utilDTD;
|
||||
<!ENTITY % bmDTD SYSTEM "chrome://communicator/locale/bookmarks/bookmarks.dtd">
|
||||
%bmDTD;
|
||||
]>
|
||||
|
||||
<window id="bookmark-window" windowtype="bookmarks:manager"
|
||||
title="&bookmarksWindowTitle.label;"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:web="http://home.netscape.com/WEB-rdf#"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
width="630" height="400" screenX="20" screenY="20"
|
||||
persist="width height screenX screenY sizemode"
|
||||
onload="Startup();" onunload="Shutdown();">
|
||||
|
||||
<!-- The order of loading of these script files is IMPORTANT -->
|
||||
|
||||
<!-- Shared Libraries -->
|
||||
<script type="application/x-javascript" src="chrome://global/content/strres.js"></script>
|
||||
|
||||
<!-- XXX - This should SO become an XBL widget -->
|
||||
<script type="application/x-javascript" src="chrome://global/content/globalOverlay.js"></script>
|
||||
|
||||
<!-- Shared Bookmarks Utility Library -->
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksOverlay.js"/>
|
||||
<!-- Tree-based Bookmarks UI Utility Library -->
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksTree.js"/>
|
||||
<!-- Bookmarks Window -->
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarks.js"/>
|
||||
|
||||
<!-- Bookmarks Window Drag & Drop -->
|
||||
<script type="application/x-javascript" src="chrome://global/content/nsDragAndDrop.js"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/nsTransferable.js"/>
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksDD.js"/>
|
||||
|
||||
<popupset id="bookmarksPopupset"/>
|
||||
|
||||
<commands id="commands">
|
||||
<commandset id="CommandUpdate_Bookmarks"
|
||||
commandupdater="true"
|
||||
events="focus,tree-select"
|
||||
oncommandupdate="document.getElementById('bookmarks-view').onCommandUpdate();">
|
||||
</commandset>
|
||||
|
||||
<commandset id="tasksCommands"/>
|
||||
|
||||
<!-- File Menu -->
|
||||
<command id="cmd_close" oncommand="close()"/>
|
||||
<command id="cmd_quit"/>
|
||||
<!-- Edit Menu -->
|
||||
<command id="cmd_undo"/>
|
||||
</commands>
|
||||
|
||||
<stringbundleset id="stringbundleset"/>
|
||||
|
||||
<keyset id="tasksKeys">
|
||||
<!-- File Menu -->
|
||||
<key id="key_close"/>
|
||||
<key id="key_quit"/>
|
||||
<!-- Edit Menu -->
|
||||
<key id="key_undo"/>
|
||||
|
||||
<!-- These keybindings do not have a command specified in the overlay,
|
||||
which is good, but we need to specify it ourselves here -->
|
||||
<key id="key_cut" command="cmd_bm_cut"/>
|
||||
<key id="key_copy" command="cmd_bm_copy"/>
|
||||
<key id="key_paste" command="cmd_bm_paste"/>
|
||||
<key id="key_selectAll" command="cmd_bm_selectAll"/>
|
||||
|
||||
<!-- We need to provide our own delete key binding because the key_delete
|
||||
handler in platformGlobalOverlay.xul maps command to "cmd_delete" which
|
||||
is NOT what we want! -->
|
||||
<key id="key_bm_delete" keycode="VK_DELETE" command="cmd_bm_delete"/>
|
||||
|
||||
<key id="bm_key_find"
|
||||
key="&edit.find.keybinding;"
|
||||
command="cmd_bm_find" modifiers="accel"/>
|
||||
<key id="bm_key_properties"
|
||||
key="&edit.properties.keybinding;"
|
||||
command="cmd_bm_properties" modifiers="accel"/>
|
||||
</keyset>
|
||||
|
||||
<toolbox id="bookmarks-toolbox">
|
||||
<menubar id="main-menubar" grippytooltiptext="&menuBar.tooltip;">
|
||||
<menu id="menu_File">
|
||||
<menupopup id="menu_FilePopup">
|
||||
<menu id="menu_New">
|
||||
<menupopup>
|
||||
<menuitem label="&menuitem.newBookmark.label;"
|
||||
accesskey="&command.newBookmark.accesskey;"
|
||||
observes="cmd_bm_newbookmark"/>
|
||||
<menuitem label="&menuitem.newFolder.label;"
|
||||
accesskey="&command.newFolder.accesskey;"
|
||||
observes="cmd_bm_newfolder"/>
|
||||
<menuitem label="&menuitem.newSeparator.label;"
|
||||
accesskey="&command.newSeparator.accesskey;"
|
||||
observes="cmd_bm_newseparator"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuitem id="menu_close"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menu id="menu_Edit">
|
||||
<menupopup>
|
||||
<menuitem id="menu_undo" disabled="true"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_bm_cut"
|
||||
label="&cutCmd.label;" accesskey="&cutCmd.accesskey;"
|
||||
key="key_cut" command="cmd_bm_cut"/>
|
||||
<menuitem id="menu_bm_copy"
|
||||
label="©Cmd.label;" accesskey="©Cmd.accesskey;"
|
||||
key="key_copy" command="cmd_bm_copy"/>
|
||||
<menuitem id="menu_bm_paste"
|
||||
label="&pasteCmd.label;" accesskey="&pasteCmd.accesskey;"
|
||||
key="key_paste" command="cmd_bm_paste"/>
|
||||
<menuitem id="menu_bm_delete"
|
||||
label="&deleteCmd.label;" accesskey="&deleteCmd.label;"
|
||||
key="key_bm_delete" command="cmd_bm_delete"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_bm_selectAll"
|
||||
label="&selectAllCmd.label;" accesskey="&selectAllCmd.accesskey;"
|
||||
key="key_selectAll" command="cmd_bm_selectAll"/>
|
||||
<menuseparator/>
|
||||
<menuitem label="&command.fileBookmark.label;"
|
||||
accesskey="&command.fileBookmark.accesskey;"
|
||||
command="cmd_bm_fileBookmark"/>
|
||||
<menuseparator/>
|
||||
<menuitem observes="cmd_bm_properties" key="bm_key_properties"
|
||||
label="&command.properties.label;"
|
||||
accesskey="&command.properties.accesskey;" />
|
||||
</menupopup>
|
||||
</menu>
|
||||
|
||||
<menu id="menu_View">
|
||||
<menupopup onpopupshowing="fillViewMenu(event)"
|
||||
oncommand="onViewMenuSortItemSelected(event);">
|
||||
<menuitem id="viewCommandToolbar" type="checkbox" class="menuitem-iconic"
|
||||
label="&menuitem.view.command.toolbar.label;"
|
||||
accesskey="&menuitem.view.command.toolbar.accesskey;"
|
||||
oncommand="goToggleToolbar('command-toolbar', 'viewCommandToolbar'); event.preventBubble();"
|
||||
persist="checked"/>
|
||||
<menuseparator id="fill-after-this-node"/>
|
||||
<menuitem id="natural" label="&menuitem.view.unsorted.label;"
|
||||
accesskey="&menuitem.view.unsorted.accesskey;"
|
||||
type="radio"
|
||||
resource="direction" name="sortSet"/>
|
||||
<menuseparator id="fill-before-this-node"/>
|
||||
<menuitem id="ascending" label="&menuitem.view.ascending.label;"
|
||||
accesskey="&menuitem.view.ascending.accesskey;"
|
||||
type="radio"
|
||||
resource="direction" name="sortDirectionSet"/>
|
||||
<menuitem id="descending" label="&menuitem.view.descending.label;"
|
||||
accesskey="&menuitem.view.descending.accesskey;"
|
||||
type="radio"
|
||||
resource="direction" name="sortDirectionSet"/>
|
||||
<menuseparator/>
|
||||
<menu id="descending" label="&menuitem.view.show_columns.label;"
|
||||
accesskey="&menuitem.view.show_columns.accesskey;">
|
||||
<menupopup id="columnsPopup" onpopupshowing="fillColumnsMenu(event);"
|
||||
oncommand="onViewMenuColumnItemSelected(event);"/>
|
||||
</menu>
|
||||
<menuseparator/>
|
||||
<menuitem label="&menuitem.newbookmarkfolder.label;"
|
||||
command="cmd_bm_setnewbookmarkfolder"
|
||||
accesskey="&menuitem.newbookmarkfolder.accesskey;"/>
|
||||
<menuitem label="&menuitem.newinternetsearchfolder.label;"
|
||||
command="cmd_bm_setnewsearchfolder"
|
||||
accesskey="&menuitem.newinternetsearchfolder.accesskey;"/>
|
||||
<menuitem label="&menuitem.personaltoolbarfolder.label;"
|
||||
command="cmd_bm_setpersonaltoolbarfolder"
|
||||
accesskey="&menuitem.personaltoolbarfolder.accesskey;"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menu id="tasksMenu">
|
||||
<menupopup id="taskPopup">
|
||||
<menuitem command="cmd_bm_find" key="bm_key_find"
|
||||
label="&menuitem.find.label;"
|
||||
accesskey="&menuitem.find.accesskey;"/>
|
||||
<menuitem label="&menuitem.import.label;"
|
||||
accesskey="&menuitem.import.accesskey;"
|
||||
observes="cmd_bm_import"/>
|
||||
<menuitem label="&menuitem.export.label;"
|
||||
accesskey="&menuitem.export.accesskey;"
|
||||
observes="cmd_bm_export"/>
|
||||
<menuseparator/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menu id="windowMenu"/>
|
||||
<menu id="menu_Help"/>
|
||||
</menubar>
|
||||
|
||||
<toolbar id="command-toolbar" tbalign="stretch" grippytooltiptext="&bookmarkToolbar.tooltip;">
|
||||
<toolbarbutton id="newfolder" label="&button.newFolder.label;"
|
||||
command="cmd_bm_newfolder"/>
|
||||
<toolbarbutton id="newseparator" label="&button.newSeparator.label;"
|
||||
command="cmd_bm_newseparator"/>
|
||||
<toolbarseparator/>
|
||||
<toolbarbutton id="fileBookmark" label="&command.fileBookmark.label;"
|
||||
command="cmd_bm_fileBookmark"/>
|
||||
<toolbarseparator/>
|
||||
<toolbarbutton id="properties" label="&command.properties.label;"
|
||||
command="cmd_bm_properties"/>
|
||||
<toolbarbutton id="rename" label="&command.rename.label;"
|
||||
command="cmd_bm_rename"/>
|
||||
<toolbarbutton id="delete" label="&command.delete.label;"
|
||||
command="cmd_bm_delete"/>
|
||||
</toolbar>
|
||||
</toolbox>
|
||||
|
||||
<bookmarks-tree id="bookmarks-view" flex="1"/>
|
||||
|
||||
</window>
|
||||
|
||||
@@ -1,508 +0,0 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/*
|
||||
This is the old bookmarks code, included here for the sake of the bookmarks sidebar panel,
|
||||
which will be fixed to use my new code in .9. In the mean time, this file provides a
|
||||
life line to various functionality.
|
||||
*/
|
||||
|
||||
|
||||
var NC_NS = "http://home.netscape.com/NC-rdf#";
|
||||
var RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
|
||||
|
||||
|
||||
|
||||
function TopLevelDrag ( event )
|
||||
{
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
function BeginDragTree ( event )
|
||||
{
|
||||
//XXX we rely on a capturer to already have determined which item the mouse was over
|
||||
//XXX and have set an attribute.
|
||||
|
||||
// if the click is on the tree proper, ignore it. We only care about clicks on items.
|
||||
|
||||
var tree = document.getElementById("bookmarksTree");
|
||||
if ( event.target == tree || event.target.localName == "treechildren" )
|
||||
return(true); // continue propagating the event
|
||||
|
||||
var childWithDatabase = tree;
|
||||
if ( ! childWithDatabase )
|
||||
return(false);
|
||||
|
||||
var dragStarted = false;
|
||||
|
||||
var trans =
|
||||
Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
|
||||
if ( !trans ) return(false);
|
||||
|
||||
var genData =
|
||||
Components.classes["@mozilla.org/supports-wstring;1"].createInstance(Components.interfaces.nsISupportsWString);
|
||||
if (!genData) return(false);
|
||||
|
||||
var genDataURL =
|
||||
Components.classes["@mozilla.org/supports-wstring;1"].createInstance(Components.interfaces.nsISupportsWString);
|
||||
if (!genDataURL) return(false);
|
||||
|
||||
trans.addDataFlavor("text/unicode");
|
||||
trans.addDataFlavor("moz/rdfitem");
|
||||
|
||||
// ref/id (url) is on the <treeitem> which is two levels above the <treecell> which is
|
||||
// the target of the event.
|
||||
var id = event.target.parentNode.parentNode.getAttribute("ref");
|
||||
if (!id || id=="")
|
||||
{
|
||||
id = event.target.parentNode.parentNode.getAttribute("id");
|
||||
}
|
||||
|
||||
var parentID = event.target.parentNode.parentNode.parentNode.parentNode.getAttribute("ref");
|
||||
if (!parentID || parentID == "")
|
||||
{
|
||||
parentID = event.target.parentNode.parentNode.parentNode.parentNode.getAttribute("id");
|
||||
}
|
||||
|
||||
var trueID = id;
|
||||
if (parentID != null)
|
||||
{
|
||||
trueID += "\n" + parentID;
|
||||
}
|
||||
genData.data = trueID;
|
||||
genDataURL.data = id;
|
||||
|
||||
var database = childWithDatabase.database;
|
||||
var rdf =
|
||||
Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
|
||||
if ((!rdf) || (!database)) { dump("CAN'T GET DATABASE\n"); return(false); }
|
||||
|
||||
// make sure its a bookmark, bookmark separator, or bookmark folder
|
||||
var src = rdf.GetResource(id, true);
|
||||
var prop = rdf.GetResource(RDF_NS + "type", true);
|
||||
var target = database.GetTarget(src, prop, true);
|
||||
|
||||
if (target) target = target.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
if (target) target = target.Value;
|
||||
if ((!target) || (target == "")) {dump("BAD\n"); return(false);}
|
||||
|
||||
if ((target != NC_NS + "BookmarkSeparator") &&
|
||||
(target != NC_NS + "Bookmark") &&
|
||||
(target != NC_NS + "Folder")) return(false);
|
||||
|
||||
trans.setTransferData ( "moz/rdfitem", genData, genData.data.length * 2); // double byte data
|
||||
trans.setTransferData ( "text/unicode", genDataURL, genDataURL.data.length * 2); // double byte data
|
||||
|
||||
var transArray =
|
||||
Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
|
||||
if ( !transArray ) return(false);
|
||||
|
||||
// put it into the transferable as an |nsISupports|
|
||||
var genTrans = trans.QueryInterface(Components.interfaces.nsISupports);
|
||||
transArray.AppendElement(genTrans);
|
||||
|
||||
var dragService =
|
||||
Components.classes["@mozilla.org/widget/dragservice;1"].getService(Components.interfaces.nsIDragService);
|
||||
if ( !dragService ) return(false);
|
||||
|
||||
var nsIDragService = Components.interfaces.nsIDragService;
|
||||
dragService.invokeDragSession ( event.target, transArray, null, nsIDragService.DRAGDROP_ACTION_COPY +
|
||||
nsIDragService.DRAGDROP_ACTION_MOVE );
|
||||
dragStarted = true;
|
||||
|
||||
return(!dragStarted);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function DragOverTree ( event )
|
||||
{
|
||||
var validFlavor = false;
|
||||
var dragSession = null;
|
||||
var retVal = true;
|
||||
|
||||
var dragService =
|
||||
Components.classes["@mozilla.org/widget/dragservice;1"].getService(Components.interfaces.nsIDragService);
|
||||
if ( !dragService ) return(false);
|
||||
|
||||
dragSession = dragService.getCurrentSession();
|
||||
if ( !dragSession ) return(false);
|
||||
|
||||
if ( dragSession.isDataFlavorSupported("moz/rdfitem") ) validFlavor = true;
|
||||
else if ( dragSession.isDataFlavorSupported("text/unicode") ) validFlavor = true;
|
||||
//XXX other flavors here...
|
||||
|
||||
// touch the attribute on the rowgroup to trigger the repaint with the drop feedback.
|
||||
if ( validFlavor )
|
||||
{
|
||||
var treeRoot = document.getElementById("bookmarksTree");
|
||||
if (!treeRoot) return(false);
|
||||
var treeDatabase = treeRoot.database;
|
||||
if (!treeDatabase) return(false);
|
||||
|
||||
//XXX this is really slow and likes to refresh N times per second.
|
||||
var rowGroup = event.target.parentNode.parentNode;
|
||||
var sortActive = treeRoot.getAttribute("sortActive");
|
||||
if (sortActive == "true")
|
||||
rowGroup.setAttribute ( "dd-triggerrepaintsorted", 0 );
|
||||
else
|
||||
rowGroup.setAttribute ( "dd-triggerrepaint", 0 );
|
||||
|
||||
dragSession.canDrop = true;
|
||||
// necessary??
|
||||
retVal = false;
|
||||
}
|
||||
return(retVal);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function DropOnTree ( event )
|
||||
{
|
||||
var treeRoot = document.getElementById("bookmarksTree");
|
||||
if (!treeRoot) return(false);
|
||||
var treeDatabase = treeRoot.database;
|
||||
if (!treeDatabase) return(false);
|
||||
|
||||
// for beta1, don't allow D&D if sorting is active
|
||||
var sortActive = treeRoot.getAttribute("sortActive");
|
||||
if (sortActive == "true")
|
||||
{
|
||||
dump("Sorry, drag&drop is currently disabled when sorting is active.\n");
|
||||
return(false);
|
||||
}
|
||||
|
||||
var RDF =
|
||||
Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
|
||||
if (!RDF) return(false);
|
||||
var RDFC =
|
||||
Components.classes["@mozilla.org/rdf/container;1"].getService(Components.interfaces.nsIRDFContainer);
|
||||
if (!RDFC) return(false);
|
||||
|
||||
var Bookmarks = RDF.GetDataSource("rdf:bookmarks");
|
||||
if (!Bookmarks) return(false);
|
||||
|
||||
// target is the <treecell>, and "ref/id" is on the <treeitem> two levels above
|
||||
var treeItem = event.target.parentNode.parentNode;
|
||||
if (!treeItem) return(false);
|
||||
|
||||
// get drop hint attributes
|
||||
var dropBefore = treeItem.getAttribute("dd-droplocation");
|
||||
var dropOn = treeItem.getAttribute("dd-dropon");
|
||||
|
||||
// calculate drop action
|
||||
var dropAction;
|
||||
if (dropBefore == "true") dropAction = "before";
|
||||
else if (dropOn == "true") dropAction = "on";
|
||||
else dropAction = "after";
|
||||
|
||||
// calculate parent container node
|
||||
var containerItem = treeItem;
|
||||
if (dropAction != "on")
|
||||
{
|
||||
containerItem = treeItem.parentNode.parentNode;
|
||||
}
|
||||
|
||||
// magical fix for bug # 33546: handle dropping after open container
|
||||
if (treeItem.getAttribute("container") == "true")
|
||||
{
|
||||
if (treeItem.getAttribute("open") == "true")
|
||||
{
|
||||
if (dropAction == "after")
|
||||
{
|
||||
dropAction = "before";
|
||||
containerItem = treeItem;
|
||||
|
||||
// find <treechildren>, drop before first child
|
||||
var treeChildren = treeItem;
|
||||
treeItem = null;
|
||||
for (var x = 0; x < treeChildren.childNodes.length; x++)
|
||||
{
|
||||
if (treeChildren.childNodes[x].tagName == "treechildren")
|
||||
{
|
||||
treeItem = treeChildren.childNodes[x].childNodes[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!treeItem)
|
||||
{
|
||||
dropAction = "on";
|
||||
containerItem = treeItem.parentNode.parentNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var targetID = getAbsoluteID("bookmarksTree", treeItem);
|
||||
if (!targetID) return(false);
|
||||
var targetNode = RDF.GetResource(targetID, true);
|
||||
if (!targetNode) return(false);
|
||||
|
||||
var containerID = getAbsoluteID("bookmarksTree", containerItem);
|
||||
if (!containerID) return(false);
|
||||
var containerNode = RDF.GetResource(containerID);
|
||||
if (!containerNode) return(false);
|
||||
|
||||
var dragService =
|
||||
Components.classes["@mozilla.org/widget/dragservice;1"].getService(Components.interfaces.nsIDragService);
|
||||
if ( !dragService ) return(false);
|
||||
|
||||
var dragSession = dragService.getCurrentSession();
|
||||
if ( !dragSession ) return(false);
|
||||
|
||||
var trans =
|
||||
Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
|
||||
if ( !trans ) return(false);
|
||||
trans.addDataFlavor("moz/rdfitem");
|
||||
trans.addDataFlavor("text/x-moz-url");
|
||||
trans.addDataFlavor("text/unicode");
|
||||
|
||||
var typeRes = RDF.GetResource(RDF_NS + "type");
|
||||
if (!typeRes) return false;
|
||||
var bmTypeRes = RDF.GetResource(NC_NS + "Bookmark");
|
||||
if (!bmTypeRes) return false;
|
||||
|
||||
var dirty = false;
|
||||
|
||||
for ( var i = 0; i < dragSession.numDropItems; ++i )
|
||||
{
|
||||
dragSession.getData ( trans, i );
|
||||
var dataObj = new Object();
|
||||
var bestFlavor = new Object();
|
||||
var len = new Object();
|
||||
trans.getAnyTransferData ( bestFlavor, dataObj, len );
|
||||
if ( dataObj ) dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsWString);
|
||||
if ( !dataObj ) continue;
|
||||
|
||||
var sourceID = null;
|
||||
var parentID = null;
|
||||
var checkNameHack = false;
|
||||
var name=null;
|
||||
|
||||
if (bestFlavor.value == "moz/rdfitem")
|
||||
{
|
||||
// pull the URL out of the data object
|
||||
var data = dataObj.data.substring(0, len.value / 2);
|
||||
|
||||
// moz/rdfitem allows parent ID specified on next line; check for it
|
||||
var cr = data.indexOf("\n");
|
||||
if (cr >= 0)
|
||||
{
|
||||
sourceID = data.substr(0, cr);
|
||||
parentID = data.substr(cr+1);
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceID = data;
|
||||
}
|
||||
}
|
||||
else if (bestFlavor.value == "text/x-moz-url")
|
||||
{
|
||||
// pull the URL out of the data object
|
||||
data = dataObj.data.substring(0, len.value / 2);
|
||||
sourceID = data;
|
||||
|
||||
// we may need to synthesize a name (just use the URL)
|
||||
checkNameHack = true;
|
||||
}
|
||||
else if (bestFlavor.value == "text/unicode")
|
||||
{
|
||||
sourceID = dataObj.data;
|
||||
|
||||
// we may need to synthesize a name (just use the URL)
|
||||
checkNameHack = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// unknown flavor, skip
|
||||
continue;
|
||||
}
|
||||
|
||||
// pull the (optional) name out of the URL
|
||||
var separator = sourceID.indexOf("\n");
|
||||
if (separator >= 0)
|
||||
{
|
||||
name = sourceID.substr(separator+1);
|
||||
sourceID = sourceID.substr(0, separator);
|
||||
}
|
||||
|
||||
var sourceNode = RDF.GetResource(sourceID, true);
|
||||
if (!sourceNode) continue;
|
||||
|
||||
var parentNode = null;
|
||||
if (parentID != null)
|
||||
{
|
||||
parentNode = RDF.GetResource(parentID, true);
|
||||
}
|
||||
|
||||
// Prevent dropping of a node before, after, or on itself
|
||||
if (sourceNode == targetNode) continue;
|
||||
// Prevent dropping of a node onto its parent container
|
||||
if ((dropAction == "on") && (containerID) && (containerID == parentID)) continue;
|
||||
|
||||
RDFC.Init(Bookmarks, containerNode);
|
||||
|
||||
// make sure appropriate bookmark type is set
|
||||
var bmTypeNode = Bookmarks.GetTarget( sourceNode, typeRes, true );
|
||||
if (!bmTypeNode)
|
||||
{
|
||||
// set default bookmark type
|
||||
Bookmarks.Assert(sourceNode, typeRes, bmTypeRes, true);
|
||||
}
|
||||
|
||||
if ((dropAction == "before") || (dropAction == "after"))
|
||||
{
|
||||
// drop before or after
|
||||
var nodeIndex;
|
||||
|
||||
nodeIndex = RDFC.IndexOf(sourceNode);
|
||||
|
||||
if (nodeIndex >= 1)
|
||||
{
|
||||
// moving a node around inside of the container
|
||||
// so remove, then re-add the node
|
||||
RDFC.RemoveElementAt(nodeIndex, true, sourceNode);
|
||||
}
|
||||
|
||||
nodeIndex = RDFC.IndexOf(targetNode);
|
||||
|
||||
if (nodeIndex < 1) return(false);
|
||||
if (dropAction == "after") ++nodeIndex;
|
||||
|
||||
RDFC.InsertElementAt(sourceNode, nodeIndex, true);
|
||||
|
||||
// select the newly added node
|
||||
if (parentID)
|
||||
{
|
||||
selectDroppedItems(treeRoot, containerID, sourceID);
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// drop on
|
||||
RDFC.AppendElement(sourceNode);
|
||||
|
||||
// select the newly added node
|
||||
if (parentID)
|
||||
{
|
||||
selectDroppedItems(treeRoot, containerID, sourceID);
|
||||
}
|
||||
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
if ((checkNameHack == true) || (name != null))
|
||||
{
|
||||
var srcArc = RDF.GetResource(sourceID, true);
|
||||
var propArc = RDF.GetResource(NC_NS + "Name", true);
|
||||
if (srcArc && propArc && Bookmarks)
|
||||
{
|
||||
var targetArc = Bookmarks.GetTarget(srcArc, propArc, true);
|
||||
if (!targetArc)
|
||||
{
|
||||
// if no name, fallback to using the URL as the name
|
||||
var defaultNameArc = RDF.GetLiteral((name != null && name != "") ? name : sourceID);
|
||||
if (defaultNameArc)
|
||||
{
|
||||
Bookmarks.Assert(srcArc, propArc, defaultNameArc, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// should we move the node? (i.e. take it out of the source container?)
|
||||
if ((parentNode != null) && (containerNode != parentNode))
|
||||
{
|
||||
try
|
||||
{
|
||||
RDFC.Init(Bookmarks, parentNode);
|
||||
nodeIndex = RDFC.IndexOf(sourceNode);
|
||||
|
||||
if (nodeIndex >= 1)
|
||||
{
|
||||
RDFC.RemoveElementAt(nodeIndex, true, sourceNode);
|
||||
}
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (dirty == true)
|
||||
{
|
||||
var remote = Bookmarks.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
|
||||
if (remote)
|
||||
{
|
||||
remote.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
function selectDroppedItems(treeRoot, containerID, targetID)
|
||||
{
|
||||
var select_list = treeRoot.getElementsByAttribute("id", targetID);
|
||||
for (var x=0; x<select_list.length; x++)
|
||||
{
|
||||
var node = select_list[x];
|
||||
if (!node) continue;
|
||||
|
||||
var parent = node.parentNode.parentNode;
|
||||
if (!parent) continue;
|
||||
|
||||
var id = parent.getAttribute("ref");
|
||||
if (!id || id=="")
|
||||
{
|
||||
id = parent.getAttribute("id");
|
||||
}
|
||||
if (!id || id=="") continue;
|
||||
|
||||
if (id == containerID)
|
||||
{
|
||||
treeRoot.selectItem(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,397 +0,0 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@netscape.com> (Original Author, v2.0)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
var NC_NS = "http://home.netscape.com/NC-rdf#";
|
||||
var RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
|
||||
|
||||
var gSpringLoadTracker = {
|
||||
timeout: 0,
|
||||
element: null,
|
||||
|
||||
open: function (aRDFNode)
|
||||
{
|
||||
if (this.element)
|
||||
this.element.setAttribute("open", "true");
|
||||
clearTimeout(this.timeout);
|
||||
}
|
||||
};
|
||||
|
||||
var bookmarksDNDObserver = {
|
||||
_RDF: null,
|
||||
get RDF ()
|
||||
{
|
||||
if (!this._RDF) {
|
||||
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
|
||||
const kRDFIID = Components.interfaces.nsIRDFService;
|
||||
this._RDF = Components.classes[kRDFContractID].getService(kRDFIID);
|
||||
}
|
||||
return this._RDF;
|
||||
},
|
||||
|
||||
// XXX I belong somewhere shared.
|
||||
getResource: function(aString)
|
||||
{
|
||||
return this.RDF.GetResource(aString, true);
|
||||
},
|
||||
|
||||
getTarget: function(aDS, aSourceID, aPropertyID)
|
||||
{
|
||||
var source = this.getResource(aSourceID);
|
||||
var property = this.getResource(aPropertyID);
|
||||
return aDS.GetTarget(source, property, true);
|
||||
},
|
||||
|
||||
onDragStart: function (aEvent, aXferData, aDragAction)
|
||||
{
|
||||
var bookmarksTree = document.getElementById("bookmarksTree");
|
||||
if (aEvent.target == bookmarksTree || aEvent.target.localName == "treechildren" ||
|
||||
aEvent.target.localName == "splitter" || aEvent.target.localName == "menu")
|
||||
throw Components.results.NS_OK; // not a draggable item.
|
||||
if (aEvent.target.parentNode && aEvent.target.parentNode.parentNode &&
|
||||
aEvent.target.parentNode.parentNode.localName == "treehead")
|
||||
throw Components.results.NS_OK; // don't drag treehead cells.
|
||||
if (bookmarksTree.getAttribute("sortActive") == "true")
|
||||
throw Components.results.NS_OK;
|
||||
|
||||
var selItems = null;
|
||||
if (bookmarksTree.selectedItems.length <= 0)
|
||||
selItems = [aEvent.target.parentNode.parentNode];
|
||||
else
|
||||
selItems = bookmarksTree.selectedItems;
|
||||
aXferData.data = new TransferDataSet();
|
||||
for (var i = 0; i < selItems.length; ++i) {
|
||||
var currItem = selItems[i];
|
||||
var currURI = NODE_ID(currItem);
|
||||
|
||||
var parentItem = currItem.parentNode.parentNode;
|
||||
var parentURI = NODE_ID(parentItem);
|
||||
|
||||
var type = this.getTarget(bookmarksTree.database, currURI, RDF_NS + "type");
|
||||
type = type.QueryInterface(Components.interfaces.nsIRDFResource).Value;
|
||||
if (!type || (type != (NC_NS + "BookmarkSeparator") &&
|
||||
type != (NC_NS + "Bookmark") &&
|
||||
type != (NC_NS + "Folder")))
|
||||
throw Components.results.NS_OK;
|
||||
var name = this.getTarget(bookmarksTree.database, currURI, NC_NS + "Name");
|
||||
var data = new TransferData();
|
||||
if (name) {
|
||||
name = name.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
||||
data.addDataForFlavour("text/x-moz-url", currURI + "\n" + name);
|
||||
}
|
||||
else {
|
||||
data.addDataForFlavour("text/x-moz-url", currURI);
|
||||
}
|
||||
data.addDataForFlavour("moz/rdfitem", currURI + "\n" + parentURI);
|
||||
|
||||
data.addDataForFlavour("text/unicode", currURI);
|
||||
aXferData.data.push(data);
|
||||
}
|
||||
|
||||
if (aEvent.ctrlKey) {
|
||||
const kDSIID = Components.interfaces.nsIDragService;
|
||||
aDragAction.action = kDSIID.DRAGDROP_ACTION_COPY + kDSIID.DRAGDROP_ACTION_LINK;
|
||||
}
|
||||
},
|
||||
|
||||
onDragOver: function (aEvent, aFlavour, aDragSession)
|
||||
{
|
||||
var bookmarksTree = document.getElementById("bookmarksTree");
|
||||
var rowGroup = aEvent.target.parentNode.parentNode;
|
||||
if (rowGroup)
|
||||
rowGroup.setAttribute("dd-triggerrepaint" +
|
||||
(bookmarksTree.getAttribute("sortActive") == "true" ? "sorted" : ""), 0);
|
||||
|
||||
var rdfNode = gBookmarksShell.findRDFNode(aEvent.target, true);
|
||||
var rdfParent = rdfNode.parentNode.parentNode;
|
||||
var isContainer = false;
|
||||
if (rdfParent && rdfParent.getAttribute("container") == "true") {
|
||||
var rDragOverContainer = this.RDF.GetResource(NODE_ID(rdfParent));
|
||||
|
||||
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
|
||||
const kRDFCUtilsContractID = "@mozilla.org/rdf/container-utils;1";
|
||||
const kRDFCUtilsIID = Components.interfaces.nsIRDFContainerUtils;
|
||||
const kRDFCUtils = Components.classes[kRDFCUtilsContractID].getService(kRDFCUtilsIID);
|
||||
isContainer = kRDFCUtils.IsContainer(kBMDS, rDragOverContainer);
|
||||
}
|
||||
|
||||
if (!isContainer || rowGroup.id == "headRow") {
|
||||
// Not a container, or dropping onto something that isn't designed to take drops
|
||||
// (e.g. the tree header)
|
||||
aDragSession.canDrop = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Springloaded folders.
|
||||
/* XXX - not yet.
|
||||
if (rdfNode && rdfNode.getAttribute("container") == "true" &&
|
||||
rdfNode.getAttribute("open") != "true") {
|
||||
if (!gSpringLoadTracker.element || gSpringLoadTracker.element.id != rdfNode.id) {
|
||||
// XXX - this is not good enough. We need to keep track of nesting and close up
|
||||
// folders after the user has dragged out of them otherwise we end up with
|
||||
// everything open and a big mess!
|
||||
if (gSpringLoadTracker.timeout)
|
||||
clearTimeout(gSpringLoadTracker.timeout);
|
||||
gSpringLoadTracker.element = rdfNode;
|
||||
gSpringLoadTracker.timeout = setTimeout("gSpringLoadTracker.open()", 100);
|
||||
}
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
_flavourSet: null,
|
||||
getSupportedFlavours: function ()
|
||||
{
|
||||
if (!this._flavourSet) {
|
||||
this._flavourSet = new FlavourSet();
|
||||
this._flavourSet.appendFlavour("moz/rdfitem");
|
||||
this._flavourSet.appendFlavour("text/x-moz-url");
|
||||
this._flavourSet.appendFlavour("text/unicode");
|
||||
}
|
||||
return this._flavourSet;
|
||||
},
|
||||
|
||||
canHandleMultipleItems: true,
|
||||
|
||||
onDrop: function (aEvent, aXferData, aDragSession)
|
||||
{
|
||||
var bookmarksTree = document.getElementById("bookmarksTree");
|
||||
// XXX lame
|
||||
if (bookmarksTree.getAttribute("sortActive") == "true") return;
|
||||
|
||||
const kRDFCContractID = "@mozilla.org/rdf/container;1";
|
||||
const kRDFIID = Components.interfaces.nsIRDFContainer;
|
||||
var RDFC = Components.classes[kRDFCContractID].getService(kRDFIID);
|
||||
|
||||
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
|
||||
|
||||
var dropItem = aEvent.target.parentNode.parentNode;
|
||||
if (aEvent.target.localName == "treechildren")
|
||||
dropItem = aEvent.target.parentNode; // handle drop on blank space.
|
||||
|
||||
// In the default view, the root node is the NC root, and we don't want to append
|
||||
// to that. Adjust accordingly...
|
||||
if (NODE_ID(dropItem) == "NC:NavCenter")
|
||||
dropItem = document.getElementById("treechildren-bookmarks").firstChild;
|
||||
|
||||
// Don't allow drops on the header row & prevent catastrophe
|
||||
if (dropItem.id == "headRow" || !dropItem) return;
|
||||
|
||||
// XXX we could probably compute this ourselves, but let the tree do this
|
||||
// automagically for now.
|
||||
var dropBefore = dropItem.getAttribute("dd-droplocation");
|
||||
var dropOn = dropItem.getAttribute("dd-dropon");
|
||||
|
||||
var dropAction = dropBefore == "true" ? "before" : dropOn == "true" ? "on" : "after";
|
||||
if (aEvent.target.localName == "treechildren")
|
||||
dropAction = "on"; // handle drop on blank space.
|
||||
var containerItem = dropAction == "on" ? dropItem : dropItem.parentNode.parentNode;
|
||||
|
||||
// XXX magical fix for bug # 33546: handle dropping after open container
|
||||
if (dropItem.getAttribute("container") && dropItem.getAttribute("open") &&
|
||||
dropAction == "after") {
|
||||
dropAction = "before";
|
||||
containerItem = dropItem;
|
||||
|
||||
dropItem = null;
|
||||
for (var i = 0; i < containerItem.childNodes.length; ++i) {
|
||||
if (containerItem.childNodes[i].localName == "treechildren") {
|
||||
dropItem = containerItem.childNodes[i].firstChild;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!dropItem) {
|
||||
dropAction = "on";
|
||||
dropItem = containerItem.parentNode.parentNode;
|
||||
}
|
||||
}
|
||||
|
||||
var rTarget = this.getResource(NODE_ID(dropItem));
|
||||
var rContainer = this.getResource(NODE_ID(containerItem));
|
||||
|
||||
const kRDFCUtilsContractID = "@mozilla.org/rdf/container-utils;1";
|
||||
const kRDFCUtilsIID = Components.interfaces.nsIRDFContainerUtils;
|
||||
const kRDFCUtils = Components.classes[kRDFCUtilsContractID].getService(kRDFCUtilsIID);
|
||||
var isContainer = kRDFCUtils.IsContainer(kBMDS, rContainer);
|
||||
|
||||
// XXX
|
||||
var rType = this.getResource(RDF_NS + "type");
|
||||
var rBookmark = this.getResource(NC_NS + "Bookmark");
|
||||
|
||||
var dirty = false;
|
||||
var additiveFlag = false;
|
||||
var numObjects = aXferData.dataList.length;
|
||||
/*
|
||||
if (numObjects > 1) {
|
||||
var bo = bookmarksTree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);
|
||||
bo.beginBatch();
|
||||
}
|
||||
*/
|
||||
|
||||
var sourceID = [], parentID = [], nameRequired = [], name = [];
|
||||
var flavourData;
|
||||
for (i = 0; i < numObjects; ++i) {
|
||||
flavourData = aXferData.dataList[i].first;
|
||||
nameRequired[i] = false;
|
||||
name[i] = null;
|
||||
var data = flavourData.data;
|
||||
switch (flavourData.flavour.contentType) {
|
||||
case "moz/rdfitem":
|
||||
var ix = data.indexOf("\n");
|
||||
sourceID[i] = ix >= 0 ? (parentID[i] = data.substr(ix+1), data.substr(0, ix)) : data;
|
||||
break;
|
||||
case "text/x-moz-url":
|
||||
ix = data.indexOf("\n");
|
||||
sourceID[i] = ix >= 0 ? (name[i] = data.substr(ix+1), data.substr(0, ix)) : data;
|
||||
break;
|
||||
case "text/unicode":
|
||||
sourceID[i] = data;
|
||||
nameRequired[i] = true;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
var rSource = this.getResource(sourceID[i]);
|
||||
var rParent = parentID[i] ? this.getResource(parentID[i]) : null;
|
||||
|
||||
// Prevent dropping node on itself, before or after itself, on its parent
|
||||
// container, or a weird situation when an open container is dropped into
|
||||
// itself (which results in data loss!).
|
||||
// Also prevent dropping into a folder that isn't actually a container
|
||||
// (and is thus probably a pseudo-container from an aggregated datasource,
|
||||
// see bug 68656 fir details).
|
||||
if (rSource == rTarget || (dropAction == "on" && rContainer == rParent) ||
|
||||
rContainer == rSource || !isContainer)
|
||||
return;
|
||||
|
||||
// Prevent dropping node into one of its own subfolders
|
||||
var dropItem2 = dropItem;
|
||||
do {
|
||||
var targetAncestor = NODE_ID(dropItem2);
|
||||
dropItem2 = dropItem2.parentNode;
|
||||
} while (targetAncestor != "NC:BookmarksRoot" && targetAncestor != sourceID[i]);
|
||||
if (targetAncestor == sourceID[i]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < numObjects; ++i) {
|
||||
flavourData = aXferData.dataList[i].first;
|
||||
rSource = this.getResource(sourceID[i]);
|
||||
rParent = parentID[i] ? this.getResource(parentID[i]) : null;
|
||||
|
||||
// XXX if any of the following fails, the nodes are gone for good!
|
||||
const kDSIID = Components.interfaces.nsIDragService;
|
||||
const kCopyAction = kDSIID.DRAGDROP_ACTION_COPY + kDSIID.DRAGDROP_ACTION_LINK;
|
||||
if (rParent) {
|
||||
if (!(aDragSession.dragAction & kCopyAction)) {
|
||||
try {
|
||||
RDFC.Init(kBMDS, rParent);
|
||||
ix = RDFC.IndexOf(rSource);
|
||||
if (ix >= 1)
|
||||
RDFC.RemoveElementAt(ix, true);
|
||||
}
|
||||
catch (ex) { }
|
||||
}
|
||||
}
|
||||
|
||||
RDFC.Init(kBMDS, rContainer);
|
||||
|
||||
// If this item already exists in this container, don't paste, as
|
||||
// this will result in the creation of multiple copies in the datasource
|
||||
// but will not result in an update of the UI. (In Short: we don't
|
||||
// handle multiple bookmarks well)
|
||||
ix = RDFC.IndexOf(rSource);
|
||||
if (ix != -1)
|
||||
continue;
|
||||
|
||||
var bmType = this.getTarget(bookmarksTree.database, sourceID[i], RDF_NS + "type");
|
||||
if (!bmType)
|
||||
kBMDS.Assert(rSource, rType, rBookmark, true);
|
||||
if (bmType == NC_NS + "Folder") {
|
||||
// If we're going to copy a folder type, we need to clone the folder
|
||||
// rather than just asserting the new node as a child of the drop folder.
|
||||
if (aDragSession.dragAction & kCopyAction)
|
||||
rSource = BookmarksUtils.cloneFolder(rSource, rContainer, rTarget);
|
||||
}
|
||||
|
||||
if (dropAction == "before" || dropAction == "after") {
|
||||
var dropIx = RDFC.IndexOf(rTarget);
|
||||
RDFC.InsertElementAt(rSource, dropAction == "after" ? ++dropIx : dropIx, true);
|
||||
}
|
||||
else
|
||||
RDFC.AppendElement(rSource); // drop on
|
||||
|
||||
dirty = true;
|
||||
|
||||
if (rParent) {
|
||||
gBookmarksShell.selectFolderItem(rContainer.Value, sourceID[i], additiveFlag);
|
||||
if (!additiveFlag) additiveFlag = true;
|
||||
}
|
||||
|
||||
// If a name is supplied, we want to assert this information into the
|
||||
// graph. E.g. user drags an internet shortcut to the app, we want to
|
||||
// preserve not only the URL but the name of the shortcut. The other case
|
||||
// where we need to assert a name is when the node does not already exist
|
||||
// in the graph, in this case we'll just use the URL as the name.
|
||||
if (name[i] || nameRequired[i]) {
|
||||
var currentName = this.getTarget(bookmarksTree.database, sourceID[i], NC_NS + "Name");
|
||||
if (!currentName) {
|
||||
var rDefaultName = this.RDF.GetLiteral(name[i] || sourceID[i]);
|
||||
if (rDefaultName) {
|
||||
var rName = this.RDF.GetResource(NC_NS + "Name");
|
||||
kBMDS.Assert(rSource, rName, rDefaultName, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (numObjects > 1) {
|
||||
var bo = bookmarksTree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);
|
||||
bo.endBatch();
|
||||
}
|
||||
*/
|
||||
|
||||
if (dirty) {
|
||||
var remoteDS = kBMDS.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
|
||||
remoteDS.Flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,954 +0,0 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@netscape.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
var NC_NS = "http://home.netscape.com/NC-rdf#";
|
||||
var RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
|
||||
const NC_NS_CMD = NC_NS + "command?cmd=";
|
||||
|
||||
/**
|
||||
* XXX - 04/16/01
|
||||
* ACK! massive command name collision problems are causing big issues
|
||||
* in getting this stuff to work in the Navigator window. For sanity's
|
||||
* sake, we need to rename all the commands to be of the form cmd_bm_*
|
||||
* otherwise there'll continue to be problems. For now, we're just
|
||||
* renaming those that affect the personal toolbar (edit operations,
|
||||
* which were clashing with the textfield controller)
|
||||
*
|
||||
* There are also several places that need to be updated if you need
|
||||
* to change a command name.
|
||||
* 1) the controller in ALL clients (bookmarksTree.js, personalToolbar.js)
|
||||
* 2) the command nodes in the overlay
|
||||
* 3) the command human-readable name key in bookmark.properties
|
||||
* 4) the function 'getAllCmds' in bookmarksOverlay.js
|
||||
* 5) the function 'execCommand' in bookmarksOverlay.js
|
||||
* Yes, this blows crusty dead goats through straws, and I should probably
|
||||
* create some constants somewhere to bring this number down to 3.
|
||||
* However, if you fail to do one of these, you WILL break something
|
||||
* and I WILL come after you with a knife.
|
||||
*/
|
||||
|
||||
function LITERAL (aDB, aElement, aPropertyID)
|
||||
{
|
||||
var RDF = BookmarksUIElement.prototype.RDF;
|
||||
var rSource = RDF.GetResource(aElement.id);
|
||||
var rProperty = RDF.GetResource(aPropertyID);
|
||||
var node = aDB.GetTarget(rSource, rProperty, true);
|
||||
return node ? node.QueryInterface(Components.interfaces.nsIRDFLiteral).Value : "";
|
||||
}
|
||||
|
||||
function BookmarksUIElement () { }
|
||||
BookmarksUIElement.prototype = {
|
||||
_rdf: null,
|
||||
get RDF ()
|
||||
{
|
||||
if (!this._rdf) {
|
||||
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
|
||||
const kRDFIID = Components.interfaces.nsIRDFService;
|
||||
this._rdf = Components.classes[kRDFContractID].getService(kRDFIID);
|
||||
}
|
||||
return this._rdf;
|
||||
},
|
||||
|
||||
propertySet: function (sourceID, propertyID, newValue)
|
||||
{
|
||||
if (!newValue) return;
|
||||
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
|
||||
const kRDFIID = Components.interfaces.nsIRDFService;
|
||||
const kRDF = Components.classes[kRDFContractID].getService(kRDFIID);
|
||||
// need to shuffle this into an API.
|
||||
const kBMDS = kRDF.GetDataSource("rdf:bookmarks");
|
||||
const krProperty = kRDF.GetResource(propertyID);
|
||||
const krItem = kRDF.GetResource(sourceID);
|
||||
var rCurrValue = kBMDS.GetTarget(krItem, krProperty, true);
|
||||
const krNewValue = kRDF.GetLiteral(newValue);
|
||||
if (!rCurrValue)
|
||||
kBMDS.Assert(krItem, krProperty, krNewValue, true);
|
||||
else {
|
||||
rCurrValue = rCurrValue.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
||||
if (rCurrValue.Value != newValue)
|
||||
kBMDS.Change(krItem, krProperty, rCurrValue, krNewValue);
|
||||
}
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Fill a context menu popup with menuitems that are appropriate for the current
|
||||
// selection.
|
||||
createContextMenu: function (aEvent)
|
||||
{
|
||||
var popup = aEvent.target;
|
||||
// clear out the old context menu contents (if any)
|
||||
while (popup.hasChildNodes())
|
||||
popup.removeChild(popup.firstChild);
|
||||
|
||||
var popupNode = document.popupNode;
|
||||
|
||||
if (!("findRDFNode" in this))
|
||||
throw "Clients must implement findRDFNode!";
|
||||
var itemNode = this.findRDFNode(popupNode, true);
|
||||
if (!itemNode || !itemNode.getAttributeNS(RDF_NS, "type") || itemNode.getAttribute("mode") == "edit") {
|
||||
aEvent.preventDefault();
|
||||
return;
|
||||
}
|
||||
if (!("getContextSelection" in this))
|
||||
throw "Clients must implement getContextSelection!";
|
||||
var selection = this.getContextSelection (itemNode);
|
||||
var commonCommands = [];
|
||||
for (var i = 0; i < selection.length; ++i) {
|
||||
var commands = this.getAllCmds(selection[i].id);
|
||||
if (!commands) {
|
||||
aEvent.preventDefault();
|
||||
return;
|
||||
}
|
||||
commands = this.flattenEnumerator(commands);
|
||||
if (!commonCommands.length) commonCommands = commands;
|
||||
commonCommands = this.findCommonNodes(commands, commonCommands);
|
||||
}
|
||||
|
||||
if (!commonCommands.length) {
|
||||
aEvent.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
// Now that we should have generated a list of commands that is valid
|
||||
// for the entire selection, build a context menu.
|
||||
for (i = 0; i < commonCommands.length; ++i) {
|
||||
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
var currCommand = commonCommands[i].QueryInterface(Components.interfaces.nsIRDFResource).Value;
|
||||
var element = null;
|
||||
if (currCommand != NC_NS_CMD + "bm_separator") {
|
||||
var commandName = this.getCommandName(currCommand);
|
||||
element = this.createMenuItem(commandName, currCommand, itemNode);
|
||||
}
|
||||
else if (i != 0 && i < commonCommands.length-1) {
|
||||
// Never append a separator as the first or last element in a context
|
||||
// menu.
|
||||
element = document.createElementNS(kXULNS, "menuseparator");
|
||||
}
|
||||
|
||||
if (element)
|
||||
popup.appendChild(element);
|
||||
}
|
||||
return;
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Given two unique arrays, return an array that contains only the elements
|
||||
// common to both.
|
||||
findCommonNodes: function (aNewArray, aOldArray)
|
||||
{
|
||||
var common = [];
|
||||
for (var i = 0; i < aNewArray.length; ++i) {
|
||||
for (var j = 0; j < aOldArray.length; ++j) {
|
||||
if (common.length > 0 && common[common.length-1] == aNewArray[i])
|
||||
continue;
|
||||
if (aNewArray[i] == aOldArray[j])
|
||||
common.push(aNewArray[i]);
|
||||
}
|
||||
}
|
||||
return common;
|
||||
},
|
||||
|
||||
flattenEnumerator: function (aEnumerator)
|
||||
{
|
||||
if ("_index" in aEnumerator)
|
||||
return aEnumerator._inner;
|
||||
|
||||
var temp = [];
|
||||
while (aEnumerator.hasMoreElements())
|
||||
temp.push(aEnumerator.getNext());
|
||||
return temp;
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// For a given URI (a unique identifier of a resource in the graph) return
|
||||
// an enumeration of applicable commands for that URI.
|
||||
getAllCmds: function (aNodeID)
|
||||
{
|
||||
var type = this.resolveType(aNodeID);
|
||||
if (!type) {
|
||||
if (aNodeID == "NC:PersonalToolbarFolder" || aNodeID == "NC:BookmarksRoot")
|
||||
type = "http://home.netscape.com/NC-rdf#Folder";
|
||||
else
|
||||
return null;
|
||||
}
|
||||
var commands = [];
|
||||
// menu order:
|
||||
//
|
||||
// bm_open
|
||||
// bm_openfolder
|
||||
// bm_openinnewwindow
|
||||
// /* bm_openinnewtab not yet supported */
|
||||
// ---------------------
|
||||
// /* bm_find removed */
|
||||
// bm_newfolder
|
||||
// ---------------------
|
||||
// bm_cut
|
||||
// bm_copy
|
||||
// bm_paste
|
||||
// bm_fileBookmark
|
||||
// ---------------------
|
||||
// bm_delete
|
||||
// bm_rename
|
||||
// ---------------------
|
||||
// bm_properties
|
||||
switch (type) {
|
||||
case "http://home.netscape.com/NC-rdf#BookmarkSeparator":
|
||||
commands = ["bm_newfolder", "bm_separator",
|
||||
"bm_cut", "bm_copy", "bm_paste", "bm_separator",
|
||||
"bm_delete"];
|
||||
break;
|
||||
case "http://home.netscape.com/NC-rdf#Bookmark":
|
||||
commands = ["bm_open", "bm_openinnewwindow", /* "bm_openinnewtab", */ "bm_separator",
|
||||
"bm_newfolder", "bm_separator",
|
||||
"bm_cut", "bm_copy", "bm_paste", "bm_fileBookmark", "bm_separator",
|
||||
"bm_delete", "bm_rename", "bm_separator",
|
||||
"bm_properties"];
|
||||
break;
|
||||
case "http://home.netscape.com/NC-rdf#Folder":
|
||||
commands = ["bm_openfolder", "bm_openinnewwindow", "bm_separator",
|
||||
"bm_newfolder", "bm_separator",
|
||||
"bm_cut", "bm_copy", "bm_paste", "bm_fileBookmark", "bm_separator",
|
||||
"bm_delete", "bm_rename", "bm_separator",
|
||||
"bm_properties"];
|
||||
break;
|
||||
case "http://home.netscape.com/NC-rdf#IEFavoriteFolder":
|
||||
commands = ["bm_openfolder", "bm_separator",
|
||||
"bm_delete"];
|
||||
break;
|
||||
case "http://home.netscape.com/NC-rdf#IEFavorite":
|
||||
commands = ["bm_open", "bm_openinnewwindow", /* "bm_openinnewtab", */ "bm_separator",
|
||||
"bm_copy"];
|
||||
break;
|
||||
case "http://home.netscape.com/NC-rdf#FileSystemObject":
|
||||
commands = ["bm_open", "bm_openinnewwindow", /* "bm_openinnewtab", */ "bm_separator",
|
||||
"bm_copy"];
|
||||
break;
|
||||
default:
|
||||
var source = this.RDF.GetResource(aNodeID);
|
||||
return this.db.GetAllCmds(source);
|
||||
}
|
||||
return new CommandArrayEnumerator(commands);
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Retrieve the human-readable name for a particular command. Used when
|
||||
// manufacturing a UI to invoke commands.
|
||||
getCommandName: function (aCommand)
|
||||
{
|
||||
var cmdName = aCommand.substring(NC_NS_CMD.length);
|
||||
try {
|
||||
// Note: this will succeed only if there's a string in the bookmarks
|
||||
// string bundle for this command name. Otherwise, <xul:stringbundle/>
|
||||
// will throw, we'll catch & stifle the error, and look up the command
|
||||
// name in the datasource.
|
||||
return this.getLocaleString ("cmd_" + cmdName);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
// XXX - WORK TO DO HERE! (rjc will cry if we don't fix this)
|
||||
// need to ask the ds for the commands for this node, however we don't
|
||||
// have the right params. This is kind of a problem.
|
||||
dump("*** BAD! EVIL! WICKED! NO! ACK! ARGH! ORGH!\n");
|
||||
const rName = this.RDF.GetResource(NC_NS + "Name");
|
||||
const rSource = this.RDF.GetResource(aNodeID);
|
||||
return this.db.GetTarget(rSource, rName, true).Value;
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Perform a command based on a UI event. XXX - work to do here.
|
||||
preExecCommand: function (aEvent)
|
||||
{
|
||||
var commandID = aEvent.target.getAttribute("cmd");
|
||||
if (!commandID) return;
|
||||
goDoCommand("cmd_" + commandID.substring(NC_NS_CMD.length));
|
||||
},
|
||||
|
||||
execCommand: function (aCommandID)
|
||||
{
|
||||
var args = [];
|
||||
var selection = this.getSelection ();
|
||||
if (selection.length >= 1)
|
||||
var selectedItem = selection[0];
|
||||
switch (aCommandID) {
|
||||
case "bm_open":
|
||||
this.open(null, selectedItem, false);
|
||||
break;
|
||||
case "bm_openfolder":
|
||||
this.commands.openFolder(selectedItem);
|
||||
break;
|
||||
case "bm_openinnewwindow":
|
||||
if (this.resolveType(selectedItem.id) == NC_NS + "Folder")
|
||||
this.openFolderInNewWindow(selectedItem);
|
||||
else
|
||||
this.open(null, selectedItem, true);
|
||||
break;
|
||||
case "bm_rename":
|
||||
// XXX - this is SO going to break if we ever do column re-ordering.
|
||||
this.commands.editCell(selectedItem, 0);
|
||||
break;
|
||||
case "bm_editurl":
|
||||
this.commands.editCell(selectedItem, 1);
|
||||
break;
|
||||
case "bm_setnewbookmarkfolder":
|
||||
case "bm_setpersonaltoolbarfolder":
|
||||
case "bm_setnewsearchfolder":
|
||||
BookmarksUtils.doBookmarksCommand(selectedItem.id, NC_NS_CMD + aCommandID, args);
|
||||
// XXX - The containing node seems to be closed here and the
|
||||
// focus/selection is destroyed.
|
||||
this.selectElement(selectedItem);
|
||||
break;
|
||||
case "bm_properties":
|
||||
this.showPropertiesForNode(selectedItem);
|
||||
break;
|
||||
case "bm_find":
|
||||
this.findInBookmarks();
|
||||
break;
|
||||
case "bm_cut":
|
||||
this.copySelection(selection);
|
||||
this.deleteSelection(selection);
|
||||
break;
|
||||
case "bm_copy":
|
||||
this.copySelection(selection);
|
||||
break;
|
||||
case "bm_paste":
|
||||
this.paste(selection);
|
||||
break;
|
||||
case "bm_delete":
|
||||
this.deleteSelection(selection);
|
||||
break;
|
||||
case "bm_fileBookmark":
|
||||
var rv = { selectedFolder: null };
|
||||
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
|
||||
"centerscreen,chrome,modal=yes,dialog=yes,resizable=yes", null, null, folder, null, "selectFolder", rv);
|
||||
if (rv.selectedFolder) {
|
||||
for (var k = 0; k < selection.length; ++k) {
|
||||
if (selection[k].id == rv.selectedFolder)
|
||||
return; // Selection contains the target folder. Just fail silently.
|
||||
}
|
||||
var additiveFlag = false;
|
||||
var selectedItems = [].concat(this.getSelection())
|
||||
for (var i = 0; i < selectedItems.length; ++i) {
|
||||
var currItem = selectedItems[i];
|
||||
var currURI = currItem.id;
|
||||
var parent = gBookmarksShell.findRDFNode(currItem, false);
|
||||
gBookmarksShell.moveBookmark(currURI, parent.id, rv.selectedFolder);
|
||||
gBookmarksShell.selectFolderItem(rv.selectedFolder, currURI, additiveFlag);
|
||||
if (!additiveFlag) additiveFlag = true;
|
||||
}
|
||||
gBookmarksShell.flushDataSource();
|
||||
}
|
||||
break;
|
||||
case "bm_newfolder":
|
||||
var nfseln = this.getBestItem();
|
||||
this.commands.createBookmarkItem("folder", nfseln);
|
||||
break;
|
||||
case "bm_newbookmark":
|
||||
var folder = this.getSelectedFolder();
|
||||
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
|
||||
"centerscreen,chrome,modal=yes,dialog=yes,resizable=no", null, null, folder, null, "newBookmark");
|
||||
break;
|
||||
case "bm_newseparator":
|
||||
nfseln = this.getBestItem();
|
||||
var parentNode = this.findRDFNode(nfseln, false);
|
||||
args = [{ property: NC_NS + "parent",
|
||||
resource: parentNode.id }];
|
||||
BookmarksUtils.doBookmarksCommand(nfseln.id, NC_NS_CMD + "newseparator", args);
|
||||
break;
|
||||
case "bm_import":
|
||||
case "bm_export":
|
||||
const isImport = aCommandID == "bm_import";
|
||||
try {
|
||||
const kFilePickerContractID = "@mozilla.org/filepicker;1";
|
||||
const kFilePickerIID = Components.interfaces.nsIFilePicker;
|
||||
const kFilePicker = Components.classes[kFilePickerContractID].createInstance(kFilePickerIID);
|
||||
|
||||
const kTitle = this.getLocaleString(isImport ? "SelectImport": "EnterExport");
|
||||
kFilePicker.init(window, kTitle, kFilePickerIID[isImport ? "modeOpen" : "modeSave"]);
|
||||
kFilePicker.appendFilters(kFilePickerIID.filterHTML | kFilePickerIID.filterAll);
|
||||
if (!isImport) kFilePicker.defaultString = "bookmarks.html";
|
||||
if (kFilePicker.show() != kFilePickerIID.returnCancel) {
|
||||
var fileName = kFilePicker.fileURL.spec;
|
||||
if (!fileName) break;
|
||||
}
|
||||
else break;
|
||||
}
|
||||
catch (e) {
|
||||
break;
|
||||
}
|
||||
var seln = this.getBestItem();
|
||||
args = [{ property: NC_NS + "URL", literal: fileName}];
|
||||
BookmarksUtils.doBookmarksCommand(seln.id, NC_NS_CMD + aCommandID, args);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
openFolderInNewWindow: function (aSelectedItem)
|
||||
{
|
||||
openDialog("chrome://communicator/content/bookmarks/bookmarks.xul",
|
||||
"", "chrome,all,dialog=no", aSelectedItem.id);
|
||||
},
|
||||
|
||||
copySelection: function (aSelection)
|
||||
{
|
||||
const kSuppArrayContractID = "@mozilla.org/supports-array;1";
|
||||
const kSuppArrayIID = Components.interfaces.nsISupportsArray;
|
||||
var itemArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID);
|
||||
|
||||
const kSuppWStringContractID = "@mozilla.org/supports-wstring;1";
|
||||
const kSuppWStringIID = Components.interfaces.nsISupportsWString;
|
||||
var bmstring = Components.classes[kSuppWStringContractID].createInstance(kSuppWStringIID);
|
||||
var unicodestring = Components.classes[kSuppWStringContractID].createInstance(kSuppWStringIID);
|
||||
var htmlstring = Components.classes[kSuppWStringContractID].createInstance(kSuppWStringIID);
|
||||
|
||||
var sBookmarkItem = ""; var sTextUnicode = ""; var sTextHTML = "";
|
||||
for (var i = 0; i < aSelection.length; ++i) {
|
||||
var url = LITERAL(this.db, aSelection[i], NC_NS + "URL");
|
||||
var name = LITERAL(this.db, aSelection[i], NC_NS + "Name");
|
||||
sBookmarkItem += aSelection[i].id + "\n";
|
||||
sTextUnicode += url + "\n";
|
||||
sTextHTML += "<A HREF=\"" + url + "\">" + name + "</A>";
|
||||
}
|
||||
|
||||
const kXferableContractID = "@mozilla.org/widget/transferable;1";
|
||||
const kXferableIID = Components.interfaces.nsITransferable;
|
||||
var xferable = Components.classes[kXferableContractID].createInstance(kXferableIID);
|
||||
|
||||
xferable.addDataFlavor("moz/bookmarkclipboarditem");
|
||||
bmstring.data = sBookmarkItem;
|
||||
xferable.setTransferData("moz/bookmarkclipboarditem", bmstring, sBookmarkItem.length*2)
|
||||
|
||||
xferable.addDataFlavor("text/html");
|
||||
htmlstring.data = sTextHTML;
|
||||
xferable.setTransferData("text/html", htmlstring, sTextHTML.length*2)
|
||||
|
||||
xferable.addDataFlavor("text/unicode");
|
||||
unicodestring.data = sTextUnicode;
|
||||
xferable.setTransferData("text/unicode", unicodestring, sTextUnicode.length*2)
|
||||
|
||||
const kClipboardContractID = "@mozilla.org/widget/clipboard;1";
|
||||
const kClipboardIID = Components.interfaces.nsIClipboard;
|
||||
var clipboard = Components.classes[kClipboardContractID].getService(kClipboardIID);
|
||||
clipboard.setData(xferable, null, kClipboardIID.kGlobalClipboard);
|
||||
},
|
||||
|
||||
paste: function (aSelection)
|
||||
{
|
||||
const kXferableContractID = "@mozilla.org/widget/transferable;1";
|
||||
const kXferableIID = Components.interfaces.nsITransferable;
|
||||
var xferable = Components.classes[kXferableContractID].createInstance(kXferableIID);
|
||||
xferable.addDataFlavor("moz/bookmarkclipboarditem");
|
||||
xferable.addDataFlavor("text/x-moz-url");
|
||||
xferable.addDataFlavor("text/unicode");
|
||||
|
||||
const kClipboardContractID = "@mozilla.org/widget/clipboard;1";
|
||||
const kClipboardIID = Components.interfaces.nsIClipboard;
|
||||
var clipboard = Components.classes[kClipboardContractID].getService(kClipboardIID);
|
||||
clipboard.getData(xferable, kClipboardIID.kGlobalClipboard);
|
||||
|
||||
var flavour = { };
|
||||
var data = { };
|
||||
var length = { };
|
||||
xferable.getAnyTransferData(flavour, data, length);
|
||||
var nodes = []; var names = [];
|
||||
data = data.value.QueryInterface(Components.interfaces.nsISupportsWString).data;
|
||||
switch (flavour.value) {
|
||||
case "moz/bookmarkclipboarditem":
|
||||
nodes = data.split("\n");
|
||||
break;
|
||||
case "text/x-moz-url":
|
||||
var ix = data.indexOf("\n");
|
||||
nodes.push(data.substring(0, ix != -1 ? ix : data.length));
|
||||
names.push(data.substring(ix));
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
const lastSelected = aSelection[aSelection.length-1];
|
||||
const kParentNode = this.resolvePasteFolder(aSelection);
|
||||
const krParent = this.RDF.GetResource(kParentNode.id);
|
||||
const krSource = this.RDF.GetResource(lastSelected.id);
|
||||
|
||||
const kRDFCContractID = "@mozilla.org/rdf/container;1";
|
||||
const kRDFCIID = Components.interfaces.nsIRDFContainer;
|
||||
const ksRDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
|
||||
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
|
||||
|
||||
var additiveFlag = false;
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
if (!nodes[i]) continue;
|
||||
var rCurrent = this.RDF.GetResource(nodes[i]);
|
||||
const krTypeProperty = this.RDF.GetResource(RDF_NS + "type");
|
||||
var rType = this.db.GetTarget(rCurrent, krTypeProperty, true);
|
||||
try {
|
||||
rType = rType.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
}
|
||||
catch (e) {
|
||||
try {
|
||||
rType = rType.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
||||
}
|
||||
catch (e) {
|
||||
// OK, no type exists, so node does not exist in the graph.
|
||||
// (e.g. user pastes url as text)
|
||||
// Do some housekeeping.
|
||||
const krName = this.RDF.GetResource(names[i]);
|
||||
const krNameProperty = this.RDF.GetResource(NC_NS + "Name");
|
||||
const krBookmark = this.RDF.GetResource(NC_NS + "Bookmark");
|
||||
kBMDS.Assert(rCurrent, krNameProperty, krName, true);
|
||||
kBMDS.Assert(rCurrent, krTypeProperty, krBookmark, true);
|
||||
}
|
||||
}
|
||||
|
||||
// If the node is a folder, then we need to create a new anonymous
|
||||
// resource and copy all the arcs over.
|
||||
if (rType && rType.Value == NC_NS + "Folder")
|
||||
rCurrent = BookmarksUtils.cloneFolder(rCurrent, krParent, krSource);
|
||||
|
||||
// If this item already exists in this container, don't paste, as
|
||||
// this will result in the creation of multiple copies in the datasource
|
||||
// but will not result in an update of the UI. (In Short: we don't
|
||||
// handle multiple bookmarks well)
|
||||
ksRDFC.Init(kBMDS, krParent);
|
||||
ix = ksRDFC.IndexOf(rCurrent);
|
||||
if (ix != -1)
|
||||
continue;
|
||||
|
||||
ix = ksRDFC.IndexOf(krSource);
|
||||
if (ix != -1)
|
||||
ksRDFC.InsertElementAt(rCurrent, ix+1, true);
|
||||
else
|
||||
ksRDFC.AppendElement(rCurrent);
|
||||
this.selectFolderItem(krSource.Value, rCurrent.Value, additiveFlag);
|
||||
if (!additiveFlag) additiveFlag = true;
|
||||
|
||||
var rds = kBMDS.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
|
||||
rds.Flush();
|
||||
}
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// For the given selection, determines the element that should form the
|
||||
// container to paste items into.
|
||||
resolvePasteFolder: function (aSelection)
|
||||
{
|
||||
const lastSelected = aSelection[aSelection.length-1];
|
||||
if (lastSelected.getAttribute("container") == "true" &&
|
||||
aSelection.length == 1)
|
||||
return lastSelected;
|
||||
return this.findRDFNode(lastSelected, false);
|
||||
},
|
||||
|
||||
canPaste: function ()
|
||||
{
|
||||
const kClipboardContractID = "@mozilla.org/widget/clipboard;1";
|
||||
const kClipboardIID = Components.interfaces.nsIClipboard;
|
||||
var clipboard = Components.classes[kClipboardContractID].getService(kClipboardIID);
|
||||
const kSuppArrayContractID = "@mozilla.org/supports-array;1";
|
||||
const kSuppArrayIID = Components.interfaces.nsISupportsArray;
|
||||
var flavourArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID);
|
||||
const kSuppStringContractID = "@mozilla.org/supports-string;1";
|
||||
const kSuppStringIID = Components.interfaces.nsISupportsString;
|
||||
|
||||
var flavours = ["moz/bookmarkclipboarditem", "text/x-moz-url"];
|
||||
for (var i = 0; i < flavours.length; ++i) {
|
||||
const kSuppString = Components.classes[kSuppStringContractID].createInstance(kSuppStringIID);
|
||||
kSuppString.data = flavours[i];
|
||||
flavourArray.AppendElement(kSuppString);
|
||||
}
|
||||
var hasFlavours = clipboard.hasDataMatchingFlavors(flavourArray, kClipboardIID.kGlobalClipboard);
|
||||
return hasFlavours;
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// aSelection is a mutable array, not a NodeList.
|
||||
deleteSelection: function (aSelection)
|
||||
{
|
||||
const kRDFCContractID = "@mozilla.org/rdf/container;1";
|
||||
const kRDFCIID = Components.interfaces.nsIRDFContainer;
|
||||
const ksRDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
|
||||
|
||||
var nextElement;
|
||||
var count = 0;
|
||||
|
||||
var selectionLength = aSelection.length;
|
||||
while (aSelection.length && aSelection[count]) {
|
||||
const currParent = this.findRDFNode(aSelection[count], false);
|
||||
const kSelectionURI = aSelection[count].id;
|
||||
|
||||
// Disallow the removal of certain 'special' nodes
|
||||
if (kSelectionURI == "NC:BookmarksRoot") {
|
||||
aSelection.splice(count++,1);
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the current bookmark is the IE Favorites folder, we have a little
|
||||
// extra work to do - set the pref |browser.bookmarks.import_system_favorites|
|
||||
// to ensure that we don't re-import next time.
|
||||
if (aSelection[count].getAttribute("type") == (NC_NS + "IEFavoriteFolder")) {
|
||||
const kPrefSvcContractID = "@mozilla.org/preferences-service;1";
|
||||
const kPrefSvcIID = Components.interfaces.nsIPrefBranch;
|
||||
const kPrefSvc = Components.classes[kPrefSvcContractID].getService(kPrefSvcIID);
|
||||
kPrefSvc.setBoolPref("browser.bookmarks.import_system_favorites", false);
|
||||
}
|
||||
|
||||
const krParent = this.RDF.GetResource(currParent.id);
|
||||
const krBookmark = this.RDF.GetResource(kSelectionURI);
|
||||
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
|
||||
|
||||
ksRDFC.Init(kBMDS, krParent);
|
||||
nextElement = this.getNextElement(aSelection[count]);
|
||||
ksRDFC.RemoveElement(krBookmark, true);
|
||||
|
||||
try {
|
||||
// XXX - UGH. Template builder is NOT removing the element from the
|
||||
// tree, and so selection remains non-zero in length and we go into
|
||||
// an infinite loop here. Tear the node out of the document.
|
||||
var parent = aSelection[count].parentNode;
|
||||
parent.removeChild(aSelection[count]);
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
// Manipulate the selection array ourselves.
|
||||
aSelection.splice(count,1);
|
||||
}
|
||||
this.selectElement(nextElement);
|
||||
},
|
||||
|
||||
moveBookmark: function (aBookmarkURI, aFromFolderURI, aToFolderURI)
|
||||
{
|
||||
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
|
||||
const kRDFCContractID = "@mozilla.org/rdf/container;1";
|
||||
const kRDFCIID = Components.interfaces.nsIRDFContainer;
|
||||
const kRDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
|
||||
const krSrc = this.RDF.GetResource(aBookmarkURI);
|
||||
const krOldParent = this.RDF.GetResource(aFromFolderURI);
|
||||
const krNewParent = this.RDF.GetResource(aToFolderURI);
|
||||
kRDFC.Init(kBMDS, krNewParent);
|
||||
kRDFC.AppendElement(krSrc);
|
||||
kRDFC.Init(kBMDS, krOldParent);
|
||||
kRDFC.RemoveElement(krSrc, true);
|
||||
},
|
||||
|
||||
open: function (aEvent, aRDFNode, aInNewWindow)
|
||||
{
|
||||
var urlValue = LITERAL(this.db, aRDFNode, NC_NS + "URL");
|
||||
|
||||
// Ignore "NC:" and empty urls.
|
||||
if (urlValue.substring(0,3) == "NC:" || !urlValue) return;
|
||||
|
||||
if (aEvent && aEvent.altKey)
|
||||
this.showPropertiesForNode (aRDFNode);
|
||||
else if (aInNewWindow)
|
||||
openDialog (getBrowserURL(), "_blank", "chrome,all,dialog=no", urlValue);
|
||||
else
|
||||
openTopWin (urlValue);
|
||||
if (aEvent)
|
||||
aEvent.preventBubble();
|
||||
},
|
||||
|
||||
showPropertiesForNode: function (aBookmarkItem)
|
||||
{
|
||||
if (aBookmarkItem.getAttribute("type") != NC_NS + "BookmarkSeparator")
|
||||
openDialog("chrome://communicator/content/bookmarks/bm-props.xul",
|
||||
"", "centerscreen,chrome,resizable=no", aBookmarkItem.id);
|
||||
},
|
||||
|
||||
findInBookmarks: function ()
|
||||
{
|
||||
openDialog("chrome://communicator/content/bookmarks/findBookmark.xul",
|
||||
"FindBookmarksWindow",
|
||||
"centerscreen,resizable=no,chrome,dependent");
|
||||
},
|
||||
|
||||
getLocaleString: function (aStringKey)
|
||||
{
|
||||
var bundle = document.getElementById("bookmarksbundle");
|
||||
return bundle.getString (aStringKey);
|
||||
},
|
||||
|
||||
flushDataSource: function ()
|
||||
{
|
||||
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
|
||||
var remoteDS = kBMDS.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
|
||||
remoteDS.Flush();
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Determine the rdf:type property for the given resource.
|
||||
resolveType: function (aID)
|
||||
{
|
||||
const krType = this.RDF.GetResource(RDF_NS + "type");
|
||||
const krElement = this.RDF.GetResource(aID);
|
||||
const type = gBookmarksShell.db.GetTarget(krElement, krType, true);
|
||||
try {
|
||||
return type.QueryInterface(Components.interfaces.nsIRDFResource).Value;
|
||||
}
|
||||
catch (e) {
|
||||
try {
|
||||
return type.QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
||||
}
|
||||
catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// takes a node and adds the appropriate adornments for a bookmark container.
|
||||
createBookmarkFolderDecorations: function (aNode)
|
||||
{
|
||||
aNode.setAttribute("type", "http://home.netscape.com/NC-rdf#Folder");
|
||||
aNode.setAttribute("container", "true");
|
||||
return aNode;
|
||||
}
|
||||
};
|
||||
|
||||
function CommandArrayEnumerator (aCommandArray)
|
||||
{
|
||||
this._inner = [];
|
||||
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
|
||||
const kRDFIID = Components.interfaces.nsIRDFService;
|
||||
const RDF = Components.classes[kRDFContractID].getService(kRDFIID);
|
||||
for (var i = 0; i < aCommandArray.length; ++i)
|
||||
this._inner.push(RDF.GetResource(NC_NS_CMD + aCommandArray[i]));
|
||||
|
||||
this._index = 0;
|
||||
}
|
||||
|
||||
CommandArrayEnumerator.prototype = {
|
||||
getNext: function ()
|
||||
{
|
||||
return this._inner[this._index];
|
||||
},
|
||||
|
||||
hasMoreElements: function ()
|
||||
{
|
||||
return this._index < this._inner.length;
|
||||
}
|
||||
};
|
||||
|
||||
var BookmarksUtils = {
|
||||
_rdf: null,
|
||||
get RDF ()
|
||||
{
|
||||
if (!this._rdf) {
|
||||
const kRDFContractID = "@mozilla.org/rdf/rdf-service;1";
|
||||
const kRDFIID = Components.interfaces.nsIRDFService;
|
||||
this._rdf = Components.classes[kRDFContractID].getService(kRDFIID);
|
||||
}
|
||||
return this._rdf;
|
||||
},
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Execute a command with the given source and arguments
|
||||
doBookmarksCommand: function (aSourceURI, aCommand, aArgumentsArray)
|
||||
{
|
||||
var rCommand = this.RDF.GetResource(aCommand);
|
||||
|
||||
var kSuppArrayContractID = "@mozilla.org/supports-array;1";
|
||||
var kSuppArrayIID = Components.interfaces.nsISupportsArray;
|
||||
var sourcesArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID);
|
||||
if (aSourceURI) {
|
||||
var rSource = this.RDF.GetResource(aSourceURI);
|
||||
sourcesArray.AppendElement (rSource);
|
||||
}
|
||||
|
||||
var argsArray = Components.classes[kSuppArrayContractID].createInstance(kSuppArrayIID);
|
||||
for (var i = 0; i < aArgumentsArray.length; ++i) {
|
||||
var rArc = this.RDF.GetResource(aArgumentsArray[i].property);
|
||||
argsArray.AppendElement(rArc);
|
||||
var rValue = null;
|
||||
if ("resource" in aArgumentsArray[i]) {
|
||||
rValue = this.RDF.GetResource(aArgumentsArray[i].resource);
|
||||
}
|
||||
else
|
||||
rValue = this.RDF.GetLiteral(aArgumentsArray[i].literal);
|
||||
argsArray.AppendElement(rValue);
|
||||
}
|
||||
|
||||
// Exec the command in the Bookmarks datasource.
|
||||
const kBMDS = this.RDF.GetDataSource("rdf:bookmarks");
|
||||
kBMDS.DoCommand(sourcesArray, rCommand, argsArray);
|
||||
},
|
||||
|
||||
cloneFolder: function (aFolder, aParent, aRelativeItem)
|
||||
{
|
||||
var BMDS = this.RDF.GetDataSource("rdf:bookmarks");
|
||||
|
||||
var nameArc = this.RDF.GetResource(NC_NS + "Name");
|
||||
var rName = BMDS.GetTarget(aFolder, nameArc, true);
|
||||
rName = rName.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
||||
|
||||
var newFolder = this.createFolderWithID(rName.Value, aRelativeItem, aParent);
|
||||
|
||||
// Now need to append kiddies.
|
||||
try {
|
||||
const kRDFCContractID = "@mozilla.org/rdf/container;1";
|
||||
const kRDFCIID = Components.interfaces.nsIRDFContainer;
|
||||
var RDFC = Components.classes[kRDFCContractID].getService(kRDFCIID);
|
||||
const kRDFCUContractID = "@mozilla.org/rdf/container-utils;1";
|
||||
const kRDFCUIID = Components.interfaces.nsIRDFContainerUtils;
|
||||
var RDFCU = Components.classes[kRDFCUContractID].getService(kRDFCUIID);
|
||||
|
||||
RDFC.Init(BMDS, aFolder);
|
||||
var elts = RDFC.GetElements();
|
||||
RDFC.Init(BMDS, newFolder);
|
||||
|
||||
while (elts.hasMoreElements()) {
|
||||
var curr = elts.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
if (RDFCU.IsContainer(BMDS, curr))
|
||||
BookmarksUtils.cloneFolder(curr, newFolder);
|
||||
else
|
||||
RDFC.AppendElement(curr);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
return newFolder;
|
||||
},
|
||||
|
||||
createFolderWithID: function (aTitle, aRelativeItem, aParentFolder)
|
||||
{
|
||||
const kRDFCContractID = "@mozilla.org/rdf/container;1";
|
||||
const kRDFCIID = Components.interfaces.nsIRDFContainer;
|
||||
var RDFC = Components.classes[kRDFCContractID].createInstance(kRDFCIID);
|
||||
var BMDS = this.RDF.GetDataSource("rdf:bookmarks");
|
||||
try {
|
||||
RDFC.Init(BMDS, aParentFolder);
|
||||
}
|
||||
catch (e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var ix = RDFC.IndexOf(aRelativeItem);
|
||||
var BMSvc = BMDS.QueryInterface(Components.interfaces.nsIBookmarksService);
|
||||
return BMSvc.createFolderWithDetails(aTitle, aParentFolder, ix);
|
||||
},
|
||||
|
||||
|
||||
addBookmarkForTabBrowser: function( aTabBrowser, aSelect )
|
||||
{
|
||||
var tabsInfo = [];
|
||||
var currentTabInfo = { name: "", url: "", charset: null };
|
||||
|
||||
const activeBrowser = aTabBrowser.selectedBrowser;
|
||||
const browsers = aTabBrowser.browsers;
|
||||
for (var i = 0; i < browsers.length; ++i) {
|
||||
var webNav = browsers[i].webNavigation;
|
||||
var url = webNav.currentURI.spec;
|
||||
var name = "";
|
||||
var charset;
|
||||
try {
|
||||
var doc = webNav.document;
|
||||
name = doc.title || url;
|
||||
charset = doc.characterSet;
|
||||
} catch (e) {
|
||||
name = url;
|
||||
}
|
||||
|
||||
tabsInfo[i] = { name: name, url: url, charset: charset };
|
||||
|
||||
if (browsers[i] == activeBrowser)
|
||||
currentTabInfo = tabsInfo[i];
|
||||
}
|
||||
|
||||
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
|
||||
"centerscreen,chrome,dialog=yes,resizable,dependent",
|
||||
currentTabInfo.name, currentTabInfo.url, null,
|
||||
currentTabInfo.charset, "addGroup" + (aSelect ? ",group" : ""), tabsInfo);
|
||||
},
|
||||
|
||||
addBookmarkForBrowser: function (aDocShell, aShowDialog)
|
||||
{
|
||||
// Bug 52536: We obtain the URL and title from the nsIWebNavigation
|
||||
// associated with a <browser/> rather than from a DOMWindow.
|
||||
// This is because when a full page plugin is loaded, there is
|
||||
// no DOMWindow (?) but information about the loaded document
|
||||
// may still be obtained from the webNavigation.
|
||||
var url = aDocShell.currentURI.spec;
|
||||
var title, docCharset = null;
|
||||
try {
|
||||
title = aDocShell.document.title || url;
|
||||
docCharset = aDocShell.document.characterSet;
|
||||
}
|
||||
catch (e) {
|
||||
title = url;
|
||||
}
|
||||
|
||||
this.addBookmark(url, title, docCharset, aShowDialog);
|
||||
},
|
||||
|
||||
addBookmark: function (aURL, aTitle, aCharset, aShowDialog)
|
||||
{
|
||||
if (aCharset === undefined) {
|
||||
var fw = document.commandDispatcher.focusedWindow;
|
||||
aCharset = fw.document.characterSet;
|
||||
}
|
||||
|
||||
if (aShowDialog)
|
||||
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
|
||||
"centerscreen,chrome,dialog=yes,resizable,dependent", aTitle, aURL, null, aCharset);
|
||||
else {
|
||||
// User has elected to override the file dialog and always file bookmarks
|
||||
// into the default bookmark folder.
|
||||
const kBMSvcContractID = "@mozilla.org/browser/bookmarks-service;1";
|
||||
const kBMSvcIID = Components.interfaces.nsIBookmarksService;
|
||||
const kBMSvc = Components.classes[kBMSvcContractID].getService(kBMSvcIID);
|
||||
kBMSvc.addBookmarkImmediately(aURL, aTitle, kBMSvcIID.BOOKMARK_DEFAULT_TYPE, aCharset);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var ContentUtils = {
|
||||
childByLocalName: function (aSelectedItem, aLocalName)
|
||||
{
|
||||
var temp = aSelectedItem.firstChild;
|
||||
while (temp) {
|
||||
if (temp.localName == aLocalName)
|
||||
return temp;
|
||||
temp = temp.nextSibling;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- -*- Mode: HTML; indent-tabs-mode: nil; -*- -->
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the Netscape Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/NPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The Original Code is mozilla.org code.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
Ben Goodger <ben@netscape.com> (Original Author)
|
||||
-->
|
||||
|
||||
<!DOCTYPE window SYSTEM "chrome://communicator/locale/bookmarks/bookmarksOverlay.dtd">
|
||||
|
||||
<overlay id="bookmarksOverlay"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<stringbundleset id="stringbundleset">
|
||||
<stringbundle id="bookmarksbundle"
|
||||
src="chrome://communicator/locale/bookmarks/bookmark.properties"/>
|
||||
</stringbundleset>
|
||||
|
||||
<popupset id="bookmarksPopupset">
|
||||
<popup id="bmContext"
|
||||
onpopupshowing="gBookmarksShell.createContextMenu(event);"/>
|
||||
</popupset>
|
||||
|
||||
<commands id="commands">
|
||||
<commandset id="bookmarksItems">
|
||||
<command id="cmd_bm_open" oncommand="goDoCommand('cmd_bm_open');"/>
|
||||
<command id="cmd_bm_openfolder" oncommand="goDoCommand('cmd_bm_openfolder');"/>
|
||||
<command id="cmd_bm_newfolder" oncommand="goDoCommand('cmd_bm_newfolder');"/>
|
||||
<command id="cmd_bm_newbookmark" oncommand="goDoCommand('cmd_bm_newbookmark');"/>
|
||||
<command id="cmd_bm_newseparator" oncommand="goDoCommand('cmd_bm_newseparator');"/>
|
||||
<command id="cmd_bm_find" oncommand="goDoCommand('cmd_bm_find');"/>
|
||||
<command id="cmd_bm_setnewbookmarkfolder" oncommand="goDoCommand('cmd_bm_setnewbookmarkfolder');"/>
|
||||
<command id="cmd_bm_setpersonaltoolbarfolder" oncommand="goDoCommand('cmd_bm_setpersonaltoolbarfolder');"/>
|
||||
<command id="cmd_bm_setnewsearchfolder" oncommand="goDoCommand('cmd_bm_setnewsearchfolder');"/>
|
||||
<command id="cmd_bm_properties" oncommand="goDoCommand('cmd_bm_properties');"/>
|
||||
<command id="cmd_bm_rename" oncommand="goDoCommand('cmd_bm_rename');"/>
|
||||
<command id="cmd_bm_openinnewwindow" oncommand="goDoCommand('cmd_bm_openinnewwindow');"/>
|
||||
<command id="cmd_bm_import" oncommand="goDoCommand('cmd_bm_import');"/>
|
||||
<command id="cmd_bm_export" oncommand="goDoCommand('cmd_bm_export');"/>
|
||||
<command id="cmd_bm_fileBookmark" oncommand="goDoCommand('cmd_bm_fileBookmark');"/>
|
||||
|
||||
<command id="cmd_bm_cut" oncommand="goDoCommand('cmd_bm_cut');"/>
|
||||
<command id="cmd_bm_copy" oncommand="goDoCommand('cmd_bm_copy');"/>
|
||||
<command id="cmd_bm_paste" oncommand="goDoCommand('cmd_bm_paste');"/>
|
||||
<command id="cmd_bm_delete" oncommand="goDoCommand('cmd_bm_delete');"/>
|
||||
<command id="cmd_bm_selectAll" oncommand="goDoCommand('cmd_bm_selectAll');"/>
|
||||
</commandset>
|
||||
<commandset id="selectEditMenuItems"/>
|
||||
<commandset id="globalEditMenuItems"/>
|
||||
</commands>
|
||||
|
||||
</overlay>
|
||||
@@ -1,64 +0,0 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@netscape.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Get the two bookmarks utility libraries running, attach controllers, focus
|
||||
// tree widget, etc.
|
||||
function Startup()
|
||||
{
|
||||
var bookmarksView = document.getElementById("bookmarks-view");
|
||||
bookmarksView.treeBoxObject.selection.select(0);
|
||||
}
|
||||
|
||||
function manageBookmarks() {
|
||||
openDialog("chrome://communicator/content/bookmarks/bookmarks.xul", "", "chrome,dialog=no,resizable=yes");
|
||||
}
|
||||
|
||||
function addBookmark() {
|
||||
var contentArea = top.document.getElementById('content');
|
||||
if (contentArea) {
|
||||
const browsers = contentArea.browsers;
|
||||
if (browsers.length > 1)
|
||||
BookmarksUtils.addBookmarkForTabBrowser(contentArea);
|
||||
else
|
||||
BookmarksUtils.addBookmarkForBrowser(contentArea.webNavigation, true);
|
||||
}
|
||||
else
|
||||
BookmarksUtils.addBookmark(null, null, undefined, true);
|
||||
}
|
||||
@@ -1,759 +0,0 @@
|
||||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@netscape.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
var gBookmarksShell = null;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Tracks the selected item, the cell last clicked on, and the number of clicks
|
||||
// given to it. Used to activate inline edit mode.
|
||||
var gSelectionTracker = { currentItem: null, currentCell: null, clickCount: 0 };
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Class which defines methods for a bookmarks UI implementation based around
|
||||
// a treeview. Subclasses BookmarksBase in bookmarksOverlay.js. Some methods
|
||||
// are required by the base class, others are for event handling. Window specific
|
||||
// glue code should go into the BookmarksWindow class in bookmarks.js
|
||||
function BookmarksTree (aID)
|
||||
{
|
||||
this.id = aID;
|
||||
}
|
||||
|
||||
BookmarksTree.prototype = {
|
||||
__proto__: BookmarksUIElement.prototype,
|
||||
|
||||
// XXX - change this to .element and move into base.
|
||||
get tree ()
|
||||
{
|
||||
return document.getElementById(this.id);
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// This method constructs a menuitem for a context menu for the given command.
|
||||
// This is implemented by the client so that it can intercept menuitem naming
|
||||
// as appropriate.
|
||||
createMenuItem: function (aDisplayName, aCommandName, aItemNode)
|
||||
{
|
||||
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
var xulElement = document.createElementNS(kXULNS, "menuitem");
|
||||
xulElement.setAttribute("cmd", aCommandName);
|
||||
xulElement.setAttribute("command", "cmd_" + aCommandName.substring(NC_NS_CMD.length));
|
||||
|
||||
switch (aCommandName) {
|
||||
case NC_NS_CMD + "open":
|
||||
xulElement.setAttribute("label", aDisplayName);
|
||||
xulElement.setAttribute("default", "true");
|
||||
break;
|
||||
case NC_NS_CMD + "openfolder":
|
||||
aDisplayName = aItemNode.getAttribute("open") == "true" ? this.getLocaleString("cmd_openfolder2") : aDisplayName;
|
||||
xulElement.setAttribute("label", aDisplayName);
|
||||
xulElement.setAttribute("default", "true");
|
||||
break;
|
||||
case NC_NS_CMD + "renamebookmark":
|
||||
if (!document.popupNode.hasAttribute("type")) {
|
||||
xulElement.setAttribute("label", this.getLocaleString("cmd_renamebookmark2"));
|
||||
xulElement.setAttribute("cmd", (NC_NS_CMD + "editurl"));
|
||||
}
|
||||
else
|
||||
xulElement.setAttribute("label", aDisplayName);
|
||||
break;
|
||||
default:
|
||||
xulElement.setAttribute("label", aDisplayName);
|
||||
break;
|
||||
}
|
||||
return xulElement;
|
||||
},
|
||||
|
||||
// XXX - ideally this would be in the base. this.tree needs to change to
|
||||
// this.element and then we can do just that.
|
||||
setRoot: function (aRoot)
|
||||
{
|
||||
this.tree.setAttribute("ref", aRoot);
|
||||
},
|
||||
|
||||
// Command implementation
|
||||
commands: {
|
||||
openFolder: function (aSelectedItem)
|
||||
{
|
||||
if (aSelectedItem.getAttribute("open") == "true")
|
||||
aSelectedItem.removeAttribute("open");
|
||||
else
|
||||
aSelectedItem.setAttribute("open", "true");
|
||||
},
|
||||
|
||||
// Things Needed to Satisfy Mac Weenies:
|
||||
// 1) need to implement timed single click edit. This could be Hard.
|
||||
// 2) need to implement some other method of key access apart from F2.
|
||||
// mpt claims that 'Cmd+U' is the excel equivalent.
|
||||
editCell: function (aSelectedItem, aCell)
|
||||
{
|
||||
// XXX throw up properties dialog with name selected so user can rename
|
||||
// that way, until tree conversion allows us to use IL again.
|
||||
goDoCommand("cmd_properties");
|
||||
return; // Disable inline edit for now.
|
||||
|
||||
var editCell = aSelectedItem.firstChild.childNodes[aCell];
|
||||
if (editCell.getAttribute("editable") != "true")
|
||||
return;
|
||||
|
||||
// Cause the inline edit cell binding to be used.
|
||||
editCell.setAttribute("class", "treecell-indent treecell-editable");
|
||||
var editColGroup = document.getElementById("theColumns");
|
||||
var count = 0;
|
||||
var property = "";
|
||||
for (var i = 0; i < editColGroup.childNodes.length; ++i) {
|
||||
var currCol = editColGroup.childNodes[i];
|
||||
if (currCol.getAttribute("hidden") == "true")
|
||||
return;
|
||||
if (count == aCell) {
|
||||
property = currCol.getAttribute("resource");
|
||||
break;
|
||||
}
|
||||
++count;
|
||||
|
||||
// Deal with interleaved column resizer splitters
|
||||
if (currCol.nextSibling.localName == "splitter") ++i;
|
||||
}
|
||||
|
||||
if (property) {
|
||||
editCell.setMode("edit");
|
||||
editCell.addObserver(this.postModifyCallback, "accept",
|
||||
[editCell, aSelectedItem, property]);
|
||||
}
|
||||
},
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Called after an inline-edit cell has left inline-edit mode, and data
|
||||
// needs to be modified in the datasource.
|
||||
postModifyCallback: function (aParams)
|
||||
{
|
||||
var selItemURI = NODE_ID(aParams[1]);
|
||||
gBookmarksShell.propertySet(selItemURI, aParams[2], aParams[3]);
|
||||
gBookmarksShell.selectFolderItem(NODE_ID(gBookmarksShell.findRDFNode(aParams[1], false)),
|
||||
selItemURI, false);
|
||||
gBookmarksShell.tree.focus();
|
||||
gSelectionTracker.clickCount = 0;
|
||||
|
||||
// Set the cell back to use the standard treecell binding.
|
||||
var editCell = aParams[0];
|
||||
editCell.setAttribute("class", "treecell-indent");
|
||||
},
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// New Folder Creation
|
||||
// Strategy: create a dummy row with edit fields to harvest information
|
||||
// from the user, then destroy these rows and create an item
|
||||
// in its place.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Edit folder name & update the datasource if name is valid
|
||||
onEditFolderName: function (aParams, aTopic)
|
||||
{
|
||||
var name = aParams[3];
|
||||
var shell = gBookmarksShell.commands; // suck
|
||||
var dummyItem = aParams[2];
|
||||
var relativeNode = aParams[1];
|
||||
var parentNode = relativeNode ? gBookmarksShell.findRDFNode(relativeNode, false) : gBookmarksShell.tree;
|
||||
|
||||
dummyItem.parentNode.removeChild(dummyItem);
|
||||
|
||||
if (!shell.validateNameAndTopic(name, aTopic, relativeNode, dummyItem)) {
|
||||
gBookmarksShell.tree.selectItem(relativeNode);
|
||||
gBookmarksShell.tree.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
if (relativeNode) {
|
||||
// If we're attempting to create a folder as a subfolder of an open folder,
|
||||
// we need to set the parentFolder to be relativeNode, which will be the
|
||||
// parent of the new folder, rather than the parent of the relativeNode,
|
||||
// which will result in the folder being created in an incorrect position
|
||||
// (adjacent to the relativeNode).
|
||||
var selKids = ContentUtils.childByLocalName(relativeNode, "treechildren");
|
||||
if (selKids && selKids.hasChildNodes() && selKids.lastChild == dummyItem)
|
||||
parentNode = relativeNode;
|
||||
}
|
||||
|
||||
var args = [{ property: NC_NS + "parent",
|
||||
resource: NODE_ID(parentNode) },
|
||||
{ property: NC_NS + "Name",
|
||||
literal: name }];
|
||||
|
||||
const kBMDS = gBookmarksShell.RDF.GetDataSource("rdf:bookmarks");
|
||||
kBMDS.AddObserver(newFolderRDFObserver);
|
||||
var relId = relativeNode ? NODE_ID(relativeNode) : "NC:BookmarksRoot";
|
||||
BookmarksUtils.doBookmarksCommand(relId, NC_NS_CMD + "newfolder", args);
|
||||
kBMDS.RemoveObserver(newFolderRDFObserver);
|
||||
var newFolderItem = document.getElementById(newFolderRDFObserver._newFolderURI);
|
||||
gBookmarksShell.tree.focus();
|
||||
gBookmarksShell.tree.selectItem(newFolderItem);
|
||||
// Can't use newFolderItem because it may not have been created yet. Hack, huh?
|
||||
var index = gBookmarksShell.tree.getIndexOfItem(relativeNode);
|
||||
gBookmarksShell.tree.ensureIndexIsVisible(index+1);
|
||||
gSelectionTracker.clickCount = 0;
|
||||
},
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Performs simple validation on what the user has entered:
|
||||
// 1) prevents entering an empty string
|
||||
// 2) in the case of a canceled operation, remove the dummy item and
|
||||
// restore selection.
|
||||
validateNameAndTopic: function (aName, aTopic, aOldSelectedItem, aDummyItem)
|
||||
{
|
||||
// Don't allow user to enter an empty string "";
|
||||
if (!aName) return false;
|
||||
|
||||
// If the user hit escape, go no further.
|
||||
if (aTopic == "reject") {
|
||||
if (aOldSelectedItem)
|
||||
gBookmarksShell.tree.selectItem(aOldSelectedItem);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Creates a dummy item that can be placed in edit mode to retrieve data
|
||||
// to create new bookmarks/folders.
|
||||
createBookmarkItem: function (aMode, aSelectedItem)
|
||||
{
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// HACK HACK HACK HACK HACK
|
||||
// Disable Inline-Edit for now and just use a dialog.
|
||||
|
||||
// XXX - most of this is just copy-pasted from the other two folder
|
||||
// creation functions. Yes it's ugly, but it'll do the trick for
|
||||
// now as this is in no way intended to be a long-term solution.
|
||||
|
||||
const kPromptSvcContractID = "@mozilla.org/embedcomp/prompt-service;1";
|
||||
const kPromptSvcIID = Components.interfaces.nsIPromptService;
|
||||
const kPromptSvc = Components.classes[kPromptSvcContractID].getService(kPromptSvcIID);
|
||||
|
||||
var defaultValue = gBookmarksShell.getLocaleString("ile_newfolder");
|
||||
var dialogTitle = gBookmarksShell.getLocaleString("newfolder_dialog_title");
|
||||
var dialogMsg = gBookmarksShell.getLocaleString("newfolder_dialog_msg");
|
||||
var stringValue = { value: defaultValue };
|
||||
if (kPromptSvc.prompt(window, dialogTitle, dialogMsg, stringValue, null, { value: 0 })) {
|
||||
var relativeNode = gBookmarksShell.tree;
|
||||
var parentNode;
|
||||
if (aSelectedItem && aSelectedItem.localName != "tree") {
|
||||
// By default, create adjacent to the selected item
|
||||
relativeNode = aSelectedItem;
|
||||
if (relativeNode.getAttribute("container") == "true" &&
|
||||
relativeNode.getAttribute("open") == "true") {
|
||||
// But if it's an open container, the relative node should be the last child.
|
||||
var treechildren = ContentUtils.childByLocalName(relativeNode, "treechildren");
|
||||
if (treechildren && treechildren.hasChildNodes())
|
||||
relativeNode = treechildren.lastChild; // folder non-empty, set relativeNode
|
||||
parentNode = aSelectedItem; // no matter what, folder is open, so make it parent
|
||||
} else {
|
||||
parentNode = relativeNode ? gBookmarksShell.findRDFNode(relativeNode, false) : gBookmarksShell.tree;
|
||||
}
|
||||
}
|
||||
|
||||
var args = [{ property: NC_NS + "parent",
|
||||
resource: NODE_ID(parentNode) },
|
||||
{ property: NC_NS + "Name",
|
||||
literal: stringValue.value }];
|
||||
|
||||
const kBMDS = gBookmarksShell.RDF.GetDataSource("rdf:bookmarks");
|
||||
kBMDS.AddObserver(newFolderRDFObserver);
|
||||
var relId = relativeNode ? NODE_ID(relativeNode) : "NC:BookmarksRoot";
|
||||
BookmarksUtils.doBookmarksCommand(relId, NC_NS_CMD + "newfolder", args);
|
||||
kBMDS.RemoveObserver(newFolderRDFObserver);
|
||||
var newFolderItem = document.getElementById(newFolderRDFObserver._newFolderURI);
|
||||
gBookmarksShell.tree.focus();
|
||||
gBookmarksShell.tree.selectItem(newFolderItem);
|
||||
// Can't use newFolderItem because it may not have been created yet. Hack, huh?
|
||||
var index = gBookmarksShell.tree.getIndexOfItem(relativeNode);
|
||||
gBookmarksShell.tree.ensureIndexIsVisible(index+1);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
// HACK HACK HACK HACK HACK
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* Disable inline edit for now
|
||||
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
var dummyItem = document.createElementNS(kXULNS, "treeitem");
|
||||
dummyItem = gBookmarksShell.createBookmarkFolderDecorations(dummyItem);
|
||||
dummyItem.setAttribute("class", "bookmark-item");
|
||||
|
||||
var dummyRow = document.createElementNS(kXULNS, "treerow");
|
||||
var dummyCell = document.createElementNS(kXULNS, "treecell");
|
||||
var dummyCell2 = document.createElementNS(kXULNS, "treecell");
|
||||
dummyCell.setAttribute("label", gBookmarksShell.getLocaleString("ile_newfolder") + " ");
|
||||
dummyCell.setAttribute("type", NC_NS + "Folder");
|
||||
dummyCell.setAttribute("editable", "true");
|
||||
dummyCell.setAttribute("class", "treecell-indent treecell-editable");
|
||||
dummyRow.appendChild(dummyCell);
|
||||
dummyItem.appendChild(dummyRow);
|
||||
|
||||
var relativeNode = null;
|
||||
|
||||
// If there are selected items, try to create the dummy item relative to the
|
||||
// best item, and position the bookmark there when created. Otherwise just
|
||||
// append to the root.
|
||||
if (aSelectedItem && aSelectedItem.localName != "tree") {
|
||||
// By default, create adjacent to the selected item
|
||||
relativeNode = aSelectedItem;
|
||||
if (relativeNode.getAttribute("container") == "true" &&
|
||||
relativeNode.getAttribute("open") == "true") {
|
||||
// But if it's an open container, the relative node should be the last child.
|
||||
var treechildren = ContentUtils.childByLocalName(relativeNode, "treechildren");
|
||||
if (treechildren && treechildren.hasChildNodes())
|
||||
relativeNode = treechildren.lastChild;
|
||||
}
|
||||
|
||||
if (aSelectedItem.getAttribute("container") == "true") {
|
||||
if (aSelectedItem.getAttribute("open") == "true") {
|
||||
var treechildren = ContentUtils.childByLocalName(aSelectedItem, "treechildren");
|
||||
if (!treechildren) {
|
||||
treechildren = document.createElementNS(kXULNS, "treechildren");
|
||||
aSelectedItem.appendChild(treechildren);
|
||||
}
|
||||
// Insert new item after last item.
|
||||
treechildren.appendChild(dummyItem);
|
||||
}
|
||||
else {
|
||||
if (aSelectedItem.nextSibling)
|
||||
aSelectedItem.parentNode.insertBefore(dummyItem, aSelectedItem.nextSibling);
|
||||
else
|
||||
aSelectedItem.parentNode.appendChild(dummyItem);
|
||||
}
|
||||
var index = gBookmarksShell.tree.getIndexOfItem(dummyItem);
|
||||
gBookmarksShell.tree.ensureIndexIsVisible(index);
|
||||
}
|
||||
else {
|
||||
if (aSelectedItem.nextSibling)
|
||||
aSelectedItem.parentNode.insertBefore(dummyItem, aSelectedItem.nextSibling);
|
||||
else
|
||||
aSelectedItem.parentNode.appendChild(dummyItem);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No items in the tree. Append to the root.
|
||||
var rootKids = document.getElementById("treechildren-bookmarks");
|
||||
rootKids.appendChild(dummyItem);
|
||||
}
|
||||
|
||||
dummyCell.setMode("edit");
|
||||
dummyCell.addObserver(this.onEditFolderName, "accept", [dummyCell, relativeNode, dummyItem]);
|
||||
dummyCell.addObserver(this.onEditFolderName, "reject", [dummyCell, relativeNode, dummyItem]);
|
||||
*/
|
||||
}
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Evaluates an event to determine whether or not it affords opening a tree
|
||||
// item. Typically, this is when the left mouse button is used, and provided
|
||||
// the click-rate matches that specified by our owning tree class. For example,
|
||||
// some trees open an item when double clicked (bookmarks/history windows) and
|
||||
// others on a single click (sidebar panels).
|
||||
isValidOpenEvent: function (aEvent)
|
||||
{
|
||||
return !(aEvent.type == "click" &&
|
||||
(aEvent.button != 0 || aEvent.detail != this.openClickCount))
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// For the given selection, selects the best adjacent element. This method is
|
||||
// useful when an action such as a cut or a deletion is performed on a
|
||||
// selection, and focus/selection needs to be restored after the operation
|
||||
// is performed.
|
||||
getNextElement: function (aElement)
|
||||
{
|
||||
if (aElement.nextSibling)
|
||||
return aElement.nextSibling;
|
||||
else if (aElement.previousSibling)
|
||||
return aElement.previousSibling;
|
||||
else
|
||||
return aElement.parentNode.parentNode;
|
||||
},
|
||||
|
||||
selectElement: function (aElement)
|
||||
{
|
||||
this.tree.selectItem(aElement);
|
||||
},
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Add the treeitem element specified by aURI to the tree's current selection.
|
||||
addItemToSelection: function (aURI)
|
||||
{
|
||||
var item = document.getElementById(aURI) // XXX flawed for multiple ids
|
||||
this.tree.addItemToSelection(item);
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Return a set of DOM nodes that represent the selection in the tree widget.
|
||||
// This method is takes a node parameter which is the popupNode for the
|
||||
// document. If the popupNode is not contained by the selection, the
|
||||
// popupNode is selected and the new selection returned.
|
||||
getSelection: function ()
|
||||
{
|
||||
// Note that we don't just the selectedItems NodeList here because that
|
||||
// is a reference to a LIVE DOM NODE LIST. We want to maintain control
|
||||
// over what is in the selection array ourselves.
|
||||
return [].concat(this.tree.selectedItems);
|
||||
},
|
||||
|
||||
getBestItem: function ()
|
||||
{
|
||||
var seln = this.getSelection ();
|
||||
if (seln.length < 1) {
|
||||
var kids = ContentUtils.childByLocalName(this.tree, "treechildren");
|
||||
return kids.lastChild || this.tree;
|
||||
}
|
||||
else
|
||||
return seln[0];
|
||||
return this.tree;
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Return a set of DOM nodes that represent the selection in the tree widget.
|
||||
// This method is takes a node parameter which is the popupNode for the
|
||||
// document. If the popupNode is not contained by the selection, the
|
||||
// popupNode is selected and the new selection returned.
|
||||
getContextSelection: function (aItemNode)
|
||||
{
|
||||
// How a context-click works:
|
||||
// if the popup node is contained by the selection, the context menu is
|
||||
// built for that selection. However, if the popup node is invoked on a
|
||||
// non-selected node, unless modifiers are pressed**, the previous
|
||||
// selection is discarded and that node selected.
|
||||
var selectedItems = this.tree.selectedItems;
|
||||
for (var i = 0; i < selectedItems.length; ++i) {
|
||||
if (selectedItems[i] == aItemNode)
|
||||
return selectedItems;
|
||||
}
|
||||
if (aItemNode.localName == "treeitem")
|
||||
this.tree.selectItem(aItemNode);
|
||||
return this.tree.selectedItems.length ? this.tree.selectedItems : [this.tree];
|
||||
},
|
||||
|
||||
getSelectedFolder: function ()
|
||||
{
|
||||
var selectedItem = this.getBestItem();
|
||||
if (!selectedItem) return "NC:BookmarksRoot";
|
||||
while (selectedItem && selectedItem.nodeType == Node.ELEMENT_NODE) {
|
||||
if (selectedItem.getAttribute("container") == "true" &&
|
||||
selectedItem.getAttribute("open") == "true")
|
||||
return NODE_ID(selectedItem);
|
||||
selectedItem = selectedItem.parentNode.parentNode;
|
||||
}
|
||||
return "NC:BookmarksRoot";
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// For a given start DOM element, find the enclosing DOM element that contains
|
||||
// the template builder RDF resource decorations (id, ref, etc).
|
||||
findRDFNode: function (aStartNode, aIncludeStartNodeFlag)
|
||||
{
|
||||
var temp = aIncludeStartNodeFlag ? aStartNode : aStartNode.parentNode;
|
||||
while (temp && temp.localName != "treeitem")
|
||||
temp = temp.parentNode;
|
||||
return temp || this.tree;
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Tree click events. This handles when to go into inline-edit mode for
|
||||
// editable cells.
|
||||
treeClicked: function (aEvent)
|
||||
{
|
||||
// We are disabling Inline Edit for now. It's too buggy in the old XUL tree widget.
|
||||
// A more solid implementation will follow the conversion to tree
|
||||
/*
|
||||
if (this.tree.selectedItems.length > 1 || aEvent.detail > 1 || aEvent.button != 0) {
|
||||
gSelectionTracker.clickCount = 0;
|
||||
return;
|
||||
}
|
||||
if (gSelectionTracker.currentItem == this.tree.currentItem &&
|
||||
gSelectionTracker.currentCell == aEvent.target)
|
||||
++gSelectionTracker.clickCount;
|
||||
else
|
||||
gSelectionTracker.clickCount = 0;
|
||||
|
||||
if (!this.tree.currentItem)
|
||||
return;
|
||||
|
||||
gSelectionTracker.currentItem = this.tree.currentItem;
|
||||
gSelectionTracker.currentCell = aEvent.target;
|
||||
|
||||
if (gSelectionTracker.currentItem.getAttribute("type") != NC_NS + "Bookmark" &&
|
||||
gSelectionTracker.currentItem.getAttribute("type") != NC_NS + "Folder")
|
||||
return;
|
||||
|
||||
var row = gSelectionTracker.currentItem.firstChild;
|
||||
if (row) {
|
||||
for (var i = 0; i < row.childNodes.length; ++i) {
|
||||
if (row.childNodes[i] == gSelectionTracker.currentCell) {
|
||||
// Don't allow inline-edit of cells other than name for folders.
|
||||
// XXX - so so skeezy. Change this to look for NC:Name or some such.
|
||||
if (gSelectionTracker.currentItem.getAttribute("type") != NC_NS + "Bookmark" && i)
|
||||
return;
|
||||
// Don't allow editing of the root folder name
|
||||
if (gSelectionTracker.currentItem.id == "NC:BookmarksRoot")
|
||||
return;
|
||||
if (gSelectionTracker.clickCount == 1 && this.openClickCount > 1)
|
||||
gBookmarksShell.commands.editCell(this.tree.currentItem, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
treeOpen: function (aEvent)
|
||||
{
|
||||
if (this.isValidOpenEvent(aEvent)) {
|
||||
var rdfNode = this.findRDFNode(aEvent.target, true);
|
||||
if (rdfNode.getAttribute("container") != "true")
|
||||
this.open(aEvent, rdfNode);
|
||||
}
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Tree key events. This handles when to go into inline-edit mode for editable
|
||||
// cells, when to load a URL, etc.
|
||||
treeKeyPress: function (aEvent)
|
||||
{
|
||||
if (this.tree.selectedItems.length > 1) return;
|
||||
|
||||
/* Disabling Inline Edit
|
||||
if (aEvent.keyCode == 113 && aEvent.shiftKey) {
|
||||
const kNodeId = NODE_ID(this.tree.currentItem);
|
||||
if (this.resolveType(kNodeId) == NC_NS + "Bookmark")
|
||||
gBookmarksShell.commands.editCell (this.tree.currentItem, 1);
|
||||
}
|
||||
else */
|
||||
if (aEvent.keyCode == 113)
|
||||
goDoCommand("cmd_rename");
|
||||
else if (aEvent.keyCode == 13) // && this.tree.currentItem.firstChild.getAttribute("inline-edit") != "true")
|
||||
goDoCommand(aEvent.altKey ? "cmd_properties" : "cmd_open");
|
||||
},
|
||||
|
||||
selectFolderItem: function (aFolderURI, aItemURI, aAdditiveFlag)
|
||||
{
|
||||
var folder = document.getElementById(aFolderURI);
|
||||
var kids = ContentUtils.childByLocalName(folder, "treechildren");
|
||||
if (!kids) return;
|
||||
|
||||
var item = kids.firstChild;
|
||||
while (item) {
|
||||
if (item.id == aItemURI) break;
|
||||
item = item.nextSibling;
|
||||
}
|
||||
if (!item) return;
|
||||
|
||||
this.tree[aAdditiveFlag ? "addItemToSelection" : "selectItem"](item);
|
||||
},
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Command handling & Updating.
|
||||
controller: {
|
||||
supportsCommand: function (aCommand)
|
||||
{
|
||||
switch(aCommand) {
|
||||
case "cmd_undo":
|
||||
case "cmd_redo":
|
||||
return false;
|
||||
case "cmd_bm_cut":
|
||||
case "cmd_bm_copy":
|
||||
case "cmd_bm_paste":
|
||||
case "cmd_bm_delete":
|
||||
case "cmd_bm_selectAll":
|
||||
return true;
|
||||
case "cmd_open":
|
||||
case "cmd_openfolder":
|
||||
case "cmd_openfolderinnewwindow":
|
||||
case "cmd_newbookmark":
|
||||
case "cmd_newfolder":
|
||||
case "cmd_newseparator":
|
||||
case "cmd_find":
|
||||
case "cmd_properties":
|
||||
case "cmd_rename":
|
||||
case "cmd_setnewbookmarkfolder":
|
||||
case "cmd_setpersonaltoolbarfolder":
|
||||
case "cmd_setnewsearchfolder":
|
||||
case "cmd_import":
|
||||
case "cmd_export":
|
||||
case "cmd_bm_fileBookmark":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
isCommandEnabled: function (aCommand)
|
||||
{
|
||||
var numSelectedItems = gBookmarksShell.tree.selectedItems.length;
|
||||
var seln, firstSelected, folderType, bItemCountCorrect;
|
||||
switch(aCommand) {
|
||||
case "cmd_undo":
|
||||
case "cmd_redo":
|
||||
return false;
|
||||
case "cmd_bm_paste":
|
||||
return gBookmarksShell.canPaste();
|
||||
case "cmd_bm_cut":
|
||||
case "cmd_bm_copy":
|
||||
case "cmd_bm_delete":
|
||||
return numSelectedItems >= 1;
|
||||
case "cmd_bm_selectAll":
|
||||
return true;
|
||||
case "cmd_open":
|
||||
seln = gBookmarksShell.tree.selectedItems;
|
||||
return numSelectedItems == 1 && seln[0].getAttribute("type") == NC_NS + "Bookmark";
|
||||
case "cmd_openfolder":
|
||||
case "cmd_openfolderinnewwindow":
|
||||
seln = gBookmarksShell.tree.selectedItems;
|
||||
return numSelectedItems == 1 && seln[0].getAttribute("type") == NC_NS + "Folder";
|
||||
case "cmd_find":
|
||||
case "cmd_newbookmark":
|
||||
case "cmd_newfolder":
|
||||
case "cmd_newseparator":
|
||||
case "cmd_import":
|
||||
case "cmd_export":
|
||||
return true;
|
||||
case "cmd_properties":
|
||||
case "cmd_rename":
|
||||
seln = gBookmarksShell.tree.selectedItems;
|
||||
return numSelectedItems == 1 && seln[0].getAttribute("type") != NC_NS + "BookmarkSeparator";
|
||||
case "cmd_setnewbookmarkfolder":
|
||||
seln = gBookmarksShell.tree.selectedItems;
|
||||
firstSelected = seln.length ? seln[0] : gBookmarksShell.tree;
|
||||
folderType = firstSelected.getAttribute("type") == (NC_NS + "Folder");
|
||||
bItemCountCorrect = seln.length ? numSelectedItems == 1 : true;
|
||||
return bItemCountCorrect && !(NODE_ID(firstSelected) == "NC:NewBookmarkFolder") && folderType;
|
||||
case "cmd_setpersonaltoolbarfolder":
|
||||
seln = gBookmarksShell.tree.selectedItems;
|
||||
firstSelected = seln.length ? seln[0] : gBookmarksShell.tree;
|
||||
folderType = firstSelected.getAttribute("type") == (NC_NS + "Folder");
|
||||
bItemCountCorrect = seln.length ? numSelectedItems == 1 : true;
|
||||
return bItemCountCorrect && !(NODE_ID(firstSelected) == "NC:PersonalToolbarFolder") && folderType;
|
||||
case "cmd_setnewsearchfolder":
|
||||
seln = gBookmarksShell.tree.selectedItems;
|
||||
firstSelected = seln.length ? seln[0] : gBookmarksShell.tree;
|
||||
folderType = firstSelected.getAttribute("type") == (NC_NS + "Folder");
|
||||
bItemCountCorrect = seln.length ? numSelectedItems == 1 : true;
|
||||
return bItemCountCorrect == 1 && !(NODE_ID(firstSelected) == "NC:NewSearchFolder") && folderType;
|
||||
case "cmd_bm_fileBookmark":
|
||||
seln = gBookmarksShell.tree.selectedItems;
|
||||
return seln.length > 0;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
doCommand: function (aCommand)
|
||||
{
|
||||
switch(aCommand) {
|
||||
case "cmd_undo":
|
||||
case "cmd_redo":
|
||||
break;
|
||||
case "cmd_bm_paste":
|
||||
case "cmd_bm_copy":
|
||||
case "cmd_bm_cut":
|
||||
case "cmd_bm_delete":
|
||||
case "cmd_newbookmark":
|
||||
case "cmd_newfolder":
|
||||
case "cmd_newseparator":
|
||||
case "cmd_properties":
|
||||
case "cmd_rename":
|
||||
case "cmd_open":
|
||||
case "cmd_openfolder":
|
||||
case "cmd_openfolderinnewwindow":
|
||||
case "cmd_setnewbookmarkfolder":
|
||||
case "cmd_setpersonaltoolbarfolder":
|
||||
case "cmd_setnewsearchfolder":
|
||||
case "cmd_find":
|
||||
case "cmd_import":
|
||||
case "cmd_export":
|
||||
case "cmd_bm_fileBookmark":
|
||||
gBookmarksShell.execCommand(aCommand.substring("cmd_".length));
|
||||
break;
|
||||
case "cmd_bm_selectAll":
|
||||
gBookmarksShell.tree.selectAll();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
onEvent: function (aEvent)
|
||||
{
|
||||
switch (aEvent) {
|
||||
case "tree-select":
|
||||
this.onCommandUpdate();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
onCommandUpdate: function ()
|
||||
{
|
||||
var commands = ["cmd_properties", "cmd_rename", "cmd_bm_copy",
|
||||
"cmd_bm_paste", "cmd_bm_cut", "cmd_bm_delete",
|
||||
"cmd_setpersonaltoolbarfolder",
|
||||
"cmd_setnewbookmarkfolder",
|
||||
"cmd_setnewsearchfolder", "cmd_bm_fileBookmark",
|
||||
"cmd_openfolderinnewwindow", "cmd_openfolder"];
|
||||
for (var i = 0; i < commands.length; ++i)
|
||||
goUpdateCommand(commands[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var newFolderRDFObserver = {
|
||||
_newFolderURI: null,
|
||||
onAssert: function (aDS, aSource, aProperty, aValue)
|
||||
{
|
||||
try {
|
||||
var value = aValue.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
if (aDS.URI == "rdf:bookmarks" && aProperty.Value == RDF_NS + "type" &&
|
||||
value.Value == NC_NS + "Folder")
|
||||
this._newFolderURI = aSource.Value;
|
||||
}
|
||||
catch (e) {
|
||||
// Failures are OK, the value could be a literal instead of a resource.
|
||||
}
|
||||
},
|
||||
|
||||
onUnassert: function (aDS, aSource, aProperty, aTarget) { },
|
||||
onChange: function (aDS, aSource, aProperty, aOldTarget, aNewTarget) { },
|
||||
onMove: function (aDS, aOldSource, aNewSource, aProperty, aTarget) { },
|
||||
beginUpdateBatch: function (aDS) { },
|
||||
endUpdateBatch: function (aDS) { }
|
||||
};
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@netscape.com> (Original Author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
const BMARKS_CONTRACTID = "@mozilla.org/browser/bookmarks-service;1";
|
||||
const nsIBookmarksService = Components.interfaces.nsIBookmarksService;
|
||||
|
||||
var gOKButton;
|
||||
var gSearchField;
|
||||
function Startup()
|
||||
{
|
||||
var bundle = document.getElementById("bookmarksBundle");
|
||||
gOKButton = document.documentElement.getButton("accept");
|
||||
gOKButton.label = bundle.getString("search_button_label");
|
||||
gOKButton.disabled = true;
|
||||
gSearchField = document.getElementById("searchField");
|
||||
gSearchField.focus();
|
||||
}
|
||||
var gCreatingNewWindow = false;
|
||||
function find()
|
||||
{
|
||||
// Build up a find URI from the search fields and open a new window
|
||||
// rooted on the URI.
|
||||
var match = document.getElementById("matchList");
|
||||
var method = document.getElementById("methodList");
|
||||
var searchURI = "find:datasource=rdf:bookmarks"
|
||||
searchURI += "&match=" + match.selectedItem.value;
|
||||
searchURI += "&method=" + method.selectedItem.value;
|
||||
searchURI += "&text=" + escape(gSearchField.value);
|
||||
var bmWindow = findMostRecentWindow("bookmarks:searchresults", "chrome://communicator/content/bookmarks/bookmarks.xul", searchURI);
|
||||
|
||||
// Update the root of the tree if we're using an existing search window.
|
||||
if (!gCreatingNewWindow)
|
||||
bmWindow.document.getElementById("bookmarks-view").tree.setAttribute("ref", searchURI);
|
||||
|
||||
bmWindow.focus();
|
||||
|
||||
if (document.getElementById("saveQuery").checked == true)
|
||||
{
|
||||
var bundle = document.getElementById("bookmarksBundle");
|
||||
var findTitle = bundle.stringBundle.formatStringFromName(
|
||||
"ShortFindTitle", [gSearchField.value], 1);
|
||||
var bmks = Components.classes[BMARKS_CONTRACTID].getService(nsIBookmarksService);
|
||||
bmks.addBookmarkImmediately(searchURI, findTitle, bmks.BOOKMARK_FIND_TYPE, null);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function findMostRecentWindow(aType, aURI, aParam)
|
||||
{
|
||||
var WM = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
|
||||
WM = WM.QueryInterface(Components.interfaces.nsIWindowMediator);
|
||||
var topWindow = WM.getMostRecentWindow(aType);
|
||||
if (!topWindow) gCreatingNewWindow = true;
|
||||
return topWindow || openDialog("chrome://communicator/content/bookmarks/bookmarks.xul",
|
||||
"", "chrome,all,dialog=no", aParam);
|
||||
}
|
||||
|
||||
function doEnabling()
|
||||
{
|
||||
gOKButton.disabled = !gSearchField.value;
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<!-- -*- Mode: HTML; indent-tabs-mode: nil; -*- -->
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the Netscape Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/NPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The Original Code is mozilla.org code.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
Ben Goodger <ben@netscape.com> (Original Author)
|
||||
-->
|
||||
|
||||
<!--
|
||||
"Find Bookmarks" window
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://communicator/skin/"?>
|
||||
<!DOCTYPE window SYSTEM "chrome://communicator/locale/bookmarks/findBookmark.dtd">
|
||||
|
||||
<dialog id="findBookmarkWindow" style="width: 36em;"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="&findBookmark.title;"
|
||||
onload="Startup();"
|
||||
ondialogaccept="return find();">
|
||||
|
||||
<stringbundle id="bookmarksBundle" src="chrome://communicator/locale/bookmarks/bookmark.properties"/>
|
||||
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/bookmarksOverlay.js"/>
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/bookmarks/findBookmark.js"/>
|
||||
|
||||
<label value="&search.for.label;"/>
|
||||
<hbox align="center">
|
||||
<menulist id="matchList" class="menulist-toolbar">
|
||||
<menupopup>
|
||||
<menuitem value="http://home.netscape.com/NC-rdf#Name" label="&search.name.label;"/>
|
||||
<menuitem value="http://home.netscape.com/NC-rdf#URL" label="&search.url.label;"/>
|
||||
<menuitem value="http://home.netscape.com/NC-rdf#Description" label="&search.description.label;"/>
|
||||
<menuitem value="http://home.netscape.com/NC-rdf#ShortcutURL" label="&search.shortcut.label;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<menulist id="methodList" class="menulist-toolbar">
|
||||
<menupopup>
|
||||
<menuitem value="contains" label="&search.contains.label;"/>
|
||||
<menuitem value="startswith" label="&search.startswith.label;"/>
|
||||
<menuitem value="endswith" label="&search.endswith.label;"/>
|
||||
<menuitem value="is" label="&search.is.label;"/>
|
||||
<menuitem value="isnot" label="&search.isnot.label;"/>
|
||||
<menuitem value="doesntcontain" label="&search.doesntcontain.label;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<textbox id="searchField" flex="1" oninput="doEnabling();"/>
|
||||
</hbox>
|
||||
<checkbox id="saveQuery" label="&save.query.label;" />
|
||||
</dialog>
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
comm.jar:
|
||||
content/communicator/bookmarks/addBookmark.xul
|
||||
content/communicator/bookmarks/addBookmark.js
|
||||
content/communicator/bookmarks/bm-props.js
|
||||
content/communicator/bookmarks/bm-props.xul
|
||||
content/communicator/bookmarks/bookmarksDD.js
|
||||
content/communicator/bookmarks/bookmarks.xul
|
||||
content/communicator/bookmarks/bookmarks.js
|
||||
content/communicator/bookmarks/bookmarks.css
|
||||
content/communicator/bookmarks/bookmarks.xml
|
||||
content/communicator/bookmarks/bookmarksTree.js
|
||||
content/communicator/bookmarks/bookmarksOverlay.xul
|
||||
content/communicator/bookmarks/bookmarksOverlay.js
|
||||
content/communicator/bookmarks/bm-panel.xul
|
||||
content/communicator/bookmarks/bookmarksPanel.js
|
||||
content/communicator/bookmarks/findBookmark.js
|
||||
content/communicator/bookmarks/findBookmark.xul
|
||||
content/communicator/bookmarks/pref-bookmarks.xul
|
||||
content/communicator/bookmarks/oTest.xul
|
||||
|
||||
en-US.jar:
|
||||
locale/en-US/communicator/bookmarks/addBookmark.dtd (locale/en-US/addBookmark.dtd)
|
||||
locale/en-US/communicator/bookmarks/bm-props.dtd (locale/en-US/bm-props.dtd)
|
||||
locale/en-US/communicator/bookmarks/bookmarks.dtd (locale/en-US/bookmarks.dtd)
|
||||
locale/en-US/communicator/bookmarks/bookmark.properties (locale/en-US/bookmark.properties)
|
||||
locale/en-US/communicator/bookmarks/bookmarksOverlay.dtd (locale/en-US/bookmarksOverlay.dtd)
|
||||
locale/en-US/communicator/bookmarks/findBookmark.dtd (locale/en-US/findBookmark.dtd)
|
||||
locale/en-US/communicator/bookmarks/pref-bookmarks.dtd (locale/en-US/pref-bookmarks.dtd)
|
||||
@@ -1,4 +0,0 @@
|
||||
en-US:bm-find.dtd
|
||||
en-US:bm-props.dtd
|
||||
en-US:bookmarks.dtd
|
||||
en-US:bookmark.properties
|
||||
@@ -1,4 +0,0 @@
|
||||
bm-find.dtd
|
||||
bm-props.dtd
|
||||
bookmark.properties
|
||||
bookmarks.dtd
|
||||
@@ -1,46 +0,0 @@
|
||||
<!--
|
||||
- The contents of this file are subject to the Mozilla Public
|
||||
- License Version 1.1 (the "License"); you may not use this file
|
||||
- except in compliance with the License. You may obtain a copy of
|
||||
- the License at http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS
|
||||
- IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
- implied. See the License for the specific language governing
|
||||
- rights and limitations under the License.
|
||||
-
|
||||
- The Original Code is Mozilla Communicator.
|
||||
-
|
||||
- The Initial Developer of the Original Code is Netscape
|
||||
- Communications Corp. Portions created by Netscape Communications
|
||||
- Corp. are Copyright (C) 1999 Netscape Communications Corp. All
|
||||
- Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Ben Goodger <ben@netscape.com> (Original Author)
|
||||
-->
|
||||
|
||||
<!ENTITY newBookmark.title "Add Bookmark">
|
||||
<!ENTITY newbookmark.label "&brandShortName; will add a bookmark to this page.">
|
||||
<!ENTITY name.label "Name:">
|
||||
<!ENTITY name.accesskey "n">
|
||||
<!ENTITY url.label "Location:">
|
||||
<!ENTITY url.accesskey "l">
|
||||
<!ENTITY button.createin.label "Create In >>">
|
||||
<!ENTITY button.createin.accesskey "c">
|
||||
<!ENTITY button.createin2.label "Create In <<">
|
||||
<!ENTITY createin.label "Create in:">
|
||||
<!ENTITY createin.accesskey "i">
|
||||
<!ENTITY button.newfolder.label "New Folder...">
|
||||
<!ENTITY button.newfolder.accesskey "w">
|
||||
<!ENTITY alwayscreateinfolder.label "Don't show this dialog again">
|
||||
<!ENTITY alwayscreateinfolder.accesskey "a">
|
||||
<!ENTITY dontshowmessage.tooltip "When this option is selected, new Bookmarks will be added using the title provided by the page.">
|
||||
<!ENTITY button.defaultfolder.label "Use Default">
|
||||
<!ENTITY button.defaultfolder.accesskey "d">
|
||||
<!ENTITY selectFolder.label "Choose Folder">
|
||||
<!ENTITY addGroup.label "Bookmark this group of tabs">
|
||||
<!ENTITY addGroup.accesskey "B">
|
||||
|
||||
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
<!--
|
||||
- The contents of this file are subject to the Mozilla Public
|
||||
- License Version 1.1 (the "License"); you may not use this file
|
||||
- except in compliance with the License. You may obtain a copy of
|
||||
- the License at http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS
|
||||
- IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
- implied. See the License for the specific language governing
|
||||
- rights and limitations under the License.
|
||||
-
|
||||
- The Original Code is Mozilla Communicator.
|
||||
-
|
||||
- The Initial Developer of the Original Code is Netscape
|
||||
- Communications Corp. Portions created by Netscape Communications
|
||||
- Corp. are Copyright (C) 1999 Netscape Communications Corp. All
|
||||
- Rights Reserved.
|
||||
-
|
||||
- Contributor(s): Stephen Lamm <slamm@netscape.com>
|
||||
- Robert John Churchill <rjc@netscape.com>
|
||||
- Ben Goodger <ben@netscape.com>
|
||||
-->
|
||||
|
||||
<!ENTITY bookmarks.windowtitle.label "Properties for "**bm_title**"">
|
||||
|
||||
<!ENTITY generalInfo.label "Info">
|
||||
<!ENTITY generalInfo.accesskey "i">
|
||||
<!ENTITY generaldesc.label "&brandShortName; can remember the locations of sites on the Internet for you. Enter the site's name and location in the fields below, then select the site from the Bookmarks menu or your Bookmarks Sidebar tab to visit the site.">
|
||||
|
||||
<!ENTITY schedule.label "Schedule">
|
||||
<!ENTITY schedule.accesskey "s">
|
||||
<!ENTITY schedule.description "&brandShortName; can check this site for updates and notify you when one occurs. Use these settings to customize the schedule for this Bookmark.">
|
||||
<!ENTITY notification.label "Notify">
|
||||
<!ENTITY notification.accesskey "n">
|
||||
<!-- ICK. fix me -->
|
||||
<!ENTITY notification.description "&brandShortName; will notify you when this site changes. Use these settings to customize notification.">
|
||||
|
||||
<!ENTITY bookmarks.information.label "Information:">
|
||||
<!ENTITY bookmarks.name.label "Name:">
|
||||
<!ENTITY bookmarks.location.label "Location:">
|
||||
<!ENTITY bookmarks.shortcut.label "Keyword:">
|
||||
<!ENTITY bookmarks.description.label "Description:">
|
||||
|
||||
<!ENTITY checkforupdates.legend.label "Check this location for updates:">
|
||||
<!ENTITY when.label "When:">
|
||||
<!ENTITY from.label "from:">
|
||||
<!ENTITY to.label "to: ">
|
||||
<!ENTITY every.label "every">
|
||||
<!ENTITY minutes.label "minute(s)">
|
||||
<!ENTITY notifications.legend.label "Notification:">
|
||||
|
||||
<!ENTITY checknever.label "Never">
|
||||
<!ENTITY checkeveryday.label "Every day">
|
||||
<!ENTITY checkweekdays.label "Weekdays">
|
||||
<!ENTITY checkweekends.label "Weekends">
|
||||
<!ENTITY checkmondays.label "Mondays">
|
||||
<!ENTITY checktuesdays.label "Tuesdays">
|
||||
<!ENTITY checkwednesdays.label "Wednesdays">
|
||||
<!ENTITY checkthursdays.label "Thursdays">
|
||||
<!ENTITY checkfridays.label "Fridays">
|
||||
<!ENTITY checksaturdays.label "Saturdays">
|
||||
<!ENTITY checksundays.label "Sundays">
|
||||
|
||||
<!ENTITY midnight.label "Midnight">
|
||||
<!ENTITY AMone.label "1 AM">
|
||||
<!ENTITY AMtwo.label "2 AM">
|
||||
<!ENTITY AMthree.label "3 AM">
|
||||
<!ENTITY AMfour.label "4 AM">
|
||||
<!ENTITY AMfive.label "5 AM">
|
||||
<!ENTITY AMsix.label "6 AM">
|
||||
<!ENTITY AMseven.label "7 AM">
|
||||
<!ENTITY AMeight.label "8 AM">
|
||||
<!ENTITY AMnine.label "9 AM">
|
||||
<!ENTITY AMten.label "10 AM">
|
||||
<!ENTITY AMeleven.label "11 AM">
|
||||
<!ENTITY noon.label "Noon">
|
||||
<!ENTITY PMone.label "1 PM">
|
||||
<!ENTITY PMtwo.label "2 PM">
|
||||
<!ENTITY PMthree.label "3 PM">
|
||||
<!ENTITY PMfour.label "4 PM">
|
||||
<!ENTITY PMfive.label "5 PM">
|
||||
<!ENTITY PMsix.label "6 PM">
|
||||
<!ENTITY PMseven.label "7 PM">
|
||||
<!ENTITY PMeight.label "8 PM">
|
||||
<!ENTITY PMnine.label "9 PM">
|
||||
<!ENTITY PMten.label "10 PM">
|
||||
<!ENTITY PMeleven.label "11 PM">
|
||||
|
||||
<!ENTITY notification.icon.label "Change the bookmark's icon">
|
||||
<!ENTITY notification.sound.label "Play a sound">
|
||||
<!ENTITY notification.alert.label "Display an alert">
|
||||
<!ENTITY notification.window.label "Open web page in a new window">
|
||||
@@ -1,80 +0,0 @@
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
cmd_bm_open = Open
|
||||
cmd_bm_openfolder = Expand
|
||||
cmd_bm_openfolder2 = Collapse
|
||||
cmd_bm_find = Find a Bookmark...
|
||||
cmd_bm_cut = Cut
|
||||
cmd_bm_copy = Copy
|
||||
cmd_bm_paste = Paste
|
||||
cmd_bm_delete = Delete
|
||||
cmd_bm_selectAll = Select All
|
||||
cmd_bm_rename = Rename...
|
||||
cmd_bm_renamebookmark2 = Change Location...
|
||||
cmd_bm_properties = Properties
|
||||
cmd_bm_fileBookmark = File Bookmark(s)...
|
||||
|
||||
cmd_bm_openinnewwindow = Open in New Window
|
||||
cmd_bm_newfolder = New Folder...
|
||||
cmd_bm_newbookmark = New Bookmark...
|
||||
cmd_bm_newseparator = New Separator
|
||||
cmd_bm_setnewbookmarkfolder = Set as New Bookmark folder
|
||||
cmd_bm_setpersonaltoolbarfolder = Set as Personal Toolbar folder
|
||||
cmd_bm_setnewsearchfolder = Set as Saved Search Results folder
|
||||
|
||||
ile_newfolder = New Folder
|
||||
ile_newbookmark = New Bookmark
|
||||
newfolder_dialog_title = Create New Folder
|
||||
newfolder_dialog_msg = Create a New Folder named:
|
||||
|
||||
window_title = %folder_name% - Bookmarks
|
||||
search_results_title = Search Results
|
||||
|
||||
file_in = File in "%folder_name%"
|
||||
|
||||
bookmarks_root = Bookmarks for %user_name%
|
||||
status_foldercount = %num_items% object(s)
|
||||
|
||||
WebPageUpdated = The following web page has been updated:
|
||||
WebPageTitle = Title:
|
||||
WebPageURL = URL:
|
||||
WebPageAskDisplay = Would you like to display it?
|
||||
WebPageAskStopOption = Stop checking for updates on this web page
|
||||
|
||||
pleaseEnterALocation = Please enter a location
|
||||
pleaseEnterADuration = Please enter a duration.
|
||||
pleaseSelectANotification = Please enter at least one notification method.
|
||||
|
||||
SortMenuItem = Sorted by %NAME%
|
||||
|
||||
ShortFindTitle = Find: '%S'
|
||||
FindTitle = Find: %S %S '%S' in %S
|
||||
|
||||
ImportedIEFavorites = Imported IE Favorites
|
||||
ImportedIEStaticFavorites = Imported IE Favorites
|
||||
ImportedNetPositiveBookmarks = Imported NetPositive Bookmarks
|
||||
DefaultPersonalToolbarFolder = Personal Toolbar Folder
|
||||
|
||||
SelectImport = Import bookmark file:
|
||||
EnterExport = Export bookmark file:
|
||||
|
||||
search_button_label = Find
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
<!--
|
||||
- The contents of this file are subject to the Mozilla Public
|
||||
- License Version 1.1 (the "License"); you may not use this file
|
||||
- except in compliance with the License. You may obtain a copy of
|
||||
- the License at http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS
|
||||
- IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
- implied. See the License for the specific language governing
|
||||
- rights and limitations under the License.
|
||||
-
|
||||
- The Original Code is Mozilla Communicator.
|
||||
-
|
||||
- The Initial Developer of the Original Code is Netscape
|
||||
- Communications Corp. Portions created by Netscape Communications
|
||||
- Corp. are Copyright (C) 1999 Netscape Communications Corp. All
|
||||
- Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Stephen Lamm <slamm@netscape.com>
|
||||
- Blake Ross <blakeross@telocity.com>
|
||||
-->
|
||||
|
||||
<!-- extracted from ./bookmarks.xul -->
|
||||
<!ENTITY menuBar.tooltip "Menu Bar">
|
||||
<!ENTITY bookmarkToolbar.tooltip "Bookmark Toolbar">
|
||||
<!ENTITY menuitem.newBookmark.label "Bookmark">
|
||||
<!ENTITY command.newBookmark.accesskey "B">
|
||||
<!ENTITY menuitem.newFolder.label "Folder">
|
||||
<!ENTITY button.newFolder.label "New Folder">
|
||||
<!ENTITY command.newFolder.accesskey "F">
|
||||
<!ENTITY menuitem.newSeparator.label "Separator">
|
||||
<!ENTITY button.newSeparator.label "New Separator">
|
||||
<!ENTITY command.newSeparator.accesskey "S">
|
||||
<!ENTITY menuitem.import.label "Import...">
|
||||
<!ENTITY menuitem.import.accesskey "i">
|
||||
<!ENTITY menuitem.export.label "Export...">
|
||||
<!ENTITY menuitem.export.accesskey "e">
|
||||
<!ENTITY menuitem.find.label "Search Bookmarks...">
|
||||
<!ENTITY command.findBookmarks.label "Search...">
|
||||
<!ENTITY menuitem.find.accesskey "S">
|
||||
<!ENTITY edit.find.keybinding "f">
|
||||
<!ENTITY command.properties.label "Properties...">
|
||||
<!ENTITY command.properties.accesskey "r">
|
||||
<!ENTITY edit.properties.keybinding "i">
|
||||
<!ENTITY command.rename.label "Rename...">
|
||||
<!ENTITY command.delete.label "Delete">
|
||||
<!ENTITY command.fileBookmark.label "File Bookmark(s)...">
|
||||
<!ENTITY command.fileBookmark.accesskey "l">
|
||||
<!ENTITY command.addBookmark.label "Add...">
|
||||
<!ENTITY command.manageBookmarks.label "Manage">
|
||||
|
||||
|
||||
<!ENTITY menuitem.view.command.toolbar.label "Toolbar">
|
||||
<!ENTITY menuitem.view.command.toolbar.accesskey "t">
|
||||
<!ENTITY menuitem.view.unsorted.label "Unsorted">
|
||||
<!ENTITY menuitem.view.unsorted.accesskey "u">
|
||||
<!ENTITY menuitem.view.ascending.label "A > Z Sort Order">
|
||||
<!ENTITY menuitem.view.ascending.accesskey "a">
|
||||
<!ENTITY menuitem.view.descending.label "Z > A Sort Order">
|
||||
<!ENTITY menuitem.view.descending.accesskey "z">
|
||||
<!ENTITY menuitem.view.show_columns.label "Show columns">
|
||||
<!ENTITY menuitem.view.show_columns.accesskey "S">
|
||||
<!ENTITY menuitem.newbookmarkfolder.label "Set as New Bookmark Folder">
|
||||
<!ENTITY menuitem.newbookmarkfolder.accesskey "b">
|
||||
<!ENTITY menuitem.newinternetsearchfolder.label "Set as New Internet Search Folder">
|
||||
<!ENTITY menuitem.newinternetsearchfolder.accesskey "i">
|
||||
<!ENTITY menuitem.personaltoolbarfolder.label "Set as Personal Toolbar Folder">
|
||||
<!ENTITY menuitem.personaltoolbarfolder.accesskey "p">
|
||||
|
||||
<!ENTITY treecol.name.label "Name">
|
||||
<!ENTITY treecol.name.accesskey "n">
|
||||
<!ENTITY treecol.url.label "Location">
|
||||
<!ENTITY treecol.url.accesskey "l">
|
||||
<!ENTITY treecol.shortcut.label "Keyword">
|
||||
<!ENTITY treecol.shortcut.accesskey "k">
|
||||
<!ENTITY treecol.addedon.label "Added">
|
||||
<!ENTITY treecol.addedon.accesskey "a">
|
||||
<!ENTITY treecol.lastmod.label "Last Modified">
|
||||
<!ENTITY treecol.lastmod.accesskey "m">
|
||||
<!ENTITY treecol.lastvisit.label "Last Visited">
|
||||
<!ENTITY treecol.lastvisit.accesskey "b">
|
||||
<!ENTITY treecol.description.label "Description">
|
||||
<!ENTITY treecol.description.accesskey "d">
|
||||
|
||||
<!ENTITY bookmarksWindowTitle.label "Bookmark Manager">
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
<!ENTITY findABookmark.label "Find a Bookmark...">
|
||||
<!ENTITY findABookmark.accesskey "f">
|
||||
<!ENTITY newBookmark.label "New Bookmark...">
|
||||
<!ENTITY newBookmark.accesskey "n">
|
||||
<!ENTITY newFolder.label "New Folder...">
|
||||
<!ENTITY newFolder.accesskey "e">
|
||||
<!ENTITY newSeparator.label "New Separator">
|
||||
<!ENTITY newSeparator.accesskey "s">
|
||||
<!ENTITY setAsNewBookmarkFolder.label "Set as new Bookmark folder">
|
||||
<!ENTITY setAsNewBookmarkFolder.accesskey "b">
|
||||
<!ENTITY setAsNewSearchFolder.label "Set as new Search Results folder">
|
||||
<!ENTITY setAsNewSearchFolder.accesskey "r">
|
||||
<!ENTITY setAsNewToolbarFolder.label "Set as new Personal Toolbar folder">
|
||||
<!ENTITY setAsNewToolbarFolder.accesskey "p">
|
||||
<!ENTITY exportBookmarks.label "Export...">
|
||||
<!ENTITY exportBookmarks.accesskey "x">
|
||||
<!ENTITY importBookmarks.label "Import...">
|
||||
<!ENTITY importBookmarks.accesskey "i">
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
<!ENTITY search.name.label "name">
|
||||
<!ENTITY search.url.label "location">
|
||||
<!ENTITY search.shortcut.label "keyword">
|
||||
<!ENTITY search.description.label "description">
|
||||
<!ENTITY search.startswith.label "starts with">
|
||||
<!ENTITY search.endswith.label "ends with">
|
||||
<!ENTITY search.is.label "is">
|
||||
<!ENTITY search.isnot.label "is not">
|
||||
<!ENTITY search.contains.label "contains">
|
||||
<!ENTITY search.doesntcontain.label "doesn't contain">
|
||||
<!ENTITY save.query.label "Save query in bookmarks">
|
||||
<!ENTITY search.for.label "Find Bookmarks whose">
|
||||
<!ENTITY findBookmark.title "Find Bookmarks">
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
#!nmake
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
DEPTH = ..\..\..\..\..\..
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
<!ENTITY lHeader "Bookmarks">
|
||||
<!ENTITY filingBookmarks.label "Adding Bookmarks">
|
||||
<!ENTITY autoFile.label "&brandShortName; will ask you to choose a title and folder when adding a new Bookmark.">
|
||||
<!ENTITY enableAutoFile.label "Automatically set title and destination">
|
||||
<!ENTITY defaultFolder.label "By default, all new Bookmarks will be added into this folder:">
|
||||
<!ENTITY chooseDefaultFolder.label "Choose Folder...">
|
||||
<!ENTITY chooseDefaultFolder.accesskey "c">
|
||||
<!ENTITY extendedDataViews.label "Extended Data Views">
|
||||
<!ENTITY extendedDataExplanation.label "&brandShortName; can display some types of special data (e.g. local file folders and ftp directories) in the bookmarks window or menu as folders, rather than as normal links.">
|
||||
<!ENTITY showExtendedData.label "Show Extended Data as folders in the Bookmarks window and menu">
|
||||
<!ENTITY showExtendedData.accesskey "x">
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#!nmake
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is Mozilla Communicator client code, released
|
||||
# March 31, 1998.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape Communications
|
||||
# Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ..\..\..\..\..
|
||||
|
||||
DIRS = en-US
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
@@ -1,27 +0,0 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
|
||||
DIRS= locale
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
packages/core.jar:
|
||||
communicator/content/bookmarks/bm-find.js
|
||||
communicator/content/bookmarks/bm-find.xul
|
||||
communicator/content/bookmarks/bm-panel.js
|
||||
communicator/content/bookmarks/bm-panel.xul
|
||||
communicator/content/bookmarks/bm-props.js
|
||||
communicator/content/bookmarks/bm-props.xul
|
||||
communicator/content/bookmarks/bookmarks.js
|
||||
communicator/content/bookmarks/bookmarksDD.js
|
||||
communicator/content/bookmarks/bookmarks.xul
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
|
||||
@@ -1,162 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
<?xml-stylesheet href="chrome://communicator/skin/"?>
|
||||
<?xml-stylesheet href="chrome://communicator/content/bookmarks/oTest.css"?>
|
||||
|
||||
<?xul-overlay href="chrome://global/content/globalOverlay.xul"?>
|
||||
|
||||
<window id="bookmarksTreeTest" width="640" height="480"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
orient="vertical"
|
||||
onload="Startup();">
|
||||
|
||||
|
||||
<script>
|
||||
<![CDATA[
|
||||
var bookmarksBuilderObserver = {
|
||||
onToggleOpenState: function (aIndex) {
|
||||
dump("*** onToggleOpenState(" + aIndex + ");\n");
|
||||
},
|
||||
|
||||
onCycleHeader: function (aColID, aDOMElement) {
|
||||
dump("*** onCycleHeader(" + aColID + ", " + aDOMElement + ");\n");
|
||||
},
|
||||
|
||||
onCycleCell: function (aIndex, aColID) {
|
||||
dump("*** onCycleCell(" + aIndex + ", " + aColID + ");\n");
|
||||
},
|
||||
|
||||
onSelectionChanged: function () {
|
||||
dump("*** onSelectionChanged\n");
|
||||
},
|
||||
|
||||
isEditable: function (aIndex, aColID) {
|
||||
dump("*** isEditable(" + aIndex + ", " + aColID + ");\n");
|
||||
return aColID == "NameColumn";
|
||||
},
|
||||
|
||||
onSetCellText: function (aIndex, aColID, aValue) {
|
||||
dump("*** onSetCellText(" + aIndex + ", " + aColID + ", " + aValue + ");\n");
|
||||
},
|
||||
|
||||
onPerformAction: function (aAction) {
|
||||
dump("*** onPerformAction(" + aAction + ");\n");
|
||||
},
|
||||
|
||||
onPerformActionOnRow: function (aAction, aIndex) {
|
||||
dump("*** onPerformActionOnRow(" + aAction + ", " + aIndex + ");\n");
|
||||
},
|
||||
|
||||
onPerformActionOnCell: function (aAction, aIndex, aColID) {
|
||||
dump("*** onPerformActionOnCell(" + aAction + ", " + aIndex + ", " + aColID + ");\n");
|
||||
}
|
||||
};
|
||||
|
||||
function Startup()
|
||||
{
|
||||
var tree = document.getElementById("tree");
|
||||
var builder = tree.builder.QueryInterface(Components.interfaces.nsIXULTreeBuilder);
|
||||
builder.addObserver(bookmarksBuilderObserver);
|
||||
}
|
||||
|
||||
function getItemRect(aEvent)
|
||||
{
|
||||
var tree = document.getElementById("tree-proper");
|
||||
var obo = tree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);
|
||||
var row = { };
|
||||
var col = { };
|
||||
var elt = { };
|
||||
obo.getCellAt(aEvent.clientX, aEvent.clientY, row, col, elt);
|
||||
|
||||
var x = { };
|
||||
var y = { };
|
||||
var w = { };
|
||||
var h = { };
|
||||
var crp = { };
|
||||
obo.getCoordsForCellItem(row.value, col.value, elt.value, x, y, w, h, crp);
|
||||
dump("*** (x,y) = (" + x.value + "," + y.value + "); (w,h) = (" + w.value + "," + h.value + ");\n");
|
||||
}
|
||||
|
||||
const kRDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
|
||||
function createContextMenu (aEvent)
|
||||
{
|
||||
var tree = document.getElementById("tree-proper");
|
||||
var obo = tree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject);
|
||||
var row = { };
|
||||
var col = { };
|
||||
var elt = { };
|
||||
obo.getCellAt(aEvent.clientX, aEvent.clientY, row, col, elt);
|
||||
dump("*** row.value = " + row.value + "\n")
|
||||
|
||||
var treeBody = document.getElementById("tree");
|
||||
var rowResource = treeBody.builder.getResourceAtIndex(row.value);
|
||||
|
||||
const kRDFSvcContractID = "@mozilla.org/rdf/rdf-service;1";
|
||||
const kRDFSvcIID = Components.interfaces.nsIRDFService;
|
||||
const kRDFSvc = Components.classes[kRDFSvcContractID].getService(kRDFSvcIID);
|
||||
var database = treeBody.database;
|
||||
|
||||
const krType = kRDFSvc.GetResource(kRDF_NS + "type");
|
||||
var typeNode = kDatabase.GetTarget(rowResource, krType, true);
|
||||
typeNode = typeNode.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
dump("*** typeNode = " + typeNode.Value + "\n");
|
||||
aEvent.preventBubble();
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<popupset id="contextSet">
|
||||
<popup id="bookmarkContextMenu" onpopupshowing="createContextMenu(event);"/>
|
||||
</popupset>
|
||||
|
||||
<toolbox>
|
||||
<toolbar>
|
||||
<button class="button-toolbar-2" label="Foopy Noopy" oncommand="alert('hi');"/>
|
||||
</toolbar>
|
||||
</toolbox>
|
||||
|
||||
<stack>
|
||||
<button label="Foopy Noopy" flex="1"/>
|
||||
<bulletinboard flex="1">
|
||||
<textbox value="NerpNerp" left="10" top="50" onblur="this.setAttribute('hidden','true');"/>
|
||||
</bulletinboard>
|
||||
</stack>
|
||||
|
||||
<tree flex="1" flags="dont-test-empty" id="tree-proper">
|
||||
<treecols>
|
||||
<treecol id="NameColumn"
|
||||
class="treecol-header treecol-inset-header sortDirectionIndicator"
|
||||
flex="1"
|
||||
sort="rdf:http://home.netscape.com/NC-rdf#Name"
|
||||
sortActive="true"
|
||||
label="Name"
|
||||
persist="width hidden sortActive sortDirection"
|
||||
primary="true" />
|
||||
|
||||
<splitter class="tree-splitter"/>
|
||||
|
||||
<treecol id="URLColumn"
|
||||
class="treecol-header treecol-inset-header sortDirectionIndicator"
|
||||
flex="1"
|
||||
sort="rdf:http://home.netscape.com/NC-rdf#URL"
|
||||
label="Location"
|
||||
persist="width hidden sortActive sortDirection" />
|
||||
</treecols>
|
||||
|
||||
<treebody id="tree" datasources="rdf:bookmarks rdf:internetsearch rdf:files" flex="1"
|
||||
onclick="getItemRect(event);" ref="NC:BookmarksRoot">
|
||||
<template>
|
||||
<treerow uri="rdf:*" properties="rdf:http://www.w3.org/1999/02/22-rdf-syntax-ns#type rdf:http://home.netscape.com/NC-rdf#loading">
|
||||
<treecell ref="NameColumn"
|
||||
label="rdf:http://home.netscape.com/NC-rdf#Name" />
|
||||
|
||||
<treecell ref="URLColumn"
|
||||
label="rdf:http://home.netscape.com/NC-rdf#URL" />
|
||||
</treerow>
|
||||
</template>
|
||||
</treebody>
|
||||
</tree>
|
||||
|
||||
</window>
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
The contents of this file are subject to the Netscape Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/NPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The Original Code is Mozilla Communicator client code, released
|
||||
March 31, 1998.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1998-1999 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
-->
|
||||
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
|
||||
|
||||
<!DOCTYPE window [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://global/locale/brand.dtd" >
|
||||
%brandDTD;
|
||||
<!ENTITY % prefBookmarkDTD SYSTEM "chrome://communicator/locale/bookmarks/pref-bookmarks.dtd">
|
||||
%prefBookmarkDTD;
|
||||
]>
|
||||
|
||||
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="parent.initPanel('chrome://communicator/content/bookmarks/pref-bookmarks.xul');"
|
||||
headertitle="&lHeader;">
|
||||
|
||||
<script type="application/x-javascript">
|
||||
<![CDATA[
|
||||
var _elementIDs = ["enableAutoFile", "showExtendedData"];
|
||||
|
||||
var gCreateInFolder = "NC:NewBookmarkFolder";
|
||||
function Startup ()
|
||||
{
|
||||
const kDisplay = document.getElementById("defaultFolder");
|
||||
const kRDFSvcContractID = "@mozilla.org/rdf/rdf-service;1";
|
||||
const kRDFSvcIID = Components.interfaces.nsIRDFService;
|
||||
const kRDFSvc = Components.classes[kRDFSvcContractID].getService(kRDFSvcIID);
|
||||
const kBMDS = kRDFSvc.GetDataSource("rdf:bookmarks");
|
||||
const krDefaultFolder = kRDFSvc.GetResource("NC:NewBookmarkFolder");
|
||||
const krType = kRDFSvc.GetResource("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
|
||||
const krFolder = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#Folder");
|
||||
const isFolder = kBMDS.HasAssertion(krDefaultFolder, krType, krFolder, true);
|
||||
const krNameArc = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#Name");
|
||||
if (!isFolder) {
|
||||
const krRoot = kRDFSvc.GetResource("NC:BookmarksRoot");
|
||||
gCreateInFolder = "NC:BookmarksRoot";
|
||||
}
|
||||
var rName = kBMDS.GetTarget(isFolder ? krDefaultFolder : krRoot, krNameArc, true);
|
||||
rName = rName.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
||||
kDisplay.value = rName.Value;
|
||||
}
|
||||
|
||||
function chooseDefaultFolder ()
|
||||
{
|
||||
var rv = { selectedFolder: null };
|
||||
openDialog("chrome://communicator/content/bookmarks/addBookmark.xul", "",
|
||||
"centerscreen,chrome,dialog=no,resizable=no",
|
||||
null, null, gCreateInFolder, null, "selectFolder", rv);
|
||||
if (rv && rv.selectedFolder) {
|
||||
const kRDFSvcContractID = "@mozilla.org/rdf/rdf-service;1";
|
||||
const kRDFSvcIID = Components.interfaces.nsIRDFService;
|
||||
const kRDFSvc = Components.classes[kRDFSvcContractID].getService(kRDFSvcIID);
|
||||
const kBMDS = kRDFSvc.GetDataSource("rdf:bookmarks");
|
||||
const krDefaultFolder = kRDFSvc.GetResource(rv.selectedFolder);
|
||||
const krNameArc = kRDFSvc.GetResource("http://home.netscape.com/NC-rdf#Name");
|
||||
rName = kBMDS.GetTarget(krDefaultFolder, krNameArc, true);
|
||||
rName = rName.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
||||
document.getElementById("defaultFolder").value = rName.Value;
|
||||
}
|
||||
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<groupbox>
|
||||
<caption label="&filingBookmarks.label;"/>
|
||||
<description flex="1">&autoFile.label;</description>
|
||||
<hbox align="center">
|
||||
<checkbox id="enableAutoFile" label="&enableAutoFile.label;"
|
||||
preftype="bool" prefstring="browser.bookmarks.add_without_dialog"
|
||||
prefattribute="checked"/>
|
||||
</hbox>
|
||||
<separator/>
|
||||
<description flex="1">&defaultFolder.label;</description>
|
||||
<hbox align="center">
|
||||
<textbox readonly="true" id="defaultFolder" crop="right" flex="1"/>
|
||||
<button label="&chooseDefaultFolder.label;" accesskey="&chooseDefaultFolder.accesskey;"
|
||||
oncommand="chooseDefaultFolder();"
|
||||
id="browser.bookmarks.choosefolder" preftype="bool"
|
||||
prefstring="pref.browser.homepage.disable_button.choose_folder" prefattribute="disabled"/>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
|
||||
<groupbox>
|
||||
<caption label="&extendedDataViews.label;"/>
|
||||
<vbox align="start">
|
||||
<description>&extendedDataExplanation.label;</description>
|
||||
<checkbox id="showExtendedData" label="&showExtendedData.label;"
|
||||
accesskey="&showExtendedData.accesskey;"
|
||||
preftype="bool" prefstring="browser.bookmarks.show_extended_data"
|
||||
prefattribute="checked"/>
|
||||
</vbox>
|
||||
</groupbox>
|
||||
|
||||
|
||||
</page>
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = appcomps
|
||||
LIBRARY_NAME = bookmarks_s
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
rdf \
|
||||
appshell \
|
||||
widget \
|
||||
necko \
|
||||
nkcache \
|
||||
uconv \
|
||||
pref \
|
||||
dom \
|
||||
intl \
|
||||
webshell \
|
||||
windowwatcher \
|
||||
unicharutil \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = nsBookmarksService.cpp
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a
|
||||
# static lib.
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
MODULE=bookmarks
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
rdf \
|
||||
appshell \
|
||||
widget \
|
||||
necko \
|
||||
nkcache \
|
||||
uconv \
|
||||
pref \
|
||||
dom \
|
||||
intl \
|
||||
webshell \
|
||||
windowwatcher \
|
||||
unicharutil \
|
||||
$(NULL)
|
||||
|
||||
CPP_OBJS= \
|
||||
.\$(OBJDIR)\nsBookmarksService.obj \
|
||||
$(NULL)
|
||||
|
||||
LIBRARY_NAME=bookmarks_s
|
||||
|
||||
LCFLAGS = \
|
||||
$(LCFLAGS) \
|
||||
$(DEFINES) \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
libs:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,258 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef bookmarksservice___h___
|
||||
#define bookmarksservice___h___
|
||||
|
||||
#include "nsIRDFDataSource.h"
|
||||
#include "nsIRDFRemoteDataSource.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIRDFObserver.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIRDFNode.h"
|
||||
#include "nsIBookmarksService.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIFileSpec.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsIIOService.h"
|
||||
#include "nsICacheService.h"
|
||||
#include "nsICacheSession.h"
|
||||
#include "nsILocalFile.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef XP_MAC
|
||||
#include <Timer.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class nsBookmarksService : public nsIBookmarksService,
|
||||
public nsIRDFDataSource,
|
||||
public nsIRDFRemoteDataSource,
|
||||
public nsIStreamListener,
|
||||
public nsIRDFObserver,
|
||||
public nsIObserver,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
protected:
|
||||
nsIRDFDataSource* mInner;
|
||||
nsCOMPtr<nsIRDFResource> busyResource;
|
||||
nsCOMPtr<nsISupportsArray> mObservers;
|
||||
nsCOMPtr<nsIStringBundle> mBundle;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
nsCOMPtr<nsIIOService> mNetService;
|
||||
nsCOMPtr<nsICacheService> mCacheService;
|
||||
nsCOMPtr<nsICacheSession> mCacheSession;
|
||||
|
||||
PRUint32 htmlSize;
|
||||
PRInt32 mUpdateBatchNest;
|
||||
nsString mPersonalToolbarName;
|
||||
PRBool mBookmarksAvailable;
|
||||
PRBool mDirty;
|
||||
PRBool mBrowserIcons;
|
||||
PRBool busySchedule;
|
||||
|
||||
// System Bookmark parsing
|
||||
#ifdef XP_WIN
|
||||
// @param aDirectory - Favorites Folder to import from.
|
||||
// @param aParentResource - Folder into which to place imported
|
||||
// Favorites.
|
||||
nsresult ParseFavoritesFolder(nsIFile* aDirectory,
|
||||
nsIRDFResource* aParentResource);
|
||||
#elif XP_MAC
|
||||
PRBool mIEFavoritesAvailable;
|
||||
|
||||
nsresult ReadFavorites();
|
||||
#endif
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_MAC)
|
||||
void HandleSystemBookmarks(nsIRDFNode* aNode);
|
||||
#endif
|
||||
|
||||
static void FireTimer(nsITimer* aTimer, void* aClosure);
|
||||
nsresult ExamineBookmarkSchedule(nsIRDFResource *theBookmark, PRBool & examineFlag);
|
||||
nsresult GetBookmarkToPing(nsIRDFResource **theBookmark);
|
||||
|
||||
nsresult GetBookmarksFile(nsFileSpec* aResult);
|
||||
nsresult WriteBookmarks(nsFileSpec *bookmarksFile, nsIRDFDataSource *ds, nsIRDFResource *root);
|
||||
nsresult WriteBookmarksContainer(nsIRDFDataSource *ds, nsOutputFileStream& strm, nsIRDFResource *container, PRInt32 level, nsISupportsArray *parentArray);
|
||||
nsresult GetTextForNode(nsIRDFNode* aNode, nsString& aResult);
|
||||
nsresult GetSynthesizedType(nsIRDFResource *aNode, nsIRDFNode **aType);
|
||||
nsresult UpdateBookmarkLastModifiedDate(nsIRDFResource *aSource);
|
||||
nsresult WriteBookmarkProperties(nsIRDFDataSource *ds, nsOutputFileStream& strm, nsIRDFResource *node,
|
||||
nsIRDFResource *property, const char *htmlAttrib, PRBool isFirst);
|
||||
PRBool CanAccept(nsIRDFResource* aSource, nsIRDFResource* aProperty, nsIRDFNode* aTarget);
|
||||
|
||||
nsresult getArgumentN(nsISupportsArray *arguments, nsIRDFResource *res, PRInt32 offset, nsIRDFNode **argValue);
|
||||
nsresult insertBookmarkItem(nsIRDFResource *src, nsISupportsArray *aArguments, nsIRDFResource *objType);
|
||||
nsresult deleteBookmarkItem(nsIRDFResource *src, nsISupportsArray *aArguments, PRInt32 parentArgIndex, nsIRDFResource *objType);
|
||||
nsresult setFolderHint(nsIRDFResource *src, nsIRDFResource *objType);
|
||||
nsresult getFolderViaHint(nsIRDFResource *src, PRBool fallbackFlag, nsIRDFResource **folder);
|
||||
nsresult importBookmarks(nsISupportsArray *aArguments);
|
||||
nsresult exportBookmarks(nsISupportsArray *aArguments);
|
||||
nsresult ProcessCachedBookmarkIcon(nsIRDFResource* aSource, const PRUnichar *iconURL, nsIRDFNode** aTarget);
|
||||
nsresult getResourceFromLiteralNode(nsIRDFNode *node, nsIRDFResource **res);
|
||||
void AnnotateBookmarkSchedule(nsIRDFResource* aSource, PRBool scheduleFlag);
|
||||
nsresult IsBookmarkedInternal(nsIRDFResource *bookmark, PRBool *isBookmarkedFlag);
|
||||
|
||||
nsresult ChangeURL(nsIRDFResource* aOldURL,
|
||||
nsIRDFResource* aNewURL);
|
||||
|
||||
nsresult getLocaleString(const char *key, nsString &str);
|
||||
|
||||
nsresult CreateFolderWithDetails(const PRUnichar* aName,
|
||||
nsIRDFResource* aParentFolder, PRInt32 aIndex,
|
||||
nsIRDFResource** aResult, PRBool aIsGroup);
|
||||
|
||||
nsresult LoadBookmarks();
|
||||
nsresult initDatasource();
|
||||
|
||||
// nsIStreamObserver methods:
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
|
||||
// nsIStreamListener methods:
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
// nsIObserver methods:
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
public:
|
||||
nsBookmarksService();
|
||||
virtual ~nsBookmarksService();
|
||||
nsresult Init();
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIBookmarksService
|
||||
NS_DECL_NSIBOOKMARKSSERVICE
|
||||
|
||||
// nsIRDFDataSource
|
||||
NS_IMETHOD GetURI(char* *uri);
|
||||
|
||||
NS_IMETHOD GetSource(nsIRDFResource* property,
|
||||
nsIRDFNode* target,
|
||||
PRBool tv,
|
||||
nsIRDFResource** source) {
|
||||
return mInner->GetSource(property, target, tv, source);
|
||||
}
|
||||
|
||||
NS_IMETHOD GetSources(nsIRDFResource* property,
|
||||
nsIRDFNode* target,
|
||||
PRBool tv,
|
||||
nsISimpleEnumerator** sources) {
|
||||
return mInner->GetSources(property, target, tv, sources);
|
||||
}
|
||||
|
||||
NS_IMETHOD GetTarget(nsIRDFResource* source,
|
||||
nsIRDFResource* property,
|
||||
PRBool tv,
|
||||
nsIRDFNode** target);
|
||||
|
||||
NS_IMETHOD GetTargets(nsIRDFResource* source,
|
||||
nsIRDFResource* property,
|
||||
PRBool tv,
|
||||
nsISimpleEnumerator** targets) {
|
||||
return mInner->GetTargets(source, property, tv, targets);
|
||||
}
|
||||
|
||||
NS_IMETHOD Assert(nsIRDFResource* aSource,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFNode* aTarget,
|
||||
PRBool aTruthValue);
|
||||
|
||||
NS_IMETHOD Unassert(nsIRDFResource* aSource,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFNode* aTarget);
|
||||
|
||||
NS_IMETHOD Change(nsIRDFResource* aSource,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFNode* aOldTarget,
|
||||
nsIRDFNode* aNewTarget);
|
||||
|
||||
NS_IMETHOD Move(nsIRDFResource* aOldSource,
|
||||
nsIRDFResource* aNewSource,
|
||||
nsIRDFResource* aProperty,
|
||||
nsIRDFNode* aTarget);
|
||||
|
||||
NS_IMETHOD HasAssertion(nsIRDFResource* source,
|
||||
nsIRDFResource* property,
|
||||
nsIRDFNode* target,
|
||||
PRBool tv,
|
||||
PRBool* hasAssertion);
|
||||
|
||||
NS_IMETHOD AddObserver(nsIRDFObserver* aObserver);
|
||||
NS_IMETHOD RemoveObserver(nsIRDFObserver* aObserver);
|
||||
|
||||
NS_IMETHOD HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, PRBool *_retval);
|
||||
NS_IMETHOD HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, PRBool *_retval);
|
||||
|
||||
NS_IMETHOD ArcLabelsIn(nsIRDFNode* node,
|
||||
nsISimpleEnumerator** labels) {
|
||||
return mInner->ArcLabelsIn(node, labels);
|
||||
}
|
||||
|
||||
NS_IMETHOD ArcLabelsOut(nsIRDFResource* source,
|
||||
nsISimpleEnumerator** labels);
|
||||
|
||||
NS_IMETHOD GetAllResources(nsISimpleEnumerator** aResult);
|
||||
|
||||
NS_IMETHOD GetAllCommands(nsIRDFResource* source,
|
||||
nsIEnumerator/*<nsIRDFResource>*/** commands);
|
||||
|
||||
NS_IMETHOD GetAllCmds(nsIRDFResource* source,
|
||||
nsISimpleEnumerator/*<nsIRDFResource>*/** commands);
|
||||
|
||||
NS_IMETHOD IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/* aSources,
|
||||
nsIRDFResource* aCommand,
|
||||
nsISupportsArray/*<nsIRDFResource>*/* aArguments,
|
||||
PRBool* aResult);
|
||||
|
||||
NS_IMETHOD DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
|
||||
nsIRDFResource* aCommand,
|
||||
nsISupportsArray/*<nsIRDFResource>*/* aArguments);
|
||||
|
||||
// nsIRDFRemoteDataSource
|
||||
NS_DECL_NSIRDFREMOTEDATASOURCE
|
||||
|
||||
// nsIRDFObserver
|
||||
NS_DECL_NSIRDFOBSERVER
|
||||
};
|
||||
|
||||
#endif // bookmarksservice___h___
|
||||
@@ -1,121 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = appcomps
|
||||
LIBRARY_NAME = appcomps
|
||||
EXPORT_LIBRARY = 1
|
||||
IS_COMPONENT = 1
|
||||
MODULE_NAME = application
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
content \
|
||||
rdf \
|
||||
necko \
|
||||
necko2 \
|
||||
nkcache \
|
||||
intl \
|
||||
locale \
|
||||
mork \
|
||||
widget \
|
||||
dom \
|
||||
downloadmanager \
|
||||
alerts\
|
||||
uriloader \
|
||||
mimetype \
|
||||
webbrowserpersist \
|
||||
progressDlg \
|
||||
pref \
|
||||
docshell \
|
||||
webshell \
|
||||
appshell \
|
||||
history \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = nsModule.cpp
|
||||
|
||||
ifdef MOZ_LDAP_XPCOM
|
||||
REQUIRES += mozldap
|
||||
DEFINES += -DMOZ_LDAP_XPCOM
|
||||
endif
|
||||
|
||||
ifdef MOZ_PERF_METRICS
|
||||
EXTRA_DSO_LIBS += mozutil_s
|
||||
endif
|
||||
|
||||
SHARED_LIBRARY_LIBS = \
|
||||
$(DIST)/lib/$(LIB_PREFIX)autocomplete_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)bookmarks_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)directory_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)downloadmanager_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)history_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)appcompintl_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)related_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)search_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)urlbarhistory_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)timebomb_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)windowds_s.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../autocomplete/src \
|
||||
-I$(srcdir)/../bookmarks/src \
|
||||
-I$(srcdir)/../directory \
|
||||
-I$(srcdir)/../download-manager/src \
|
||||
-I$(srcdir)/../history/src \
|
||||
-I$(srcdir)/../related/src \
|
||||
-I$(srcdir)/../search/src \
|
||||
-I$(srcdir)/../timebomb \
|
||||
-I$(srcdir)/../urlbarhistory/src \
|
||||
-I$(srcdir)/../windowds \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
DEFINES += -DWIN32_LEAN_AND_MEAN
|
||||
SHARED_LIBRARY_LIBS += \
|
||||
$(DIST)/lib/$(LIB_PREFIX)urlwidgt_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)winhooks_s.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)alerts_s.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
OS_LIBS += ole32.lib shell32.lib
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(srcdir)/../urlwidget \
|
||||
-I$(srcdir)/../winhooks \
|
||||
-I$(srcdir)/../alerts/src \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
EXTRA_DSO_LDOPTS = \
|
||||
$(MOZ_COMPONENT_LIBS) \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(MOZ_UNICHARUTIL_LIBS) \
|
||||
$(MOZ_JS_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..
|
||||
MODULE=appcomps
|
||||
LIBRARY_NAME=appcomps
|
||||
MODULE_NAME=application
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
rdf \
|
||||
necko \
|
||||
necko2 \
|
||||
nkcache \
|
||||
intl \
|
||||
locale \
|
||||
mork \
|
||||
widget \
|
||||
dom \
|
||||
pref \
|
||||
docshell \
|
||||
downloadmanager \
|
||||
webshell \
|
||||
timebomb \
|
||||
bookmarks \
|
||||
content \
|
||||
history \
|
||||
search \
|
||||
alerts \
|
||||
progressDlg \
|
||||
related \
|
||||
urlbarhistory \
|
||||
uriloader \
|
||||
mimetype \
|
||||
mozldap \
|
||||
webbrowserpersist \
|
||||
appshell \
|
||||
$(NULL)
|
||||
|
||||
LCFLAGS = -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
!if !defined(DISABLE_LDAP)
|
||||
LCFLAGS = $(LCFLAGS) -DMOZ_LDAP_XPCOM
|
||||
!endif
|
||||
|
||||
CPP_OBJS= \
|
||||
.\$(OBJDIR)\nsModule.obj \
|
||||
$(NULL)
|
||||
|
||||
SUB_LIBRARIES= \
|
||||
$(DIST)\lib\autocomplete_s.lib \
|
||||
$(DIST)\lib\bookmarks_s.lib \
|
||||
$(DIST)\lib\directory_s.lib \
|
||||
$(DIST)\lib\downloadmanager_s.lib \
|
||||
$(DIST)\lib\history_s.lib \
|
||||
$(DIST)\lib\appcompintl_s.lib \
|
||||
$(DIST)\lib\related_s.lib \
|
||||
$(DIST)\lib\search_s.lib \
|
||||
$(DIST)\lib\alerts_s.lib \
|
||||
$(DIST)\lib\timebomb_s.lib \
|
||||
$(DIST)\lib\urlbarhistory_s.lib \
|
||||
$(DIST)\lib\urlwidgt_s.lib \
|
||||
$(DIST)\lib\windowds_s.lib \
|
||||
$(DIST)\lib\winhooks_s.lib \
|
||||
$(NULL)
|
||||
|
||||
WIN_LIBS = \
|
||||
ole32.lib \
|
||||
shell32.lib \
|
||||
$(NULL)
|
||||
|
||||
LLIBS= \
|
||||
$(DIST)\lib\js3250.lib \
|
||||
$(DIST)\lib\xpcom.lib \
|
||||
$(DIST)\lib\unicharutil_s.lib \
|
||||
$(LIBNSPR) \
|
||||
$(NULL)
|
||||
|
||||
INCS = $(INCS) \
|
||||
-I$(DEPTH)\xpfe\components\autocomplete\src \
|
||||
-I$(DEPTH)\xpfe\components\bookmarks\src \
|
||||
-I$(DEPTH)\xpfe\components\directory \
|
||||
-I$(DEPTH)\xpfe\components\download-manager\src \
|
||||
-I$(DEPTH)\xpfe\components\history\src \
|
||||
-I$(DEPTH)\xpfe\components\related\src \
|
||||
-I$(DEPTH)\xpfe\components\search\src \
|
||||
-I$(DEPTH)\xpfe\components\timebomb \
|
||||
-I$(DEPTH)\xpfe\components\urlbarhistory\src \
|
||||
-I$(DEPTH)\xpfe\components\urlwidget \
|
||||
-I$(DEPTH)\xpfe\components\windowds \
|
||||
-I$(DEPTH)\xpfe\components\winhooks \
|
||||
-I$(DEPTH)\xpfe\components\alerts\src \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
@@ -1,207 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the NPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#include "nsIGenericFactory.h"
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsAutoComplete.h"
|
||||
#include "nsBookmarksService.h"
|
||||
#include "nsDirectoryViewer.h"
|
||||
#include "nsDownloadManager.h"
|
||||
#include "nsDownloadProxy.h"
|
||||
#include "nsGlobalHistory.h"
|
||||
#include "rdf.h"
|
||||
#include "nsTimeBomb.h"
|
||||
#include "nsLocalSearchService.h"
|
||||
#include "nsInternetSearchService.h"
|
||||
#include "nsRelatedLinksHandlerImpl.h"
|
||||
#include "nsUrlbarHistory.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsCharsetMenu.h"
|
||||
#include "nsFontPackageHandler.h"
|
||||
#include "nsWindowDataSource.h"
|
||||
#if defined(XP_WIN)
|
||||
#include "nsAlertsService.h"
|
||||
#include "nsUrlWidget.h"
|
||||
#include "nsWindowsHooks.h"
|
||||
#endif // Windows
|
||||
#if defined(MOZ_LDAP_XPCOM)
|
||||
#include "nsLDAPAutoCompleteSession.h"
|
||||
#endif
|
||||
|
||||
// Factory constructors
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAutoCompleteItem)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAutoCompleteResults)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsBookmarksService, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsHTTPIndex, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDirectoryViewerFactory)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDownloadManager, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDownloadProxy)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGlobalHistory, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(LocalSearchDataSource, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(InternetSearchDataSource, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(RelatedLinksHandlerImpl, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimeBomb)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsUrlbarHistory)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFontPackageHandler)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWindowDataSource, Init)
|
||||
#if defined(XP_WIN)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAlertsService)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUrlWidget, Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindowsHooks)
|
||||
#endif // Windows
|
||||
#if defined(MOZ_LDAP_XPCOM)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsLDAPAutoCompleteSession)
|
||||
#endif
|
||||
|
||||
static NS_METHOD
|
||||
RegisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const char *componentType,
|
||||
const nsModuleComponentInfo *info)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICategoryManager> catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// add the MIME types layotu can handle to the handlers category.
|
||||
// this allows users of layout's viewers (the docshell for example)
|
||||
// to query the types of viewers layout can create.
|
||||
nsXPIDLCString previous;
|
||||
rv = catman->AddCategoryEntry("Gecko-Content-Viewers", "application/http-index-format",
|
||||
NS_DOCUMENT_LOADER_FACTORY_CONTRACTID_PREFIX "view;1?type=application/http-index-format",
|
||||
PR_TRUE,
|
||||
PR_TRUE,
|
||||
getter_Copies(previous));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = catman->AddCategoryEntry("Gecko-Content-Viewers", "application/http-index-format; x-view-type=view-source",
|
||||
NS_DOCUMENT_LOADER_FACTORY_CONTRACTID_PREFIX "view;1?type=application/http-index-format; x-view-type=view-source",
|
||||
PR_TRUE,
|
||||
PR_TRUE,
|
||||
getter_Copies(previous));
|
||||
|
||||
return rv;
|
||||
}
|
||||
static NS_METHOD
|
||||
UnregisterProc(nsIComponentManager *aCompMgr,
|
||||
nsIFile *aPath,
|
||||
const char *registryLocation,
|
||||
const nsModuleComponentInfo *info)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsICategoryManager> catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = catman->DeleteCategoryEntry("Gecko-Content-Viewers",
|
||||
"application/http-index-format", PR_TRUE);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = catman->DeleteCategoryEntry("Gecko-Content-Viewers",
|
||||
"application/http-index-format; x-view-type=view-source", PR_TRUE);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
static const nsModuleComponentInfo components[] = {
|
||||
{ "AutoComplete Search Results", NS_AUTOCOMPLETERESULTS_CID, NS_AUTOCOMPLETERESULTS_CONTRACTID,
|
||||
nsAutoCompleteResultsConstructor},
|
||||
{ "AutoComplete Search Item", NS_AUTOCOMPLETEITEM_CID, NS_AUTOCOMPLETEITEM_CONTRACTID,
|
||||
nsAutoCompleteItemConstructor},
|
||||
{ "Bookmarks", NS_BOOKMARKS_SERVICE_CID, NS_BOOKMARKS_SERVICE_CONTRACTID,
|
||||
nsBookmarksServiceConstructor },
|
||||
{ "Bookmarks", NS_BOOKMARKS_SERVICE_CID, NS_BOOKMARKS_DATASOURCE_CONTRACTID,
|
||||
nsBookmarksServiceConstructor },
|
||||
{ "Directory Viewer", NS_DIRECTORYVIEWERFACTORY_CID,
|
||||
NS_DOCUMENT_LOADER_FACTORY_CONTRACTID_PREFIX "view;1?type=application/http-index-format",
|
||||
nsDirectoryViewerFactoryConstructor, RegisterProc, UnregisterProc },
|
||||
{ "Directory Viewer", NS_DIRECTORYVIEWERFACTORY_CID,
|
||||
NS_DOCUMENT_LOADER_FACTORY_CONTRACTID_PREFIX "view;1?type=application/http-index-format; x-view-type=view-source",
|
||||
nsDirectoryViewerFactoryConstructor }, // Let the standard type do the registration
|
||||
{ "Directory Viewer", NS_HTTPINDEX_SERVICE_CID, NS_HTTPINDEX_SERVICE_CONTRACTID,
|
||||
nsHTTPIndexConstructor },
|
||||
{ "Directory Viewer", NS_HTTPINDEX_SERVICE_CID, NS_HTTPINDEX_DATASOURCE_CONTRACTID,
|
||||
nsHTTPIndexConstructor },
|
||||
{ "Download Manager", NS_DOWNLOADMANAGER_CID, NS_DOWNLOADMANAGER_CONTRACTID,
|
||||
nsDownloadManagerConstructor },
|
||||
{ "Download", NS_DOWNLOAD_CID, NS_DOWNLOAD_CONTRACTID,
|
||||
nsDownloadProxyConstructor },
|
||||
{ "Global History", NS_GLOBALHISTORY_CID, NS_GLOBALHISTORY_CONTRACTID,
|
||||
nsGlobalHistoryConstructor },
|
||||
{ "Global History", NS_GLOBALHISTORY_CID, NS_GLOBALHISTORY_DATASOURCE_CONTRACTID,
|
||||
nsGlobalHistoryConstructor },
|
||||
{ "Global History", NS_GLOBALHISTORY_CID, NS_GLOBALHISTORY_AUTOCOMPLETE_CONTRACTID,
|
||||
nsGlobalHistoryConstructor },
|
||||
{ "Local Search", NS_RDFFINDDATASOURCE_CID,
|
||||
NS_LOCALSEARCH_SERVICE_CONTRACTID, LocalSearchDataSourceConstructor },
|
||||
{ "Local Search", NS_RDFFINDDATASOURCE_CID,
|
||||
NS_LOCALSEARCH_DATASOURCE_CONTRACTID, LocalSearchDataSourceConstructor },
|
||||
{ "Internet Search", NS_RDFSEARCHDATASOURCE_CID,
|
||||
NS_INTERNETSEARCH_SERVICE_CONTRACTID, InternetSearchDataSourceConstructor },
|
||||
{ "Internet Search", NS_RDFSEARCHDATASOURCE_CID,
|
||||
NS_INTERNETSEARCH_DATASOURCE_CONTRACTID, InternetSearchDataSourceConstructor },
|
||||
{ "Related Links Handler", NS_RELATEDLINKSHANDLER_CID, NS_RELATEDLINKSHANDLER_CONTRACTID,
|
||||
RelatedLinksHandlerImplConstructor},
|
||||
{ "Netscape TimeBomb", NS_TIMEBOMB_CID, NS_TIMEBOMB_CONTRACTID, nsTimeBombConstructor},
|
||||
{ "nsUrlbarHistory", NS_URLBARHISTORY_CID,
|
||||
NS_URLBARHISTORY_CONTRACTID, nsUrlbarHistoryConstructor },
|
||||
{ "nsUrlbarHistory", NS_URLBARHISTORY_CID,
|
||||
NS_URLBARAUTOCOMPLETE_CONTRACTID, nsUrlbarHistoryConstructor },
|
||||
{ "nsCharsetMenu", NS_CHARSETMENU_CID,
|
||||
NS_RDF_DATASOURCE_CONTRACTID_PREFIX NS_CHARSETMENU_PID,
|
||||
NS_NewCharsetMenu },
|
||||
{ "nsFontPackageHandler", NS_FONTPACKAGEHANDLER_CID,
|
||||
"@mozilla.org/locale/default-font-package-handler;1",
|
||||
nsFontPackageHandlerConstructor },
|
||||
{ "nsWindowDataSource",
|
||||
NS_WINDOWDATASOURCE_CID,
|
||||
NS_RDF_DATASOURCE_CONTRACTID_PREFIX "window-mediator",
|
||||
nsWindowDataSourceConstructor },
|
||||
#if defined(XP_WIN)
|
||||
{ NS_IURLWIDGET_CLASSNAME, NS_IURLWIDGET_CID, NS_IURLWIDGET_CONTRACTID,
|
||||
nsUrlWidgetConstructor },
|
||||
{ "nsAlertsService", NS_ALERTSSERVICE_CID, NS_ALERTSERVICE_CONTRACTID, nsAlertsServiceConstructor},
|
||||
{ NS_IWINDOWSHOOKS_CLASSNAME, NS_IWINDOWSHOOKS_CID, NS_IWINDOWSHOOKS_CONTRACTID,
|
||||
nsWindowsHooksConstructor },
|
||||
#endif // Windows
|
||||
#if defined(MOZ_LDAP_XPCOM)
|
||||
{ "LDAP Autocomplete Session", NS_LDAPAUTOCOMPLETESESSION_CID,
|
||||
"@mozilla.org/autocompleteSession;1?type=ldap",
|
||||
nsLDAPAutoCompleteSessionConstructor },
|
||||
#endif
|
||||
};
|
||||
|
||||
NS_IMPL_NSGETMODULE(application, components)
|
||||
@@ -1,256 +0,0 @@
|
||||
?StartAssignment@?$nsMdbPtr@VnsIMdbThumb@@@@QAEPAPAVnsIMdbThumb@@XZ ; 18413
|
||||
??1?$nsMdbPtr@VnsIMdbRow@@@@QAE@XZ ; 18363
|
||||
?assign_assuming_AddRef@nsCOMPtr_base@@IAEXPAVnsISupports@@@Z ; 12166
|
||||
?ExamineBookmarkSchedule@nsBookmarksService@@IAEIPAVnsIRDFResource@@AAH@Z ; 10780
|
||||
?HasAssertion@nsBookmarksService@@UAGIPAVnsIRDFResource@@0PAVnsIRDFNode@@HPAH@Z ; 10016
|
||||
?HasAssertion@LocalSearchDataSource@@UAGIPAVnsIRDFResource@@0PAVnsIRDFNode@@HPAH@Z ; 9886
|
||||
?OpenDB@nsGlobalHistory@@IAEIXZ ; 9142
|
||||
?FindRow@nsGlobalHistory@@IAEIIPBDPAPAVnsIMdbRow@@@Z ; 9142
|
||||
?IsVisited@nsGlobalHistory@@UAGIPBDPAH@Z ; 8972
|
||||
?HasAssertion@InternetSearchDataSource@@UAGIPAVnsIRDFResource@@0PAVnsIRDFNode@@HPAH@Z ; 8845
|
||||
?WriteBookmarkProperties@nsBookmarksService@@IAEIPAVnsIRDFDataSource@@AAVnsOutputFileStream@@PAVnsIRDFResource@@2PBDH@Z ; 2484
|
||||
?HasAssertion@nsHTTPIndex@@UAGIPAVnsIRDFResource@@0PAVnsIRDFNode@@HPAH@Z ; 2326
|
||||
?AddRef@nsBookmarksService@@UAGKXZ ; 1466
|
||||
?Release@nsBookmarksService@@UAGKXZ ; 1459
|
||||
?isSearchURI@InternetSearchDataSource@@IAEHPAVnsIRDFResource@@@Z ; 1154
|
||||
?isSearchCategoryURI@InternetSearchDataSource@@IAEHPAVnsIRDFResource@@@Z ; 923
|
||||
?isSearchCategoryEngineURI@InternetSearchDataSource@@IAEHPAVnsIRDFResource@@@Z ; 921
|
||||
?OnAssert@nsBookmarksService@@UAGIPAVnsIRDFDataSource@@PAVnsIRDFResource@@1PAVnsIRDFNode@@@Z ; 911
|
||||
?isEngineURI@InternetSearchDataSource@@IAEHPAVnsIRDFResource@@@Z ; 686
|
||||
?GetTextForNode@nsBookmarksService@@IAEIPAVnsIRDFNode@@AAVnsString@@@Z ; 618
|
||||
?GetData@InternetSearchDataSource@@IAEIPBGPBDI1AAVnsString@@@Z ; 589
|
||||
?NotifyAssert@nsGlobalHistory@@IAEIPAVnsIRDFResource@@0PAVnsIRDFNode@@@Z ; 570
|
||||
?updateAtom@BookmarkParser@@IAEIPAVnsIRDFDataSource@@PAVnsIRDFResource@@1PAVnsIRDFNode@@PAH@Z ; 536
|
||||
?GetHostIndex@nsUrlbarHistory@@MAGIPBGPAH@Z ; 505
|
||||
?GetTarget@InternetSearchDataSource@@UAGIPAVnsIRDFResource@@0HPAPAVnsIRDFNode@@@Z ; 437
|
||||
?isSearchCommand@InternetSearchDataSource@@IAEHPAVnsIRDFResource@@@Z ; 437
|
||||
?QueryInterface@nsBookmarksService@@UAGIABUnsID@@PAPAX@Z ; 371
|
||||
?GetFindUriPrefix@nsGlobalHistory@@IAEXABUsearchQuery@@HAAVnsACString@@@Z ; 324
|
||||
?GetSources@nsBookmarksService@@UAGIPAVnsIRDFResource@@PAVnsIRDFNode@@HPAPAVnsISimpleEnumerator@@@Z ; 291
|
||||
?QueryInterface@InternetSearchDataSource@@UAGIABUnsID@@PAPAX@Z ; 262
|
||||
?ParseDate@BookmarkParser@@KAIPAVnsIRDFResource@@AAVnsString@@PAPAVnsIRDFNode@@@Z ; 256
|
||||
?AddRef@nsAutoCompleteResults@@UAGKXZ ; 249
|
||||
?HasArcOut@InternetSearchDataSource@@UAGIPAVnsIRDFResource@@0PAH@Z ; 248
|
||||
?FindData@InternetSearchDataSource@@IAEIPAVnsIRDFResource@@PAPAVnsIRDFLiteral@@@Z ; 247
|
||||
?GetTargets@InternetSearchDataSource@@UAGIPAVnsIRDFResource@@0HPAPAVnsISimpleEnumerator@@@Z ; 237
|
||||
?AddRef@InternetSearchDataSource@@UAGKXZ ; 234
|
||||
?GetTargets@LocalSearchDataSource@@UAGIPAVnsIRDFResource@@0HPAPAVnsISimpleEnumerator@@@Z ; 230
|
||||
?GetTargets@nsHTTPIndex@@UAGIPAVnsIRDFResource@@0HPAPAVnsISimpleEnumerator@@@Z ; 230
|
||||
?GetTargets@nsBookmarksService@@UAGIPAVnsIRDFResource@@0HPAPAVnsISimpleEnumerator@@@Z ; 230
|
||||
?Release@InternetSearchDataSource@@UAGKXZ ; 228
|
||||
?Release@nsAutoCompleteItem@@UAGKXZ ; 225
|
||||
?ArcLabelsIn@nsBookmarksService@@UAGIPAVnsIRDFNode@@PAPAVnsISimpleEnumerator@@@Z ; 181
|
||||
?ParseLiteral@BookmarkParser@@KAIPAVnsIRDFResource@@AAVnsString@@PAPAVnsIRDFNode@@@Z ; 167
|
||||
?GetTarget@nsHTTPIndex@@UAGIPAVnsIRDFResource@@0HPAPAVnsIRDFNode@@@Z ; 165
|
||||
??1searchTerm@@QAE@XZ ; 162
|
||||
??0searchTerm@@QAE@PBDI0I0I0I@Z ; 162
|
||||
?GetNow@nsGlobalHistory@@IAE_JXZ ; 162
|
||||
?getEOL@BookmarkParser@@IAEHPBDHH@Z ; 153
|
||||
?isWellknownContainerURI@nsHTTPIndex@@IAEHPAVnsIRDFResource@@@Z ; 153
|
||||
?GetDestination@nsHTTPIndex@@IAEPADPAVnsIRDFResource@@@Z ; 153
|
||||
?ProcessLine@BookmarkParser@@QAEIPAVnsIRDFContainer@@PAVnsIRDFResource@@AAV?$nsCOMPtr@VnsIRDFResource@@@@ABVnsString@@AAV5@AAH5@Z ; 152
|
||||
?DecodeBuffer@BookmarkParser@@QAEIAAVnsString@@PADI@Z ; 152
|
||||
?AddRef@nsGlobalHistory@@UAGKXZ ; 132
|
||||
?SetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IAB_J@Z ; 131
|
||||
?Release@nsGlobalHistory@@UAGKXZ ; 128
|
||||
?HasArcOut@nsBookmarksService@@UAGIPAVnsIRDFResource@@0PAH@Z ; 124
|
||||
?HasArcOut@nsHTTPIndex@@UAGIPAVnsIRDFResource@@0PAH@Z ; 122
|
||||
?HasArcOut@LocalSearchDataSource@@UAGIPAVnsIRDFResource@@0PAH@Z ; 122
|
||||
?QueryInterface@nsAutoCompleteItem@@UAGIABUnsID@@PAPAX@Z ; 118
|
||||
?OnUnassert@nsBookmarksService@@UAGIPAVnsIRDFDataSource@@PAVnsIRDFResource@@1PAVnsIRDFNode@@@Z ; 115
|
||||
?ParseResource@BookmarkParser@@KAIPAVnsIRDFResource@@AAVnsString@@PAPAVnsIRDFNode@@@Z ; 114
|
||||
?ParseBookmarkInfo@BookmarkParser@@IAEIPAUBookmarkField@1@HABVnsString@@ABV?$nsCOMPtr@VnsIRDFContainer@@@@PAVnsIRDFResource@@AAV?$nsCOMPtr@VnsIRDFResource@@@@@Z ; 114
|
||||
?Unescape@RelatedLinksStreamListener@@QAEIAAVnsString@@@Z ; 114
|
||||
?GetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IPA_J@Z ; 112
|
||||
?FireTimer@nsBookmarksService@@KAXPAVnsITimer@@PAX@Z ; 110
|
||||
?GetBookmarkToPing@nsBookmarksService@@IAEIPAPAVnsIRDFResource@@@Z ; 110
|
||||
?QueryInterface@nsGlobalHistory@@UAGIABUnsID@@PAPAX@Z ; 105
|
||||
?SetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IPBD@Z ; 100
|
||||
?ParseHeaderEnd@BookmarkParser@@IAEIABVnsString@@@Z ; 96
|
||||
?GetLastCharset@nsBookmarksService@@UAGIPBDPAPAG@Z ; 91
|
||||
?SetPageTitle@nsGlobalHistory@@UAGIPBDPBG@Z ; 89
|
||||
?GetItems@nsAutoCompleteResults@@UAGIPAPAVnsISupportsArray@@@Z ; 89
|
||||
?GetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IAAVnsAString@@@Z ; 87
|
||||
?SetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IPBG@Z ; 87
|
||||
?NotifyChange@nsGlobalHistory@@IAEIPAVnsIRDFResource@@0PAVnsIRDFNode@@1@Z ; 84
|
||||
?GetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IAAVnsACString@@@Z ; 82
|
||||
?AddPage@nsGlobalHistory@@UAGIPBD@Z ; 81
|
||||
?AddPageToDatabase@nsGlobalHistory@@IAEIPBD_J@Z ; 81
|
||||
?SaveLastPageVisited@nsGlobalHistory@@IAEIPBD@Z ; 81
|
||||
?do_GetService@@YA?BVnsGetServiceByCID@@ABUnsID@@PAI@Z ; 81
|
||||
?NotifyFindAssertions@nsGlobalHistory@@IAEIPAVnsIRDFResource@@PAVnsIMdbRow@@@Z ; 81
|
||||
?SetDirty@nsGlobalHistory@@IAEIXZ ; 81
|
||||
?GetTarget@nsBookmarksService@@UAGIPAVnsIRDFResource@@0HPAPAVnsIRDFNode@@@Z ; 78
|
||||
?QueryInterface@nsAutoCompleteResults@@UAGIABUnsID@@PAPAX@Z ; 76
|
||||
?Release@InternetSearchContext@@UAGKXZ ; 62
|
||||
?AddRef@InternetSearchContext@@UAGKXZ ; 62
|
||||
?GetValue@nsAutoCompleteItem@@UAGIPAPAG@Z ; 58
|
||||
?updateAtom@InternetSearchDataSource@@IAEIPAVnsIRDFDataSource@@PAVnsIRDFResource@@1PAVnsIRDFNode@@PAH@Z ; 58
|
||||
?SetURLToHiddenControl@nsUrlWidget@@UAGIPBDPAVnsIDOMWindowInternal@@@Z ; 50
|
||||
?FindInternetSearchResults@InternetSearchDataSource@@UAGIPBDPAH@Z ; 50
|
||||
?UpdateBookmarkLastVisitedDate@nsBookmarksService@@UAGIPBDPBG@Z ; 50
|
||||
?AddNewPageToDatabase@nsGlobalHistory@@IAEIPBD_JPAPAVnsIMdbRow@@@Z ; 50
|
||||
?do_GetIOService@@YA?BVnsGetServiceByCID@@PAI@Z ; 48
|
||||
?NS_NewURI@@YAIPAPAVnsIURI@@PBDPAV1@PAVnsIIOService@@@Z ; 48
|
||||
?ArcLabelsOut@nsBookmarksService@@UAGIPAVnsIRDFResource@@PAPAVnsISimpleEnumerator@@@Z ; 45
|
||||
?QueryInterface@InternetSearchContext@@UAGIABUnsID@@PAPAX@Z ; 44
|
||||
?ArcLabelsOut@nsHTTPIndex@@UAGIPAVnsIRDFResource@@PAPAVnsISimpleEnumerator@@@Z ; 43
|
||||
??_GnsArrayEnumerator@@UAEPAXI@Z ; 43
|
||||
?ArcLabelsOut@InternetSearchDataSource@@UAGIPAVnsIRDFResource@@PAPAVnsISimpleEnumerator@@@Z ; 43
|
||||
?ArcLabelsOut@LocalSearchDataSource@@UAGIPAVnsIRDFResource@@PAPAVnsISimpleEnumerator@@@Z ; 43
|
||||
?isSearchResultFiltered@InternetSearchDataSource@@IAEHABVnsString@@@Z ; 42
|
||||
?ConvertEntities@InternetSearchDataSource@@IAEIAAVnsString@@HHH@Z ; 42
|
||||
?OnDataAvailable@InternetSearchDataSource@@UAGIPAVnsIRequest@@PAVnsISupports@@PAVnsIInputStream@@II@Z ; 38
|
||||
?GetUnicodeDecoder@InternetSearchContext@@UAGIPAPAVnsIUnicodeDecoder@@@Z ; 38
|
||||
?AppendUnicodeBytes@InternetSearchContext@@UAGIPBGH@Z ; 37
|
||||
?GetDefaultItemIndex@nsAutoCompleteResults@@UAGIPAH@Z ; 36
|
||||
?AddRef@nsUrlbarHistory@@UAGKXZ ; 32
|
||||
?SetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IH@Z ; 31
|
||||
?GetRowValue@nsGlobalHistory@@IAEIPAVnsIMdbRow@@IPAH@Z ; 31
|
||||
?AddExistingPageToDatabase@nsGlobalHistory@@IAEIPAVnsIMdbRow@@_JPA_JPAH@Z ; 31
|
||||
?WriteBookmarksContainer@nsBookmarksService@@IAEIPAVnsIRDFDataSource@@AAVnsOutputFileStream@@PAVnsIRDFResource@@HPAVnsISupportsArray@@@Z ; 30
|
||||
?GetSearchEngineToPing@InternetSearchDataSource@@IAEIPAPAVnsIRDFResource@@AAVnsCString@@@Z ; 28
|
||||
?FireTimer@InternetSearchDataSource@@KAXPAVnsITimer@@PAX@Z ; 28
|
||||
?Flush@nsGlobalHistory@@UAGIXZ ; 26
|
||||
?SetValue@nsAutoCompleteItem@@UAGIPBG@Z ; 26
|
||||
?Commit@nsGlobalHistory@@IAEIW4eCommitType@1@@Z ; 26
|
||||
?Sync@nsGlobalHistory@@IAEXXZ ; 25
|
||||
?fireSyncTimer@nsGlobalHistory@@KAXPAVnsITimer@@PAX@Z ; 25
|
||||
??1RegistryEntry@@QAE@XZ ; 24
|
||||
??_EnsString@@UAEPAXI@Z ; 20
|
||||
?SetDefaultItemIndex@nsAutoCompleteResults@@UAGIH@Z ; 17
|
||||
?OnChange@nsBookmarksService@@UAGIPAVnsIRDFDataSource@@PAVnsIRDFResource@@1PAVnsIRDFNode@@2@Z ; 16
|
||||
?Release@nsUrlbarHistory@@UAGKXZ ; 16
|
||||
?Refresh@nsBookmarksService@@UAGIH@Z ; 16
|
||||
?Parse@BookmarkParser@@QAEIPAVnsIRDFResource@@0@Z ; 15
|
||||
??1nsAutoCompleteItem@@UAE@XZ ; 15
|
||||
??_EnsAutoCompleteItem@@UAEPAXI@Z ; 15
|
||||
??0nsAutoCompleteItem@@QAE@XZ ; 15
|
||||
?currentSetting@RegistryEntry@@QBE?AVnsCString@@XZ ; 13
|
||||
??BBoolRegistryEntry@@QAEPAXXZ ; 13
|
||||
??0RegistryEntry@@QAE@PAUHKEY__@@PBD11@Z ; 13
|
||||
?valueNameArg@RegistryEntry@@QBEPBDXZ ; 13
|
||||
??0nsAutoCompleteResults@@QAE@XZ ; 12
|
||||
??1nsAutoCompleteResults@@UAE@XZ ; 12
|
||||
?AddRef@nsHTTPIndex@@UAGKXZ ; 12
|
||||
?QueryInterface@nsUrlbarHistory@@UAGIABUnsID@@PAPAX@Z ; 12
|
||||
??_EnsAutoCompleteResults@@UAEPAXI@Z ; 12
|
||||
?GetTarget@LocalSearchDataSource@@UAGIPAVnsIRDFResource@@0HPAPAVnsIRDFNode@@@Z ; 12
|
||||
??0ProtocolRegistryEntry@@QAE@PBD@Z ; 11
|
||||
?Release@LocalSearchDataSource@@UAGKXZ ; 10
|
||||
?Release@nsWindowsHooks@@UAGKXZ ; 10
|
||||
?Release@nsUrlWidget@@UAGKXZ ; 10
|
||||
?QueryInterface@nsUrlWidget@@UAGIABUnsID@@PAPAX@Z ; 10
|
||||
?QueryInterface@nsWindowsHooks@@UAGIABUnsID@@PAPAX@Z ; 10
|
||||
?CheckItemAvailability@nsUrlbarHistory@@MAGIPBGPAVnsIAutoCompleteResults@@PAH@Z ; 9
|
||||
?AddObserver@InternetSearchDataSource@@UAGIPAVnsIRDFObserver@@@Z ; 8
|
||||
?SetParam@nsAutoCompleteItem@@UAGIPAVnsISupports@@@Z ; 8
|
||||
?Release@nsHTTPIndex@@UAGKXZ ; 8
|
||||
?NS_GetSpecialDirectory@@YAIPBDPAPAVnsIFile@@@Z ; 8
|
||||
?SaveEngineInfoIntoGraph@InternetSearchDataSource@@IAEIPAVnsIFile@@0PBG1H@Z ; 7
|
||||
?GetContextType@InternetSearchContext@@UAGIPAI@Z ; 6
|
||||
?MapEncoding@InternetSearchDataSource@@IAEIABVnsString@@AAV2@@Z ; 6
|
||||
??0InternetSearchContext@@QAE@IPAVnsIRDFResource@@0PAVnsIUnicodeDecoder@@PBG@Z ; 6
|
||||
??1InternetSearchContext@@UAE@XZ ; 6
|
||||
?OnStopRequest@InternetSearchDataSource@@UAGIPAVnsIRequest@@PAVnsISupports@@IPBG@Z ; 6
|
||||
?AddObserver@LocalSearchDataSource@@UAGIPAVnsIRDFObserver@@@Z ; 6
|
||||
?AddObserver@nsBookmarksService@@UAGIPAVnsIRDFObserver@@@Z ; 6
|
||||
?updateDataHintsInGraph@InternetSearchDataSource@@IAEIPAVnsIRDFResource@@PBG@Z ; 6
|
||||
??_EInternetSearchContext@@UAEPAXI@Z ; 6
|
||||
?ReadFileContents@InternetSearchDataSource@@IAEIABVnsFileSpec@@AAVnsString@@@Z ; 6
|
||||
?NS_OpenURI@@YAIPAPAVnsIChannel@@PAVnsIURI@@PAVnsIIOService@@PAVnsILoadGroup@@PAVnsIInterfaceRequestor@@I@Z ; 6
|
||||
??1FileTypeRegistryEntry@@QAE@XZ ; 6
|
||||
?NS_NewInternetSearchContext@@YAIIPAVnsIRDFResource@@0PAVnsIUnicodeDecoder@@PBGPAPAVnsIInternetSearchContext@@@Z ; 6
|
||||
?OnStartLookup@nsUrlbarHistory@@UAGIPBGPAVnsIAutoCompleteResults@@PAVnsIAutoCompleteListener@@@Z ; 5
|
||||
?VerifyAndCreateEntry@nsUrlbarHistory@@MAGIPBGPAGPAVnsIAutoCompleteResults@@@Z ; 5
|
||||
?GetBufferConst@InternetSearchContext@@UAGIPAPBG@Z ; 5
|
||||
?SearchCache@nsUrlbarHistory@@MAGIPBGPAVnsIAutoCompleteResults@@@Z ; 5
|
||||
?OnStartRequest@InternetSearchDataSource@@UAGIPAVnsIRequest@@PAVnsISupports@@@Z ; 4
|
||||
?Truncate@InternetSearchContext@@UAGIXZ ; 4
|
||||
?GetEngine@InternetSearchContext@@UAGIPAPAVnsIRDFResource@@@Z ; 4
|
||||
?AddObserver@nsHTTPIndex@@UAGIPAVnsIRDFObserver@@@Z ; 4
|
||||
?OnAutoComplete@nsUrlbarHistory@@UAGIPBGPAVnsIAutoCompleteResults@@PAVnsIAutoCompleteListener@@@Z ; 3
|
||||
?Release@nsTimeBomb@@UAGKXZ ; 3
|
||||
?DoSearch@InternetSearchDataSource@@IAEIPAVnsIRDFResource@@0ABVnsString@@1@Z ; 3
|
||||
?QueryInterface@nsHTTPIndex@@UAGIABUnsID@@PAPAX@Z ; 3
|
||||
?validateEngine@InternetSearchDataSource@@IAEIPAVnsIRDFResource@@@Z ; 3
|
||||
?QueryInterface@LocalSearchDataSource@@UAGIABUnsID@@PAPAX@Z ; 3
|
||||
?ParseHTML@InternetSearchDataSource@@IAEIPAVnsIURI@@PAVnsIRDFResource@@1PBG@Z ; 3
|
||||
?Stop@InternetSearchDataSource@@UAGIXZ ; 3
|
||||
?FindShortcut@nsBookmarksService@@UAGIPBGPAPAD@Z ; 3
|
||||
?GetBookmarksFile@nsBookmarksService@@IAEIPAVnsFileSpec@@@Z ; 3
|
||||
?GetSource@nsBookmarksService@@UAGIPAVnsIRDFResource@@PAVnsIRDFNode@@HPAPAV2@@Z ; 3
|
||||
?GetParent@InternetSearchContext@@UAGIPAPAVnsIRDFResource@@@Z ; 3
|
||||
?GetNumInterpretSections@InternetSearchDataSource@@IAEIPBGAAI@Z ; 3
|
||||
?GetSearchFolder@InternetSearchDataSource@@IAEIPAPAVnsIFile@@@Z ; 3
|
||||
?RememberLastSearchText@InternetSearchDataSource@@UAGIPBG@Z ; 3
|
||||
?ClearResults@InternetSearchDataSource@@UAGIH@Z ; 3
|
||||
?webSearchFinalize@InternetSearchDataSource@@IAEIPAVnsIChannel@@PAVnsIInternetSearchContext@@@Z ; 3
|
||||
?GetInputs@InternetSearchDataSource@@IAEIPBGAAVnsString@@ABV2@1@Z ; 3
|
||||
?Flush@nsBookmarksService@@UAGIXZ ; 2
|
||||
?CheckSettings@nsWindowsHooks@@UAGIPAVnsIDOMWindowInternal@@@Z ; 2
|
||||
?saveContents@InternetSearchDataSource@@IAEIPAVnsIChannel@@PAVnsIInternetSearchContext@@I@Z ; 2
|
||||
?RemoveObserver@InternetSearchDataSource@@UAGIPAVnsIRDFObserver@@@Z ; 2
|
||||
?NS_NewLoadGroup@@YAIPAPAVnsILoadGroup@@PAVnsIStreamObserver@@@Z ; 2
|
||||
?WriteBookmarks@nsBookmarksService@@IAEIPAVnsFileSpec@@PAVnsIRDFDataSource@@PAVnsIRDFResource@@@Z ; 2
|
||||
?getLocaleString@nsBookmarksService@@IAEIPBDAAVnsString@@@Z ; 2
|
||||
?GetBufferLength@InternetSearchContext@@UAGIPAH@Z ; 2
|
||||
??1nsWindowsHooksSettings@@UAE@XZ ; 1
|
||||
??1nsUrlbarHistory@@MAE@XZ ; 1
|
||||
??1nsUrlWidget@@UAE@XZ ; 1
|
||||
?Init@nsTimeBomb@@UAGIXZ ; 1
|
||||
?CreateAnonymousResource@BookmarkParser@@KAIPAV?$nsCOMPtr@VnsIRDFResource@@@@@Z ; 1
|
||||
?GetURI@nsBookmarksService@@UAGIPAPAD@Z ; 1
|
||||
?validateEngineNow@InternetSearchDataSource@@IAEIPAVnsIRDFResource@@@Z ; 1
|
||||
?DeferredInit@InternetSearchDataSource@@QAGIXZ ; 1
|
||||
??_EnsUrlbarHistory@@MAEPAXI@Z ; 1
|
||||
??0nsGlobalHistory@@QAE@XZ ; 1
|
||||
?GetURI@LocalSearchDataSource@@UAGIPAPAD@Z ; 1
|
||||
??0InternetSearchDataSource@@QAE@XZ ; 1
|
||||
?GetSettings@nsWindowsHooks@@MAGIPAPAVnsWindowsHooksSettings@@@Z ; 1
|
||||
?Init@nsBookmarksService@@QAEIXZ ; 1
|
||||
?Init@LocalSearchDataSource@@QAEIXZ ; 1
|
||||
?GetSearchEngineList@InternetSearchDataSource@@IAEIPAVnsIFile@@H@Z ; 1
|
||||
?Release@nsWindowsHooksSettings@@UAGKXZ ; 1
|
||||
?CreateTokens@nsGlobalHistory@@IAEIXZ ; 1
|
||||
??0nsUrlWidget@@QAE@XZ ; 1
|
||||
?AppendBytes@InternetSearchContext@@UAGIPBDH@Z ; 1
|
||||
?GetInt64ForPref@nsTimeBomb@@IAEIPBDPA_J@Z ; 1
|
||||
?Init@nsGlobalHistory@@QAGIXZ ; 1
|
||||
?Init@nsHTTPIndex@@QAEIXZ ; 1
|
||||
?GetFirstLaunch@nsTimeBomb@@UAGIPA_J@Z ; 1
|
||||
??0nsWindowsHooksSettings@@QAE@XZ ; 1
|
||||
??0BookmarkParser@@QAE@XZ ; 1
|
||||
??_EnsWindowsHooksSettings@@UAEPAXI@Z ; 1
|
||||
?GetURI@nsHTTPIndex@@UAGIPAPAD@Z ; 1
|
||||
??_GnsUrlWidget@@UAEPAXI@Z ; 1
|
||||
??_EnsWindowsHooks@@UAEPAXI@Z ; 1
|
||||
?CommonInit@nsHTTPIndex@@IAEIXZ ; 1
|
||||
?GetURI@InternetSearchDataSource@@UAGIPAPAD@Z ; 1
|
||||
??0nsUrlbarHistory@@QAE@XZ ; 1
|
||||
??1BookmarkParser@@QAE@XZ ; 1
|
||||
??1nsTimeBomb@@UAE@XZ ; 1
|
||||
??0nsHTTPIndex@@QAE@XZ ; 1
|
||||
?GetCategoryList@InternetSearchDataSource@@IAEIXZ ; 1
|
||||
??_GnsTimeBomb@@UAEPAXI@Z ; 1
|
||||
?GetCategoryDataSource@InternetSearchDataSource@@UAGIPAPAVnsIRDFDataSource@@@Z ; 1
|
||||
?CheckHostnameEntries@nsGlobalHistory@@IAEIXZ ; 1
|
||||
??0nsTimeBomb@@QAE@XZ ; 1
|
||||
_NSGetModule ; 1
|
||||
??0LocalSearchDataSource@@QAE@XZ ; 1
|
||||
?Init@InternetSearchDataSource@@QAGIXZ ; 1
|
||||
?ParseBookmarkSeparator@BookmarkParser@@IAEIABVnsString@@ABV?$nsCOMPtr@VnsIRDFContainer@@@@@Z ; 1
|
||||
?setFolderHint@BookmarkParser@@IAEIPAVnsIRDFResource@@0@Z ; 1
|
||||
?Init@BookmarkParser@@QAEIPAVnsFileSpec@@PAVnsIRDFDataSource@@ABVnsString@@@Z ; 1
|
||||
??1nsWindowsHooks@@UAE@XZ ; 1
|
||||
?GetEnabled@nsTimeBomb@@UAGIPAH@Z ; 1
|
||||
?QueryInterface@nsTimeBomb@@UAGIABUnsID@@PAPAX@Z ; 1
|
||||
?CheckWithUI@nsTimeBomb@@UAGIPAH@Z ; 1
|
||||
?AddSearchEngine@InternetSearchDataSource@@UAGIPBD0PBG1@Z ; 1
|
||||
?OpenExistingFile@nsGlobalHistory@@IAEIPAVnsIMdbFactory@@PBD@Z ; 1
|
||||
??0nsWindowsHooks@@QAE@XZ ; 1
|
||||
??0nsBookmarksService@@QAE@XZ ; 1
|
||||
?ParseMetaTag@BookmarkParser@@IAEIABVnsString@@PAPAVnsIUnicodeDecoder@@@Z ; 1
|
||||
?GetURI@nsGlobalHistory@@UAGIPAPAD@Z ; 1
|
||||
?ReadBookmarks@nsBookmarksService@@UAGIXZ ; 1
|
||||
?Init@nsUrlWidget@@QAEIXZ ; 1
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user