~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/content/html/content/src/nsHTMLSharedLeafElement.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Netscape Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/NPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is Mozilla Communicator client code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is 
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1998
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 *
 
25
 * Alternatively, the contents of this file may be used under the terms of
 
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
29
 * of those above. If you wish to allow use of your version of this file only
 
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
31
 * use your version of this file under the terms of the NPL, indicate your
 
32
 * decision by deleting the provisions above and replace them with the notice
 
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
34
 * the provisions above, a recipient may use your version of this file under
 
35
 * the terms of any one of the NPL, the GPL or the LGPL.
 
36
 *
 
37
 * ***** END LICENSE BLOCK ***** */
 
38
#include "nsIDOMHTMLEmbedElement.h"
 
39
#include "nsIDOMHTMLIsIndexElement.h"
 
40
#include "nsIDOMHTMLParamElement.h"
 
41
#include "nsIDOMHTMLBaseElement.h"
 
42
#include "nsIDOMEventReceiver.h"
 
43
#include "nsIHTMLContent.h"
 
44
#include "nsGenericHTMLElement.h"
 
45
#include "nsImageLoadingContent.h"
 
46
#include "nsHTMLAtoms.h"
 
47
#include "nsStyleConsts.h"
 
48
#include "nsIPresContext.h"
 
49
#include "nsRuleNode.h"
 
50
#include "nsMappedAttributes.h"
 
51
#include "nsStyleContext.h"
 
52
 
 
53
 
 
54
class nsHTMLSharedLeafElement : public nsGenericHTMLElement,
 
55
                                public nsImageLoadingContent,
 
56
                                public nsIDOMHTMLEmbedElement,
 
57
                                public nsIDOMHTMLIsIndexElement,
 
58
                                public nsIDOMHTMLParamElement,
 
59
                                public nsIDOMHTMLBaseElement
 
60
{
 
61
public:
 
62
  nsHTMLSharedLeafElement();
 
63
  virtual ~nsHTMLSharedLeafElement();
 
64
 
 
65
  // nsISupports
 
66
  NS_DECL_ISUPPORTS_INHERITED
 
67
 
 
68
  // nsIDOMNode
 
69
  NS_FORWARD_NSIDOMNODE_NO_CLONENODE(nsGenericHTMLElement::)
 
70
 
 
71
  // nsIDOMElement
 
72
  NS_FORWARD_NSIDOMELEMENT(nsGenericHTMLElement::)
 
73
 
 
74
  // nsIDOMHTMLElement
 
75
  NS_FORWARD_NSIDOMHTMLELEMENT(nsGenericHTMLElement::)
 
76
 
 
77
  // nsIDOMHTMLEmbedElement
 
78
  NS_DECL_NSIDOMHTMLEMBEDELEMENT
 
79
 
 
80
  // nsIDOMHTMLIsIndexElement
 
81
  NS_DECL_NSIDOMHTMLISINDEXELEMENT
 
82
 
 
83
  // nsIDOMHTMLParamElement Can't use the macro
 
84
  // NS_DECL_NSIDOMHTMLPARAMELEMENT since some of the methods in
 
85
  // nsIDOMHTMLParamElement clashes with methods in
 
86
  // nsIDOMHTMLEmbedElement
 
87
 
 
88
  NS_IMETHOD GetValue(nsAString& aValue);
 
89
  NS_IMETHOD SetValue(const nsAString& aValue);
 
90
  NS_IMETHOD GetValueType(nsAString& aValueType);
 
91
  NS_IMETHOD SetValueType(const nsAString& aValueType);
 
92
 
 
93
  // nsIDOMHTMLBaseElement
 
94
  NS_DECL_NSIDOMHTMLBASEELEMENT
 
95
 
 
96
  virtual PRBool ParseAttribute(nsIAtom* aAttribute,
 
97
                                const nsAString& aValue,
 
98
                                nsAttrValue& aResult);
 
99
  NS_IMETHOD AttributeToString(nsIAtom* aAttribute,
 
100
                               const nsHTMLValue& aValue,
 
101
                               nsAString& aResult) const;
 
102
  NS_IMETHOD GetAttributeMappingFunction(nsMapRuleToAttributesFunc& aMapRuleFunc) const;
 
103
  NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
 
104
 
 
105
protected:
 
106
  nsCString mType;
 
107
};
 
108
 
 
109
nsresult
 
110
NS_NewHTMLSharedLeafElement(nsIHTMLContent** aInstancePtrResult,
 
111
                            nsINodeInfo *aNodeInfo, PRBool aFromParser)
 
112
{
 
113
  NS_ENSURE_ARG_POINTER(aInstancePtrResult);
 
114
 
 
115
  nsHTMLSharedLeafElement* it = new nsHTMLSharedLeafElement();
 
116
 
 
117
  if (!it) {
 
118
    return NS_ERROR_OUT_OF_MEMORY;
 
119
  }
 
120
 
 
121
  nsresult rv = it->Init(aNodeInfo);
 
122
 
 
123
  if (NS_FAILED(rv)) {
 
124
    delete it;
 
125
 
 
126
    return rv;
 
127
  }
 
128
 
 
129
  *aInstancePtrResult = NS_STATIC_CAST(nsIHTMLContent *, it);
 
130
  NS_ADDREF(*aInstancePtrResult);
 
131
 
 
132
  return NS_OK;
 
133
}
 
134
 
 
135
 
 
136
nsHTMLSharedLeafElement::nsHTMLSharedLeafElement()
 
137
{
 
138
}
 
139
 
 
140
nsHTMLSharedLeafElement::~nsHTMLSharedLeafElement()
 
141
{
 
142
}
 
143
 
 
144
 
 
145
NS_IMPL_ADDREF_INHERITED(nsHTMLSharedLeafElement, nsGenericElement)
 
146
NS_IMPL_RELEASE_INHERITED(nsHTMLSharedLeafElement, nsGenericElement)
 
147
 
 
148
 
 
149
// QueryInterface implementation for nsHTMLSharedLeafElement
 
150
NS_HTML_CONTENT_INTERFACE_MAP_AMBIGOUS_BEGIN(nsHTMLSharedLeafElement,
 
151
                                             nsGenericHTMLElement,
 
152
                                             nsIDOMHTMLEmbedElement)
 
153
  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMHTMLElement, nsIDOMHTMLEmbedElement)
 
154
  NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLEmbedElement, embed)
 
155
  NS_INTERFACE_MAP_ENTRY_IF_TAG(imgIDecoderObserver, embed)
 
156
  NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIImageLoadingContent, embed)
 
157
  NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLParamElement, param)
 
158
  NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLIsIndexElement, isindex)
 
159
  NS_INTERFACE_MAP_ENTRY_IF_TAG(nsIDOMHTMLBaseElement, base)
 
160
 
 
161
  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLEmbedElement, embed)
 
162
  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLParamElement, param)
 
163
  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLWBRElement, wbr)
 
164
  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLIsIndexElement, isindex)
 
165
  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLBaseElement, base)
 
166
  NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO_IF_TAG(HTMLSpacerElement, spacer)
 
167
NS_HTML_CONTENT_INTERFACE_MAP_END
 
168
 
 
169
 
 
170
nsresult
 
171
nsHTMLSharedLeafElement::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
 
172
{
 
173
  NS_ENSURE_ARG_POINTER(aReturn);
 
174
  *aReturn = nsnull;
 
175
 
 
176
  nsHTMLSharedLeafElement* it = new nsHTMLSharedLeafElement();
 
177
 
 
178
  if (!it) {
 
179
    return NS_ERROR_OUT_OF_MEMORY;
 
180
  }
 
181
 
 
182
  nsCOMPtr<nsISupports> kungFuDeathGrip =
 
183
    NS_STATIC_CAST(nsIDOMHTMLEmbedElement *, it);
 
184
 
 
185
  nsresult rv = it->Init(mNodeInfo);
 
186
 
 
187
  if (NS_FAILED(rv))
 
188
    return rv;
 
189
 
 
190
  CopyInnerTo(it, aDeep);
 
191
 
 
192
  *aReturn = NS_STATIC_CAST(nsIDOMHTMLEmbedElement *, it);
 
193
 
 
194
  NS_ADDREF(*aReturn);
 
195
 
 
196
  return NS_OK;
 
197
}
 
198
 
 
199
/////////////////////////////////////////////
 
200
// Implement nsIDOMHTMLEmbedElement interface
 
201
NS_IMPL_STRING_ATTR(nsHTMLSharedLeafElement, Align, align)
 
202
NS_IMPL_STRING_ATTR(nsHTMLSharedLeafElement, Height, height)
 
203
NS_IMPL_STRING_ATTR(nsHTMLSharedLeafElement, Width, width)
 
204
NS_IMPL_STRING_ATTR(nsHTMLSharedLeafElement, Name, name)
 
205
//NS_IMPL_STRING_ATTR(nsHTMLSharedLeafElement, Type, type)
 
206
NS_IMPL_STRING_ATTR(nsHTMLSharedLeafElement, Src, src)
 
207
 
 
208
NS_IMETHODIMP
 
209
nsHTMLSharedLeafElement::GetType(nsAString& aType)
 
210
{
 
211
  if (mType.IsEmpty()) {
 
212
    GetAttr(kNameSpaceID_None, nsHTMLAtoms::type, aType);
 
213
  } else {
 
214
    CopyUTF8toUTF16(mType, aType);
 
215
  }
 
216
 
 
217
  return NS_OK;
 
218
}
 
219
 
 
220
NS_IMETHODIMP
 
221
nsHTMLSharedLeafElement::SetType(const nsAString& aType)
 
222
{
 
223
  CopyUTF16toUTF8(aType, mType);
 
224
 
 
225
  return NS_OK;
 
226
}
 
227
 
 
228
// nsIDOMHTMLParamElement
 
229
NS_IMPL_STRING_ATTR(nsHTMLSharedLeafElement, Value, value)
 
230
NS_IMPL_STRING_ATTR(nsHTMLSharedLeafElement, ValueType, valuetype)
 
231
 
 
232
// nsIDOMHTMLIsIndexElement
 
233
NS_IMPL_STRING_ATTR(nsHTMLSharedLeafElement, Prompt, prompt)
 
234
 
 
235
 
 
236
NS_IMETHODIMP
 
237
nsHTMLSharedLeafElement::GetForm(nsIDOMHTMLFormElement** aForm)
 
238
{
 
239
  *aForm = FindForm().get();
 
240
 
 
241
  return NS_OK;
 
242
}
 
243
 
 
244
// nsIDOMHTMLBaseElement
 
245
NS_IMPL_URI_ATTR(nsHTMLSharedLeafElement, Href, href)
 
246
NS_IMPL_STRING_ATTR(nsHTMLSharedLeafElement, Target, target)
 
247
 
 
248
// spacer element code
 
249
 
 
250
PRBool
 
251
nsHTMLSharedLeafElement::ParseAttribute(nsIAtom* aAttribute,
 
252
                                        const nsAString& aValue,
 
253
                                        nsAttrValue& aResult)
 
254
{
 
255
  if (mNodeInfo->Equals(nsHTMLAtoms::embed)) {
 
256
    if (aAttribute == nsHTMLAtoms::align) {
 
257
      return ParseAlignValue(aValue, aResult);
 
258
    }
 
259
    if (ParseImageAttribute(aAttribute, aValue, aResult)) {
 
260
      return PR_TRUE;
 
261
    }
 
262
  } else if (mNodeInfo->Equals(nsHTMLAtoms::spacer)) {
 
263
    if (aAttribute == nsHTMLAtoms::size) {
 
264
      return aResult.ParseIntWithBounds(aValue, 0);
 
265
    }
 
266
    if (aAttribute == nsHTMLAtoms::align) {
 
267
      return ParseAlignValue(aValue, aResult);
 
268
    }
 
269
    if (aAttribute == nsHTMLAtoms::width ||
 
270
        aAttribute == nsHTMLAtoms::height) {
 
271
      return aResult.ParseSpecialIntValue(aValue, PR_TRUE, PR_FALSE);
 
272
    }
 
273
  }
 
274
 
 
275
  return nsGenericHTMLElement::ParseAttribute(aAttribute, aValue, aResult);
 
276
}
 
277
 
 
278
NS_IMETHODIMP
 
279
nsHTMLSharedLeafElement::AttributeToString(nsIAtom* aAttribute,
 
280
                                           const nsHTMLValue& aValue,
 
281
                                           nsAString& aResult) const
 
282
{
 
283
  if (mNodeInfo->Equals(nsHTMLAtoms::embed)) {
 
284
    if (aAttribute == nsHTMLAtoms::align) {
 
285
      if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
 
286
        AlignValueToString(aValue, aResult);
 
287
        return NS_CONTENT_ATTR_HAS_VALUE;
 
288
      }
 
289
    }
 
290
  } else if (mNodeInfo->Equals(nsHTMLAtoms::spacer)) {
 
291
    if (aAttribute == nsHTMLAtoms::align) {
 
292
      if (eHTMLUnit_Enumerated == aValue.GetUnit()) {
 
293
        AlignValueToString(aValue, aResult);
 
294
        return NS_CONTENT_ATTR_HAS_VALUE;
 
295
      }
 
296
    }
 
297
  }
 
298
 
 
299
  return nsGenericHTMLElement::AttributeToString(aAttribute, aValue, aResult);
 
300
}
 
301
 
 
302
static void
 
303
SpacerMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
 
304
                            nsRuleData* aData)
 
305
{
 
306
  nsGenericHTMLElement::MapImageMarginAttributeInto(aAttributes, aData);
 
307
  nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aData);
 
308
 
 
309
  if (aData->mSID == eStyleStruct_Position) {
 
310
    nsHTMLValue value;
 
311
 
 
312
    const nsStyleDisplay* display = aData->mStyleContext->GetStyleDisplay();
 
313
 
 
314
    PRBool typeIsBlock = (display->mDisplay == NS_STYLE_DISPLAY_BLOCK);
 
315
 
 
316
    if (typeIsBlock) {
 
317
      // width: value
 
318
      if (aData->mPositionData->mWidth.GetUnit() == eCSSUnit_Null) {
 
319
        aAttributes->GetAttribute(nsHTMLAtoms::width, value);
 
320
        if (value.GetUnit() == eHTMLUnit_Integer) {
 
321
          aData->mPositionData->
 
322
            mWidth.SetFloatValue((float)value.GetIntValue(), eCSSUnit_Pixel);
 
323
        } else if (value.GetUnit() == eHTMLUnit_Percent) {
 
324
          aData->mPositionData->
 
325
            mWidth.SetPercentValue(value.GetPercentValue());
 
326
        }
 
327
      }
 
328
 
 
329
      // height: value
 
330
      if (aData->mPositionData->mHeight.GetUnit() == eCSSUnit_Null) {
 
331
        aAttributes->GetAttribute(nsHTMLAtoms::height, value);
 
332
        if (value.GetUnit() == eHTMLUnit_Integer) {
 
333
          aData->mPositionData->
 
334
            mHeight.SetFloatValue((float)value.GetIntValue(),
 
335
                                  eCSSUnit_Pixel);
 
336
        } else if (value.GetUnit() == eHTMLUnit_Percent) {
 
337
          aData->mPositionData->
 
338
            mHeight.SetPercentValue(value.GetPercentValue());
 
339
        }
 
340
      }
 
341
    } else {
 
342
      // size: value
 
343
      if (aData->mPositionData->mWidth.GetUnit() == eCSSUnit_Null) {
 
344
        aAttributes->GetAttribute(nsHTMLAtoms::size, value);
 
345
        if (value.GetUnit() == eHTMLUnit_Integer)
 
346
          aData->mPositionData->
 
347
            mWidth.SetFloatValue((float)value.GetIntValue(),
 
348
                                 eCSSUnit_Pixel);
 
349
      }
 
350
    }
 
351
  } else if (aData->mSID == eStyleStruct_Display) {
 
352
    nsHTMLValue value;
 
353
    aAttributes->GetAttribute(nsHTMLAtoms::align, value);
 
354
    if (value.GetUnit() == eHTMLUnit_Enumerated) {
 
355
      PRUint8 align = (PRUint8)(value.GetIntValue());
 
356
      if (aData->mDisplayData->mFloat.GetUnit() == eCSSUnit_Null) {
 
357
        if (align == NS_STYLE_TEXT_ALIGN_LEFT)
 
358
          aData->mDisplayData->mFloat.SetIntValue(NS_STYLE_FLOAT_LEFT,
 
359
                                                  eCSSUnit_Enumerated);
 
360
        else if (align == NS_STYLE_TEXT_ALIGN_RIGHT)
 
361
          aData->mDisplayData->mFloat.SetIntValue(NS_STYLE_FLOAT_RIGHT,
 
362
                                                  eCSSUnit_Enumerated);
 
363
      }
 
364
    }
 
365
 
 
366
    if (aData->mDisplayData->mDisplay == eCSSUnit_Null) {
 
367
      if (aAttributes->GetAttribute(nsHTMLAtoms::type, value) !=
 
368
          NS_CONTENT_ATTR_NOT_THERE &&
 
369
          eHTMLUnit_String == value.GetUnit()) {
 
370
        nsAutoString tmp;
 
371
        value.GetStringValue(tmp);
 
372
        if (tmp.EqualsIgnoreCase("line") ||
 
373
            tmp.EqualsIgnoreCase("vert") ||
 
374
            tmp.EqualsIgnoreCase("vertical") ||
 
375
            tmp.EqualsIgnoreCase("block")) {
 
376
          // This is not strictly 100% compatible: if the spacer is given
 
377
          // a width of zero then it is basically ignored.
 
378
          aData->mDisplayData->mDisplay = NS_STYLE_DISPLAY_BLOCK;
 
379
        }
 
380
      }
 
381
    }
 
382
  }
 
383
 
 
384
  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
 
385
}
 
386
 
 
387
static void
 
388
EmbedMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
 
389
                           nsRuleData* aData)
 
390
{
 
391
  if (!aData)
 
392
    return;
 
393
 
 
394
  nsGenericHTMLElement::MapImageBorderAttributeInto(aAttributes, aData);
 
395
  nsGenericHTMLElement::MapImageMarginAttributeInto(aAttributes, aData);
 
396
  nsGenericHTMLElement::MapImageSizeAttributesInto(aAttributes, aData);
 
397
  nsGenericHTMLElement::MapImageAlignAttributeInto(aAttributes, aData);
 
398
  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
 
399
}
 
400
 
 
401
 
 
402
static void
 
403
PlainMapAttributesIntoRule(const nsMappedAttributes* aAttributes,
 
404
                           nsRuleData* aData)
 
405
{
 
406
  nsGenericHTMLElement::MapCommonAttributesInto(aAttributes, aData);
 
407
}
 
408
 
 
409
 
 
410
NS_IMETHODIMP_(PRBool)
 
411
nsHTMLSharedLeafElement::IsAttributeMapped(const nsIAtom* aAttribute) const
 
412
{
 
413
  if (mNodeInfo->Equals(nsHTMLAtoms::embed)) {
 
414
    static const MappedAttributeEntry* const map[] = {
 
415
      sCommonAttributeMap,
 
416
      sImageMarginSizeAttributeMap,
 
417
      sImageAlignAttributeMap,
 
418
      sImageBorderAttributeMap
 
419
    };
 
420
    
 
421
    return FindAttributeDependence(aAttribute, map, NS_ARRAY_LENGTH(map));
 
422
  }
 
423
 
 
424
  if (mNodeInfo->Equals(nsHTMLAtoms::spacer)) {
 
425
    static const MappedAttributeEntry attributes[] = {
 
426
      // XXXldb This is just wrong.
 
427
      { &nsHTMLAtoms::usemap },
 
428
      { &nsHTMLAtoms::ismap },
 
429
      { &nsHTMLAtoms::align },
 
430
      { nsnull }
 
431
    };
 
432
 
 
433
    static const MappedAttributeEntry* const map[] = {
 
434
      attributes,
 
435
      sCommonAttributeMap,
 
436
      sImageMarginSizeAttributeMap,
 
437
      sImageBorderAttributeMap,
 
438
    };
 
439
    
 
440
    return FindAttributeDependence(aAttribute, map, NS_ARRAY_LENGTH(map));
 
441
  }
 
442
 
 
443
  return nsGenericHTMLElement::IsAttributeMapped(aAttribute);
 
444
}
 
445
 
 
446
NS_IMETHODIMP
 
447
nsHTMLSharedLeafElement::GetAttributeMappingFunction(nsMapRuleToAttributesFunc& aMapRuleFunc) const
 
448
{
 
449
  if (mNodeInfo->Equals(nsHTMLAtoms::embed)) {
 
450
    aMapRuleFunc = &EmbedMapAttributesIntoRule;
 
451
  } else if (mNodeInfo->Equals(nsHTMLAtoms::spacer)) {
 
452
    aMapRuleFunc = &SpacerMapAttributesIntoRule;
 
453
  } else {
 
454
    aMapRuleFunc = &PlainMapAttributesIntoRule;
 
455
  }
 
456
 
 
457
  return NS_OK;
 
458
}